From 7f0e8c7ef70c62814c274f110367db92f01cbb26 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 10 Mar 2015 00:41:59 -0400 Subject: C++11'd everything! Also moved location information from physics components into entity. --- CMakeLists.txt | 2 +- src/components.cpp | 353 +++++++++++++++++++++++++---------------------------- src/components.h | 76 ++++++------ src/entity.cpp | 32 +++-- src/entity.h | 81 ++++++------ src/game.cpp | 135 ++++++++++---------- src/game.h | 38 +++--- src/main.cpp | 10 +- src/map.cpp | 41 ++++++- src/map.h | 14 ++- src/renderer.cpp | 256 +++++++++++++++----------------------- src/renderer.h | 44 +++---- src/world.cpp | 32 ----- src/world.h | 27 ---- 14 files changed, 511 insertions(+), 630 deletions(-) delete mode 100644 src/world.cpp delete mode 100644 src/world.h 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 # include_directories(${SDL2_INCLUDE_DIR}) set(CMAKE_BUILD_TYPE Debug) -add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp src/world.cpp src/entity.cpp src/components.cpp src/game.cpp) +add_executable(Aromatherapy src/main.cpp src/map.cpp src/renderer.cpp src/entity.cpp src/components.cpp src/game.cpp) target_link_libraries(Aromatherapy ${ALL_LIBS}) 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 @@ // User movement component -void UserMovementComponent::input(int key, int action) +void UserMovementComponent::input(Game& game, Entity& entity, int key, int action) { if (action == GLFW_PRESS) { @@ -11,30 +11,22 @@ void UserMovementComponent::input(int key, int action) { holdingLeft = true; - message_t msg; - msg.type = CM_WALK_LEFT; - - entity.send(msg); + Message msg(Message::Type::walkLeft); + entity.send(game, msg); } else if (key == GLFW_KEY_RIGHT) { holdingRight = true; - message_t msg; - msg.type = CM_WALK_RIGHT; - - entity.send(msg); + Message msg(Message::Type::walkRight); + entity.send(game, msg); } else if (key == GLFW_KEY_UP) { - message_t msg; - msg.type = CM_JUMP; - - entity.send(msg); + Message msg(Message::Type::jump); + entity.send(game, msg); } else if (key == GLFW_KEY_DOWN) { - message_t msg; - msg.type = CM_CAN_DROP; - - entity.send(msg); + Message msg(Message::Type::canDrop); + entity.send(game, msg); } } else if (action == GLFW_RELEASE) { @@ -44,15 +36,11 @@ void UserMovementComponent::input(int key, int action) if (holdingRight) { - message_t msg; - msg.type = CM_WALK_RIGHT; - - entity.send(msg); + Message msg(Message::Type::walkRight); + entity.send(game, msg); } else { - message_t msg; - msg.type = CM_STOP_WALKING; - - entity.send(msg); + Message msg(Message::Type::stopWalking); + entity.send(game, msg); } } else if (key == GLFW_KEY_RIGHT) { @@ -60,95 +48,82 @@ void UserMovementComponent::input(int key, int action) if (holdingLeft) { - message_t msg; - msg.type = CM_WALK_LEFT; - - entity.send(msg); + Message msg(Message::Type::walkLeft); + entity.send(game, msg); } else { - message_t msg; - msg.type = CM_STOP_WALKING; - - entity.send(msg); + Message msg(Message::Type::stopWalking); + entity.send(game, msg); } } else if (key == GLFW_KEY_DOWN) { - message_t msg; - msg.type = CM_CANT_DROP; - - entity.send(msg); + Message msg(Message::Type::cantDrop); + entity.send(game, msg); } else if (key == GLFW_KEY_UP) { - message_t msg; - msg.type = CM_STOP_JUMP; - - entity.send(msg); + Message msg(Message::Type::stopJump); + entity.send(game, msg); } } } // Physics component -void PhysicsBodyComponent::receive(message_t msg) +void PhysicsBodyComponent::receive(Game&, Entity&, Message& msg) { - if (msg.type == CM_WALK_LEFT) + if (msg.type == Message::Type::walkLeft) { velocity.first = -1.5; - } else if (msg.type == CM_WALK_RIGHT) + } else if (msg.type == Message::Type::walkRight) { velocity.first = 1.5; - } else if (msg.type == CM_STOP_WALKING) + } else if (msg.type == Message::Type::stopWalking) { velocity.first = 0.0; + } else if (msg.type == Message::Type::stopMovingHorizontally) + { + velocity.first = 0.0; + } else if (msg.type == Message::Type::stopMovingVertically) + { + velocity.second = 0.0; } } -void PhysicsBodyComponent::tick() +void PhysicsBodyComponent::tick(Game&, Entity& entity) { velocity.first += accel.first; velocity.second += accel.second; - position.first += velocity.first; - position.second += velocity.second; + entity.position.first += velocity.first; + entity.position.second += velocity.second; } -void PhysicsBodyComponent::detectCollision(Entity& player, Locatable& physics, std::pair old_position) +void PhysicsBodyComponent::detectCollision(Game& game, Entity& entity, Entity& collider, std::pair old_position) { // If already colliding, do nothing! - if ((old_position.first + physics.size.first > this->position.first) - && (old_position.first < this->position.first + this->size.first) - && (old_position.second + physics.size.second > this->position.second) - && (old_position.second < this->position.second + this->size.second)) + if ((old_position.first + collider.size.first > entity.position.first) + && (old_position.first < entity.position.first + entity.size.first) + && (old_position.second + collider.size.second > entity.position.second) + && (old_position.second < entity.position.second + entity.size.second)) { return; } // If newly colliding, SHOCK AND HORROR! - if ((physics.position.first + physics.size.first > this->position.first) - && (physics.position.first < this->position.first + this->size.first) - && (physics.position.second + physics.size.second > this->position.second) - && (physics.position.second < this->position.second + this->size.second)) - { - message_t msg; - msg.type = CM_COLLISION; - msg.collisionEntity = &player; + if ((collider.position.first + collider.size.first > entity.position.first) + && (collider.position.first < entity.position.first + entity.size.first) + && (collider.position.second + collider.size.second > entity.position.second) + && (collider.position.second < entity.position.second + entity.size.second)) + { + Message msg(Message::Type::collision); + msg.collisionEntity = &collider; - entity.send(msg); + entity.send(game, msg); } } // Render player -PlayerSpriteComponent::PlayerSpriteComponent(Entity& entity, Locatable& physics) : Component(entity), physics(physics) -{ - sprite = loadTextureFromFile("../res/Starla.png"); -} - -PlayerSpriteComponent::~PlayerSpriteComponent() -{ - destroyTexture(sprite); -} - -void PlayerSpriteComponent::render(Texture* buffer) +void PlayerSpriteComponent::render(Game&, Entity& entity, Texture& buffer) { int frame = 0; if (isMoving) @@ -162,28 +137,28 @@ void PlayerSpriteComponent::render(Texture* buffer) } if (facingLeft) frame++; - Rectangle src_rect(frame*10, 0, 10, 12); - Rectangle dst_rect((int) physics.position.first, (int) physics.position.second, physics.size.first, physics.size.second); - blitTexture(sprite, buffer, &src_rect, &dst_rect); + Rectangle src_rect {frame*10, 0, 10, 12}; + Rectangle dst_rect {(int) entity.position.first, (int) entity.position.second, entity.size.first, entity.size.second}; + buffer.blit(sprite, src_rect, dst_rect); } -void PlayerSpriteComponent::receive(message_t msg) +void PlayerSpriteComponent::receive(Game&, Entity&, Message& msg) { - if (msg.type == CM_WALK_LEFT) + if (msg.type == Message::Type::walkLeft) { facingLeft = true; isMoving = true; - } else if (msg.type == CM_WALK_RIGHT) + } else if (msg.type == Message::Type::walkRight) { facingLeft = false; isMoving = true; - } else if (msg.type == CM_STOP_WALKING) + } else if (msg.type == Message::Type::stopWalking) { isMoving = false; } } -void PlayerSpriteComponent::tick() +void PlayerSpriteComponent::tick(Game&, Entity&) { animFrame++; animFrame %= 20; @@ -194,7 +169,7 @@ void PlayerSpriteComponent::tick() #define JUMP_VELOCITY(h, l) (-2 * (h) / (l)) #define JUMP_GRAVITY(h, l) (2 * ((h) / (l)) / (l)) -PlayerPhysicsComponent::PlayerPhysicsComponent(Entity& entity) : Component(entity) +PlayerPhysicsComponent::PlayerPhysicsComponent() { jump_velocity = JUMP_VELOCITY(TILE_HEIGHT*4.5, 0.3*FRAMES_PER_SECOND); jump_gravity = JUMP_GRAVITY(TILE_HEIGHT*4.5, 0.3*FRAMES_PER_SECOND); @@ -203,46 +178,52 @@ PlayerPhysicsComponent::PlayerPhysicsComponent(Entity& entity) : Component(entit accel.second = jump_gravity_short; } -void PlayerPhysicsComponent::receive(message_t msg) +void PlayerPhysicsComponent::receive(Game&, Entity& entity, Message& msg) { - if (msg.type == CM_WALK_LEFT) + if (msg.type == Message::Type::walkLeft) { velocity.first = -1.5; direction = -1; - } else if (msg.type == CM_WALK_RIGHT) + } else if (msg.type == Message::Type::walkRight) { velocity.first = 1.5; direction = 1; - } else if (msg.type == CM_STOP_WALKING) + } else if (msg.type == Message::Type::stopWalking) { velocity.first = 0.0; direction = 0; - } else if (msg.type == CM_JUMP) + } else if (msg.type == Message::Type::stopMovingHorizontally) + { + velocity.first = 0.0; + } else if (msg.type == Message::Type::stopMovingVertically) + { + velocity.second = 0.0; + } else if (msg.type == Message::Type::jump) { velocity.second = jump_velocity; accel.second = jump_gravity; - } else if (msg.type == CM_STOP_JUMP) + } else if (msg.type == Message::Type::stopJump) { accel.second = jump_gravity_short; - } else if (msg.type == CM_CAN_DROP) + } else if (msg.type == Message::Type::canDrop) { canDrop = true; - } else if (msg.type == CM_CANT_DROP) + } else if (msg.type == Message::Type::cantDrop) { canDrop = false; - } else if (msg.type == CM_DROP) + } else if (msg.type == Message::Type::drop) { if (canDrop) { canDrop = false; } else { - position.second = msg.dropAxis - size.second; + entity.position.second = msg.dropAxis - entity.size.second; velocity.second = 0; } } } -void PlayerPhysicsComponent::tick() +void PlayerPhysicsComponent::tick(Game& game, Entity& entity) { // Continue walking even if blocked earlier if (velocity.first == 0) @@ -273,80 +254,67 @@ void PlayerPhysicsComponent::tick() if (velocity.second > 16) velocity.second = 16; // Do the movement - std::pair old_position = std::make_pair(position.first, position.second); - position.first += velocity.first; - position.second += velocity.second; + std::pair old_position = entity.position; + entity.position.first += velocity.first; + entity.position.second += velocity.second; // Check for collisions - for (auto it = entity.world->bodies.begin(); it != entity.world->bodies.end(); it++) - { - auto poop = *it; - poop->detectCollision(entity, *this, old_position); - } + game.detectCollision(entity, old_position); } // Map rendering -MapRenderComponent::MapRenderComponent(Entity& entity, Map* map) : Component(entity) +MapRenderComponent::MapRenderComponent(Map& map) { - screen = createTexture(GAME_WIDTH, GAME_HEIGHT); - fillTexture(screen, NULL, 0, 0, 0); + screen.fill(screen.entirety(), 0, 0, 0); - Texture* tiles = loadTextureFromFile("../res/tiles.png"); + Texture tiles("../res/tiles.png"); for (int i=0; imapdata()[i]; + int tile = map.mapdata()[i]; int x = i % MAP_WIDTH; int y = i / MAP_WIDTH; - Rectangle dst(x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); - Rectangle src(tile%8*TILE_WIDTH, tile/8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); - + Rectangle dst {x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; + Rectangle src {tile%8*TILE_WIDTH, tile/8*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; + if (tile > 0) { - blitTexture(tiles, screen, &src, &dst); + screen.blit(tiles, src, dst); } } - destroyTexture(tiles); - - Texture* font = loadTextureFromFile("../res/font.bmp"); - const char* map_name = map->title(); + Texture font("../res/font.bmp"); + const char* map_name = map.title(); int start_x = (40/2) - (strlen(map_name)/2); for (size_t i=0; imap = map; + leftMap = map.getLeftMap(); + rightMap = map.getRightMap(); - add_collision(-6, 0, GAME_WIDTH, left, (map->getLeftMap() == NULL) ? 1 : 2); - add_collision(GAME_WIDTH+6, 0, GAME_WIDTH, right, (map->getRightMap() == NULL) ? 3 : 2); + add_collision(-6, 0, GAME_WIDTH, left, (map.getLeftMap() == nullptr) ? 1 : 2); + add_collision(GAME_WIDTH+6, 0, GAME_WIDTH, right, (map.getRightMap() == nullptr) ? 3 : 2); for (int i=0; imapdata()[i]; + int tile = map.mapdata()[i]; if ((tile > 0) && (!((tile >= 5) && (tile <= 7)))) { @@ -410,34 +378,36 @@ void MapCollisionComponent::add_collision(int axis, int lower, int upper, direct } } -void MapCollisionComponent::detectCollision(Entity& player, Locatable& physics, std::pair old_position) +void MapCollisionComponent::detectCollision(Game& game, Entity&, Entity& collider, std::pair old_position) { - int fixed_x = (int) physics.position.first; - int fixed_y = (int) physics.position.second; + int fixed_x = (int) collider.position.first; + int fixed_y = (int) collider.position.second; int fixed_ox = (int) old_position.first; int fixed_oy = (int) old_position.second; if (fixed_x < fixed_ox) { - for (auto it=left_collisions.begin(); it!=left_collisions.end(); it++) + for (auto collision : left_collisions) { - if (it->axis > fixed_ox) continue; - if (it->axis < fixed_x) break; + if (collision.axis > fixed_ox) continue; + if (collision.axis < fixed_x) break; - if ((fixed_oy+physics.size.second > it->lower) && (fixed_oy < it->upper)) + if ((fixed_oy+collider.size.second > collision.lower) && (fixed_oy < collision.upper)) { // We have a collision! - if (it->type == 0) + if (collision.type == 0) { - physics.position.first = it->axis; - physics.velocity.first = 0; - } else if (it->type == 1) + collider.position.first = collision.axis; + + Message msg(Message::Type::stopMovingHorizontally); + collider.send(game, msg); + } else if (collision.type == 1) { - physics.position.first = GAME_WIDTH-physics.size.first/2; - } else if (it->type == 2) + collider.position.first = GAME_WIDTH-collider.size.first/2; + } else if (collision.type == 2) { - physics.position.first = GAME_WIDTH-physics.size.first/2; - Game::getInstance().loadMap(map->getLeftMap()); + collider.position.first = GAME_WIDTH-collider.size.first/2; + game.loadMap(*leftMap); } break; @@ -445,32 +415,33 @@ void MapCollisionComponent::detectCollision(Entity& player, Locatable& physics, } } else if (fixed_x > fixed_ox) { - for (auto it=right_collisions.begin(); it!=right_collisions.end(); it++) + for (auto collision : right_collisions) { - if (it->axis < fixed_ox+physics.size.first) continue; - if (it->axis > fixed_x+physics.size.first) break; + if (collision.axis < fixed_ox+collider.size.first) continue; + if (collision.axis > fixed_x+collider.size.first) break; - if ((fixed_oy+physics.size.second > it->lower) && (fixed_oy < it->upper)) + if ((fixed_oy+collider.size.second > collision.lower) && (fixed_oy < collision.upper)) { // We have a collision! - if (it->type == 0) + if (collision.type == 0) { - physics.position.first = it->axis - physics.size.first; - physics.velocity.first = 0; - } else if (it->type == 1) + collider.position.first = collision.axis - collider.size.first; + + Message msg(Message::Type::stopMovingHorizontally); + collider.send(game, msg); + } else if (collision.type == 1) { - physics.position.first = -physics.size.first/2; - } else if (it->type == 2) + collider.position.first = -collider.size.first/2; + } else if (collision.type == 2) { - physics.position.first = -physics.size.first/2; - Game::getInstance().loadMap(map->getRightMap()); - } else if (it->type == 3) + collider.position.first = -collider.size.first/2; + game.loadMap(*rightMap); + } else if (collision.type == 3) { - physics.position.first = it->axis - physics.size.first; + collider.position.first = collision.axis - collider.size.first; - message_t msg; - msg.type = CM_WALK_LEFT; - player.send(msg); + Message msg(Message::Type::walkLeft); + collider.send(game, msg); } break; @@ -478,26 +449,28 @@ void MapCollisionComponent::detectCollision(Entity& player, Locatable& physics, } } - fixed_x = (int) physics.position.first; - fixed_y = (int) physics.position.second; + fixed_x = (int) collider.position.first; + fixed_y = (int) collider.position.second; if (fixed_y < fixed_oy) { - for (auto it=up_collisions.begin(); it!=up_collisions.end(); it++) + for (auto collision : up_collisions) { - if (it->axis > fixed_oy) continue; - if (it->axis < fixed_y) break; + if (collision.axis > fixed_oy) continue; + if (collision.axis < fixed_y) break; - if ((fixed_x+physics.size.first > it->lower) && (fixed_x < it->upper)) + if ((fixed_x+collider.size.first > collision.lower) && (fixed_x < collision.upper)) { // We have a collision! - if (it->type == 0) + if (collision.type == 0) { - physics.position.second = it->axis; - physics.velocity.second = 0; - } else if (it->type == 1) + collider.position.second = collision.axis; + + Message msg(Message::Type::stopMovingVertically); + collider.send(game, msg); + } else if (collision.type == 1) { - physics.position.second = GAME_HEIGHT-physics.size.second/2-1; + collider.position.second = GAME_HEIGHT-collider.size.second/2-1; } break; @@ -505,29 +478,29 @@ void MapCollisionComponent::detectCollision(Entity& player, Locatable& physics, } } else if (fixed_y > fixed_oy) { - for (auto it=down_collisions.begin(); it!=down_collisions.end(); it++) + for (auto collision : down_collisions) { - if (it->axis < fixed_oy+physics.size.second) continue; - if (it->axis > fixed_y+physics.size.second) break; + if (collision.axis < fixed_oy+collider.size.second) continue; + if (collision.axis > fixed_y+collider.size.second) break; - if ((fixed_x+physics.size.first > it->lower) && (fixed_x < it->upper)) + if ((fixed_x+collider.size.first > collision.lower) && (fixed_x < collision.upper)) { // We have a collision! - if (it->type == 0) + if (collision.type == 0) { - physics.position.second = it->axis - physics.size.second; - physics.velocity.second = 0; - //mob->onGround = true; - } else if (it->type == 1) + collider.position.second = collision.axis - collider.size.second; + + Message msg(Message::Type::stopMovingVertically); + collider.send(game, msg); + } else if (collision.type == 1) { - physics.position.second = -physics.size.second/2; - } else if (it->type == 3) + collider.position.second = -collider.size.second/2; + } else if (collision.type == 3) { - message_t msg; - msg.type = CM_DROP; - msg.dropAxis = it->axis; - - player.send(msg); + Message msg(Message::Type::drop); + msg.dropAxis = collision.axis; + + collider.send(game, msg); } 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 @@ #include #include #include "map.h" +#include class UserMovementComponent : public Component { public: - UserMovementComponent(Entity& parent) : Component(parent) {}; - void input(int key, int action); + void input(Game& game, Entity& entity, int key, int action); private: bool holdingLeft = false; bool holdingRight = false; }; -class PhysicsBodyComponent : public Component, public Collidable, public Locatable { +class PhysicsBodyComponent : public Component { public: - PhysicsBodyComponent(Entity& parent) : Component(parent) {}; - void receive(message_t msg); - void tick(); - void detectCollision(Entity& player, Locatable& physics, std::pair old_position); + void receive(Game& game, Entity& entity, Message& msg); + void tick(Game& game, Entity& entity); + void detectCollision(Game& game, Entity& entity, Entity& collider, std::pair old_position); + + private: + std::pair velocity; + std::pair accel; }; class PlayerSpriteComponent : public Component { public: - PlayerSpriteComponent(Entity& parent, Locatable& physics); - ~PlayerSpriteComponent(); - void render(Texture* buffer); - void receive(message_t msg); - void tick(); + void render(Game& game, Entity& entity, Texture& buffer); + void receive(Game& game, Entity& entity, Message& msg); + void tick(Game& game, Entity& entity); private: - Locatable& physics; - Texture* sprite; + Texture sprite{"../res/Starla.png"}; int animFrame = 0; bool facingLeft = false; bool isMoving = false; }; -class PlayerPhysicsComponent : public Component, public Locatable { +class PlayerPhysicsComponent : public Component { public: - PlayerPhysicsComponent(Entity& parent); - void tick(); - void receive(message_t msg); + PlayerPhysicsComponent(); + void tick(Game& game, Entity& entity); + void receive(Game& game, Entity& entity, Message& msg); private: + std::pair velocity; + std::pair accel; double jump_velocity; double jump_gravity; double jump_gravity_short; @@ -56,38 +58,38 @@ class PlayerPhysicsComponent : public Component, public Locatable { class MapRenderComponent : public Component { public: - MapRenderComponent(Entity& parent, Map* map); - ~MapRenderComponent(); - void render(Texture* buffer); + MapRenderComponent(Map& map); + void render(Game& game, Entity& entity, Texture& buffer); private: - Texture* screen; -}; - -enum direction_t { - up, left, down, right + Texture screen{GAME_WIDTH, GAME_HEIGHT}; }; -typedef struct { - int axis; - int lower; - int upper; - int type; -} collision_t; - -class MapCollisionComponent : public Component, public Collidable { +class MapCollisionComponent : public Component { public: - MapCollisionComponent(Entity& parent, Map* map); - void detectCollision(Entity& player, Locatable& physics, std::pair old_position); + MapCollisionComponent(Map& map); + void detectCollision(Game& game, Entity& entity, Entity& collider, std::pair old_position); private: + enum direction_t { + up, left, down, right + }; + + typedef struct { + int axis; + int lower; + int upper; + int type; + } collision_t; + void add_collision(int axis, int lower, int upper, direction_t dir, int type); std::list left_collisions; std::list right_collisions; std::list up_collisions; std::list down_collisions; - Map* map; + Map* leftMap; + Map* rightMap; }; #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 c) components.push_back(c); } -void Entity::send(message_t msg) +void Entity::send(Game& game, Message& msg) { - for (auto it = components.begin(); it != components.end(); it++) + for (auto component : components) { - (*it)->receive(msg); + component->receive(game, *this, msg); } } -void Entity::tick() +void Entity::tick(Game& game) { - for (auto it = components.begin(); it != components.end(); it++) + for (auto component : components) { - (*it)->tick(); + component->tick(game, *this); } } -void Entity::input(int key, int action) +void Entity::input(Game& game, int key, int action) { - for (auto it = components.begin(); it != components.end(); it++) + for (auto component : components) { - (*it)->input(key, action); + component->input(game, *this, key, action); } } -void Entity::render(Texture* buffer) +void Entity::render(Game& game, Texture& buffer) { - for (auto it = components.begin(); it != components.end(); it++) + for (auto component : components) { - (*it)->render(buffer); + component->render(game, *this, buffer); + } +} + +void Entity::detectCollision(Game& game, Entity& collider, std::pair old_position) +{ + for (auto component : components) + { + component->detectCollision(game, *this, collider, old_position); } } 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 @@ class Entity; class Component; -class Locatable; -class Collidable; #include #include "renderer.h" -#include "world.h" +#include "game.h" -enum message_type { - CM_WALK_LEFT, - CM_WALK_RIGHT, - CM_STOP_WALKING, - CM_COLLISION, - CM_JUMP, - CM_STOP_JUMP, - CM_DROP, - CM_CAN_DROP, - CM_CANT_DROP +class Message { + public: + enum class Type { + walkLeft, + walkRight, + stopWalking, + stopMovingHorizontally, + stopMovingVertically, + collision, + jump, + stopJump, + drop, + canDrop, + cantDrop + }; + + Message(Type type) : type(type) {} + + Type type; + Entity* collisionEntity; + int dropAxis; }; -typedef struct { - message_type type; - Entity* collisionEntity; - int dropAxis; -} message_t; - class Entity { public: - Entity(World* world) : world(world) {} - ~Entity() {}; void addComponent(std::shared_ptr c); - void send(message_t msg); - void tick(); - void input(int key, int action); - void render(Texture* buffer); + void send(Game& game, Message& msg); + void tick(Game& game); + void input(Game& game, int key, int action); + void render(Game& game, Texture& buffer); + void detectCollision(Game& game, Entity& collider, std::pair old_position); - World* world; + std::pair position; + std::pair size; private: std::list> components; @@ -46,27 +49,11 @@ class Entity { class Component { public: - Component(Entity& entity) : entity(entity) {} - virtual ~Component() {}; - virtual void receive(message_t msg) {(void)msg;} - virtual void render(Texture* tex) {(void)tex;} - virtual void tick() {} - virtual void input(int key, int action) {(void)key; (void)action;} - - Entity& entity; -}; - -class Locatable { - public: - std::pair position; - std::pair size; - std::pair velocity; - std::pair accel; -}; - -class Collidable { - public: - virtual void detectCollision(Entity& player, Locatable& physics, std::pair old_position) = 0; + virtual void receive(Game&, Entity&, Message&) {} + virtual void render(Game&, Entity&, Texture&) {} + virtual void tick(Game&, Entity&) {} + virtual void input(Game&, Entity&, int, int) {} + virtual void detectCollision(Game&, Entity&, Entity&, std::pair) {} }; #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 @@ #include "game.h" #include "renderer.h" +#include "components.h" Game::Game() -{ - window = initRenderer(); - glfwSwapInterval(1); - - m = new Map("../maps/embarass.txt"); - m2 = new Map("../maps/second.txt"); - - m->setLeftMap(m2); - m2->setRightMap(m); - - world = new World(); +{ + m.setLeftMap(&m2); + m2.setRightMap(&m); - auto player = std::make_shared(world); + player = std::make_shared(); + player->position = std::make_pair(100.0,100.0); + player->size = std::make_pair(10.0,12.0); - auto player_input = std::make_shared(*player); + auto player_input = std::make_shared(); player->addComponent(player_input); - auto player_physics = std::make_shared(*player); - player_physics->position = std::make_pair(100.0,100.0); - player_physics->size = std::make_pair(10.0,12.0); + auto player_physics = std::make_shared(); player->addComponent(player_physics); - auto player_anim = std::make_shared(*player, *player_physics); + auto player_anim = std::make_shared(); player->addComponent(player_anim); - world->addEntity(player); - world->player = player; - loadMap(m); } -Game::~Game() +void key_callback(GLFWwindow* window, int key, int, int action, int) { - if (world != 0) - { - delete world; - } + Game* game = (Game*) glfwGetWindowUserPointer(window); - if (nextWorld != 0) + if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS)) { - delete nextWorld; + game->shouldQuit = true; } - delete m; - delete m2; - - destroyRenderer(); -} - -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - (void)window; - (void)scancode; - (void)mods; - - if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS)) + for (auto entity : game->entities) { - Game::getInstance().shouldQuit = true; + entity->input(*game, key, action); } - - Game::getInstance().input(key, action); } -void Game::execute() +void Game::execute(GLFWwindow* window) { + glfwSwapInterval(1); + glfwSetWindowUserPointer(window, this); glfwSetKeyCallback(window, key_callback); - Texture* buffer = createTexture(GAME_WIDTH, GAME_HEIGHT); + Texture buffer(GAME_WIDTH, GAME_HEIGHT); + double lastTime = glfwGetTime(); + int nbFrames = 0; while (!(shouldQuit || glfwWindowShouldClose(window))) { + double currentTime = glfwGetTime(); + nbFrames++; + if (currentTime - lastTime >= 1.0) + { + printf("%f ms/frame\n", 1000.0/double(nbFrames)); + nbFrames = 0; + lastTime += 1.0; + } + // Should we load a new world? - if (nextWorld != 0) + if (newWorld) { - delete world; - world = nextWorld; - world->player->world = world; - nextWorld = 0; + newWorld = false; + entities.clear(); + entities = std::move(nextEntities); } // Handle input glfwPollEvents(); // Tick! - world->tick(); + for (auto entity : entities) + { + entity->tick(*this); + } // Do rendering - world->render(buffer); - renderScreen(buffer); - } - - destroyTexture(buffer); -} + buffer.fill(buffer.entirety(), 0, 0, 0); + for (auto entity : entities) + { + entity->render(*this, buffer); + } -void Game::input(int key, int action) -{ - if (world != NULL) - { - world->input(key, action); + buffer.renderScreen(); } } -void Game::loadMap(Map* map) +void Game::loadMap(Map& map) { - nextWorld = new World(); - - nextWorld->player = world->player; - - auto mapEn = std::make_shared(nextWorld); + auto mapEn = std::make_shared(); - auto map_render = std::make_shared(*mapEn, map); + auto map_render = std::make_shared(map); mapEn->addComponent(map_render); - auto map_collision = std::make_shared(*mapEn, map); + auto map_collision = std::make_shared(map); mapEn->addComponent(map_collision); - nextWorld->bodies.push_back(map_collision.get()); - nextWorld->addEntity(mapEn); - nextWorld->addEntity(nextWorld->player); + nextEntities.clear(); + nextEntities.push_back(mapEn); + nextEntities.push_back(player); + + newWorld = true; +} + +void Game::detectCollision(Entity& collider, std::pair old_position) +{ + for (auto entity : entities) + { + entity->detectCollision(*this, collider, old_position); + } } 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 @@ #ifndef GAME_H #define GAME_H -#include "components.h" +class Game; + +#include "map.h" +#include +#include "entity.h" const int TILE_WIDTH = 8; const int TILE_HEIGHT = 8; @@ -15,29 +19,21 @@ const double SECONDS_PER_FRAME = 1.0 / FRAMES_PER_SECOND; class Game { public: - static Game& getInstance() - { - static Game instance; - - return instance; - } - - ~Game(); - void execute(); - void loadMap(Map* map); - void input(int key, int action); + Game(); + void execute(GLFWwindow* window); + void loadMap(Map& map); + void detectCollision(Entity& collider, std::pair old_position); bool shouldQuit = false; private: - Game(); - Game(Game const&); - void operator=(Game const&); - - GLFWwindow* window; - World* world; - World* nextWorld; - Map* m; - Map* m2; + friend void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); + + std::list> entities; + std::list> nextEntities; + bool newWorld; + std::shared_ptr player; + Map m{"../maps/embarass.txt"}; + Map m2{"../maps/second.txt"}; }; #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() { srand(time(NULL)); - Game::getInstance().execute(); + GLFWwindow* window = initRenderer(); + + // Put this in a block so game goes out of scope before we destroy the renderer + { + Game game; + game.execute(window); + } + + destroyRenderer(); return 0; } 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 @@ #include "map.h" #include "game.h" +#include +#include -Map::Map(char* filename) +Map::Map() +{ + +} + +Map::Map(const char* filename) { FILE* f = fopen(filename, "r"); @@ -22,12 +29,44 @@ Map::Map(char* filename) fclose(f); } +Map::Map(Map& map) +{ + m_mapdata = (int*) malloc(MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); + memcpy(m_mapdata, map.m_mapdata, MAP_WIDTH*(MAP_HEIGHT-1)*sizeof(int)); + + m_title = (char*) malloc((MAP_WIDTH+1)*sizeof(char)); + strncpy(m_title, map.m_title, MAP_WIDTH+1); + + m_leftMap = map.m_leftMap; + m_rightMap = map.m_rightMap; +} + +Map::Map(Map&& map) : Map() +{ + swap(*this, map); +} + Map::~Map() { free(m_mapdata); free(m_title); } +Map& Map::operator= (Map map) +{ + swap(*this, map); + + return *this; +} + +void swap(Map& first, Map& second) +{ + std::swap(first.m_mapdata, second.m_mapdata); + std::swap(first.m_title, second.m_title); + std::swap(first.m_leftMap, second.m_leftMap); + std::swap(first.m_rightMap, second.m_rightMap); +} + const int* Map::mapdata() { 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 @@ class Map { public: - Map(); - Map(char* filename); + Map(const char* filename); + Map(Map& map); + Map(Map&& map); ~Map(); + Map& operator= (Map other); + friend void swap(Map& first, Map& second); + const int* mapdata(); const char* title(); Map* getLeftMap(); @@ -13,10 +17,12 @@ class Map { void setLeftMap(Map* m); void setRightMap(Map* m); private: + Map(); + int* m_mapdata; char* m_title; - Map* m_leftMap = 0; - Map* m_rightMap = 0; + Map* m_leftMap; + Map* m_rightMap; }; #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 @@ #include #include #include "game.h" +#include +#include // include stb_image #define STB_IMAGE_IMPLEMENTATION @@ -86,27 +88,27 @@ GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) // Compile Vertex Shader printf("Compiling shader : %s\n", vertex_file_path); char const * VertexSourcePointer = VertexShaderCode.c_str(); - glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer , nullptr); glCompileShader(VertexShaderID); // Check Vertex Shader glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector VertexShaderErrorMessage(InfoLogLength); - glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]); fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]); // Compile Fragment Shader printf("Compiling shader : %s\n", fragment_file_path); char const * FragmentSourcePointer = FragmentShaderCode.c_str(); - glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , nullptr); glCompileShader(FragmentShaderID); // Check Fragment Shader glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector FragmentShaderErrorMessage(InfoLogLength); - glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]); fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]); // Link the program @@ -120,7 +122,7 @@ GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); std::vector ProgramErrorMessage( glm::max(InfoLogLength, int(1)) ); - glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + glGetProgramInfoLog(ProgramID, InfoLogLength, nullptr, &ProgramErrorMessage[0]); fprintf(stdout, "%s\n", &ProgramErrorMessage[0]); glDeleteShader(VertexShaderID); @@ -147,7 +149,7 @@ void flipImageData(unsigned char* data, int width, int height, int comps) void loadMesh(const char* filename, std::vector& out_vertices, std::vector& out_uvs, std::vector& out_normals) { FILE* file = fopen(filename, "r"); - if (file == NULL) + if (file == nullptr) { fprintf(stderr, "Could not open mesh file %s\n", filename); exit(1); @@ -168,17 +170,17 @@ void loadMesh(const char* filename, std::vector& out_vertices, std::v if (!strncmp(lineHeader, "v", 2)) { - vec3 vertex; + glm::vec3 vertex; fscanf(file, "%f %f %f\n", &vertex.x,&vertex.y,&vertex.z); temp_vertices.push_back(vertex); } else if (!strncmp(lineHeader, "vt", 3)) { - vec2 uv; + glm::vec2 uv; fscanf(file, "%f %f\n", &uv.x, &uv.y); temp_uvs.push_back(uv); } else if (!strncmp(lineHeader, "vn", 3)) { - vec3 normal; + glm::vec3 normal; fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z); temp_normals.push_back(normal); } else if (!strncmp(lineHeader, "f", 2)) @@ -265,8 +267,8 @@ GLFWwindow* initRenderer() glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Create a window - window = glfwCreateWindow(1024, 768, "Aromatherapy", NULL, NULL); - if (window == NULL) + window = glfwCreateWindow(1024, 768, "Aromatherapy", nullptr, nullptr); + if (window == nullptr) { fprintf(stderr, "Failed to open GLFW window\n"); glfwTerminate(); @@ -367,15 +369,15 @@ GLFWwindow* initRenderer() glGenBuffers(1, &mesh_vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, mesh_vertexbuffer); - glBufferData(GL_ARRAY_BUFFER, mesh_vertices.size() * sizeof(vec3), &mesh_vertices[0], GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mesh_vertices.size() * sizeof(glm::vec3), &mesh_vertices[0], GL_STATIC_DRAW); glGenBuffers(1, &mesh_uvbuffer); glBindBuffer(GL_ARRAY_BUFFER, mesh_uvbuffer); - glBufferData(GL_ARRAY_BUFFER, mesh_uvs.size() * sizeof(vec3), &mesh_uvs[0], GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mesh_uvs.size() * sizeof(glm::vec3), &mesh_uvs[0], GL_STATIC_DRAW); glGenBuffers(1, &mesh_normalbuffer); glBindBuffer(GL_ARRAY_BUFFER, mesh_normalbuffer); - glBufferData(GL_ARRAY_BUFFER, mesh_normals.size() * sizeof(vec3), &mesh_normals[0], GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mesh_normals.size() * sizeof(glm::vec3), &mesh_normals[0], GL_STATIC_DRAW); // Load the vertices of a flat surface GLfloat g_quad_vertex_buffer_data[] = { @@ -471,7 +473,7 @@ void destroyRenderer() rendererInitialized = false; } -Texture* createTexture(int width, int height) +Texture::Texture(int width, int height) { if (!rendererInitialized) { @@ -479,22 +481,19 @@ Texture* createTexture(int width, int height) exit(-1); } - Texture* tex = new Texture(); - tex->width = width; - tex->height = height; + this->width = width; + this->height = height; - glGenTextures(1, &(tex->texID)); - glBindTexture(GL_TEXTURE_2D, tex->texID); + glGenTextures(1, &texID); + glBindTexture(GL_TEXTURE_2D, texID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - - return tex; } -void destroyTexture(Texture* tex) +Texture::Texture(const char* filename) { if (!rendererInitialized) { @@ -502,12 +501,19 @@ void destroyTexture(Texture* tex) exit(-1); } - glDeleteTextures(1, &(tex->texID)); - - delete tex; + glGenTextures(1, &texID); + glBindTexture(GL_TEXTURE_2D, texID); + unsigned char* data = stbi_load(filename, &width, &height, 0, 4); + flipImageData(data, width, height, 4); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + stbi_image_free(data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } -Texture* loadTextureFromFile(char* filename) +Texture::Texture(Texture& tex) { if (!rendererInitialized) { @@ -515,22 +521,30 @@ Texture* loadTextureFromFile(char* filename) exit(-1); } - Texture* tex = new Texture(); - glGenTextures(1, &(tex->texID)); - glBindTexture(GL_TEXTURE_2D, tex->texID); - unsigned char* data = stbi_load(filename, &(tex->width), &(tex->height), 0, 4); - flipImageData(data, tex->width, tex->height, 4); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->width, tex->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - stbi_image_free(data); + width = tex.width; + height = tex.height; + + unsigned char* data = (unsigned char*) malloc(4 * width * height); + glBindTexture(GL_TEXTURE_2D, tex.texID); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + + glGenTextures(1, &texID); + glBindTexture(GL_TEXTURE_2D, texID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - return tex; + free(data); } -void saveTextureToBMP(Texture* tex, char* filename) +Texture::Texture(Texture&& tex) : Texture(0, 0) +{ + swap(*this, tex); +} + +Texture::~Texture() { if (!rendererInitialized) { @@ -538,29 +552,24 @@ void saveTextureToBMP(Texture* tex, char* filename) exit(-1); } - int size = 54 + 3*tex->width*tex->height; - - char* buf = (char*) calloc(size, sizeof(char)); - buf[0x00] = 'B'; - buf[0x01] = 'M'; - *(int*)&(buf[0x0A]) = 54; - *(int*)&(buf[0x12]) = tex->width; - *(int*)&(buf[0x16]) = tex->height; - *(int*)&(buf[0x1C]) = 24; - *(int*)&(buf[0x1E]) = 0; - *(int*)&(buf[0x22]) = size; - - glBindTexture(GL_TEXTURE_2D, tex->texID); - glGetTexImage(GL_TEXTURE_2D, 0, GL_BGR, GL_UNSIGNED_BYTE, buf + 54); - - FILE* f = fopen(filename, "wb"); - fwrite(buf, sizeof(char), size, f); - fclose(f); + glDeleteTextures(1, &texID); +} + +Texture& Texture::operator= (Texture tex) +{ + swap(*this, tex); - free(buf); + return *this; +} + +void swap(Texture& tex1, Texture& tex2) +{ + std::swap(tex1.width, tex2.width); + std::swap(tex1.height, tex2.height); + std::swap(tex1.texID, tex2.texID); } -void fillTexture(Texture* tex, Rectangle* dstrect, int r, int g, int b) +void Texture::fill(Rectangle dstrect, int r, int g, int b) { if (!rendererInitialized) { @@ -570,18 +579,13 @@ void fillTexture(Texture* tex, Rectangle* dstrect, int r, int g, int b) // Target the framebuffer glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex->texID, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texID, 0); // Set up the vertex attributes - GLfloat minx = (dstrect == NULL) ? 0.0f : dstrect->x; - GLfloat miny = (dstrect == NULL) ? 0.0f : dstrect->y; - GLfloat maxx = (dstrect == NULL) ? tex->width : dstrect->x + dstrect->w; - GLfloat maxy = (dstrect == NULL) ? tex->height : dstrect->y + dstrect->h; - - minx = minx / tex->width * 2.0 - 1.0; - miny = -(miny / tex->height * 2.0 - 1.0); - maxx = maxx / tex->width * 2.0 - 1.0; - maxy = -(maxy / tex->height * 2.0 - 1.0); + GLfloat minx = (GLfloat) dstrect.x / width * 2.0 - 1.0; + GLfloat miny = -((GLfloat) dstrect.y / height * 2.0 - 1.0); + GLfloat maxx = (GLfloat) (dstrect.x + dstrect.w) / width * 2.0 - 1.0; + GLfloat maxy = -((GLfloat) (dstrect.y + dstrect.h) / height * 2.0 - 1.0); GLfloat vertexbuffer_data[] = { minx, miny, @@ -598,7 +602,7 @@ void fillTexture(Texture* tex, Rectangle* dstrect, int r, int g, int b) glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); - glViewport(0, 0, tex->width, tex->height); + glViewport(0, 0, width, height); glClear(GL_DEPTH_BUFFER_BIT); glUseProgram(fillShader); 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) glDeleteBuffers(1, &vertexbuffer); } -void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle* dstrect) +void Texture::blit(Texture& srctex, Rectangle srcrect, Rectangle dstrect) { if (!rendererInitialized) { @@ -619,18 +623,13 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle // Target the framebuffer glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dsttex->texID, 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texID, 0); // Set up the vertex attributes - GLfloat minx = (dstrect == NULL) ? 0.0f : dstrect->x; - GLfloat miny = (dstrect == NULL) ? 0.0f : dstrect->y; - GLfloat maxx = (dstrect == NULL) ? dsttex->width : dstrect->x + dstrect->w; - GLfloat maxy = (dstrect == NULL) ? dsttex->height : dstrect->y + dstrect->h; - - minx = minx / dsttex->width * 2.0 - 1.0; - miny = -(miny / dsttex->height * 2.0 - 1.0); - maxx = maxx / dsttex->width * 2.0 - 1.0; - maxy = -(maxy / dsttex->height * 2.0 - 1.0); + GLfloat minx = (GLfloat) dstrect.x / width * 2.0 - 1.0; + GLfloat miny = -((GLfloat) dstrect.y / height * 2.0 - 1.0); + GLfloat maxx = (GLfloat) (dstrect.x + dstrect.w) / width * 2.0 - 1.0; + GLfloat maxy = -((GLfloat) (dstrect.y + dstrect.h) / height * 2.0 - 1.0); GLfloat vertexbuffer_data[] = { minx, miny, @@ -645,15 +644,10 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); - GLfloat minu = (srcrect == NULL) ? 0.0f : srcrect->x; - GLfloat minv = (srcrect == NULL) ? 0.0f : srcrect->y; - GLfloat maxu = (srcrect == NULL) ? srctex->width : srcrect->x + srcrect->w; - GLfloat maxv = (srcrect == NULL) ? srctex->height : srcrect->y + srcrect->h; - - minu = minu / srctex->width; - minv = 1 - (minv / srctex->height); - maxu = maxu / srctex->width; - maxv = 1 - (maxv / srctex->height); + GLfloat minu = (GLfloat) srcrect.x / srctex.width; + GLfloat minv = 1 - ((GLfloat) srcrect.y / srctex.height); + GLfloat maxu = (GLfloat) (srcrect.x + srcrect.w) / srctex.width; + GLfloat maxv = 1 - ((GLfloat) (srcrect.y + srcrect.h) / srctex.height); GLfloat texcoordbuffer_data[] = { minu, minv, @@ -671,10 +665,10 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle // Set up the shader glUseProgram(blitShader); glClear(GL_DEPTH_BUFFER_BIT); - glViewport(0, 0, dsttex->width, dsttex->height); + glViewport(0, 0, width, height); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, srctex->texID); + glBindTexture(GL_TEXTURE_2D, srctex.texID); glUniform1i(glGetUniformLocation(blitShader, "srctex"), 0); // Blit! @@ -687,63 +681,7 @@ void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle glDeleteBuffers(1, &vertexbuffer); } -void renderWithoutEffects(Texture* tex) -{ - if (!rendererInitialized) - { - fprintf(stderr, "Renderer not initialized\n"); - exit(-1); - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, buffer_width, buffer_height); - glClear(GL_COLOR_BUFFER_BIT); - glUseProgram(blitShader); - - const GLfloat fullBlitVertices_data[] = { - -1.0, -1.0, - 1.0, -1.0, - -1.0, 1.0, - 1.0, 1.0 - }; - - GLuint fullBlitVertices; - glGenBuffers(1, &fullBlitVertices); - glBindBuffer(GL_ARRAY_BUFFER, fullBlitVertices); - glBufferData(GL_ARRAY_BUFFER, sizeof(fullBlitVertices_data), fullBlitVertices_data, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); - - const GLfloat fullBlitTex_data[] = { - 0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0 - }; - - GLuint fullBlitTex; - glGenBuffers(1, &fullBlitTex); - glBindBuffer(GL_ARRAY_BUFFER, fullBlitTex); - glBufferData(GL_ARRAY_BUFFER, sizeof(fullBlitTex_data), fullBlitTex_data, GL_STATIC_DRAW); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex->texID); - glUniform1i(glGetUniformLocation(blitShader, "srctex"), 0); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(0); - - glDeleteBuffers(1, &fullBlitTex); - glDeleteBuffers(1, &fullBlitVertices); - - glfwSwapBuffers(window); -} - -void bloomPass1(GLuint srcTex, GLuint dstTex, bool horizontal, vec2 srcRes, vec2 dstRes) +void bloomPass1(GLuint srcTex, GLuint dstTex, bool horizontal, glm::vec2 srcRes, glm::vec2 dstRes) { glBindFramebuffer(GL_FRAMEBUFFER, generic_framebuffer); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dstTex, 0); @@ -755,7 +693,7 @@ void bloomPass1(GLuint srcTex, GLuint dstTex, bool horizontal, vec2 srcRes, vec2 glBindTexture(GL_TEXTURE_2D, srcTex); glUniform1i(glGetUniformLocation(bloom1Shader, "inTex"), 0); - vec2 offset = vec2(0.0); + glm::vec2 offset = glm::vec2(0.0); if (horizontal) { offset.x = 1.2/srcRes.x; @@ -772,7 +710,7 @@ void bloomPass1(GLuint srcTex, GLuint dstTex, bool horizontal, vec2 srcRes, vec2 glDisableVertexAttribArray(0); } -void renderScreen(Texture* tex) +void Texture::renderScreen() { if (!rendererInitialized) { @@ -792,7 +730,7 @@ void renderScreen(Texture* tex) // Use the current frame texture, nearest neighbor and clamped to edge glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex->texID); + glBindTexture(GL_TEXTURE_2D, texID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -832,7 +770,6 @@ void renderScreen(Texture* tex) // We're going to render the screen now glBindFramebuffer(GL_FRAMEBUFFER, bloom_framebuffer); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, preBloomTex, 0); - //glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0,0,buffer_width,buffer_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(finalShader); @@ -855,11 +792,10 @@ void renderScreen(Texture* tex) glUniform1i(glGetUniformLocation(finalShader, "scanlinestex"), 1); // Initialize the MVP matrices - mat4 p_matrix = perspective(42.5f, (float) buffer_width / (float) buffer_height, 0.1f, 100.0f); - mat4 v_matrix = lookAt(vec3(2,0,0), vec3(0,0,0), vec3(0,1,0)); - mat4 m_matrix = mat4(1.0); - mat4 mvp_matrix = p_matrix * v_matrix * m_matrix; - //mat4 mv_matrix = v_matrix * m_matrix; + glm::mat4 p_matrix = glm::perspective(42.5f, (float) buffer_width / (float) buffer_height, 0.1f, 100.0f); + glm::mat4 v_matrix = glm::lookAt(glm::vec3(2,0,0), glm::vec3(0,0,0), glm::vec3(0,1,0)); + glm::mat4 m_matrix = glm::mat4(1.0); + glm::mat4 mvp_matrix = p_matrix * v_matrix * m_matrix; glUniformMatrix4fv(glGetUniformLocation(finalShader, "MVP"), 1, GL_FALSE, &mvp_matrix[0][0]); glUniformMatrix4fv(glGetUniformLocation(finalShader, "worldMat"), 1, GL_FALSE, &m_matrix[0][0]); @@ -884,7 +820,7 @@ void renderScreen(Texture* tex) glDisableVertexAttribArray(0); // First pass of bloom! - vec2 buffer_size = vec2(buffer_width, buffer_height); + glm::vec2 buffer_size = glm::vec2(buffer_width, buffer_height); bloomPass1(preBloomTex, bloomPassTex1, true, buffer_size, buffer_size / 4.0f); bloomPass1(bloomPassTex1, bloomPassTex2, false, buffer_size / 4.0f, buffer_size / 4.0f); @@ -903,7 +839,6 @@ void renderScreen(Texture* tex) glUniform1i(glGetUniformLocation(bloom2Shader, "blurTex"), 1); glUniform1f(glGetUniformLocation(bloom2Shader, "iGlobalTime"), glfwGetTime()); -// glUniform2f(glGetUniformLocation(bloom2Shader, "resolution"), buffer_width, buffer_height); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); @@ -915,3 +850,8 @@ void renderScreen(Texture* tex) curBuf = (curBuf + 1) % 2; } + +Rectangle Texture::entirety() +{ + return {0, 0, width, height}; +} 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 @@ #include #include -#include -#include - -using namespace glm; #ifndef RENDERER_H #define RENDERER_H @@ -13,33 +9,29 @@ struct Rectangle { int y; int w; int h; - - Rectangle() {}; - - Rectangle(int m_x, int m_y, int m_w, int m_h) - { - x = m_x; - y = m_y; - w = m_w; - h = m_h; - } }; -struct Texture { - GLuint texID; - int width; - int height; +class Texture { + public: + Texture(int width, int height); + Texture(const char* file); + Texture(Texture& tex); + Texture(Texture&& tex); + ~Texture(); + Texture& operator= (Texture tex); + friend void swap(Texture& tex1, Texture& tex2); + void fill(Rectangle loc, int r, int g, int b); + void blit(Texture& src, Rectangle srcrect, Rectangle dstrect); + void renderScreen(); + Rectangle entirety(); + + private: + GLuint texID; + int width; + int height; }; GLFWwindow* initRenderer(); void destroyRenderer(); -Texture* createTexture(int width, int height); -void destroyTexture(Texture* tex); -Texture* loadTextureFromFile(char* filename); -void saveTextureToBMP(Texture* tex, char* filename); -void fillTexture(Texture* tex, Rectangle* loc, int r, int g, int b); -void blitTexture(Texture* srctex, Texture* dsttex, Rectangle* srcrect, Rectangle* dstrect); -void renderWithoutEffects(Texture* tex); -void renderScreen(Texture* tex); #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 @@ -#include "world.h" - -void World::tick() -{ - for (auto it = entities.begin(); it != entities.end(); it++) - { - (*it)->tick(); - } -} - -void World::input(int key, int action) -{ - for (auto it = entities.begin(); it != entities.end(); it++) - { - (*it)->input(key, action); - } -} - -void World::render(Texture* buffer) -{ - fillTexture(buffer, NULL, 0, 0, 0); - - for (auto it = entities.begin(); it != entities.end(); it++) - { - (*it)->render(buffer); - } -} - -void World::addEntity(std::shared_ptr e) -{ - entities.push_back(e); -} 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 @@ -#ifndef WORLD_H -#define WORLD_H - -class World; - -#include -#include "renderer.h" -#include "entity.h" -#include - -class World { - public: - World() {}; - ~World() {}; - void tick(); - void input(int key, int action); - void render(Texture* buffer); - void addEntity(std::shared_ptr e); - - std::list bodies; - std::shared_ptr player; - - private: - std::list> entities; -}; - -#endif -- cgit 1.4.1