33#define _USE_MATH_DEFINES
44#include < cmath>
55
6- #include < GL/gl.h>
7-
86#include < iostream>
97#include < utility>
8+ #include < stdexcept>
9+ #include < string>
10+ #include < map>
11+
12+ #include < SDL2/SDL.h>
13+ #include < SDL2/SDL_opengl.h>
14+ #include < GL/gl.h>
1015
1116#include " GameBoard.h"
1217#include " Player.h"
1318
19+ using std::make_pair;
1420using std::pair;
15- using std::sin;
16- using std::cos;
21+ using std::runtime_error;
22+ using std::string;
23+
24+ GLuint loadImageAsTexture (const string& name) {
25+ SDL_Surface* imageSurface = SDL_LoadBMP (name.c_str ());
26+ if (imageSurface == nullptr ) {
27+ string error = SDL_GetError ();
28+ SDL_ClearError ();
29+ throw runtime_error (" Unable to load image: " + error);
30+ }
31+ // Adapted from http://stackoverflow.com/questions/18934865/sdl2-with-opengl-texture-displaying-incorrectly
32+ GLuint texture;
33+ glGenTextures (1 , &texture);
34+ glBindTexture (GL_TEXTURE_2D, texture);
35+
36+ glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA, imageSurface->w , imageSurface->h , 0 , GL_BGR, GL_UNSIGNED_BYTE, imageSurface->pixels );
37+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
38+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
39+ glBindTexture (GL_TEXTURE_2D, 0 );
40+
41+ SDL_FreeSurface (imageSurface);
42+
43+ return texture;
44+ }
1745
1846inline pair<float , float > coordToScreen (const Coordinate& coord) {
47+ using std::sin;
48+ using std::cos;
1949 // TODO not magic numbers
2050 float scale = 0 .1f ;
2151 float angle = M_PI / 3 .f ;
@@ -24,40 +54,69 @@ inline pair<float, float> coordToScreen(const Coordinate& coord) {
2454 return std::make_pair (x, y);
2555}
2656
27- inline void glVertexCoord (const Coordinate& coord) {
57+ inline void vertexPair (const Coordinate& coord) {
2858 pair<float , float > screenCoord = coordToScreen (coord);
2959 glVertex2f (screenCoord.first , screenCoord.second );
3060}
3161
62+ inline void texCoordPair (const pair<float , float >& p) {
63+ glTexCoord2f (p.first / 2048 ., p.second / 2048 .);
64+ }
65+
66+ inline pair<float , float > averagePoint (const std::vector<pair<float , float >>& points) {
67+ pair<float , float > average;
68+ for (auto & it : points) {
69+ average.first += it.first ;
70+ average.second += it.second ;
71+ }
72+ average.first /= (float ) points.size ();
73+ average.second /= (float ) points.size ();
74+ return average;
75+ }
76+
3277void drawHex (const Coordinate& coord, const ResourceTile& tile) {
33- switch (tile.getType ()) {
34- case ResourceTile::WOOD:
35- glColor3d (133 . / 255 ., 66 . / 255 ., 11 . / 255 .);
36- break ;
37- case ResourceTile::SHEEP:
38- glColor3d (191 . / 255 ., 255 . / 255 ., 189 . / 255 .);
39- break ;
40- case ResourceTile::ORE:
41- glColor3d (59 . / 255 ., 59 . / 255 ., 69 . / 255 .);
42- break ;
43- case ResourceTile::BRICK:
44- glColor3d (196 . / 255 ., 0 , 0 );
45- break ;
46- case ResourceTile::GRAIN:
47- glColor3d (255 / 255 ., 249 / 255 ., 87 / 255 .);
48- break ;
49- case ResourceTile::DESERT:
50- glColor3d (255 . / 255 ., 220 . / 255 ., 138 . / 138 .);
51- break ;
78+ static GLuint tileTextures = loadImageAsTexture (" resources/tiles.bmp" );
79+ glBindTexture (GL_TEXTURE_2D, tileTextures);
80+ typedef std::vector<pair<float , float > > texCoordList;
81+ static const std::map<ResourceTile::Type, texCoordList> resourceTexCoords = {
82+ make_pair (ResourceTile::GRAIN, texCoordList { make_pair (377 , 73 ), make_pair (500 , 285 ),
83+ make_pair (380 , 502 ), make_pair (136 , 503 ), make_pair (10 , 288 ), make_pair (134 , 74 )}),
84+ make_pair (ResourceTile::SHEEP, texCoordList { make_pair (959 , 75 ), make_pair (1076 , 288 ),
85+ make_pair (955 , 503 ), make_pair (712 , 501 ), make_pair (586 , 289 ), make_pair (708 , 73 )}),
86+ make_pair (ResourceTile::WOOD, texCoordList { make_pair (1491 , 60 ), make_pair (1618 , 269 ),
87+ make_pair (1479 , 490 ), make_pair (1260 , 493 ), make_pair (1126 , 283 ), make_pair (1246 , 65 )}),
88+ make_pair (ResourceTile::ORE, texCoordList { make_pair (382 , 689 ), make_pair (506 , 898 ),
89+ make_pair (386 , 1118 ), make_pair (142 , 1120 ), make_pair (17 , 905 ), make_pair (138 , 691 )}),
90+ make_pair (ResourceTile::BRICK, texCoordList { make_pair (1496 , 690 ), make_pair (1617 , 908 ),
91+ make_pair (1490 , 1120 ), make_pair (1248 , 1118 ), make_pair (1124 , 898 ), make_pair (1250 , 688 )}),
92+ make_pair (ResourceTile::DESERT, texCoordList { make_pair (1496 , 690 ), make_pair (1617 , 908 ),
93+ make_pair (1490 , 1120 ), make_pair (1248 , 1118 ), make_pair (1124 , 898 ), make_pair (1250 , 688 )}),
94+ };
95+ static Coordinate adjacentCoordDiffs[] = {Coordinate (0 , 1 ), Coordinate (1 , 0 ), Coordinate (1 , -1 ), Coordinate (0 , -1 ), Coordinate (-1 , 0 ), Coordinate (-1 , 1 )};
96+ if (resourceTexCoords.find (tile.getType ()) == resourceTexCoords.end ()) {
97+ throw runtime_error (" Cannot draw this tile; it is invalid." );
5298 }
53- Coordinate adjacentCoordDiffs[] = { Coordinate ( 0 , 1 ), Coordinate ( 1 , 0 ), Coordinate ( 1 , - 1 ), Coordinate ( 0 , - 1 ), Coordinate (- 1 , 0 ), Coordinate (- 1 , 1 )} ;
99+ const texCoordList& texCoords = resourceTexCoords. at (tile. getType ()) ;
54100 glBegin (GL_TRIANGLE_FAN);
55- glVertexCoord (coord);
56- for (const Coordinate& diff : adjacentCoordDiffs) {
57- glVertexCoord (Coordinate (coord.first + diff.first , coord.second + diff.second ));
101+ texCoordPair (averagePoint (texCoords));
102+ vertexPair (coord);
103+ for (unsigned int i = 0 ; i < texCoords.size (); i++) {
104+ texCoordPair (texCoords[i]);
105+ Coordinate diff = adjacentCoordDiffs[i];
106+ vertexPair (Coordinate (coord.first + diff.first , coord.second + diff.second ));
58107 }
59- glVertexCoord (Coordinate (coord.first + adjacentCoordDiffs[0 ].first , coord.second + adjacentCoordDiffs[0 ].second ));
108+ texCoordPair (texCoords[0 ]);
109+ vertexPair (Coordinate (coord.first + adjacentCoordDiffs[0 ].first , coord.second + adjacentCoordDiffs[0 ].second ));
110+ glEnd ();
111+ /*
112+ glBegin(GL_QUADS);
113+ glTexCoord2f(0, 0); glVertex2f(0, 0);
114+ glTexCoord2f(1, 0); glVertex2f(1, 0);
115+ glTexCoord2f(1, 1); glVertex2f(1, 1);
116+ glTexCoord2f(0, 1); glVertex2f(0, 1);
60117 glEnd();
118+ */
119+ glBindTexture (GL_TEXTURE_2D, 0 );
61120}
62121
63122void renderBoard (const GameBoard& board, const Player& perspective) {
0 commit comments