diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 21 | ||||
-rw-r--r-- | src/map.cpp | 10 | ||||
-rw-r--r-- | src/map.h | 4 | ||||
-rw-r--r-- | src/mapview.cpp | 112 | ||||
-rw-r--r-- | src/mapview.h | 6 | ||||
-rw-r--r-- | src/mob.h | 2 | ||||
-rw-r--r-- | src/renderer.cpp | 197 | ||||
-rw-r--r-- | src/renderer.h | 1 |
8 files changed, 287 insertions, 66 deletions
diff --git a/src/main.cpp b/src/main.cpp index 2a1d9ea..ec485e7 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -30,20 +30,31 @@ int main() | |||
30 | glfwSwapInterval(1); | 30 | glfwSwapInterval(1); |
31 | glfwSetKeyCallback(window, key_callback); | 31 | glfwSetKeyCallback(window, key_callback); |
32 | 32 | ||
33 | Map* m = new Map("../maps/bigmap.txt"); | 33 | Map* m = new Map("../maps/embarass.txt"); |
34 | Map* m2 = new Map("../maps/cozy.txt"); | 34 | //Map* m2 = new Map("../maps/cozy.txt"); |
35 | 35 | ||
36 | m->setLeftMap(m2); | 36 | //m->setLeftMap(m2); |
37 | m2->setRightMap(m); | 37 | //m2->setRightMap(m); |
38 | 38 | ||
39 | curGameState = new MapView(m, 100, 100); | 39 | curGameState = new MapView(m, 100, 100); |
40 | 40 | ||
41 | Texture* buffer = createTexture(GAME_WIDTH, GAME_HEIGHT); | 41 | Texture* buffer = createTexture(GAME_WIDTH, GAME_HEIGHT); |
42 | 42 | ||
43 | double lastTime = glfwGetTime(); | ||
44 | double accum = 0.0; | ||
45 | |||
43 | while (!(quit || glfwWindowShouldClose(window))) | 46 | while (!(quit || glfwWindowShouldClose(window))) |
44 | { | 47 | { |
45 | // Tick! | 48 | // Tick! |
46 | curGameState->tick(); | 49 | accum += (glfwGetTime() - lastTime); |
50 | if (accum < 0) accum = 0; | ||
51 | while (accum > SECONDS_PER_FRAME) | ||
52 | { | ||
53 | curGameState->tick(); | ||
54 | accum -= SECONDS_PER_FRAME; | ||
55 | } | ||
56 | |||
57 | lastTime = glfwGetTime(); | ||
47 | 58 | ||
48 | // Do rendering | 59 | // Do rendering |
49 | curGameState->render(buffer); | 60 | curGameState->render(buffer); |
diff --git a/src/map.cpp b/src/map.cpp index cb1ce72..5f9e7bd 100644 --- a/src/map.cpp +++ b/src/map.cpp | |||
@@ -4,11 +4,15 @@ | |||
4 | Map::Map(char* filename) | 4 | Map::Map(char* filename) |
5 | { | 5 | { |
6 | FILE* f = fopen(filename, "r"); | 6 | FILE* f = fopen(filename, "r"); |
7 | m_mapdata = (char*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(char)); | ||
8 | 7 | ||
8 | m_mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | ||
9 | for (int i=0; i<MAP_HEIGHT-1; i++) | 9 | for (int i=0; i<MAP_HEIGHT-1; i++) |
10 | { | 10 | { |
11 | fread(m_mapdata + i*MAP_WIDTH, sizeof(char), MAP_WIDTH, f); | 11 | for (int j=0; j<MAP_WIDTH; j++) |
12 | { | ||
13 | fscanf(f, "%d,", &(m_mapdata[i*MAP_WIDTH + j])); | ||
14 | } | ||
15 | |||
12 | fgetc(f); | 16 | fgetc(f); |
13 | } | 17 | } |
14 | 18 | ||
@@ -24,7 +28,7 @@ Map::~Map() | |||
24 | free(m_title); | 28 | free(m_title); |
25 | } | 29 | } |
26 | 30 | ||
27 | const char* Map::mapdata() | 31 | const int* Map::mapdata() |
28 | { | 32 | { |
29 | return m_mapdata; | 33 | return m_mapdata; |
30 | } | 34 | } |
diff --git a/src/map.h b/src/map.h index 3c09238..2acce59 100644 --- a/src/map.h +++ b/src/map.h | |||
@@ -5,14 +5,14 @@ class Map { | |||
5 | public: | 5 | public: |
6 | Map(char* filename); | 6 | Map(char* filename); |
7 | ~Map(); | 7 | ~Map(); |
8 | const char* mapdata(); | 8 | const int* mapdata(); |
9 | const char* title(); | 9 | const char* title(); |
10 | Map* getLeftMap(); | 10 | Map* getLeftMap(); |
11 | Map* getRightMap(); | 11 | Map* getRightMap(); |
12 | void setLeftMap(Map* m); | 12 | void setLeftMap(Map* m); |
13 | void setRightMap(Map* m); | 13 | void setRightMap(Map* m); |
14 | private: | 14 | private: |
15 | char* m_mapdata; | 15 | int* m_mapdata; |
16 | char* m_title; | 16 | char* m_title; |
17 | Map* m_leftMap = 0; | 17 | Map* m_leftMap = 0; |
18 | Map* m_rightMap = 0; | 18 | Map* m_rightMap = 0; |
diff --git a/src/mapview.cpp b/src/mapview.cpp index f524d46..78dd770 100644 --- a/src/mapview.cpp +++ b/src/mapview.cpp | |||
@@ -17,7 +17,13 @@ MapView::MapView(Map* first, int x, int y) | |||
17 | player->x_accel = 0; | 17 | player->x_accel = 0; |
18 | player->y_accel = jump_gravity; | 18 | player->y_accel = jump_gravity; |
19 | player->w = 10; | 19 | player->w = 10; |
20 | player->h = 14; | 20 | player->h = 12; |
21 | player->onGround = false; | ||
22 | player->animFrame = 0; | ||
23 | |||
24 | bg = createTexture(GAME_WIDTH, GAME_HEIGHT); | ||
25 | chara = loadTextureFromBMP("../res/Starla.bmp"); | ||
26 | tiles = loadTextureFromBMP("../res/tiles2.bmp"); | ||
21 | 27 | ||
22 | loadMap(first); | 28 | loadMap(first); |
23 | } | 29 | } |
@@ -25,6 +31,8 @@ MapView::MapView(Map* first, int x, int y) | |||
25 | MapView::~MapView() | 31 | MapView::~MapView() |
26 | { | 32 | { |
27 | destroyTexture(bg); | 33 | destroyTexture(bg); |
34 | destroyTexture(chara); | ||
35 | destroyTexture(tiles); | ||
28 | 36 | ||
29 | delete player; | 37 | delete player; |
30 | } | 38 | } |
@@ -41,55 +49,47 @@ void MapView::loadMap(Map* m) | |||
41 | add_collision(-6, 0, GAME_WIDTH, left, (m->getLeftMap() == NULL) ? 1 : 2); | 49 | add_collision(-6, 0, GAME_WIDTH, left, (m->getLeftMap() == NULL) ? 1 : 2); |
42 | add_collision(GAME_WIDTH+6, 0, GAME_WIDTH, right, (m->getRightMap() == NULL) ? 1 : 2); | 50 | add_collision(GAME_WIDTH+6, 0, GAME_WIDTH, right, (m->getRightMap() == NULL) ? 1 : 2); |
43 | 51 | ||
44 | if (bg == NULL) | ||
45 | { | ||
46 | bg = createTexture(GAME_WIDTH, GAME_HEIGHT); | ||
47 | } | ||
48 | |||
49 | fillTexture(bg, NULL, 0, 0, 0); | 52 | fillTexture(bg, NULL, 0, 0, 0); |
50 | 53 | ||
51 | const char* mapbuf = m->mapdata(); | 54 | const int* mapbuf = m->mapdata(); |
52 | 55 | ||
53 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) | 56 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) |
54 | { | 57 | { |
55 | int x = i % MAP_WIDTH; | 58 | int x = i % MAP_WIDTH; |
56 | int y = i / MAP_WIDTH; | 59 | int y = i / MAP_WIDTH; |
57 | Rectangle dst(x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); | 60 | Rectangle dst(x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); |
58 | //Rectangle src; | 61 | Rectangle src(mapbuf[i]%8*TILE_WIDTH, mapbuf[i]/8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); |
59 | 62 | ||
60 | switch (mapbuf[i]) | 63 | if (mapbuf[i] > 0) |
61 | { | 64 | { |
62 | case ' ': break; | 65 | blitTexture(tiles, bg, &src, &dst); |
63 | case 'X': fillTexture(bg, &dst, 255, 85, 85); break; | 66 | } |
64 | case 'P': fillTexture(bg, &dst, 85, 255, 255); break; | ||
65 | } | ||
66 | |||
67 | //blitTexture(tiles, bg, &src, &dst); | 67 | //blitTexture(tiles, bg, &src, &dst); |
68 | 68 | ||
69 | if (mapbuf[i] == 'X') | 69 | if ((mapbuf[i] > 0) && (!((mapbuf[i] >= 5) && (mapbuf[i] <= 7)))) |
70 | { | 70 | { |
71 | if ((x != 0) && (mapbuf[i-1] != 'X')) | 71 | //if ((x != 0) && (mapbuf[i-1] != 'X')) |
72 | { | 72 | { |
73 | add_collision(x*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, right, 0); | 73 | add_collision(x*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, right, 0); |
74 | } | 74 | } |
75 | 75 | ||
76 | if ((x != 39) && (mapbuf[i+1] != 'X')) | 76 | //if ((x != 39) && (mapbuf[i+1] != 'X')) |
77 | { | 77 | { |
78 | add_collision((x+1)*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, left, 0); | 78 | add_collision((x+1)*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, left, 0); |
79 | } | 79 | } |
80 | 80 | ||
81 | if ((y != 0) && (mapbuf[i-MAP_WIDTH] != 'X')) | 81 | //if ((y != 0) && (mapbuf[i-MAP_WIDTH] != 'X')) |
82 | { | 82 | { |
83 | add_collision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, down, 0); | 83 | add_collision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, down, 0); |
84 | } | 84 | } |
85 | 85 | ||
86 | if ((y != 23) && (mapbuf[i+MAP_WIDTH] != 'X')) | 86 | //if ((y != 23) && (mapbuf[i+MAP_WIDTH] != 'X')) |
87 | { | 87 | { |
88 | add_collision((y+1)*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, up, 0); | 88 | add_collision((y+1)*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, up, 0); |
89 | } | 89 | } |
90 | } else if (mapbuf[i] == 'P') | 90 | } else if ((mapbuf[i] >= 5) && (mapbuf[i] <= 7)) |
91 | { | 91 | { |
92 | add_collision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, down, 0); | 92 | add_collision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, down, 3); |
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
@@ -112,16 +112,38 @@ void MapView::input(int key, int action) | |||
112 | { | 112 | { |
113 | switch (key) | 113 | switch (key) |
114 | { | 114 | { |
115 | case GLFW_KEY_LEFT: holding_left = true; break; | 115 | case GLFW_KEY_LEFT: |
116 | case GLFW_KEY_RIGHT: holding_right = true; break; | 116 | holding_left = true; |
117 | case GLFW_KEY_UP: player->y_vel = jump_velocity; break; | 117 | break; |
118 | case GLFW_KEY_RIGHT: | ||
119 | holding_right = true; | ||
120 | break; | ||
121 | case GLFW_KEY_UP: | ||
122 | if (player->onGround) | ||
123 | { | ||
124 | player->y_vel = jump_velocity; | ||
125 | player->onGround = false; | ||
126 | } | ||
127 | break; | ||
128 | case GLFW_KEY_DOWN: | ||
129 | holding_down = true; | ||
130 | break; | ||
118 | } | 131 | } |
119 | } else if (action == GLFW_RELEASE) | 132 | } else if (action == GLFW_RELEASE) |
120 | { | 133 | { |
121 | switch (key) | 134 | switch (key) |
122 | { | 135 | { |
123 | case GLFW_KEY_LEFT: holding_left = false; break; | 136 | case GLFW_KEY_LEFT: |
124 | case GLFW_KEY_RIGHT: holding_right = false; break; | 137 | holding_left = false; |
138 | if (!holding_right) player->animFrame = 1; | ||
139 | break; | ||
140 | case GLFW_KEY_RIGHT: | ||
141 | holding_right = false; | ||
142 | if (!holding_left) player->animFrame = 0; | ||
143 | break; | ||
144 | case GLFW_KEY_DOWN: | ||
145 | holding_down = false; | ||
146 | break; | ||
125 | } | 147 | } |
126 | } | 148 | } |
127 | } | 149 | } |
@@ -153,12 +175,37 @@ void MapView::tick() | |||
153 | 175 | ||
154 | void MapView::render(Texture* tex) | 176 | void MapView::render(Texture* tex) |
155 | { | 177 | { |
178 | if (animFrame == 0) | ||
179 | { | ||
180 | if (holding_left) | ||
181 | { | ||
182 | if (player->animFrame == 3) | ||
183 | { | ||
184 | player->animFrame = 5; | ||
185 | } else { | ||
186 | player->animFrame = 3; | ||
187 | } | ||
188 | } else if (holding_right) | ||
189 | { | ||
190 | if (player->animFrame == 2) | ||
191 | { | ||
192 | player->animFrame = 4; | ||
193 | } else { | ||
194 | player->animFrame = 2; | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | |||
199 | animFrame++; | ||
200 | animFrame %= 10; | ||
201 | |||
156 | // Draw the background | 202 | // Draw the background |
157 | blitTexture(bg, tex, NULL, NULL); | 203 | blitTexture(bg, tex, NULL, NULL); |
158 | 204 | ||
159 | // Draw the player | 205 | // Draw the player |
206 | Rectangle src_rect(player->animFrame * 10, 0, 10, 12); | ||
160 | Rectangle dst_rect(player->x, player->y, player->w, player->h); | 207 | Rectangle dst_rect(player->x, player->y, player->w, player->h); |
161 | fillTexture(tex, &dst_rect, 255, 255, 255); | 208 | blitTexture(chara, tex, &src_rect, &dst_rect); |
162 | } | 209 | } |
163 | 210 | ||
164 | void MapView::add_collision(int axis, int lower, int upper, direction_t dir, int type) | 211 | void MapView::add_collision(int axis, int lower, int upper, direction_t dir, int type) |
@@ -305,9 +352,20 @@ void MapView::check_collisions(mob_t* mob, int x_next, int y_next) | |||
305 | { | 352 | { |
306 | y_next = it->axis - mob->h; | 353 | y_next = it->axis - mob->h; |
307 | mob->y_vel = 0; | 354 | mob->y_vel = 0; |
355 | mob->onGround = true; | ||
308 | } else if (it->type == 1) | 356 | } else if (it->type == 1) |
309 | { | 357 | { |
310 | y_next = 1 - mob->h/2; | 358 | y_next = 1 - mob->h/2; |
359 | } else if (it->type == 3) | ||
360 | { | ||
361 | if (holding_down) | ||
362 | { | ||
363 | holding_down = false; | ||
364 | } else { | ||
365 | y_next = it->axis - mob->h; | ||
366 | mob->y_vel = 0; | ||
367 | mob->onGround = true; | ||
368 | } | ||
311 | } | 369 | } |
312 | 370 | ||
313 | break; | 371 | break; |
diff --git a/src/mapview.h b/src/mapview.h index 70ffb3b..06309e3 100644 --- a/src/mapview.h +++ b/src/mapview.h | |||
@@ -16,6 +16,7 @@ const int MAP_WIDTH = GAME_WIDTH/TILE_WIDTH; | |||
16 | const int MAP_HEIGHT = GAME_HEIGHT/TILE_HEIGHT; | 16 | const int MAP_HEIGHT = GAME_HEIGHT/TILE_HEIGHT; |
17 | 17 | ||
18 | const int FRAMES_PER_SECOND = 60; | 18 | const int FRAMES_PER_SECOND = 60; |
19 | const double SECONDS_PER_FRAME = 1.0 / FRAMES_PER_SECOND; | ||
19 | 20 | ||
20 | enum direction_t { | 21 | enum direction_t { |
21 | up, left, down, right | 22 | up, left, down, right |
@@ -47,12 +48,17 @@ class MapView : public State { | |||
47 | list<collision_t> down_collisions; | 48 | list<collision_t> down_collisions; |
48 | 49 | ||
49 | Texture* bg = NULL; | 50 | Texture* bg = NULL; |
51 | Texture* chara; | ||
52 | Texture* tiles; | ||
50 | 53 | ||
51 | bool holding_left = false; | 54 | bool holding_left = false; |
52 | bool holding_right = false; | 55 | bool holding_right = false; |
56 | bool holding_down = false; | ||
53 | mob_t* player; | 57 | mob_t* player; |
54 | 58 | ||
55 | Map* curMap; | 59 | Map* curMap; |
60 | |||
61 | int animFrame = 0; | ||
56 | }; | 62 | }; |
57 | 63 | ||
58 | #endif | 64 | #endif |
diff --git a/src/mob.h b/src/mob.h index 7a4b707..213b062 100644 --- a/src/mob.h +++ b/src/mob.h | |||
@@ -7,4 +7,6 @@ typedef struct { | |||
7 | double y_accel; | 7 | double y_accel; |
8 | int w; | 8 | int w; |
9 | int h; | 9 | int h; |
10 | bool onGround; | ||
11 | int animFrame; | ||
10 | } mob_t; | 12 | } mob_t; |
diff --git a/src/renderer.cpp b/src/renderer.cpp index 2ee0642..00ae7ef 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <fstream> | 3 | #include <fstream> |
4 | #include <vector> | 4 | #include <vector> |
5 | #include <cstdio> | 5 | #include <cstdio> |
6 | #include <cstring> | ||
6 | #include "mapview.h" | 7 | #include "mapview.h" |
7 | 8 | ||
8 | static bool rendererInitialized = false; | 9 | static bool rendererInitialized = false; |
@@ -10,6 +11,8 @@ static bool rendererInitialized = false; | |||
10 | static GLFWwindow* window; | 11 | static GLFWwindow* window; |
11 | 12 | ||
12 | static GLuint FramebufferName; // The framebuffer | 13 | static GLuint FramebufferName; // The framebuffer |
14 | static GLuint depthrenderbuffer; | ||
15 | |||
13 | static GLuint ntscShader; // The NTSC shader | 16 | static GLuint ntscShader; // The NTSC shader |
14 | static GLuint finalShader; // The passthrough shader | 17 | static GLuint finalShader; // The passthrough shader |
15 | static GLuint blitShader; // The blitting shader | 18 | static GLuint blitShader; // The blitting shader |
@@ -33,6 +36,12 @@ static GLuint VertexArrayID; | |||
33 | // A plane that fills the renderbuffer | 36 | // A plane that fills the renderbuffer |
34 | static GLuint quad_vertexbuffer; | 37 | static GLuint quad_vertexbuffer; |
35 | 38 | ||
39 | // Buffers for the mesh | ||
40 | static GLuint mesh_vertexbuffer; | ||
41 | static GLuint mesh_uvbuffer; | ||
42 | static GLuint mesh_normalbuffer; | ||
43 | static int mesh_numvertices; | ||
44 | |||
36 | GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) | 45 | GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) |
37 | { | 46 | { |
38 | // Create the shaders | 47 | // Create the shaders |
@@ -188,6 +197,58 @@ GLuint loadBMP_custom(const char * imagepath){ | |||
188 | return textureID; | 197 | return textureID; |
189 | } | 198 | } |
190 | 199 | ||
200 | void loadMesh(const char* filename, std::vector<glm::vec3>& out_vertices, std::vector<glm::vec2>& out_uvs, std::vector<glm::vec3>& out_normals) | ||
201 | { | ||
202 | FILE* file = fopen(filename, "r"); | ||
203 | if (file == NULL) | ||
204 | { | ||
205 | fprintf(stderr, "Could not open mesh file %s\n", filename); | ||
206 | exit(1); | ||
207 | } | ||
208 | |||
209 | std::vector<glm::vec3> temp_vertices; | ||
210 | std::vector<glm::vec2> temp_uvs; | ||
211 | std::vector<glm::vec3> temp_normals; | ||
212 | |||
213 | for (;;) | ||
214 | { | ||
215 | char lineHeader[256]; | ||
216 | int res = fscanf(file, "%s", lineHeader); | ||
217 | if (res == EOF) | ||
218 | { | ||
219 | break; | ||
220 | } | ||
221 | |||
222 | if (!strncmp(lineHeader, "v", 2)) | ||
223 | { | ||
224 | vec3 vertex; | ||
225 | fscanf(file, "%f %f %f\n", &vertex.x,&vertex.y,&vertex.z); | ||
226 | temp_vertices.push_back(vertex); | ||
227 | } else if (!strncmp(lineHeader, "vt", 3)) | ||
228 | { | ||
229 | vec2 uv; | ||
230 | fscanf(file, "%f %f\n", &uv.x, &uv.y); | ||
231 | temp_uvs.push_back(uv); | ||
232 | } else if (!strncmp(lineHeader, "vn", 3)) | ||
233 | { | ||
234 | vec3 normal; | ||
235 | fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); | ||
236 | temp_normals.push_back(normal); | ||
237 | } else if (!strncmp(lineHeader, "f", 2)) | ||
238 | { | ||
239 | int vertexIDs[3], uvIDs[3], normalIDs[3]; | ||
240 | fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIDs[0], &uvIDs[0], &normalIDs[0], &vertexIDs[1], &uvIDs[1], &normalIDs[1], &vertexIDs[2], &uvIDs[2], &normalIDs[2]); | ||
241 | |||
242 | for (int i=0; i<3; i++) | ||
243 | { | ||
244 | out_vertices.push_back(temp_vertices[vertexIDs[i] - 1]); | ||
245 | out_uvs.push_back(temp_uvs[uvIDs[i] - 1]); | ||
246 | out_normals.push_back(temp_normals[normalIDs[i] - 1]); | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | } | ||
251 | |||
191 | GLFWwindow* initRenderer() | 252 | GLFWwindow* initRenderer() |
192 | { | 253 | { |
193 | if (rendererInitialized) | 254 | if (rendererInitialized) |
@@ -230,12 +291,20 @@ GLFWwindow* initRenderer() | |||
230 | glGenVertexArrays(1, &VertexArrayID); | 291 | glGenVertexArrays(1, &VertexArrayID); |
231 | glBindVertexArray(VertexArrayID); | 292 | glBindVertexArray(VertexArrayID); |
232 | 293 | ||
294 | glEnable(GL_DEPTH_TEST); | ||
295 | glDepthFunc(GL_LESS); | ||
296 | |||
233 | // Set up the framebuffer | 297 | // Set up the framebuffer |
234 | glGenFramebuffers(1, &FramebufferName); | 298 | glGenFramebuffers(1, &FramebufferName); |
235 | glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); | 299 | glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); |
236 | GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; | 300 | GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; |
237 | glDrawBuffers(1, DrawBuffers); | 301 | glDrawBuffers(1, DrawBuffers); |
238 | 302 | ||
303 | glGenRenderbuffers(1, &depthrenderbuffer); | ||
304 | glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); | ||
305 | glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1024, 768); | ||
306 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); | ||
307 | |||
239 | // Set up the NTSC rendering buffers | 308 | // Set up the NTSC rendering buffers |
240 | glGenTextures(1, &renderedTex1); | 309 | glGenTextures(1, &renderedTex1); |
241 | glBindTexture(GL_TEXTURE_2D, renderedTex1); | 310 | glBindTexture(GL_TEXTURE_2D, renderedTex1); |
@@ -274,6 +343,26 @@ GLFWwindow* initRenderer() | |||
274 | 343 | ||
275 | curBuf = 0; | 344 | curBuf = 0; |
276 | 345 | ||
346 | // Load the mesh! | ||
347 | std::vector<glm::vec3> mesh_vertices; | ||
348 | std::vector<glm::vec2> mesh_uvs; | ||
349 | std::vector<glm::vec3> mesh_normals; | ||
350 | loadMesh("../res/monitor-fef.obj", mesh_vertices, mesh_uvs, mesh_normals); | ||
351 | |||
352 | mesh_numvertices = mesh_vertices.size(); | ||
353 | |||
354 | glGenBuffers(1, &mesh_vertexbuffer); | ||
355 | glBindBuffer(GL_ARRAY_BUFFER, mesh_vertexbuffer); | ||
356 | glBufferData(GL_ARRAY_BUFFER, mesh_vertices.size() * sizeof(vec3), &mesh_vertices[0], GL_STATIC_DRAW); | ||
357 | |||
358 | glGenBuffers(1, &mesh_uvbuffer); | ||
359 | glBindBuffer(GL_ARRAY_BUFFER, mesh_uvbuffer); | ||
360 | glBufferData(GL_ARRAY_BUFFER, mesh_uvs.size() * sizeof(vec3), &mesh_uvs[0], GL_STATIC_DRAW); | ||
361 | |||
362 | glGenBuffers(1, &mesh_normalbuffer); | ||
363 | glBindBuffer(GL_ARRAY_BUFFER, mesh_normalbuffer); | ||
364 | glBufferData(GL_ARRAY_BUFFER, mesh_normals.size() * sizeof(vec3), &mesh_normals[0], GL_STATIC_DRAW); | ||
365 | |||
277 | // Load the vertices of a flat surface | 366 | // Load the vertices of a flat surface |
278 | GLfloat g_quad_vertex_buffer_data[] = { | 367 | GLfloat g_quad_vertex_buffer_data[] = { |
279 | -1.0f, -1.0f, 0.0f, | 368 | -1.0f, -1.0f, 0.0f, |
@@ -314,6 +403,9 @@ void destroyRenderer() | |||
314 | 403 | ||
315 | // Delete the plane buffer | 404 | // Delete the plane buffer |
316 | glDeleteBuffers(1, &quad_vertexbuffer); | 405 | glDeleteBuffers(1, &quad_vertexbuffer); |
406 | glDeleteBuffers(1, &mesh_vertexbuffer); | ||
407 | glDeleteBuffers(1, &mesh_uvbuffer); | ||
408 | glDeleteBuffers(1, &mesh_normalbuffer); | ||
317 | 409 | ||
318 | // Delete the shaders | 410 | // Delete the shaders |
319 | glDeleteProgram(ntscShader); | 411 | glDeleteProgram(ntscShader); |
@@ -332,6 +424,7 @@ void destroyRenderer() | |||
332 | glDeleteTextures(1, &bloomPassTex); | 424 | glDeleteTextures(1, &bloomPassTex); |
333 | 425 | ||
334 | // Delete the framebuffer | 426 | // Delete the framebuffer |
427 | glDeleteRenderbuffers(1, &depthrenderbuffer); | ||
335 | glDeleteFramebuffers(1, &FramebufferName); | 428 | glDeleteFramebuffers(1, &FramebufferName); |
336 | 429 | ||
337 | // Delete the VAO | 430 | // Delete the VAO |
@@ -466,6 +559,7 @@ void fillTexture(Texture* tex, Rectangle* dstrect, int r, int g, int b) | |||
466 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); | 559 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); |
467 | 560 | ||
468 | glViewport(0, 0, tex->width, tex->height); | 561 | glViewport(0, 0, tex->width, tex->height); |
562 | glClear(GL_DEPTH_BUFFER_BIT); | ||
469 | glUseProgram(fillShader); | 563 | glUseProgram(fillShader); |
470 | glUniform3f(glGetUniformLocation(fillShader, "vecColor"), r / 255.0, g / 255.0, b / 255.0); | 564 | glUniform3f(glGetUniformLocation(fillShader, "vecColor"), r / 255.0, g / 255.0, b / 255.0); |
471 | 565 | ||
@@ -536,6 +630,7 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle | |||
536 | 630 | ||
537 | // Set up the shader | 631 | // Set up the shader |
538 | glUseProgram(blitShader); | 632 | glUseProgram(blitShader); |
633 | glClear(GL_DEPTH_BUFFER_BIT); | ||
539 | glViewport(0, 0, dsttex->width, dsttex->height); | 634 | glViewport(0, 0, dsttex->width, dsttex->height); |
540 | 635 | ||
541 | glActiveTexture(GL_TEXTURE0); | 636 | glActiveTexture(GL_TEXTURE0); |
@@ -552,6 +647,62 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle | |||
552 | glDeleteBuffers(1, &vertexbuffer); | 647 | glDeleteBuffers(1, &vertexbuffer); |
553 | } | 648 | } |
554 | 649 | ||
650 | void renderWithoutEffects(Texture* tex) | ||
651 | { | ||
652 | if (!rendererInitialized) | ||
653 | { | ||
654 | fprintf(stderr, "Renderer not initialized\n"); | ||
655 | exit(-1); | ||
656 | } | ||
657 | |||
658 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
659 | glViewport(0, 0, 1024, 768); | ||
660 | glClear(GL_COLOR_BUFFER_BIT); | ||
661 | glUseProgram(blitShader); | ||
662 | |||
663 | const GLfloat fullBlitVertices_data[] = { | ||
664 | -1.0, -1.0, | ||
665 | 1.0, -1.0, | ||
666 | -1.0, 1.0, | ||
667 | 1.0, 1.0 | ||
668 | }; | ||
669 | |||
670 | GLuint fullBlitVertices; | ||
671 | glGenBuffers(1, &fullBlitVertices); | ||
672 | glBindBuffer(GL_ARRAY_BUFFER, fullBlitVertices); | ||
673 | glBufferData(GL_ARRAY_BUFFER, sizeof(fullBlitVertices_data), fullBlitVertices_data, GL_STATIC_DRAW); | ||
674 | glEnableVertexAttribArray(0); | ||
675 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); | ||
676 | |||
677 | const GLfloat fullBlitTex_data[] = { | ||
678 | 0.0, 0.0, | ||
679 | 1.0, 0.0, | ||
680 | 0.0, 1.0, | ||
681 | 1.0, 1.0 | ||
682 | }; | ||
683 | |||
684 | GLuint fullBlitTex; | ||
685 | glGenBuffers(1, &fullBlitTex); | ||
686 | glBindBuffer(GL_ARRAY_BUFFER, fullBlitTex); | ||
687 | glBufferData(GL_ARRAY_BUFFER, sizeof(fullBlitTex_data), fullBlitTex_data, GL_STATIC_DRAW); | ||
688 | glEnableVertexAttribArray(1); | ||
689 | glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); | ||
690 | |||
691 | glActiveTexture(GL_TEXTURE0); | ||
692 | glBindTexture(GL_TEXTURE_2D, tex->texID); | ||
693 | glUniform1i(glGetUniformLocation(blitShader, "srctex"), 0); | ||
694 | |||
695 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | ||
696 | |||
697 | glDisableVertexAttribArray(1); | ||
698 | glDisableVertexAttribArray(0); | ||
699 | |||
700 | glDeleteBuffers(1, &fullBlitTex); | ||
701 | glDeleteBuffers(1, &fullBlitVertices); | ||
702 | |||
703 | glfwSwapBuffers(window); | ||
704 | } | ||
705 | |||
555 | void renderScreen(Texture* tex) | 706 | void renderScreen(Texture* tex) |
556 | { | 707 | { |
557 | if (!rendererInitialized) | 708 | if (!rendererInitialized) |
@@ -565,9 +716,9 @@ void renderScreen(Texture* tex) | |||
565 | glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); | 716 | glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); |
566 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexBufs[curBuf], 0); | 717 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexBufs[curBuf], 0); |
567 | 718 | ||
568 | // Set up the shaer | 719 | // Set up the shader |
569 | glViewport(0,0,GAME_WIDTH,GAME_HEIGHT); | 720 | glViewport(0,0,GAME_WIDTH,GAME_HEIGHT); |
570 | glClear(GL_COLOR_BUFFER_BIT); | 721 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
571 | glUseProgram(ntscShader); | 722 | glUseProgram(ntscShader); |
572 | 723 | ||
573 | // Use the current frame texture, nearest neighbor and clamped to edge | 724 | // Use the current frame texture, nearest neighbor and clamped to edge |
@@ -601,26 +752,11 @@ void renderScreen(Texture* tex) | |||
601 | glDrawArrays(GL_TRIANGLES, 0, 6); | 752 | glDrawArrays(GL_TRIANGLES, 0, 6); |
602 | glDisableVertexAttribArray(0); | 753 | glDisableVertexAttribArray(0); |
603 | 754 | ||
604 | // Load the normal vertices of a flat surface | ||
605 | GLfloat g_norms_data[] = { | ||
606 | 0.0f, 0.0f, 1.0f, | ||
607 | 0.0f, 0.0f, 1.0f, | ||
608 | 0.0f, 0.0f, 1.0f, | ||
609 | 0.0f, 0.0f, 1.0f, | ||
610 | 0.0f, 0.0f, 1.0f, | ||
611 | 0.0f, 0.0f, 1.0f | ||
612 | }; | ||
613 | |||
614 | GLuint g_norms; | ||
615 | glGenBuffers(1, &g_norms); | ||
616 | glBindBuffer(GL_ARRAY_BUFFER, g_norms); | ||
617 | glBufferData(GL_ARRAY_BUFFER, sizeof(g_norms_data), g_norms_data, GL_STATIC_DRAW); | ||
618 | |||
619 | // We're going to render the screen now | 755 | // We're going to render the screen now |
620 | //glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
621 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, preBloomTex, 0); | 756 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, preBloomTex, 0); |
757 | //glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
622 | glViewport(0,0,1024,768); | 758 | glViewport(0,0,1024,768); |
623 | glClear(GL_COLOR_BUFFER_BIT); | 759 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
624 | glUseProgram(finalShader); | 760 | glUseProgram(finalShader); |
625 | 761 | ||
626 | // Use the composited frame texture, linearly filtered and filling in black for the border | 762 | // Use the composited frame texture, linearly filtered and filling in black for the border |
@@ -641,9 +777,9 @@ void renderScreen(Texture* tex) | |||
641 | glUniform1i(glGetUniformLocation(finalShader, "scanlinestex"), 1); | 777 | glUniform1i(glGetUniformLocation(finalShader, "scanlinestex"), 1); |
642 | 778 | ||
643 | // Initialize the MVP matrices | 779 | // Initialize the MVP matrices |
644 | mat4 p_matrix = perspective(90.0f, 4.0f / 4.0f, 0.1f, 100.0f); | 780 | mat4 p_matrix = perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f); |
645 | mat4 v_matrix = lookAt(vec3(0,0,1), vec3(0,0,0), vec3(0,1,0)); | 781 | mat4 v_matrix = lookAt(vec3(2,0,0), vec3(0,0,0), vec3(0,1,0)); |
646 | mat4 m_matrix = mat4(1.0f); | 782 | mat4 m_matrix = mat4(1.0); |
647 | mat4 mvp_matrix = p_matrix * v_matrix * m_matrix; | 783 | mat4 mvp_matrix = p_matrix * v_matrix * m_matrix; |
648 | //mat4 mv_matrix = v_matrix * m_matrix; | 784 | //mat4 mv_matrix = v_matrix * m_matrix; |
649 | 785 | ||
@@ -651,21 +787,26 @@ void renderScreen(Texture* tex) | |||
651 | glUniformMatrix4fv(glGetUniformLocation(finalShader, "worldMat"), 1, GL_FALSE, &m_matrix[0][0]); | 787 | glUniformMatrix4fv(glGetUniformLocation(finalShader, "worldMat"), 1, GL_FALSE, &m_matrix[0][0]); |
652 | 788 | ||
653 | glEnableVertexAttribArray(0); | 789 | glEnableVertexAttribArray(0); |
654 | glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); | 790 | glBindBuffer(GL_ARRAY_BUFFER, mesh_vertexbuffer); |
655 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); | 791 | glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); |
656 | 792 | ||
657 | glEnableVertexAttribArray(1); | 793 | glEnableVertexAttribArray(1); |
658 | glBindBuffer(GL_ARRAY_BUFFER, g_norms); | 794 | glBindBuffer(GL_ARRAY_BUFFER, mesh_normalbuffer); |
659 | glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); | 795 | glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); |
660 | 796 | ||
661 | glDrawArrays(GL_TRIANGLES, 0, 6); | 797 | glEnableVertexAttribArray(2); |
798 | glBindBuffer(GL_ARRAY_BUFFER, mesh_uvbuffer); | ||
799 | glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); | ||
800 | |||
801 | glDrawArrays(GL_TRIANGLES, 0, mesh_numvertices); | ||
802 | glDisableVertexAttribArray(2); | ||
662 | glDisableVertexAttribArray(1); | 803 | glDisableVertexAttribArray(1); |
663 | glDisableVertexAttribArray(0); | 804 | glDisableVertexAttribArray(0); |
664 | 805 | ||
665 | // Do the first pass of bloom (downsampling and tapping) | 806 | // Do the first pass of bloom (downsampling and tapping) |
666 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, bloomPassTex, 0); | 807 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, bloomPassTex, 0); |
667 | glViewport(0, 0, 64, 48); | 808 | glViewport(0, 0, 64, 48); |
668 | glClear(GL_COLOR_BUFFER_BIT); | 809 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
669 | glUseProgram(bloom1Shader); | 810 | glUseProgram(bloom1Shader); |
670 | 811 | ||
671 | glActiveTexture(GL_TEXTURE0); | 812 | glActiveTexture(GL_TEXTURE0); |
@@ -683,7 +824,7 @@ void renderScreen(Texture* tex) | |||
683 | // Do the second pass of bloom and render to screen | 824 | // Do the second pass of bloom and render to screen |
684 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | 825 | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
685 | glViewport(0, 0, 1024, 768); | 826 | glViewport(0, 0, 1024, 768); |
686 | glClear(GL_COLOR_BUFFER_BIT); | 827 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
687 | glUseProgram(bloom2Shader); | 828 | glUseProgram(bloom2Shader); |
688 | 829 | ||
689 | glActiveTexture(GL_TEXTURE0); | 830 | glActiveTexture(GL_TEXTURE0); |
@@ -704,7 +845,5 @@ void renderScreen(Texture* tex) | |||
704 | 845 | ||
705 | glfwSwapBuffers(window); | 846 | glfwSwapBuffers(window); |
706 | 847 | ||
707 | glDeleteBuffers(1, &g_norms); | ||
708 | |||
709 | curBuf = (curBuf + 1) % 2; | 848 | curBuf = (curBuf + 1) % 2; |
710 | } | 849 | } |
diff --git a/src/renderer.h b/src/renderer.h index 057337c..144956a 100644 --- a/src/renderer.h +++ b/src/renderer.h | |||
@@ -39,6 +39,7 @@ Texture* loadTextureFromBMP(char* filename); | |||
39 | void saveTextureToBMP(Texture* tex, char* filename); | 39 | void saveTextureToBMP(Texture* tex, char* filename); |
40 | void fillTexture(Texture* tex, Rectangle* loc, int r, int g, int b); | 40 | void fillTexture(Texture* tex, Rectangle* loc, int r, int g, int b); |
41 | void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle* dstrect); | 41 | void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle* dstrect); |
42 | void renderWithoutEffects(Texture* tex); | ||
42 | void renderScreen(Texture* tex); | 43 | void renderScreen(Texture* tex); |
43 | 44 | ||
44 | #endif | 45 | #endif |