diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/components.cpp | 353 | ||||
-rw-r--r-- | src/components.h | 76 | ||||
-rw-r--r-- | src/entity.cpp | 32 | ||||
-rw-r--r-- | src/entity.h | 81 | ||||
-rw-r--r-- | src/game.cpp | 135 | ||||
-rw-r--r-- | src/game.h | 38 | ||||
-rw-r--r-- | src/main.cpp | 10 | ||||
-rw-r--r-- | src/map.cpp | 41 | ||||
-rw-r--r-- | src/map.h | 14 | ||||
-rw-r--r-- | src/renderer.cpp | 256 | ||||
-rw-r--r-- | src/renderer.h | 44 | ||||
-rw-r--r-- | src/world.cpp | 32 | ||||
-rw-r--r-- | src/world.h | 27 |
14 files changed, 511 insertions, 630 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0937493..82ac3cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -34,6 +34,6 @@ set(ALL_LIBS | |||
34 | 34 | ||
35 | # include_directories(${SDL2_INCLUDE_DIR}) | 35 | # include_directories(${SDL2_INCLUDE_DIR}) |
36 | set(CMAKE_BUILD_TYPE Debug) | 36 | set(CMAKE_BUILD_TYPE Debug) |
37 | add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp src/world.cpp src/entity.cpp src/components.cpp src/game.cpp) | 37 | add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp src/entity.cpp src/components.cpp src/game.cpp) |
38 | target_link_libraries(Aromatherapy ${ALL_LIBS}) | 38 | target_link_libraries(Aromatherapy ${ALL_LIBS}) |
39 | install(TARGETS Aromatherapy RUNTIME DESTINATION ${BIN_DIR}) | 39 | install(TARGETS Aromatherapy RUNTIME DESTINATION ${BIN_DIR}) |
diff --git a/src/components.cpp b/src/components.cpp index f9c7c10..369bb9e 100644 --- a/src/components.cpp +++ b/src/components.cpp | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | // User movement component | 4 | // User movement component |
5 | 5 | ||
6 | void UserMovementComponent::input(int key, int action) | 6 | void UserMovementComponent::input(Game& game, Entity& entity, int key, int action) |
7 | { | 7 | { |
8 | if (action == GLFW_PRESS) | 8 | if (action == GLFW_PRESS) |
9 | { | 9 | { |
@@ -11,30 +11,22 @@ void UserMovementComponent::input(int key, int action) | |||
11 | { | 11 | { |
12 | holdingLeft = true; | 12 | holdingLeft = true; |
13 | 13 | ||
14 | message_t msg; | 14 | Message msg(Message::Type::walkLeft); |
15 | msg.type = CM_WALK_LEFT; | 15 | entity.send(game, msg); |
16 | |||
17 | entity.send(msg); | ||
18 | } else if (key == GLFW_KEY_RIGHT) | 16 | } else if (key == GLFW_KEY_RIGHT) |
19 | { | 17 | { |
20 | holdingRight = true; | 18 | holdingRight = true; |
21 | 19 | ||
22 | message_t msg; | 20 | Message msg(Message::Type::walkRight); |
23 | msg.type = CM_WALK_RIGHT; | 21 | entity.send(game, msg); |
24 | |||
25 | entity.send(msg); | ||
26 | } else if (key == GLFW_KEY_UP) | 22 | } else if (key == GLFW_KEY_UP) |
27 | { | 23 | { |
28 | message_t msg; | 24 | Message msg(Message::Type::jump); |
29 | msg.type = CM_JUMP; | 25 | entity.send(game, msg); |
30 | |||
31 | entity.send(msg); | ||
32 | } else if (key == GLFW_KEY_DOWN) | 26 | } else if (key == GLFW_KEY_DOWN) |
33 | { | 27 | { |
34 | message_t msg; | 28 | Message msg(Message::Type::canDrop); |
35 | msg.type = CM_CAN_DROP; | 29 | entity.send(game, msg); |
36 | |||
37 | entity.send(msg); | ||
38 | } | 30 | } |
39 | } else if (action == GLFW_RELEASE) | 31 | } else if (action == GLFW_RELEASE) |
40 | { | 32 | { |
@@ -44,15 +36,11 @@ void UserMovementComponent::input(int key, int action) | |||
44 | 36 | ||
45 | if (holdingRight) | 37 | if (holdingRight) |
46 | { | 38 | { |
47 | message_t msg; | 39 | Message msg(Message::Type::walkRight); |
48 | msg.type = CM_WALK_RIGHT; | 40 | entity.send(game, msg); |
49 | |||
50 | entity.send(msg); | ||
51 | } else { | 41 | } else { |
52 | message_t msg; | 42 | Message msg(Message::Type::stopWalking); |
53 | msg.type = CM_STOP_WALKING; | 43 | entity.send(game, msg); |
54 | |||
55 | entity.send(msg); | ||
56 | } | 44 | } |
57 | } else if (key == GLFW_KEY_RIGHT) | 45 | } else if (key == GLFW_KEY_RIGHT) |
58 | { | 46 | { |
@@ -60,95 +48,82 @@ void UserMovementComponent::input(int key, int action) | |||
60 | 48 | ||
61 | if (holdingLeft) | 49 | if (holdingLeft) |
62 | { | 50 | { |
63 | message_t msg; | 51 | Message msg(Message::Type::walkLeft); |
64 | msg.type = CM_WALK_LEFT; | 52 | entity.send(game, msg); |
65 | |||
66 | entity.send(msg); | ||
67 | } else { | 53 | } else { |
68 | message_t msg; | 54 | Message msg(Message::Type::stopWalking); |
69 | msg.type = CM_STOP_WALKING; | 55 | entity.send(game, msg); |
70 | |||
71 | entity.send(msg); | ||
72 | } | 56 | } |
73 | } else if (key == GLFW_KEY_DOWN) | 57 | } else if (key == GLFW_KEY_DOWN) |
74 | { | 58 | { |
75 | message_t msg; | 59 | Message msg(Message::Type::cantDrop); |
76 | msg.type = CM_CANT_DROP; | 60 | entity.send(game, msg); |
77 | |||
78 | entity.send(msg); | ||
79 | } else if (key == GLFW_KEY_UP) | 61 | } else if (key == GLFW_KEY_UP) |
80 | { | 62 | { |
81 | message_t msg; | 63 | Message msg(Message::Type::stopJump); |
82 | msg.type = CM_STOP_JUMP; | 64 | entity.send(game, msg); |
83 | |||
84 | entity.send(msg); | ||
85 | } | 65 | } |
86 | } | 66 | } |
87 | } | 67 | } |
88 | 68 | ||
89 | // Physics component | 69 | // Physics component |
90 | 70 | ||
91 | void PhysicsBodyComponent::receive(message_t msg) | 71 | void PhysicsBodyComponent::receive(Game&, Entity&, Message& msg) |
92 | { | 72 | { |
93 | if (msg.type == CM_WALK_LEFT) | 73 | if (msg.type == Message::Type::walkLeft) |
94 | { | 74 | { |
95 | velocity.first = -1.5; | 75 | velocity.first = -1.5; |
96 | } else if (msg.type == CM_WALK_RIGHT) | 76 | } else if (msg.type == Message::Type::walkRight) |
97 | { | 77 | { |
98 | velocity.first = 1.5; | 78 | velocity.first = 1.5; |
99 | } else if (msg.type == CM_STOP_WALKING) | 79 | } else if (msg.type == Message::Type::stopWalking) |
100 | { | 80 | { |
101 | velocity.first = 0.0; | 81 | velocity.first = 0.0; |
82 | } else if (msg.type == Message::Type::stopMovingHorizontally) | ||
83 | { | ||
84 | velocity.first = 0.0; | ||
85 | } else if (msg.type == Message::Type::stopMovingVertically) | ||
86 | { | ||
87 | velocity.second = 0.0; | ||
102 | } | 88 | } |
103 | } | 89 | } |
104 | 90 | ||
105 | void PhysicsBodyComponent::tick() | 91 | void PhysicsBodyComponent::tick(Game&, Entity& entity) |
106 | { | 92 | { |
107 | velocity.first += accel.first; | 93 | velocity.first += accel.first; |
108 | velocity.second += accel.second; | 94 | velocity.second += accel.second; |
109 | 95 | ||
110 | position.first += velocity.first; | 96 | entity.position.first += velocity.first; |
111 | position.second += velocity.second; | 97 | entity.position.second += velocity.second; |
112 | } | 98 | } |
113 | 99 | ||
114 | void PhysicsBodyComponent::detectCollision(Entity& player, Locatable& physics, std::pair<double, double> old_position) | 100 | void PhysicsBodyComponent::detectCollision(Game& game, Entity& entity, Entity& collider, std::pair<double, double> old_position) |
115 | { | 101 | { |
116 | // If already colliding, do nothing! | 102 | // If already colliding, do nothing! |
117 | if ((old_position.first + physics.size.first > this->position.first) | 103 | if ((old_position.first + collider.size.first > entity.position.first) |
118 | && (old_position.first < this->position.first + this->size.first) | 104 | && (old_position.first < entity.position.first + entity.size.first) |
119 | && (old_position.second + physics.size.second > this->position.second) | 105 | && (old_position.second + collider.size.second > entity.position.second) |
120 | && (old_position.second < this->position.second + this->size.second)) | 106 | && (old_position.second < entity.position.second + entity.size.second)) |
121 | { | 107 | { |
122 | return; | 108 | return; |
123 | } | 109 | } |
124 | 110 | ||
125 | // If newly colliding, SHOCK AND HORROR! | 111 | // If newly colliding, SHOCK AND HORROR! |
126 | if ((physics.position.first + physics.size.first > this->position.first) | 112 | if ((collider.position.first + collider.size.first > entity.position.first) |
127 | && (physics.position.first < this->position.first + this->size.first) | 113 | && (collider.position.first < entity.position.first + entity.size.first) |
128 | && (physics.position.second + physics.size.second > this->position.second) | 114 | && (collider.position.second + collider.size.second > entity.position.second) |
129 | && (physics.position.second < this->position.second + this->size.second)) | 115 | && (collider.position.second < entity.position.second + entity.size.second)) |
130 | { | 116 | { |
131 | message_t msg; | 117 | Message msg(Message::Type::collision); |
132 | msg.type = CM_COLLISION; | 118 | msg.collisionEntity = &collider; |
133 | msg.collisionEntity = &player; | ||
134 | 119 | ||
135 | entity.send(msg); | 120 | entity.send(game, msg); |
136 | } | 121 | } |
137 | } | 122 | } |
138 | 123 | ||
139 | // Render player | 124 | // Render player |
140 | 125 | ||
141 | PlayerSpriteComponent::PlayerSpriteComponent(Entity& entity, Locatable& physics) : Component(entity), physics(physics) | 126 | void PlayerSpriteComponent::render(Game&, Entity& entity, Texture& buffer) |
142 | { | ||
143 | sprite = loadTextureFromFile("../res/Starla.png"); | ||
144 | } | ||
145 | |||
146 | PlayerSpriteComponent::~PlayerSpriteComponent() | ||
147 | { | ||
148 | destroyTexture(sprite); | ||
149 | } | ||
150 | |||
151 | void PlayerSpriteComponent::render(Texture* buffer) | ||
152 | { | 127 | { |
153 | int frame = 0; | 128 | int frame = 0; |
154 | if (isMoving) | 129 | if (isMoving) |
@@ -162,28 +137,28 @@ void PlayerSpriteComponent::render(Texture* buffer) | |||
162 | } | 137 | } |
163 | if (facingLeft) frame++; | 138 | if (facingLeft) frame++; |
164 | 139 | ||
165 | Rectangle src_rect(frame*10, 0, 10, 12); | 140 | Rectangle src_rect {frame*10, 0, 10, 12}; |
166 | Rectangle dst_rect((int) physics.position.first, (int) physics.position.second, physics.size.first, physics.size.second); | 141 | Rectangle dst_rect {(int) entity.position.first, (int) entity.position.second, entity.size.first, entity.size.second}; |
167 | blitTexture(sprite, buffer, &src_rect, &dst_rect); | 142 | buffer.blit(sprite, src_rect, dst_rect); |
168 | } | 143 | } |
169 | 144 | ||
170 | void PlayerSpriteComponent::receive(message_t msg) | 145 | void PlayerSpriteComponent::receive(Game&, Entity&, Message& msg) |
171 | { | 146 | { |
172 | if (msg.type == CM_WALK_LEFT) | 147 | if (msg.type == Message::Type::walkLeft) |
173 | { | 148 | { |
174 | facingLeft = true; | 149 | facingLeft = true; |
175 | isMoving = true; | 150 | isMoving = true; |
176 | } else if (msg.type == CM_WALK_RIGHT) | 151 | } else if (msg.type == Message::Type::walkRight) |
177 | { | 152 | { |
178 | facingLeft = false; | 153 | facingLeft = false; |
179 | isMoving = true; | 154 | isMoving = true; |
180 | } else if (msg.type == CM_STOP_WALKING) | 155 | } else if (msg.type == Message::Type::stopWalking) |
181 | { | 156 | { |
182 | isMoving = false; | 157 | isMoving = false; |
183 | } | 158 | } |
184 | } | 159 | } |
185 | 160 | ||
186 | void PlayerSpriteComponent::tick() | 161 | void PlayerSpriteComponent::tick(Game&, Entity&) |
187 | { | 162 | { |
188 | animFrame++; | 163 | animFrame++; |
189 | animFrame %= 20; | 164 | animFrame %= 20; |
@@ -194,7 +169,7 @@ void PlayerSpriteComponent::tick() | |||
194 | #define JUMP_VELOCITY(h, l) (-2 * (h) / (l)) | 169 | #define JUMP_VELOCITY(h, l) (-2 * (h) / (l)) |
195 | #define JUMP_GRAVITY(h, l) (2 * ((h) / (l)) / (l)) | 170 | #define JUMP_GRAVITY(h, l) (2 * ((h) / (l)) / (l)) |
196 | 171 | ||
197 | PlayerPhysicsComponent::PlayerPhysicsComponent(Entity& entity) : Component(entity) | 172 | PlayerPhysicsComponent::PlayerPhysicsComponent() |
198 | { | 173 | { |
199 | jump_velocity = JUMP_VELOCITY(TILE_HEIGHT*4.5, 0.3*FRAMES_PER_SECOND); | 174 | jump_velocity = JUMP_VELOCITY(TILE_HEIGHT*4.5, 0.3*FRAMES_PER_SECOND); |
200 | jump_gravity = JUMP_GRAVITY(TILE_HEIGHT*4.5, 0.3*FRAMES_PER_SECOND); | 175 | jump_gravity = JUMP_GRAVITY(TILE_HEIGHT*4.5, 0.3*FRAMES_PER_SECOND); |
@@ -203,46 +178,52 @@ PlayerPhysicsComponent::PlayerPhysicsComponent(Entity& entity) : Component(entit | |||
203 | accel.second = jump_gravity_short; | 178 | accel.second = jump_gravity_short; |
204 | } | 179 | } |
205 | 180 | ||
206 | void PlayerPhysicsComponent::receive(message_t msg) | 181 | void PlayerPhysicsComponent::receive(Game&, Entity& entity, Message& msg) |
207 | { | 182 | { |
208 | if (msg.type == CM_WALK_LEFT) | 183 | if (msg.type == Message::Type::walkLeft) |
209 | { | 184 | { |
210 | velocity.first = -1.5; | 185 | velocity.first = -1.5; |
211 | direction = -1; | 186 | direction = -1; |
212 | } else if (msg.type == CM_WALK_RIGHT) | 187 | } else if (msg.type == Message::Type::walkRight) |
213 | { | 188 | { |
214 | velocity.first = 1.5; | 189 | velocity.first = 1.5; |
215 | direction = 1; | 190 | direction = 1; |
216 | } else if (msg.type == CM_STOP_WALKING) | 191 | } else if (msg.type == Message::Type::stopWalking) |
217 | { | 192 | { |
218 | velocity.first = 0.0; | 193 | velocity.first = 0.0; |
219 | direction = 0; | 194 | direction = 0; |
220 | } else if (msg.type == CM_JUMP) | 195 | } else if (msg.type == Message::Type::stopMovingHorizontally) |
196 | { | ||
197 | velocity.first = 0.0; | ||
198 | } else if (msg.type == Message::Type::stopMovingVertically) | ||
199 | { | ||
200 | velocity.second = 0.0; | ||
201 | } else if (msg.type == Message::Type::jump) | ||
221 | { | 202 | { |
222 | velocity.second = jump_velocity; | 203 | velocity.second = jump_velocity; |
223 | accel.second = jump_gravity; | 204 | accel.second = jump_gravity; |
224 | } else if (msg.type == CM_STOP_JUMP) | 205 | } else if (msg.type == Message::Type::stopJump) |
225 | { | 206 | { |
226 | accel.second = jump_gravity_short; | 207 | accel.second = jump_gravity_short; |
227 | } else if (msg.type == CM_CAN_DROP) | 208 | } else if (msg.type == Message::Type::canDrop) |
228 | { | 209 | { |
229 | canDrop = true; | 210 | canDrop = true; |
230 | } else if (msg.type == CM_CANT_DROP) | 211 | } else if (msg.type == Message::Type::cantDrop) |
231 | { | 212 | { |
232 | canDrop = false; | 213 | canDrop = false; |
233 | } else if (msg.type == CM_DROP) | 214 | } else if (msg.type == Message::Type::drop) |
234 | { | 215 | { |
235 | if (canDrop) | 216 | if (canDrop) |
236 | { | 217 | { |
237 | canDrop = false; | 218 | canDrop = false; |
238 | } else { | 219 | } else { |
239 | position.second = msg.dropAxis - size.second; | 220 | entity.position.second = msg.dropAxis - entity.size.second; |
240 | velocity.second = 0; | 221 | velocity.second = 0; |
241 | } | 222 | } |
242 | } | 223 | } |
243 | } | 224 | } |
244 | 225 | ||
245 | void PlayerPhysicsComponent::tick() | 226 | void PlayerPhysicsComponent::tick(Game& game, Entity& entity) |
246 | { | 227 | { |
247 | // Continue walking even if blocked earlier | 228 | // Continue walking even if blocked earlier |
248 | if (velocity.first == 0) | 229 | if (velocity.first == 0) |
@@ -273,80 +254,67 @@ void PlayerPhysicsComponent::tick() | |||
273 | if (velocity.second > 16) velocity.second = 16; | 254 | if (velocity.second > 16) velocity.second = 16; |
274 | 255 | ||
275 | // Do the movement | 256 | // Do the movement |
276 | std::pair<double, double> old_position = std::make_pair(position.first, position.second); | 257 | std::pair<double, double> old_position = entity.position; |
277 | position.first += velocity.first; | 258 | entity.position.first += velocity.first; |
278 | position.second += velocity.second; | 259 | entity.position.second += velocity.second; |
279 | 260 | ||
280 | // Check for collisions | 261 | // Check for collisions |
281 | for (auto it = entity.world->bodies.begin(); it != entity.world->bodies.end(); it++) | 262 | game.detectCollision(entity, old_position); |
282 | { | ||
283 | auto poop = *it; | ||
284 | poop->detectCollision(entity, *this, old_position); | ||
285 | } | ||
286 | } | 263 | } |
287 | 264 | ||
288 | // Map rendering | 265 | // Map rendering |
289 | 266 | ||
290 | MapRenderComponent::MapRenderComponent(Entity& entity, Map* map) : Component(entity) | 267 | MapRenderComponent::MapRenderComponent(Map& map) |
291 | { | 268 | { |
292 | screen = createTexture(GAME_WIDTH, GAME_HEIGHT); | 269 | screen.fill(screen.entirety(), 0, 0, 0); |
293 | fillTexture(screen, NULL, 0, 0, 0); | ||
294 | 270 | ||
295 | Texture* tiles = loadTextureFromFile("../res/tiles.png"); | 271 | Texture tiles("../res/tiles.png"); |
296 | 272 | ||
297 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) | 273 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) |
298 | { | 274 | { |
299 | int tile = map->mapdata()[i]; | 275 | int tile = map.mapdata()[i]; |
300 | int x = i % MAP_WIDTH; | 276 | int x = i % MAP_WIDTH; |
301 | int y = i / MAP_WIDTH; | 277 | int y = i / MAP_WIDTH; |
302 | Rectangle dst(x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); | 278 | Rectangle dst {x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; |
303 | Rectangle src(tile%8*TILE_WIDTH, tile/8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); | 279 | Rectangle src {tile%8*TILE_WIDTH, tile/8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; |
304 | 280 | ||
305 | if (tile > 0) | 281 | if (tile > 0) |
306 | { | 282 | { |
307 | blitTexture(tiles, screen, &src, &dst); | 283 | screen.blit(tiles, src, dst); |
308 | } | 284 | } |
309 | } | 285 | } |
310 | 286 | ||
311 | destroyTexture(tiles); | 287 | Texture font("../res/font.bmp"); |
312 | 288 | const char* map_name = map.title(); | |
313 | Texture* font = loadTextureFromFile("../res/font.bmp"); | ||
314 | const char* map_name = map->title(); | ||
315 | int start_x = (40/2) - (strlen(map_name)/2); | 289 | int start_x = (40/2) - (strlen(map_name)/2); |
316 | for (size_t i=0; i<strlen(map_name); i++) | 290 | for (size_t i=0; i<strlen(map_name); i++) |
317 | { | 291 | { |
318 | Rectangle srcRect(map_name[i] % 16 * 8, map_name[i] / 16 * 8, 8, 8); | 292 | Rectangle srcRect {map_name[i] % 16 * 8, map_name[i] / 16 * 8, 8, 8}; |
319 | Rectangle dstRect((start_x + i)*8, 24*8, 8, 8); | 293 | Rectangle dstRect {(start_x + (int)i)*8, 24*8, 8, 8}; |
320 | blitTexture(font, screen, &srcRect, &dstRect); | 294 | screen.blit(font, srcRect, dstRect); |
321 | } | 295 | } |
322 | |||
323 | destroyTexture(font); | ||
324 | } | 296 | } |
325 | 297 | ||
326 | MapRenderComponent::~MapRenderComponent() | 298 | void MapRenderComponent::render(Game&, Entity&, Texture& buffer) |
327 | { | 299 | { |
328 | destroyTexture(screen); | 300 | buffer.blit(screen, screen.entirety(), buffer.entirety()); |
329 | } | ||
330 | |||
331 | void MapRenderComponent::render(Texture* buffer) | ||
332 | { | ||
333 | blitTexture(screen, buffer, NULL, NULL); | ||
334 | } | 301 | } |
335 | 302 | ||
336 | // Map collision | 303 | // Map collision |
337 | 304 | ||
338 | MapCollisionComponent::MapCollisionComponent(Entity& entity, Map* map) : Component(entity) | 305 | MapCollisionComponent::MapCollisionComponent(Map& map) |
339 | { | 306 | { |
340 | this->map = map; | 307 | leftMap = map.getLeftMap(); |
308 | rightMap = map.getRightMap(); | ||
341 | 309 | ||
342 | add_collision(-6, 0, GAME_WIDTH, left, (map->getLeftMap() == NULL) ? 1 : 2); | 310 | add_collision(-6, 0, GAME_WIDTH, left, (map.getLeftMap() == nullptr) ? 1 : 2); |
343 | add_collision(GAME_WIDTH+6, 0, GAME_WIDTH, right, (map->getRightMap() == NULL) ? 3 : 2); | 311 | add_collision(GAME_WIDTH+6, 0, GAME_WIDTH, right, (map.getRightMap() == nullptr) ? 3 : 2); |
344 | 312 | ||
345 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) | 313 | for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++) |
346 | { | 314 | { |
347 | int x = i % MAP_WIDTH; | 315 | int x = i % MAP_WIDTH; |
348 | int y = i / MAP_WIDTH; | 316 | int y = i / MAP_WIDTH; |
349 | int tile = map->mapdata()[i]; | 317 | int tile = map.mapdata()[i]; |
350 | 318 | ||
351 | if ((tile > 0) && (!((tile >= 5) && (tile <= 7)))) | 319 | if ((tile > 0) && (!((tile >= 5) && (tile <= 7)))) |
352 | { | 320 | { |
@@ -410,34 +378,36 @@ void MapCollisionComponent::add_collision(int axis, int lower, int upper, direct | |||
410 | } | 378 | } |
411 | } | 379 | } |
412 | 380 | ||
413 | void MapCollisionComponent::detectCollision(Entity& player, Locatable& physics, std::pair<double, double> old_position) | 381 | void MapCollisionComponent::detectCollision(Game& game, Entity&, Entity& collider, std::pair<double, double> old_position) |
414 | { | 382 | { |
415 | int fixed_x = (int) physics.position.first; | 383 | int fixed_x = (int) collider.position.first; |
416 | int fixed_y = (int) physics.position.second; | 384 | int fixed_y = (int) collider.position.second; |
417 | int fixed_ox = (int) old_position.first; | 385 | int fixed_ox = (int) old_position.first; |
418 | int fixed_oy = (int) old_position.second; | 386 | int fixed_oy = (int) old_position.second; |
419 | 387 | ||
420 | if (fixed_x < fixed_ox) | 388 | if (fixed_x < fixed_ox) |
421 | { | 389 | { |
422 | for (auto it=left_collisions.begin(); it!=left_collisions.end(); it++) | 390 | for (auto collision : left_collisions) |
423 | { | 391 | { |
424 | if (it->axis > fixed_ox) continue; | 392 | if (collision.axis > fixed_ox) continue; |
425 | if (it->axis < fixed_x) break; | 393 | if (collision.axis < fixed_x) break; |
426 | 394 | ||
427 | if ((fixed_oy+physics.size.second > it->lower) && (fixed_oy < it->upper)) | 395 | if ((fixed_oy+collider.size.second > collision.lower) && (fixed_oy < collision.upper)) |
428 | { | 396 | { |
429 | // We have a collision! | 397 | // We have a collision! |
430 | if (it->type == 0) | 398 | if (collision.type == 0) |
431 | { | 399 | { |
432 | physics.position.first = it->axis; | 400 | collider.position.first = collision.axis; |
433 | physics.velocity.first = 0; | 401 | |
434 | } else if (it->type == 1) | 402 | Message msg(Message::Type::stopMovingHorizontally); |
403 | collider.send(game, msg); | ||
404 | } else if (collision.type == 1) | ||
435 | { | 405 | { |
436 | physics.position.first = GAME_WIDTH-physics.size.first/2; | 406 | collider.position.first = GAME_WIDTH-collider.size.first/2; |
437 | } else if (it->type == 2) | 407 | } else if (collision.type == 2) |
438 | { | 408 | { |
439 | physics.position.first = GAME_WIDTH-physics.size.first/2; | 409 | collider.position.first = GAME_WIDTH-collider.size.first/2; |
440 | Game::getInstance().loadMap(map->getLeftMap()); | 410 | game.loadMap(*leftMap); |
441 | } | 411 | } |
442 | 412 | ||
443 | break; | 413 | break; |
@@ -445,32 +415,33 @@ void MapCollisionComponent::detectCollision(Entity& player, Locatable& physics, | |||
445 | } | 415 | } |
446 | } else if (fixed_x > fixed_ox) | 416 | } else if (fixed_x > fixed_ox) |
447 | { | 417 | { |
448 | for (auto it=right_collisions.begin(); it!=right_collisions.end(); it++) | 418 | for (auto collision : right_collisions) |
449 | { | 419 | { |
450 | if (it->axis < fixed_ox+physics.size.first) continue; | 420 | if (collision.axis < fixed_ox+collider.size.first) continue; |
451 | if (it->axis > fixed_x+physics.size.first) break; | 421 | if (collision.axis > fixed_x+collider.size.first) break; |
452 | 422 | ||
453 | if ((fixed_oy+physics.size.second > it->lower) && (fixed_oy < it->upper)) | 423 | if ((fixed_oy+collider.size.second > collision.lower) && (fixed_oy < collision.upper)) |
454 | { | 424 | { |
455 | // We have a collision! | 425 | // We have a collision! |
456 | if (it->type == 0) | 426 | if (collision.type == 0) |
457 | { | 427 | { |
458 | physics.position.first = it->axis - physics.size.first; | 428 | collider.position.first = collision.axis - collider.size.first; |
459 | physics.velocity.first = 0; | 429 | |
460 | } else if (it->type == 1) | 430 | Message msg(Message::Type::stopMovingHorizontally); |
431 | collider.send(game, msg); | ||
432 | } else if (collision.type == 1) | ||
461 | { | 433 | { |
462 | physics.position.first = -physics.size.first/2; | 434 | collider.position.first = -collider.size.first/2; |
463 | } else if (it->type == 2) | 435 | } else if (collision.type == 2) |
464 | { | 436 | { |
465 | physics.position.first = -physics.size.first/2; | 437 | collider.position.first = -collider.size.first/2; |
466 | Game::getInstance().loadMap(map->getRightMap()); | 438 | game.loadMap(*rightMap); |
467 | } else if (it->type == 3) | 439 | } else if (collision.type == 3) |
468 | { | 440 | { |
469 | physics.position.first = it->axis - physics.size.first; | 441 | collider.position.first = collision.axis - collider.size.first; |
470 | 442 | ||
471 | message_t msg; | 443 | Message msg(Message::Type::walkLeft); |
472 | msg.type = CM_WALK_LEFT; | 444 | collider.send(game, msg); |
473 | player.send(msg); | ||
474 | } | 445 | } |
475 | 446 | ||
476 | break; | 447 | break; |
@@ -478,26 +449,28 @@ void MapCollisionComponent::detectCollision(Entity& player, Locatable& physics, | |||
478 | } | 449 | } |
479 | } | 450 | } |
480 | 451 | ||
481 | fixed_x = (int) physics.position.first; | 452 | fixed_x = (int) collider.position.first; |
482 | fixed_y = (int) physics.position.second; | 453 | fixed_y = (int) collider.position.second; |
483 | 454 | ||
484 | if (fixed_y < fixed_oy) | 455 | if (fixed_y < fixed_oy) |
485 | { | 456 | { |
486 | for (auto it=up_collisions.begin(); it!=up_collisions.end(); it++) | 457 | for (auto collision : up_collisions) |
487 | { | 458 | { |
488 | if (it->axis > fixed_oy) continue; | 459 | if (collision.axis > fixed_oy) continue; |
489 | if (it->axis < fixed_y) break; | 460 | if (collision.axis < fixed_y) break; |
490 | 461 | ||
491 | if ((fixed_x+physics.size.first > it->lower) && (fixed_x < it->upper)) | 462 | if ((fixed_x+collider.size.first > collision.lower) && (fixed_x < collision.upper)) |
492 | { | 463 | { |
493 | // We have a collision! | 464 | // We have a collision! |
494 | if (it->type == 0) | 465 | if (collision.type == 0) |
495 | { | 466 | { |
496 | physics.position.second = it->axis; | 467 | collider.position.second = collision.axis; |
497 | physics.velocity.second = 0; | 468 | |
498 | } else if (it->type == 1) | 469 | Message msg(Message::Type::stopMovingVertically); |
470 | collider.send(game, msg); | ||
471 | } else if (collision.type == 1) | ||
499 | { | 472 | { |
500 | physics.position.second = GAME_HEIGHT-physics.size.second/2-1; | 473 | collider.position.second = GAME_HEIGHT-collider.size.second/2-1; |
501 | } | 474 | } |
502 | 475 | ||
503 | break; | 476 | break; |
@@ -505,29 +478,29 @@ void MapCollisionComponent::detectCollision(Entity& player, Locatable& physics, | |||
505 | } | 478 | } |
506 | } else if (fixed_y > fixed_oy) | 479 | } else if (fixed_y > fixed_oy) |
507 | { | 480 | { |
508 | for (auto it=down_collisions.begin(); it!=down_collisions.end(); it++) | 481 | for (auto collision : down_collisions) |
509 | { | 482 | { |
510 | if (it->axis < fixed_oy+physics.size.second) continue; | 483 | if (collision.axis < fixed_oy+collider.size.second) continue; |
511 | if (it->axis > fixed_y+physics.size.second) break; | 484 | if (collision.axis > fixed_y+collider.size.second) break; |
512 | 485 | ||
513 | if ((fixed_x+physics.size.first > it->lower) && (fixed_x < it->upper)) | 486 | if ((fixed_x+collider.size.first > collision.lower) && (fixed_x < collision.upper)) |
514 | { | 487 | { |
515 | // We have a collision! | 488 | // We have a collision! |
516 | if (it->type == 0) | 489 | if (collision.type == 0) |
517 | { | 490 | { |
518 | physics.position.second = it->axis - physics.size.second; | 491 | collider.position.second = collision.axis - collider.size.second; |
519 | physics.velocity.second = 0; | 492 | |
520 | //mob->onGround = true; | 493 | Message msg(Message::Type::stopMovingVertically); |
521 | } else if (it->type == 1) | 494 | collider.send(game, msg); |
495 | } else if (collision.type == 1) | ||
522 | { | 496 | { |
523 | physics.position.second = -physics.size.second/2; | 497 | collider.position.second = -collider.size.second/2; |
524 | } else if (it->type == 3) | 498 | } else if (collision.type == 3) |
525 | { | 499 | { |
526 | message_t msg; | 500 | Message msg(Message::Type::drop); |
527 | msg.type = CM_DROP; | 501 | msg.dropAxis = collision.axis; |
528 | msg.dropAxis = it->axis; | 502 | |
529 | 503 | collider.send(game, msg); | |
530 | player.send(msg); | ||
531 | } | 504 | } |
532 | 505 | ||
533 | break; | 506 | break; |
diff --git a/src/components.h b/src/components.h index 687eab1..f9b6e1e 100644 --- a/src/components.h +++ b/src/components.h | |||
@@ -5,48 +5,50 @@ | |||
5 | #include <utility> | 5 | #include <utility> |
6 | #include <list> | 6 | #include <list> |
7 | #include "map.h" | 7 | #include "map.h" |
8 | #include <memory> | ||
8 | 9 | ||
9 | class UserMovementComponent : public Component { | 10 | class UserMovementComponent : public Component { |
10 | public: | 11 | public: |
11 | UserMovementComponent(Entity& parent) : Component(parent) {}; | 12 | void input(Game& game, Entity& entity, int key, int action); |
12 | void input(int key, int action); | ||
13 | 13 | ||
14 | private: | 14 | private: |
15 | bool holdingLeft = false; | 15 | bool holdingLeft = false; |
16 | bool holdingRight = false; | 16 | bool holdingRight = false; |
17 | }; | 17 | }; |
18 | 18 | ||
19 | class PhysicsBodyComponent : public Component, public Collidable, public Locatable { | 19 | class PhysicsBodyComponent : public Component { |
20 | public: | 20 | public: |
21 | PhysicsBodyComponent(Entity& parent) : Component(parent) {}; | 21 | void receive(Game& game, Entity& entity, Message& msg); |
22 | void receive(message_t msg); | 22 | void tick(Game& game, Entity& entity); |
23 | void tick(); | 23 | void detectCollision(Game& game, Entity& entity, Entity& collider, std::pair<double, double> old_position); |
24 | void detectCollision(Entity& player, Locatable& physics, std::pair<double, double> old_position); | 24 | |
25 | private: | ||
26 | std::pair<double, double> velocity; | ||
27 | std::pair<double, double> accel; | ||
25 | }; | 28 | }; |
26 | 29 | ||
27 | class PlayerSpriteComponent : public Component { | 30 | class PlayerSpriteComponent : public Component { |
28 | public: | 31 | public: |
29 | PlayerSpriteComponent(Entity& parent, Locatable& physics); | 32 | void render(Game& game, Entity& entity, Texture& buffer); |
30 | ~PlayerSpriteComponent(); | 33 | void receive(Game& game, Entity& entity, Message& msg); |
31 | void render(Texture* buffer); | 34 | void tick(Game& game, Entity& entity); |
32 | void receive(message_t msg); | ||
33 | void tick(); | ||
34 | 35 | ||
35 | private: | 36 | private: |
36 | Locatable& physics; | 37 | Texture sprite{"../res/Starla.png"}; |
37 | Texture* sprite; | ||
38 | int animFrame = 0; | 38 | int animFrame = 0; |
39 | bool facingLeft = false; | 39 | bool facingLeft = false; |
40 | bool isMoving = false; | 40 | bool isMoving = false; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | class PlayerPhysicsComponent : public Component, public Locatable { | 43 | class PlayerPhysicsComponent : public Component { |
44 | public: | 44 | public: |
45 | PlayerPhysicsComponent(Entity& parent); | 45 | PlayerPhysicsComponent(); |
46 | void tick(); | 46 | void tick(Game& game, Entity& entity); |
47 | void receive(message_t msg); | 47 | void receive(Game& game, Entity& entity, Message& msg); |
48 | 48 | ||
49 | private: | 49 | private: |
50 | std::pair<double, double> velocity; | ||
51 | std::pair<double, double> accel; | ||
50 | double jump_velocity; | 52 | double jump_velocity; |
51 | double jump_gravity; | 53 | double jump_gravity; |
52 | double jump_gravity_short; | 54 | double jump_gravity_short; |
@@ -56,38 +58,38 @@ class PlayerPhysicsComponent : public Component, public Locatable { | |||
56 | 58 | ||
57 | class MapRenderComponent : public Component { | 59 | class MapRenderComponent : public Component { |
58 | public: | 60 | public: |
59 | MapRenderComponent(Entity& parent, Map* map); | 61 | MapRenderComponent(Map& map); |
60 | ~MapRenderComponent(); | 62 | void render(Game& game, Entity& entity, Texture& buffer); |
61 | void render(Texture* buffer); | ||
62 | 63 | ||
63 | private: | 64 | private: |
64 | Texture* screen; | 65 | Texture screen{GAME_WIDTH, GAME_HEIGHT}; |
65 | }; | ||
66 | |||
67 | enum direction_t { | ||
68 | up, left, down, right | ||
69 | }; | 66 | }; |
70 | 67 | ||
71 | typedef struct { | 68 | class MapCollisionComponent : public Component { |
72 | int axis; | ||
73 | int lower; | ||
74 | int upper; | ||
75 | int type; | ||
76 | } collision_t; | ||
77 | |||
78 | class MapCollisionComponent : public Component, public Collidable { | ||
79 | public: | 69 | public: |
80 | MapCollisionComponent(Entity& parent, Map* map); | 70 | MapCollisionComponent(Map& map); |
81 | void detectCollision(Entity& player, Locatable& physics, std::pair<double, double> old_position); | 71 | void detectCollision(Game& game, Entity& entity, Entity& collider, std::pair<double, double> old_position); |
82 | 72 | ||
83 | private: | 73 | private: |
74 | enum direction_t { | ||
75 | up, left, down, right | ||
76 | }; | ||
77 | |||
78 | typedef struct { | ||
79 | int axis; | ||
80 | int lower; | ||
81 | int upper; | ||
82 | int type; | ||
83 | } collision_t; | ||
84 | |||
84 | void add_collision(int axis, int lower, int upper, direction_t dir, int type); | 85 | void add_collision(int axis, int lower, int upper, direction_t dir, int type); |
85 | 86 | ||
86 | std::list<collision_t> left_collisions; | 87 | std::list<collision_t> left_collisions; |
87 | std::list<collision_t> right_collisions; | 88 | std::list<collision_t> right_collisions; |
88 | std::list<collision_t> up_collisions; | 89 | std::list<collision_t> up_collisions; |
89 | std::list<collision_t> down_collisions; | 90 | std::list<collision_t> down_collisions; |
90 | Map* map; | 91 | Map* leftMap; |
92 | Map* rightMap; | ||
91 | }; | 93 | }; |
92 | 94 | ||
93 | #endif | 95 | #endif |
diff --git a/src/entity.cpp b/src/entity.cpp index 405de24..950969e 100644 --- a/src/entity.cpp +++ b/src/entity.cpp | |||
@@ -5,34 +5,42 @@ void Entity::addComponent(std::shared_ptr<Component> c) | |||
5 | components.push_back(c); | 5 | components.push_back(c); |
6 | } | 6 | } |
7 | 7 | ||
8 | void Entity::send(message_t msg) | 8 | void Entity::send(Game& game, Message& msg) |
9 | { | 9 | { |
10 | for (auto it = components.begin(); it != components.end(); it++) | 10 | for (auto component : components) |
11 | { | 11 | { |
12 | (*it)->receive(msg); | 12 | component->receive(game, *this, msg); |
13 | } | 13 | } |
14 | } | 14 | } |
15 | 15 | ||
16 | void Entity::tick() | 16 | void Entity::tick(Game& game) |
17 | { | 17 | { |
18 | for (auto it = components.begin(); it != components.end(); it++) | 18 | for (auto component : components) |
19 | { | 19 | { |
20 | (*it)->tick(); | 20 | component->tick(game, *this); |
21 | } | 21 | } |
22 | } | 22 | } |
23 | 23 | ||
24 | void Entity::input(int key, int action) | 24 | void Entity::input(Game& game, int key, int action) |
25 | { | 25 | { |
26 | for (auto it = components.begin(); it != components.end(); it++) | 26 | for (auto component : components) |
27 | { | 27 | { |
28 | (*it)->input(key, action); | 28 | component->input(game, *this, key, action); |
29 | } | 29 | } |
30 | } | 30 | } |
31 | 31 | ||
32 | void Entity::render(Texture* buffer) | 32 | void Entity::render(Game& game, Texture& buffer) |
33 | { | 33 | { |
34 | for (auto it = components.begin(); it != components.end(); it++) | 34 | for (auto component : components) |
35 | { | 35 | { |
36 | (*it)->render(buffer); | 36 | component->render(game, *this, buffer); |
37 | } | ||
38 | } | ||
39 | |||
40 | void Entity::detectCollision(Game& game, Entity& collider, std::pair<double, double> old_position) | ||
41 | { | ||
42 | for (auto component : components) | ||
43 | { | ||
44 | component->detectCollision(game, *this, collider, old_position); | ||
37 | } | 45 | } |
38 | } | 46 | } |
diff --git a/src/entity.h b/src/entity.h index 5a37147..803a9b8 100644 --- a/src/entity.h +++ b/src/entity.h | |||
@@ -3,42 +3,45 @@ | |||
3 | 3 | ||
4 | class Entity; | 4 | class Entity; |
5 | class Component; | 5 | class Component; |
6 | class Locatable; | ||
7 | class Collidable; | ||
8 | 6 | ||
9 | #include <list> | 7 | #include <list> |
10 | #include "renderer.h" | 8 | #include "renderer.h" |
11 | #include "world.h" | 9 | #include "game.h" |
12 | 10 | ||
13 | enum message_type { | 11 | class Message { |
14 | CM_WALK_LEFT, | 12 | public: |
15 | CM_WALK_RIGHT, | 13 | enum class Type { |
16 | CM_STOP_WALKING, | 14 | walkLeft, |
17 | CM_COLLISION, | 15 | walkRight, |
18 | CM_JUMP, | 16 | stopWalking, |
19 | CM_STOP_JUMP, | 17 | stopMovingHorizontally, |
20 | CM_DROP, | 18 | stopMovingVertically, |
21 | CM_CAN_DROP, | 19 | collision, |
22 | CM_CANT_DROP | 20 | jump, |
21 | stopJump, | ||
22 | drop, | ||
23 | canDrop, | ||
24 | cantDrop | ||
25 | }; | ||
26 | |||
27 | Message(Type type) : type(type) {} | ||
28 | |||
29 | Type type; | ||
30 | Entity* collisionEntity; | ||
31 | int dropAxis; | ||
23 | }; | 32 | }; |
24 | 33 | ||
25 | typedef struct { | ||
26 | message_type type; | ||
27 | Entity* collisionEntity; | ||
28 | int dropAxis; | ||
29 | } message_t; | ||
30 | |||
31 | class Entity { | 34 | class Entity { |
32 | public: | 35 | public: |
33 | Entity(World* world) : world(world) {} | ||
34 | ~Entity() {}; | ||
35 | void addComponent(std::shared_ptr<Component> c); | 36 | void addComponent(std::shared_ptr<Component> c); |
36 | void send(message_t msg); | 37 | void send(Game& game, Message& msg); |
37 | void tick(); | 38 | void tick(Game& game); |
38 | void input(int key, int action); | 39 | void input(Game& game, int key, int action); |
39 | void render(Texture* buffer); | 40 | void render(Game& game, Texture& buffer); |
41 | void detectCollision(Game& game, Entity& collider, std::pair<double, double> old_position); | ||
40 | 42 | ||
41 | World* world; | 43 | std::pair<double, double> position; |
44 | std::pair<int, int> size; | ||
42 | 45 | ||
43 | private: | 46 | private: |
44 | std::list<std::shared_ptr<Component>> components; | 47 | std::list<std::shared_ptr<Component>> components; |
@@ -46,27 +49,11 @@ class Entity { | |||
46 | 49 | ||
47 | class Component { | 50 | class Component { |
48 | public: | 51 | public: |
49 | Component(Entity& entity) : entity(entity) {} | 52 | virtual void receive(Game&, Entity&, Message&) {} |
50 | virtual ~Component() {}; | 53 | virtual void render(Game&, Entity&, Texture&) {} |
51 | virtual void receive(message_t msg) {(void)msg;} | 54 | virtual void tick(Game&, Entity&) {} |
52 | virtual void render(Texture* tex) {(void)tex;} | 55 | virtual void input(Game&, Entity&, int, int) {} |
53 | virtual void tick() {} | 56 | virtual void detectCollision(Game&, Entity&, Entity&, std::pair<double, double>) {} |
54 | virtual void input(int key, int action) {(void)key; (void)action;} | ||
55 | |||
56 | Entity& entity; | ||
57 | }; | ||
58 | |||
59 | class Locatable { | ||
60 | public: | ||
61 | std::pair<double, double> position; | ||
62 | std::pair<int, int> size; | ||
63 | std::pair<double, double> velocity; | ||
64 | std::pair<double, double> accel; | ||
65 | }; | ||
66 | |||
67 | class Collidable { | ||
68 | public: | ||
69 | virtual void detectCollision(Entity& player, Locatable& physics, std::pair<double, double> old_position) = 0; | ||
70 | }; | 57 | }; |
71 | 58 | ||
72 | #endif | 59 | #endif |
diff --git a/src/game.cpp b/src/game.cpp index 2db0a2c..cbbae06 100644 --- a/src/game.cpp +++ b/src/game.cpp | |||
@@ -1,124 +1,113 @@ | |||
1 | #include "game.h" | 1 | #include "game.h" |
2 | #include "renderer.h" | 2 | #include "renderer.h" |
3 | #include "components.h" | ||
3 | 4 | ||
4 | Game::Game() | 5 | Game::Game() |
5 | { | 6 | { |
6 | window = initRenderer(); | 7 | m.setLeftMap(&m2); |
7 | glfwSwapInterval(1); | 8 | m2.setRightMap(&m); |
8 | |||
9 | m = new Map("../maps/embarass.txt"); | ||
10 | m2 = new Map("../maps/second.txt"); | ||
11 | |||
12 | m->setLeftMap(m2); | ||
13 | m2->setRightMap(m); | ||
14 | |||
15 | world = new World(); | ||
16 | 9 | ||
17 | auto player = std::make_shared<Entity>(world); | 10 | player = std::make_shared<Entity>(); |
11 | player->position = std::make_pair(100.0,100.0); | ||
12 | player->size = std::make_pair(10.0,12.0); | ||
18 | 13 | ||
19 | auto player_input = std::make_shared<UserMovementComponent>(*player); | 14 | auto player_input = std::make_shared<UserMovementComponent>(); |
20 | player->addComponent(player_input); | 15 | player->addComponent(player_input); |
21 | 16 | ||
22 | auto player_physics = std::make_shared<PlayerPhysicsComponent>(*player); | 17 | auto player_physics = std::make_shared<PlayerPhysicsComponent>(); |
23 | player_physics->position = std::make_pair(100.0,100.0); | ||
24 | player_physics->size = std::make_pair(10.0,12.0); | ||
25 | player->addComponent(player_physics); | 18 | player->addComponent(player_physics); |
26 | 19 | ||
27 | auto player_anim = std::make_shared<PlayerSpriteComponent>(*player, *player_physics); | 20 | auto player_anim = std::make_shared<PlayerSpriteComponent>(); |
28 | player->addComponent(player_anim); | 21 | player->addComponent(player_anim); |
29 | 22 | ||
30 | world->addEntity(player); | ||
31 | world->player = player; | ||
32 | |||
33 | loadMap(m); | 23 | loadMap(m); |
34 | } | 24 | } |
35 | 25 | ||
36 | Game::~Game() | 26 | void key_callback(GLFWwindow* window, int key, int, int action, int) |
37 | { | 27 | { |
38 | if (world != 0) | 28 | Game* game = (Game*) glfwGetWindowUserPointer(window); |
39 | { | ||
40 | delete world; | ||
41 | } | ||
42 | 29 | ||
43 | if (nextWorld != 0) | 30 | if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS)) |
44 | { | 31 | { |
45 | delete nextWorld; | 32 | game->shouldQuit = true; |
46 | } | 33 | } |
47 | 34 | ||
48 | delete m; | 35 | for (auto entity : game->entities) |
49 | delete m2; | ||
50 | |||
51 | destroyRenderer(); | ||
52 | } | ||
53 | |||
54 | void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) | ||
55 | { | ||
56 | (void)window; | ||
57 | (void)scancode; | ||
58 | (void)mods; | ||
59 | |||
60 | if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS)) | ||
61 | { | 36 | { |
62 | Game::getInstance().shouldQuit = true; | 37 | entity->input(*game, key, action); |
63 | } | 38 | } |
64 | |||
65 | Game::getInstance().input(key, action); | ||
66 | } | 39 | } |
67 | 40 | ||
68 | void Game::execute() | 41 | void Game::execute(GLFWwindow* window) |
69 | { | 42 | { |
43 | glfwSwapInterval(1); | ||
44 | glfwSetWindowUserPointer(window, this); | ||
70 | glfwSetKeyCallback(window, key_callback); | 45 | glfwSetKeyCallback(window, key_callback); |
71 | 46 | ||
72 | Texture* buffer = createTexture(GAME_WIDTH, GAME_HEIGHT); | 47 | Texture buffer(GAME_WIDTH, GAME_HEIGHT); |
73 | 48 | ||
49 | double lastTime = glfwGetTime(); | ||
50 | int nbFrames = 0; | ||
74 | while (!(shouldQuit || glfwWindowShouldClose(window))) | 51 | while (!(shouldQuit || glfwWindowShouldClose(window))) |
75 | { | 52 | { |
53 | double currentTime = glfwGetTime(); | ||
54 | nbFrames++; | ||
55 | if (currentTime - lastTime >= 1.0) | ||
56 | { | ||
57 | printf("%f ms/frame\n", 1000.0/double(nbFrames)); | ||
58 | nbFrames = 0; | ||
59 | lastTime += 1.0; | ||
60 | } | ||
61 | |||
76 | // Should we load a new world? | 62 | // Should we load a new world? |
77 | if (nextWorld != 0) | 63 | if (newWorld) |
78 | { | 64 | { |
79 | delete world; | 65 | newWorld = false; |
80 | world = nextWorld; | 66 | entities.clear(); |
81 | world->player->world = world; | 67 | entities = std::move(nextEntities); |
82 | nextWorld = 0; | ||
83 | } | 68 | } |
84 | 69 | ||
85 | // Handle input | 70 | // Handle input |
86 | glfwPollEvents(); | 71 | glfwPollEvents(); |
87 | 72 | ||
88 | // Tick! | 73 | // Tick! |
89 | world->tick(); | 74 | for (auto entity : entities) |
75 | { | ||
76 | entity->tick(*this); | ||
77 | } | ||
90 | 78 | ||
91 | // Do rendering | 79 | // Do rendering |
92 | world->render(buffer); | 80 | buffer.fill(buffer.entirety(), 0, 0, 0); |
93 | renderScreen(buffer); | 81 | for (auto entity : entities) |
94 | } | 82 | { |
95 | 83 | entity->render(*this, buffer); | |
96 | destroyTexture(buffer); | 84 | } |
97 | } | ||
98 | 85 | ||
99 | void Game::input(int key, int action) | 86 | buffer.renderScreen(); |
100 | { | ||
101 | if (world != NULL) | ||
102 | { | ||
103 | world->input(key, action); | ||
104 | } | 87 | } |
105 | } | 88 | } |
106 | 89 | ||
107 | void Game::loadMap(Map* map) | 90 | void Game::loadMap(Map& map) |
108 | { | 91 | { |
109 | nextWorld = new World(); | 92 | auto mapEn = std::make_shared<Entity>(); |
110 | |||
111 | nextWorld->player = world->player; | ||
112 | |||
113 | auto mapEn = std::make_shared<Entity>(nextWorld); | ||
114 | 93 | ||
115 | auto map_render = std::make_shared<MapRenderComponent>(*mapEn, map); | 94 | auto map_render = std::make_shared<MapRenderComponent>(map); |
116 | mapEn->addComponent(map_render); | 95 | mapEn->addComponent(map_render); |
117 | 96 | ||
118 | auto map_collision = std::make_shared<MapCollisionComponent>(*mapEn, map); | 97 | auto map_collision = std::make_shared<MapCollisionComponent>(map); |
119 | mapEn->addComponent(map_collision); | 98 | mapEn->addComponent(map_collision); |
120 | nextWorld->bodies.push_back(map_collision.get()); | ||
121 | 99 | ||
122 | nextWorld->addEntity(mapEn); | 100 | nextEntities.clear(); |
123 | nextWorld->addEntity(nextWorld->player); | 101 | nextEntities.push_back(mapEn); |
102 | nextEntities.push_back(player); | ||
103 | |||
104 | newWorld = true; | ||
105 | } | ||
106 | |||
107 | void Game::detectCollision(Entity& collider, std::pair<double, double> old_position) | ||
108 | { | ||
109 | for (auto entity : entities) | ||
110 | { | ||
111 | entity->detectCollision(*this, collider, old_position); | ||
112 | } | ||
124 | } | 113 | } |
diff --git a/src/game.h b/src/game.h index 69224dc..c419c5d 100644 --- a/src/game.h +++ b/src/game.h | |||
@@ -1,7 +1,11 @@ | |||
1 | #ifndef GAME_H | 1 | #ifndef GAME_H |
2 | #define GAME_H | 2 | #define GAME_H |
3 | 3 | ||
4 | #include "components.h" | 4 | class Game; |
5 | |||
6 | #include "map.h" | ||
7 | #include <memory> | ||
8 | #include "entity.h" | ||
5 | 9 | ||
6 | const int TILE_WIDTH = 8; | 10 | const int TILE_WIDTH = 8; |
7 | const int TILE_HEIGHT = 8; | 11 | const int TILE_HEIGHT = 8; |
@@ -15,29 +19,21 @@ const double SECONDS_PER_FRAME = 1.0 / FRAMES_PER_SECOND; | |||
15 | 19 | ||
16 | class Game { | 20 | class Game { |
17 | public: | 21 | public: |
18 | static Game& getInstance() | 22 | Game(); |
19 | { | 23 | void execute(GLFWwindow* window); |
20 | static Game instance; | 24 | void loadMap(Map& map); |
21 | 25 | void detectCollision(Entity& collider, std::pair<double, double> old_position); | |
22 | return instance; | ||
23 | } | ||
24 | |||
25 | ~Game(); | ||
26 | void execute(); | ||
27 | void loadMap(Map* map); | ||
28 | void input(int key, int action); | ||
29 | 26 | ||
30 | bool shouldQuit = false; | 27 | bool shouldQuit = false; |
31 | private: | 28 | private: |
32 | Game(); | 29 | friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); |
33 | Game(Game const&); | 30 | |
34 | void operator=(Game const&); | 31 | std::list<std::shared_ptr<Entity>> entities; |
35 | 32 | std::list<std::shared_ptr<Entity>> nextEntities; | |
36 | GLFWwindow* window; | 33 | bool newWorld; |
37 | World* world; | 34 | std::shared_ptr<Entity> player; |
38 | World* nextWorld; | 35 | Map m{"../maps/embarass.txt"}; |
39 | Map* m; | 36 | Map m2{"../maps/second.txt"}; |
40 | Map* m2; | ||
41 | }; | 37 | }; |
42 | 38 | ||
43 | #endif | 39 | #endif |
diff --git a/src/main.cpp b/src/main.cpp index c552d2a..e37c2dd 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -8,7 +8,15 @@ int main() | |||
8 | { | 8 | { |
9 | srand(time(NULL)); | 9 | srand(time(NULL)); |
10 | 10 | ||
11 | Game::getInstance().execute(); | 11 | GLFWwindow* window = initRenderer(); |
12 | |||
13 | // Put this in a block so game goes out of scope before we destroy the renderer | ||
14 | { | ||
15 | Game game; | ||
16 | game.execute(window); | ||
17 | } | ||
18 | |||
19 | destroyRenderer(); | ||
12 | 20 | ||
13 | return 0; | 21 | return 0; |
14 | } | 22 | } |
diff --git a/src/map.cpp b/src/map.cpp index fda8009..87080e8 100644 --- a/src/map.cpp +++ b/src/map.cpp | |||
@@ -1,7 +1,14 @@ | |||
1 | #include "map.h" | 1 | #include "map.h" |
2 | #include "game.h" | 2 | #include "game.h" |
3 | #include <cstdlib> | ||
4 | #include <cstring> | ||
3 | 5 | ||
4 | Map::Map(char* filename) | 6 | Map::Map() |
7 | { | ||
8 | |||
9 | } | ||
10 | |||
11 | Map::Map(const char* filename) | ||
5 | { | 12 | { |
6 | FILE* f = fopen(filename, "r"); | 13 | FILE* f = fopen(filename, "r"); |
7 | 14 | ||
@@ -22,12 +29,44 @@ Map::Map(char* filename) | |||
22 | fclose(f); | 29 | fclose(f); |
23 | } | 30 | } |
24 | 31 | ||
32 | Map::Map(Map& map) | ||
33 | { | ||
34 | m_mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | ||
35 | memcpy(m_mapdata, map.m_mapdata, MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); | ||
36 | |||
37 | m_title = (char*) malloc((MAP_WIDTH+1)*sizeof(char)); | ||
38 | strncpy(m_title, map.m_title, MAP_WIDTH+1); | ||
39 | |||
40 | m_leftMap = map.m_leftMap; | ||
41 | m_rightMap = map.m_rightMap; | ||
42 | } | ||
43 | |||
44 | Map::Map(Map&& map) : Map() | ||
45 | { | ||
46 | swap(*this, map); | ||
47 | } | ||
48 | |||
25 | Map::~Map() | 49 | Map::~Map() |
26 | { | 50 | { |
27 | free(m_mapdata); | 51 | free(m_mapdata); |
28 | free(m_title); | 52 | free(m_title); |
29 | } | 53 | } |
30 | 54 | ||
55 | Map& Map::operator= (Map map) | ||
56 | { | ||
57 | swap(*this, map); | ||
58 | |||
59 | return *this; | ||
60 | } | ||
61 | |||
62 | void swap(Map& first, Map& second) | ||
63 | { | ||
64 | std::swap(first.m_mapdata, second.m_mapdata); | ||
65 | std::swap(first.m_title, second.m_title); | ||
66 | std::swap(first.m_leftMap, second.m_leftMap); | ||
67 | std::swap(first.m_rightMap, second.m_rightMap); | ||
68 | } | ||
69 | |||
31 | const int* Map::mapdata() | 70 | const int* Map::mapdata() |
32 | { | 71 | { |
33 | return m_mapdata; | 72 | return m_mapdata; |
diff --git a/src/map.h b/src/map.h index d7b4ecf..e3d1802 100644 --- a/src/map.h +++ b/src/map.h | |||
@@ -3,9 +3,13 @@ | |||
3 | 3 | ||
4 | class Map { | 4 | class Map { |
5 | public: | 5 | public: |
6 | Map(); | 6 | Map(const char* filename); |
7 | Map(char* filename); | 7 | Map(Map& map); |
8 | Map(Map&& map); | ||
8 | ~Map(); | 9 | ~Map(); |
10 | Map& operator= (Map other); | ||
11 | friend void swap(Map& first, Map& second); | ||
12 | |||
9 | const int* mapdata(); | 13 | const int* mapdata(); |
10 | const char* title(); | 14 | const char* title(); |
11 | Map* getLeftMap(); | 15 | Map* getLeftMap(); |
@@ -13,10 +17,12 @@ class Map { | |||
13 | void setLeftMap(Map* m); | 17 | void setLeftMap(Map* m); |
14 | void setRightMap(Map* m); | 18 | void setRightMap(Map* m); |
15 | private: | 19 | private: |
20 | Map(); | ||
21 | |||
16 | int* m_mapdata; | 22 | int* m_mapdata; |
17 | char* m_title; | 23 | char* m_title; |
18 | Map* m_leftMap = 0; | 24 | Map* m_leftMap; |
19 | Map* m_rightMap = 0; | 25 | Map* m_rightMap; |
20 | }; | 26 | }; |
21 | 27 | ||
22 | #endif | 28 | #endif |
diff --git a/src/renderer.cpp b/src/renderer.cpp index e7db069..cf6b2bd 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
@@ -6,6 +6,8 @@ | |||
6 | #include <cstring> | 6 | #include <cstring> |
7 | #include <cstdlib> | 7 | #include <cstdlib> |
8 | #include "game.h" | 8 | #include "game.h" |
9 | #include <glm/glm.hpp> | ||
10 | #include <glm/gtc/matrix_transform.hpp> | ||
9 | 11 | ||
10 | // include stb_image | 12 | // include stb_image |
11 | #define STB_IMAGE_IMPLEMENTATION | 13 | #define STB_IMAGE_IMPLEMENTATION |
@@ -86,27 +88,27 @@ GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) | |||
86 | // Compile Vertex Shader | 88 | // Compile Vertex Shader |
87 | printf("Compiling shader : %s\n", vertex_file_path); | 89 | printf("Compiling shader : %s\n", vertex_file_path); |
88 | char const * VertexSourcePointer = VertexShaderCode.c_str(); | 90 | char const * VertexSourcePointer = VertexShaderCode.c_str(); |
89 | glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); | 91 | glShaderSource(VertexShaderID, 1, &VertexSourcePointer , nullptr); |
90 | glCompileShader(VertexShaderID); | 92 | glCompileShader(VertexShaderID); |
91 | 93 | ||
92 | // Check Vertex Shader | 94 | // Check Vertex Shader |
93 | glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); | 95 | glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); |
94 | glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); | 96 | glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); |
95 | std::vector<char> VertexShaderErrorMessage(InfoLogLength); | 97 | std::vector<char> VertexShaderErrorMessage(InfoLogLength); |
96 | glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); | 98 | glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]); |
97 | fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]); | 99 | fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]); |
98 | 100 | ||
99 | // Compile Fragment Shader | 101 | // Compile Fragment Shader |
100 | printf("Compiling shader : %s\n", fragment_file_path); | 102 | printf("Compiling shader : %s\n", fragment_file_path); |
101 | char const * FragmentSourcePointer = FragmentShaderCode.c_str(); | 103 | char const * FragmentSourcePointer = FragmentShaderCode.c_str(); |
102 | glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); | 104 | glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , nullptr); |
103 | glCompileShader(FragmentShaderID); | 105 | glCompileShader(FragmentShaderID); |
104 | 106 | ||
105 | // Check Fragment Shader | 107 | // Check Fragment Shader |
106 | glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); | 108 | glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); |
107 | glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); | 109 | glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); |
108 | std::vector<char> FragmentShaderErrorMessage(InfoLogLength); | 110 | std::vector<char> FragmentShaderErrorMessage(InfoLogLength); |
109 | glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); | 111 | glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]); |
110 | fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]); | 112 | fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]); |
111 | 113 | ||
112 | // Link the program | 114 | // Link the program |
@@ -120,7 +122,7 @@ GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) | |||
120 | glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); | 122 | glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); |
121 | glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); | 123 | glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); |
122 | std::vector<char> ProgramErrorMessage( glm::max(InfoLogLength, int(1)) ); | 124 | std::vector<char> ProgramErrorMessage( glm::max(InfoLogLength, int(1)) ); |
123 | glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); | 125 | glGetProgramInfoLog(ProgramID, InfoLogLength, nullptr, &ProgramErrorMessage[0]); |
124 | fprintf(stdout, "%s\n", &ProgramErrorMessage[0]); | 126 | fprintf(stdout, "%s\n", &ProgramErrorMessage[0]); |
125 | 127 | ||
126 | glDeleteShader(VertexShaderID); | 128 | glDeleteShader(VertexShaderID); |
@@ -147,7 +149,7 @@ void flipImageData(unsigned char* data, int width, int height, int comps) | |||
147 | void loadMesh(const char* filename, std::vector<glm::vec3>& out_vertices, std::vector<glm::vec2>& out_uvs, std::vector<glm::vec3>& out_normals) | 149 | void loadMesh(const char* filename, std::vector<glm::vec3>& out_vertices, std::vector<glm::vec2>& out_uvs, std::vector<glm::vec3>& out_normals) |
148 | { | 150 | { |
149 | FILE* file = fopen(filename, "r"); | 151 | FILE* file = fopen(filename, "r"); |
150 | if (file == NULL) | 152 | if (file == nullptr) |
151 | { | 153 | { |
152 | fprintf(stderr, "Could not open mesh file %s\n", filename); | 154 | fprintf(stderr, "Could not open mesh file %s\n", filename); |
153 | exit(1); | 155 | exit(1); |
@@ -168,17 +170,17 @@ void loadMesh(const char* filename, std::vector<glm::vec3>& out_vertices, std::v | |||
168 | 170 | ||
169 | if (!strncmp(lineHeader, "v", 2)) | 171 | if (!strncmp(lineHeader, "v", 2)) |
170 | { | 172 | { |
171 | vec3 vertex; | 173 | glm::vec3 vertex; |
172 | fscanf(file, "%f %f %f\n", &vertex.x,&vertex.y,&vertex.z); | 174 | fscanf(file, "%f %f %f\n", &vertex.x,&vertex.y,&vertex.z); |
173 | temp_vertices.push_back(vertex); | 175 | temp_vertices.push_back(vertex); |
174 | } else if (!strncmp(lineHeader, "vt", 3)) | 176 | } else if (!strncmp(lineHeader, "vt", 3)) |
175 | { | 177 | { |
176 | vec2 uv; | 178 | glm::vec2 uv; |
177 | fscanf(file, "%f %f\n", &uv.x, &uv.y); | 179 | fscanf(file, "%f %f\n", &uv.x, &uv.y); |
178 | temp_uvs.push_back(uv); | 180 | temp_uvs.push_back(uv); |
179 | } else if (!strncmp(lineHeader, "vn", 3)) | 181 | } else if (!strncmp(lineHeader, "vn", 3)) |
180 | { | 182 | { |
181 | vec3 normal; | 183 | glm::vec3 normal; |
182 | fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); | 184 | fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); |
183 | temp_normals.push_back(normal); | 185 | temp_normals.push_back(normal); |
184 | } else if (!strncmp(lineHeader, "f", 2)) | 186 | } else if (!strncmp(lineHeader, "f", 2)) |
@@ -265,8 +267,8 @@ GLFWwindow* initRenderer() | |||
265 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | 267 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); |
266 | 268 | ||
267 | // Create a window | 269 | // Create a window |
268 | window = glfwCreateWindow(1024, 768, "Aromatherapy", NULL, NULL); | 270 | window = glfwCreateWindow(1024, 768, "Aromatherapy", nullptr, nullptr); |
269 | if (window == NULL) | 271 | if (window == nullptr) |
270 | { | 272 | { |
271 | fprintf(stderr, "Failed to open GLFW window\n"); | 273 | fprintf(stderr, "Failed to open GLFW window\n"); |
272 | glfwTerminate(); | 274 | glfwTerminate(); |
@@ -367,15 +369,15 @@ GLFWwindow* initRenderer() | |||
367 | 369 | ||
368 | glGenBuffers(1, &mesh_vertexbuffer); | 370 | glGenBuffers(1, &mesh_vertexbuffer); |
369 | glBindBuffer(GL_ARRAY_BUFFER, mesh_vertexbuffer); | 371 | glBindBuffer(GL_ARRAY_BUFFER, mesh_vertexbuffer); |
370 | glBufferData(GL_ARRAY_BUFFER, mesh_vertices.size() * sizeof(vec3), &mesh_vertices[0], GL_STATIC_DRAW); | 372 | glBufferData(GL_ARRAY_BUFFER, mesh_vertices.size() * sizeof(glm::vec3), &mesh_vertices[0], GL_STATIC_DRAW); |
371 | 373 | ||
372 | glGenBuffers(1, &mesh_uvbuffer); | 374 | glGenBuffers(1, &mesh_uvbuffer); |
373 | glBindBuffer(GL_ARRAY_BUFFER, mesh_uvbuffer); | 375 | glBindBuffer(GL_ARRAY_BUFFER, mesh_uvbuffer); |
374 | glBufferData(GL_ARRAY_BUFFER, mesh_uvs.size() * sizeof(vec3), &mesh_uvs[0], GL_STATIC_DRAW); | 376 | glBufferData(GL_ARRAY_BUFFER, mesh_uvs.size() * sizeof(glm::vec3), &mesh_uvs[0], GL_STATIC_DRAW); |
375 | 377 | ||
376 | glGenBuffers(1, &mesh_normalbuffer); | 378 | glGenBuffers(1, &mesh_normalbuffer); |
377 | glBindBuffer(GL_ARRAY_BUFFER, mesh_normalbuffer); | 379 | glBindBuffer(GL_ARRAY_BUFFER, mesh_normalbuffer); |
378 | glBufferData(GL_ARRAY_BUFFER, mesh_normals.size() * sizeof(vec3), &mesh_normals[0], GL_STATIC_DRAW); | 380 | glBufferData(GL_ARRAY_BUFFER, mesh_normals.size() * sizeof(glm::vec3), &mesh_normals[0], GL_STATIC_DRAW); |
379 | 381 | ||
380 | // Load the vertices of a flat surface | 382 | // Load the vertices of a flat surface |
381 | GLfloat g_quad_vertex_buffer_data[] = { | 383 | GLfloat g_quad_vertex_buffer_data[] = { |
@@ -471,7 +473,7 @@ void destroyRenderer() | |||
471 | rendererInitialized = false; | 473 | rendererInitialized = false; |
472 | } | 474 | } |
473 | 475 | ||
474 | Texture* createTexture(int width, int height) | 476 | Texture::Texture(int width, int height) |
475 | { | 477 | { |
476 | if (!rendererInitialized) | 478 | if (!rendererInitialized) |
477 | { | 479 | { |
@@ -479,22 +481,19 @@ Texture* createTexture(int width, int height) | |||
479 | exit(-1); | 481 | exit(-1); |
480 | } | 482 | } |
481 | 483 | ||
482 | Texture* tex = new Texture(); | 484 | this->width = width; |
483 | tex->width = width; | 485 | this->height = height; |
484 | tex->height = height; | ||
485 | 486 | ||
486 | glGenTextures(1, &(tex->texID)); | 487 | glGenTextures(1, &texID); |
487 | glBindTexture(GL_TEXTURE_2D, tex->texID); | 488 | glBindTexture(GL_TEXTURE_2D, texID); |
488 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); | 489 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
489 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 490 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
490 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 491 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
491 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 492 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
492 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 493 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
493 | |||
494 | return tex; | ||
495 | } | 494 | } |
496 | 495 | ||
497 | void destroyTexture(Texture* tex) | 496 | Texture::Texture(const char* filename) |
498 | { | 497 | { |
499 | if (!rendererInitialized) | 498 | if (!rendererInitialized) |
500 | { | 499 | { |
@@ -502,12 +501,19 @@ void destroyTexture(Texture* tex) | |||
502 | exit(-1); | 501 | exit(-1); |
503 | } | 502 | } |
504 | 503 | ||
505 | glDeleteTextures(1, &(tex->texID)); | 504 | glGenTextures(1, &texID); |
506 | 505 | glBindTexture(GL_TEXTURE_2D, texID); | |
507 | delete tex; | 506 | unsigned char* data = stbi_load(filename, &width, &height, 0, 4); |
507 | flipImageData(data, width, height, 4); | ||
508 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | ||
509 | stbi_image_free(data); | ||
510 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
511 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
512 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
513 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
508 | } | 514 | } |
509 | 515 | ||
510 | Texture* loadTextureFromFile(char* filename) | 516 | Texture::Texture(Texture& tex) |
511 | { | 517 | { |
512 | if (!rendererInitialized) | 518 | if (!rendererInitialized) |
513 | { | 519 | { |
@@ -515,22 +521,30 @@ Texture* loadTextureFromFile(char* filename) | |||
515 | exit(-1); | 521 | exit(-1); |
516 | } | 522 | } |
517 | 523 | ||
518 | Texture* tex = new Texture(); | 524 | width = tex.width; |
519 | glGenTextures(1, &(tex->texID)); | 525 | height = tex.height; |
520 | glBindTexture(GL_TEXTURE_2D, tex->texID); | 526 | |
521 | unsigned char* data = stbi_load(filename, &(tex->width), &(tex->height), 0, 4); | 527 | unsigned char* data = (unsigned char*) malloc(4 * width * height); |
522 | flipImageData(data, tex->width, tex->height, 4); | 528 | glBindTexture(GL_TEXTURE_2D, tex.texID); |
523 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->width, tex->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | 529 | glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); |
524 | stbi_image_free(data); | 530 | |
531 | glGenTextures(1, &texID); | ||
532 | glBindTexture(GL_TEXTURE_2D, texID); | ||
533 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); | ||
525 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 534 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
526 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 535 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
527 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
528 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 536 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
537 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
529 | 538 | ||
530 | return tex; | 539 | free(data); |
531 | } | 540 | } |
532 | 541 | ||
533 | void saveTextureToBMP(Texture* tex, char* filename) | 542 | Texture::Texture(Texture&& tex) : Texture(0, 0) |
543 | { | ||
544 | swap(*this, tex); | ||
545 | } | ||
546 | |||
547 | Texture::~Texture() | ||
534 | { | 548 | { |
535 | if (!rendererInitialized) | 549 | if (!rendererInitialized) |
536 | { | 550 | { |
@@ -538,29 +552,24 @@ void saveTextureToBMP(Texture* tex, char* filename) | |||
538 | exit(-1); | 552 | exit(-1); |
539 | } | 553 | } |
540 | 554 | ||
541 | int size = 54 + 3*tex->width*tex->height; | 555 | glDeleteTextures(1, &texID); |
542 | 556 | } | |
543 | char* buf = (char*) calloc(size, sizeof(char)); | 557 | |
544 | buf[0x00] = 'B'; | 558 | Texture& Texture::operator= (Texture tex) |
545 | buf[0x01] = 'M'; | 559 | { |
546 | *(int*)&(buf[0x0A]) = 54; | 560 | swap(*this, tex); |
547 | *(int*)&(buf[0x12]) = tex->width; | ||
548 | *(int*)&(buf[0x16]) = tex->height; | ||
549 | *(int*)&(buf[0x1C]) = 24; | ||
550 | *(int*)&(buf[0x1E]) = 0; | ||
551 | *(int*)&(buf[0x22]) = size; | ||
552 | |||
553 | glBindTexture(GL_TEXTURE_2D, tex->texID); | ||
554 | glGetTexImage(GL_TEXTURE_2D, 0, GL_BGR, GL_UNSIGNED_BYTE, buf + 54); | ||
555 | |||
556 | FILE* f = fopen(filename, "wb"); | ||
557 | fwrite(buf, sizeof(char), size, f); | ||
558 | fclose(f); | ||
559 | 561 | ||
560 | free(buf); | 562 | return *this; |
563 | } | ||
564 | |||
565 | void swap(Texture& tex1, Texture& tex2) | ||
566 | { | ||
567 | std::swap(tex1.width, tex2.width); | ||
568 | std::swap(tex1.height, tex2.height); | ||
569 | std::swap(tex1.texID, tex2.texID); | ||
561 | } | 570 | } |
562 | 571 | ||
563 | void fillTexture(Texture* tex, Rectangle* dstrect, int r, int g, int b) | 572 | void Texture::fill(Rectangle dstrect, int r, int g, int b) |
564 | { | 573 | { |
565 | if (!rendererInitialized) | 574 | if (!rendererInitialized) |
566 | { | 575 | { |
@@ -570,18 +579,13 @@ void fillTexture(Texture* tex, Rectangle* dstrect, int r, int g, int b) | |||
570 | 579 | ||
571 | // Target the framebuffer | 580 | // Target the framebuffer |
572 | glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); | 581 | glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); |
573 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex->texID, 0); | 582 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texID, 0); |
574 | 583 | ||
575 | // Set up the vertex attributes | 584 | // Set up the vertex attributes |
576 | GLfloat minx = (dstrect == NULL) ? 0.0f : dstrect->x; | 585 | GLfloat minx = (GLfloat) dstrect.x / width * 2.0 - 1.0; |
577 | GLfloat miny = (dstrect == NULL) ? 0.0f : dstrect->y; | 586 | GLfloat miny = -((GLfloat) dstrect.y / height * 2.0 - 1.0); |
578 | GLfloat maxx = (dstrect == NULL) ? tex->width : dstrect->x + dstrect->w; | 587 | GLfloat maxx = (GLfloat) (dstrect.x + dstrect.w) / width * 2.0 - 1.0; |
579 | GLfloat maxy = (dstrect == NULL) ? tex->height : dstrect->y + dstrect->h; | 588 | GLfloat maxy = -((GLfloat) (dstrect.y + dstrect.h) / height * 2.0 - 1.0); |
580 | |||
581 | minx = minx / tex->width * 2.0 - 1.0; | ||
582 | miny = -(miny / tex->height * 2.0 - 1.0); | ||
583 | maxx = maxx / tex->width * 2.0 - 1.0; | ||
584 | maxy = -(maxy / tex->height * 2.0 - 1.0); | ||
585 | 589 | ||
586 | GLfloat vertexbuffer_data[] = { | 590 | GLfloat vertexbuffer_data[] = { |
587 | minx, miny, | 591 | minx, miny, |
@@ -598,7 +602,7 @@ void fillTexture(Texture* tex, Rectangle* dstrect, int r, int g, int b) | |||
598 | glEnableVertexAttribArray(0); | 602 | glEnableVertexAttribArray(0); |
599 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); | 603 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); |
600 | 604 | ||
601 | glViewport(0, 0, tex->width, tex->height); | 605 | glViewport(0, 0, width, height); |
602 | glClear(GL_DEPTH_BUFFER_BIT); | 606 | glClear(GL_DEPTH_BUFFER_BIT); |
603 | glUseProgram(fillShader); | 607 | glUseProgram(fillShader); |
604 | glUniform3f(glGetUniformLocation(fillShader, "vecColor"), r / 255.0, g / 255.0, b / 255.0); | 608 | glUniform3f(glGetUniformLocation(fillShader, "vecColor"), r / 255.0, g / 255.0, b / 255.0); |
@@ -609,7 +613,7 @@ void fillTexture(Texture* tex, Rectangle* dstrect, int r, int g, int b) | |||
609 | glDeleteBuffers(1, &vertexbuffer); | 613 | glDeleteBuffers(1, &vertexbuffer); |
610 | } | 614 | } |
611 | 615 | ||
612 | void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle* dstrect) | 616 | void Texture::blit(Texture& srctex, Rectangle srcrect, Rectangle dstrect) |
613 | { | 617 | { |
614 | if (!rendererInitialized) | 618 | if (!rendererInitialized) |
615 | { | 619 | { |
@@ -619,18 +623,13 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle | |||
619 | 623 | ||
620 | // Target the framebuffer | 624 | // Target the framebuffer |
621 | glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); | 625 | glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); |
622 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dsttex->texID, 0); | 626 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texID, 0); |
623 | 627 | ||
624 | // Set up the vertex attributes | 628 | // Set up the vertex attributes |
625 | GLfloat minx = (dstrect == NULL) ? 0.0f : dstrect->x; | 629 | GLfloat minx = (GLfloat) dstrect.x / width * 2.0 - 1.0; |
626 | GLfloat miny = (dstrect == NULL) ? 0.0f : dstrect->y; | 630 | GLfloat miny = -((GLfloat) dstrect.y / height * 2.0 - 1.0); |
627 | GLfloat maxx = (dstrect == NULL) ? dsttex->width : dstrect->x + dstrect->w; | 631 | GLfloat maxx = (GLfloat) (dstrect.x + dstrect.w) / width * 2.0 - 1.0; |
628 | GLfloat maxy = (dstrect == NULL) ? dsttex->height : dstrect->y + dstrect->h; | 632 | GLfloat maxy = -((GLfloat) (dstrect.y + dstrect.h) / height * 2.0 - 1.0); |
629 | |||
630 | minx = minx / dsttex->width * 2.0 - 1.0; | ||
631 | miny = -(miny / dsttex->height * 2.0 - 1.0); | ||
632 | maxx = maxx / dsttex->width * 2.0 - 1.0; | ||
633 | maxy = -(maxy / dsttex->height * 2.0 - 1.0); | ||
634 | 633 | ||
635 | GLfloat vertexbuffer_data[] = { | 634 | GLfloat vertexbuffer_data[] = { |
636 | minx, miny, | 635 | minx, miny, |
@@ -645,15 +644,10 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle | |||
645 | glEnableVertexAttribArray(0); | 644 | glEnableVertexAttribArray(0); |
646 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); | 645 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); |
647 | 646 | ||
648 | GLfloat minu = (srcrect == NULL) ? 0.0f : srcrect->x; | 647 | GLfloat minu = (GLfloat) srcrect.x / srctex.width; |
649 | GLfloat minv = (srcrect == NULL) ? 0.0f : srcrect->y; | 648 | GLfloat minv = 1 - ((GLfloat) srcrect.y / srctex.height); |
650 | GLfloat maxu = (srcrect == NULL) ? srctex->width : srcrect->x + srcrect->w; | 649 | GLfloat maxu = (GLfloat) (srcrect.x + srcrect.w) / srctex.width; |
651 | GLfloat maxv = (srcrect == NULL) ? srctex->height : srcrect->y + srcrect->h; | 650 | GLfloat maxv = 1 - ((GLfloat) (srcrect.y + srcrect.h) / srctex.height); |
652 | |||
653 | minu = minu / srctex->width; | ||
654 | minv = 1 - (minv / srctex->height); | ||
655 | maxu = maxu / srctex->width; | ||
656 | maxv = 1 - (maxv / srctex->height); | ||
657 | 651 | ||
658 | GLfloat texcoordbuffer_data[] = { | 652 | GLfloat texcoordbuffer_data[] = { |
659 | minu, minv, | 653 | minu, minv, |
@@ -671,10 +665,10 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle | |||
671 | // Set up the shader | 665 | // Set up the shader |
672 | glUseProgram(blitShader); | 666 | glUseProgram(blitShader); |
673 | glClear(GL_DEPTH_BUFFER_BIT); | 667 | glClear(GL_DEPTH_BUFFER_BIT); |
674 | glViewport(0, 0, dsttex->width, dsttex->height); | 668 | glViewport(0, 0, width, height); |
675 | 669 | ||
676 | glActiveTexture(GL_TEXTURE0); | 670 | glActiveTexture(GL_TEXTURE0); |
677 | glBindTexture(GL_TEXTURE_2D, srctex->texID); | 671 | glBindTexture(GL_TEXTURE_2D, srctex.texID); |
678 | glUniform1i(glGetUniformLocation(blitShader, "srctex"), 0); | 672 | glUniform1i(glGetUniformLocation(blitShader, "srctex"), 0); |
679 | 673 | ||
680 | // Blit! | 674 | // Blit! |
@@ -687,63 +681,7 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle | |||
687 | glDeleteBuffers(1, &vertexbuffer); | 681 | glDeleteBuffers(1, &vertexbuffer); |
688 | } | 682 | } |
689 | 683 | ||
690 | void renderWithoutEffects(Texture* tex) | 684 | void bloomPass1(GLuint srcTex, GLuint dstTex, bool horizontal, glm::vec2 srcRes, glm::vec2 dstRes) |
691 | { | ||
692 | if (!rendererInitialized) | ||
693 | { | ||
694 | fprintf(stderr, "Renderer not initialized\n"); | ||
695 | exit(-1); | ||
696 | } | ||
697 | |||
698 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
699 | glViewport(0, 0, buffer_width, buffer_height); | ||
700 | glClear(GL_COLOR_BUFFER_BIT); | ||
701 | glUseProgram(blitShader); | ||
702 | |||
703 | const GLfloat fullBlitVertices_data[] = { | ||
704 | -1.0, -1.0, | ||
705 | 1.0, -1.0, | ||
706 | -1.0, 1.0, | ||
707 | 1.0, 1.0 | ||
708 | }; | ||
709 | |||
710 | GLuint fullBlitVertices; | ||
711 | glGenBuffers(1, &fullBlitVertices); | ||
712 | glBindBuffer(GL_ARRAY_BUFFER, fullBlitVertices); | ||
713 | glBufferData(GL_ARRAY_BUFFER, sizeof(fullBlitVertices_data), fullBlitVertices_data, GL_STATIC_DRAW); | ||
714 | glEnableVertexAttribArray(0); | ||
715 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); | ||
716 | |||
717 | const GLfloat fullBlitTex_data[] = { | ||
718 | 0.0, 0.0, | ||
719 | 1.0, 0.0, | ||
720 | 0.0, 1.0, | ||
721 | 1.0, 1.0 | ||
722 | }; | ||
723 | |||
724 | GLuint fullBlitTex; | ||
725 | glGenBuffers(1, &fullBlitTex); | ||
726 | glBindBuffer(GL_ARRAY_BUFFER, fullBlitTex); | ||
727 | glBufferData(GL_ARRAY_BUFFER, sizeof(fullBlitTex_data), fullBlitTex_data, GL_STATIC_DRAW); | ||
728 | glEnableVertexAttribArray(1); | ||
729 | glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); | ||
730 | |||
731 | glActiveTexture(GL_TEXTURE0); | ||
732 | glBindTexture(GL_TEXTURE_2D, tex->texID); | ||
733 | glUniform1i(glGetUniformLocation(blitShader, "srctex"), 0); | ||
734 | |||
735 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | ||
736 | |||
737 | glDisableVertexAttribArray(1); | ||
738 | glDisableVertexAttribArray(0); | ||
739 | |||
740 | glDeleteBuffers(1, &fullBlitTex); | ||
741 | glDeleteBuffers(1, &fullBlitVertices); | ||
742 | |||
743 | glfwSwapBuffers(window); | ||
744 | } | ||
745 | |||
746 | void bloomPass1(GLuint srcTex, GLuint dstTex, bool horizontal, vec2 srcRes, vec2 dstRes) | ||
747 | { | 685 | { |
748 | glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); | 686 | glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); |
749 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstTex, 0); | 687 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstTex, 0); |
@@ -755,7 +693,7 @@ void bloomPass1(GLuint srcTex, GLuint dstTex, bool horizontal, vec2 srcRes, vec2 | |||
755 | glBindTexture(GL_TEXTURE_2D, srcTex); | 693 | glBindTexture(GL_TEXTURE_2D, srcTex); |
756 | glUniform1i(glGetUniformLocation(bloom1Shader, "inTex"), 0); | 694 | glUniform1i(glGetUniformLocation(bloom1Shader, "inTex"), 0); |
757 | 695 | ||
758 | vec2 offset = vec2(0.0); | 696 | glm::vec2 offset = glm::vec2(0.0); |
759 | if (horizontal) | 697 | if (horizontal) |
760 | { | 698 | { |
761 | offset.x = 1.2/srcRes.x; | 699 | offset.x = 1.2/srcRes.x; |
@@ -772,7 +710,7 @@ void bloomPass1(GLuint srcTex, GLuint dstTex, bool horizontal, vec2 srcRes, vec2 | |||
772 | glDisableVertexAttribArray(0); | 710 | glDisableVertexAttribArray(0); |
773 | } | 711 | } |
774 | 712 | ||
775 | void renderScreen(Texture* tex) | 713 | void Texture::renderScreen() |
776 | { | 714 | { |
777 | if (!rendererInitialized) | 715 | if (!rendererInitialized) |
778 | { | 716 | { |
@@ -792,7 +730,7 @@ void renderScreen(Texture* tex) | |||
792 | 730 | ||
793 | // Use the current frame texture, nearest neighbor and clamped to edge | 731 | // Use the current frame texture, nearest neighbor and clamped to edge |
794 | glActiveTexture(GL_TEXTURE0); | 732 | glActiveTexture(GL_TEXTURE0); |
795 | glBindTexture(GL_TEXTURE_2D, tex->texID); | 733 | glBindTexture(GL_TEXTURE_2D, texID); |
796 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 734 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
797 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 735 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
798 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 736 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
@@ -832,7 +770,6 @@ void renderScreen(Texture* tex) | |||
832 | // We're going to render the screen now | 770 | // We're going to render the screen now |
833 | glBindFramebuffer(GL_FRAMEBUFFER, bloom_framebuffer); | 771 | glBindFramebuffer(GL_FRAMEBUFFER, bloom_framebuffer); |
834 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, preBloomTex, 0); | 772 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, preBloomTex, 0); |
835 | //glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
836 | glViewport(0,0,buffer_width,buffer_height); | 773 | glViewport(0,0,buffer_width,buffer_height); |
837 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 774 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
838 | glUseProgram(finalShader); | 775 | glUseProgram(finalShader); |
@@ -855,11 +792,10 @@ void renderScreen(Texture* tex) | |||
855 | glUniform1i(glGetUniformLocation(finalShader, "scanlinestex"), 1); | 792 | glUniform1i(glGetUniformLocation(finalShader, "scanlinestex"), 1); |
856 | 793 | ||
857 | // Initialize the MVP matrices | 794 | // Initialize the MVP matrices |
858 | mat4 p_matrix = perspective(42.5f, (float) buffer_width / (float) buffer_height, 0.1f, 100.0f); | 795 | glm::mat4 p_matrix = glm::perspective(42.5f, (float) buffer_width / (float) buffer_height, 0.1f, 100.0f); |
859 | mat4 v_matrix = lookAt(vec3(2,0,0), vec3(0,0,0), vec3(0,1,0)); | 796 | glm::mat4 v_matrix = glm::lookAt(glm::vec3(2,0,0), glm::vec3(0,0,0), glm::vec3(0,1,0)); |
860 | mat4 m_matrix = mat4(1.0); | 797 | glm::mat4 m_matrix = glm::mat4(1.0); |
861 | mat4 mvp_matrix = p_matrix * v_matrix * m_matrix; | 798 | glm::mat4 mvp_matrix = p_matrix * v_matrix * m_matrix; |
862 | //mat4 mv_matrix = v_matrix * m_matrix; | ||
863 | 799 | ||
864 | glUniformMatrix4fv(glGetUniformLocation(finalShader, "MVP"), 1, GL_FALSE, &mvp_matrix[0][0]); | 800 | glUniformMatrix4fv(glGetUniformLocation(finalShader, "MVP"), 1, GL_FALSE, &mvp_matrix[0][0]); |
865 | glUniformMatrix4fv(glGetUniformLocation(finalShader, "worldMat"), 1, GL_FALSE, &m_matrix[0][0]); | 801 | glUniformMatrix4fv(glGetUniformLocation(finalShader, "worldMat"), 1, GL_FALSE, &m_matrix[0][0]); |
@@ -884,7 +820,7 @@ void renderScreen(Texture* tex) | |||
884 | glDisableVertexAttribArray(0); | 820 | glDisableVertexAttribArray(0); |
885 | 821 | ||
886 | // First pass of bloom! | 822 | // First pass of bloom! |
887 | vec2 buffer_size = vec2(buffer_width, buffer_height); | 823 | glm::vec2 buffer_size = glm::vec2(buffer_width, buffer_height); |
888 | bloomPass1(preBloomTex, bloomPassTex1, true, buffer_size, buffer_size / 4.0f); | 824 | bloomPass1(preBloomTex, bloomPassTex1, true, buffer_size, buffer_size / 4.0f); |
889 | bloomPass1(bloomPassTex1, bloomPassTex2, false, buffer_size / 4.0f, buffer_size / 4.0f); | 825 | bloomPass1(bloomPassTex1, bloomPassTex2, false, buffer_size / 4.0f, buffer_size / 4.0f); |
890 | 826 | ||
@@ -903,7 +839,6 @@ void renderScreen(Texture* tex) | |||
903 | glUniform1i(glGetUniformLocation(bloom2Shader, "blurTex"), 1); | 839 | glUniform1i(glGetUniformLocation(bloom2Shader, "blurTex"), 1); |
904 | 840 | ||
905 | glUniform1f(glGetUniformLocation(bloom2Shader, "iGlobalTime"), glfwGetTime()); | 841 | glUniform1f(glGetUniformLocation(bloom2Shader, "iGlobalTime"), glfwGetTime()); |
906 | // glUniform2f(glGetUniformLocation(bloom2Shader, "resolution"), buffer_width, buffer_height); | ||
907 | 842 | ||
908 | glEnableVertexAttribArray(0); | 843 | glEnableVertexAttribArray(0); |
909 | glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); | 844 | glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); |
@@ -915,3 +850,8 @@ void renderScreen(Texture* tex) | |||
915 | 850 | ||
916 | curBuf = (curBuf + 1) % 2; | 851 | curBuf = (curBuf + 1) % 2; |
917 | } | 852 | } |
853 | |||
854 | Rectangle Texture::entirety() | ||
855 | { | ||
856 | return {0, 0, width, height}; | ||
857 | } | ||
diff --git a/src/renderer.h b/src/renderer.h index a4e21f7..509e935 100644 --- a/src/renderer.h +++ b/src/renderer.h | |||
@@ -1,9 +1,5 @@ | |||
1 | #include <GL/glew.h> | 1 | #include <GL/glew.h> |
2 | #include <GLFW/glfw3.h> | 2 | #include <GLFW/glfw3.h> |
3 | #include <glm/glm.hpp> | ||
4 | #include <glm/gtc/matrix_transform.hpp> | ||
5 | |||
6 | using namespace glm; | ||
7 | 3 | ||
8 | #ifndef RENDERER_H | 4 | #ifndef RENDERER_H |
9 | #define RENDERER_H | 5 | #define RENDERER_H |
@@ -13,33 +9,29 @@ struct Rectangle { | |||
13 | int y; | 9 | int y; |
14 | int w; | 10 | int w; |
15 | int h; | 11 | int h; |
16 | |||
17 | Rectangle() {}; | ||
18 | |||
19 | Rectangle(int m_x, int m_y, int m_w, int m_h) | ||
20 | { | ||
21 | x = m_x; | ||
22 | y = m_y; | ||
23 | w = m_w; | ||
24 | h = m_h; | ||
25 | } | ||
26 | }; | 12 | }; |
27 | 13 | ||
28 | struct Texture { | 14 | class Texture { |
29 | GLuint texID; | 15 | public: |
30 | int width; | 16 | Texture(int width, int height); |
31 | int height; | 17 | Texture(const char* file); |
18 | Texture(Texture& tex); | ||
19 | Texture(Texture&& tex); | ||
20 | ~Texture(); | ||
21 | Texture& operator= (Texture tex); | ||
22 | friend void swap(Texture& tex1, Texture& tex2); | ||
23 | void fill(Rectangle loc, int r, int g, int b); | ||
24 | void blit(Texture& src, Rectangle srcrect, Rectangle dstrect); | ||
25 | void renderScreen(); | ||
26 | Rectangle entirety(); | ||
27 | |||
28 | private: | ||
29 | GLuint texID; | ||
30 | int width; | ||
31 | int height; | ||
32 | }; | 32 | }; |
33 | 33 | ||
34 | GLFWwindow* initRenderer(); | 34 | GLFWwindow* initRenderer(); |
35 | void destroyRenderer(); | 35 | void destroyRenderer(); |
36 | Texture* createTexture(int width, int height); | ||
37 | void destroyTexture(Texture* tex); | ||
38 | Texture* loadTextureFromFile(char* filename); | ||
39 | void saveTextureToBMP(Texture* tex, char* filename); | ||
40 | void fillTexture(Texture* tex, Rectangle* loc, int r, int g, int b); | ||
41 | void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle* dstrect); | ||
42 | void renderWithoutEffects(Texture* tex); | ||
43 | void renderScreen(Texture* tex); | ||
44 | 36 | ||
45 | #endif | 37 | #endif |
diff --git a/src/world.cpp b/src/world.cpp deleted file mode 100644 index 90d9ab8..0000000 --- a/src/world.cpp +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | #include "world.h" | ||
2 | |||
3 | void World::tick() | ||
4 | { | ||
5 | for (auto it = entities.begin(); it != entities.end(); it++) | ||
6 | { | ||
7 | (*it)->tick(); | ||
8 | } | ||
9 | } | ||
10 | |||
11 | void World::input(int key, int action) | ||
12 | { | ||
13 | for (auto it = entities.begin(); it != entities.end(); it++) | ||
14 | { | ||
15 | (*it)->input(key, action); | ||
16 | } | ||
17 | } | ||
18 | |||
19 | void World::render(Texture* buffer) | ||
20 | { | ||
21 | fillTexture(buffer, NULL, 0, 0, 0); | ||
22 | |||
23 | for (auto it = entities.begin(); it != entities.end(); it++) | ||
24 | { | ||
25 | (*it)->render(buffer); | ||
26 | } | ||
27 | } | ||
28 | |||
29 | void World::addEntity(std::shared_ptr<Entity> e) | ||
30 | { | ||
31 | entities.push_back(e); | ||
32 | } | ||
diff --git a/src/world.h b/src/world.h deleted file mode 100644 index ad6c788..0000000 --- a/src/world.h +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | #ifndef WORLD_H | ||
2 | #define WORLD_H | ||
3 | |||
4 | class World; | ||
5 | |||
6 | #include <list> | ||
7 | #include "renderer.h" | ||
8 | #include "entity.h" | ||
9 | #include <cstdio> | ||
10 | |||
11 | class World { | ||
12 | public: | ||
13 | World() {}; | ||
14 | ~World() {}; | ||
15 | void tick(); | ||
16 | void input(int key, int action); | ||
17 | void render(Texture* buffer); | ||
18 | void addEntity(std::shared_ptr<Entity> e); | ||
19 | |||
20 | std::list<Collidable*> bodies; | ||
21 | std::shared_ptr<Entity> player; | ||
22 | |||
23 | private: | ||
24 | std::list<std::shared_ptr<Entity>> entities; | ||
25 | }; | ||
26 | |||
27 | #endif | ||