improved support for different resolutions + general documentation and cleanup
This commit is contained in:
parent
6ad1272d7d
commit
701ac3e151
14 changed files with 614 additions and 653 deletions
|
|
@ -1,31 +1,19 @@
|
|||
-- global vars
|
||||
patrolDestination = { x=500.0, y=500.0, z=0.0 }
|
||||
moveLeft = true
|
||||
MoveLeft = true
|
||||
-- helper functions
|
||||
function watchPosition(actor, pos)
|
||||
local function watchPosition(actor, pos)
|
||||
local y = pos.y - actor.position.y
|
||||
local x = pos.x - actor.position.x
|
||||
local rotation = math.atan2(y, x)
|
||||
actor.rotation = math.deg(rotation)
|
||||
end
|
||||
|
||||
function distance(a, b)
|
||||
local function distance(a, b)
|
||||
local dx = a.x - b.x
|
||||
local dy = a.y - b.y
|
||||
return math.sqrt(dx * dx + dy * dy)
|
||||
end
|
||||
|
||||
function moveTo(actor, pos)
|
||||
local a = actor
|
||||
local p = pos
|
||||
watchPosition(a, p)
|
||||
if distance(a.position, p) < 50 then
|
||||
return true
|
||||
end
|
||||
a:moveForward()
|
||||
return false
|
||||
end
|
||||
|
||||
-- Behaviour Functions called on AI
|
||||
|
||||
-- These functions are ai behaviour functions called in the game
|
||||
|
|
@ -48,24 +36,12 @@ end
|
|||
function patrol(actor, target)
|
||||
local a = actor
|
||||
local t = target
|
||||
if t ~= nil then
|
||||
-- print("target is at " .. target.position.x)
|
||||
end
|
||||
--if moveTo(actor, patrolDestination) == true then
|
||||
-- patrolDestination = { x=math.random(400.0, 750.0), y=math.random(400.0, 750.0), z=0.0 }
|
||||
--end
|
||||
-- performRaycast returns if true if the raycast hits the target position it also sets the getter function
|
||||
-- distFromWall, at bot creation distFromWall is and infinite float value.
|
||||
-- This performRaycast function is highly discourage due to slow down
|
||||
--if raycaster:performRaycast(actor.position, actor.rotation, target.position) == true then
|
||||
--ai.state = AIState.Alert
|
||||
--end
|
||||
if raycaster:bresenhamRaycast(a.position, a.rotation, t.position) == true then
|
||||
--target hit!
|
||||
ai.state = AIState.Alert
|
||||
end
|
||||
if raycaster:distFromWall() < 3 then
|
||||
upOrDown = math.random(2)
|
||||
local upOrDown = math.random(2)
|
||||
if moveLeft == true then
|
||||
if upOrDown == 1 then
|
||||
a.rotation = 180
|
||||
|
|
@ -90,10 +66,8 @@ function alert(actor, target)
|
|||
local a = actor
|
||||
local t = target
|
||||
if target ~= nil then
|
||||
-- print("target is at " .. target.position.x)
|
||||
watchPosition(a, t.position)
|
||||
end
|
||||
--print("actor is alert at " .. actor.position.x)
|
||||
if distance(a.position, t.position) > 300 then
|
||||
a:moveForward()
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
-- helper functions
|
||||
|
||||
function lookAway(actor, pos)
|
||||
y = actor.position.y - pos.y
|
||||
x = actor.position.x - pos.x
|
||||
rotation = math.atan(y, x)
|
||||
local function lookAway(actor, pos)
|
||||
local y = actor.position.y - pos.y
|
||||
local x = actor.position.x - pos.x
|
||||
local rotation = math.atan(y, x)
|
||||
actor.rotation = math.deg(rotation)
|
||||
end
|
||||
|
||||
function distance(a, b)
|
||||
local function distance(a, b)
|
||||
return math.sqrt((math.abs(a.x - b.x) ^ 2) + (math.abs(a.y - b.y) ^ 2))
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
|
||||
find_package(SDL2 2.30.2 REQUIRED)
|
||||
find_package(SDL2_IMAGE 2.8.2 REQUIRED)
|
||||
find_package(SDL2_image 2.8.2 REQUIRED)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LuaJIT REQUIRED IMPORTED_TARGET GLOBAL luajit)
|
||||
find_package(sol2 REQUIRED)
|
||||
|
|
@ -42,6 +42,7 @@ add_executable (YuppleMayham
|
|||
"src/utility/ftfont.cpp"
|
||||
"src/graphics/sprite.cpp"
|
||||
"src/graphics/mesh.cpp"
|
||||
"src/graphics/glwindow.cpp"
|
||||
"src/gameplay/entity.cpp"
|
||||
"src/gameplay/gameactor.cpp"
|
||||
"src/graphics/shader.cpp"
|
||||
|
|
@ -104,6 +105,6 @@ endif()
|
|||
|
||||
target_include_directories(YuppleMayham PRIVATE "${PROJECT_SOURCE_DIR}/YuppleMayham/include" ${LuaJIT_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIR_ft2build})
|
||||
|
||||
target_link_libraries(YuppleMayham SDL2::SDL2main SDL2::SDL2 SDL2_image::SDL2_image openal glm::glm-header-only tinyxml2 freetype ${LuaJIT_LINK_LIBRARIES})
|
||||
target_link_libraries(YuppleMayham SDL2::SDL2main SDL2::SDL2 SDL2_image::SDL2_image openal glm::glm tinyxml2 freetype ${LuaJIT_LINK_LIBRARIES})
|
||||
|
||||
# TODO: Add tests and install targets if needed.
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
#ifndef _H_GAME_H
|
||||
#define _H_GAME_H
|
||||
|
||||
#include <memory>
|
||||
#include <SDL_events.h>
|
||||
#include <memory>
|
||||
#include <utility/events.h>
|
||||
|
||||
#include "gameplay/camera.h"
|
||||
|
||||
class InputHandler;
|
||||
class Scene;
|
||||
class Text;
|
||||
|
|
@ -13,15 +15,9 @@ class Renderer;
|
|||
class AudioEngine;
|
||||
class GLWindow;
|
||||
|
||||
enum {
|
||||
GAME_QUITTING = 0,
|
||||
GAME_RUNNING = 1,
|
||||
GAME_MENU = 2,
|
||||
GAME_PLAYING = 4
|
||||
};
|
||||
enum { GAME_QUITTING = 0, GAME_RUNNING = 1, GAME_MENU = 2, GAME_PLAYING = 4 };
|
||||
|
||||
class Game
|
||||
{
|
||||
class Game {
|
||||
public:
|
||||
Game() {}
|
||||
bool init();
|
||||
|
|
@ -47,6 +43,7 @@ private:
|
|||
|
||||
std::shared_ptr<GLWindow> window;
|
||||
|
||||
std::unique_ptr<Camera> camera;
|
||||
std::shared_ptr<Scene> currentScene;
|
||||
std::shared_ptr<InputHandler> inputHandler;
|
||||
std::shared_ptr<ResourceManager> resourceManager;
|
||||
|
|
|
|||
|
|
@ -2,17 +2,14 @@
|
|||
#define _H_GLWINDOW_H
|
||||
|
||||
#include <SDL_video.h>
|
||||
//#include <SDL_opengl.h>
|
||||
|
||||
#include <thirdparty/glad/glad.h>
|
||||
|
||||
class GLWindow
|
||||
{
|
||||
#include "utility/logger.h"
|
||||
|
||||
class GLWindow {
|
||||
public:
|
||||
GLWindow(const char* windowName, int width, int height) :
|
||||
w(width),
|
||||
h(height),
|
||||
name(windowName) {};
|
||||
GLWindow(const char *windowName, int width, int height)
|
||||
: w(width), h(height), name(windowName) {};
|
||||
~GLWindow();
|
||||
|
||||
bool Init();
|
||||
|
|
@ -20,11 +17,12 @@ public:
|
|||
void swap() { SDL_GL_SwapWindow(window); }
|
||||
void makeCurrent() { SDL_GL_MakeCurrent(window, glContext); }
|
||||
|
||||
unsigned width() const { return w; }
|
||||
unsigned height() const { return h; }
|
||||
unsigned Width() const { return w; }
|
||||
unsigned Height() const { return h; }
|
||||
|
||||
SDL_Window *getWindow() const { return window; }
|
||||
const SDL_GLContext &getContext() const { return glContext; }
|
||||
|
||||
private:
|
||||
SDL_Window *window = nullptr;
|
||||
SDL_GLContext glContext = NULL;
|
||||
|
|
@ -33,21 +31,4 @@ private:
|
|||
const char *name;
|
||||
};
|
||||
|
||||
bool GLWindow::Init()
|
||||
{
|
||||
window = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_OPENGL);
|
||||
if (!window)
|
||||
return false;
|
||||
glContext = SDL_GL_CreateContext(window);
|
||||
if (!glContext)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLWindow::~GLWindow()
|
||||
{
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
|
||||
#endif // _H_GLWINDOW_H
|
||||
|
|
|
|||
|
|
@ -1,31 +1,25 @@
|
|||
#ifndef _H_RENDERER_H
|
||||
#define _H_RENDERER_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "graphics/quad.h"
|
||||
#include "graphics/drawable.h"
|
||||
#include "graphics/glwindow.h"
|
||||
#include "graphics/postprocess.h"
|
||||
#include "graphics/quad.h"
|
||||
|
||||
class ResourceManager;
|
||||
class Shader;
|
||||
|
||||
enum class RenderLayer {
|
||||
Background,
|
||||
Map,
|
||||
GameObjects,
|
||||
Effects,
|
||||
HUD,
|
||||
Menu
|
||||
};
|
||||
enum class RenderLayer { Background, Map, GameObjects, Effects, HUD, Menu };
|
||||
|
||||
class Renderer
|
||||
{
|
||||
class Renderer {
|
||||
public:
|
||||
Renderer(const std::shared_ptr<ResourceManager>&);
|
||||
Renderer(const std::shared_ptr<ResourceManager> &,
|
||||
const std::shared_ptr<GLWindow> &);
|
||||
|
||||
void clear();
|
||||
|
||||
|
|
@ -41,15 +35,11 @@ private:
|
|||
std::unordered_map<RenderLayer, std::vector<Drawable *>> worldLayerPool;
|
||||
std::unordered_map<RenderLayer, std::vector<Drawable *>> HUDLayerPool;
|
||||
std::vector<RenderLayer> renderingOrder = {
|
||||
RenderLayer::Background,
|
||||
RenderLayer::Map,
|
||||
RenderLayer::GameObjects,
|
||||
RenderLayer::Effects,
|
||||
RenderLayer::HUD,
|
||||
RenderLayer::Menu
|
||||
};
|
||||
RenderLayer::Background, RenderLayer::Map, RenderLayer::GameObjects,
|
||||
RenderLayer::Effects, RenderLayer::HUD, RenderLayer::Menu};
|
||||
|
||||
void uploadUniforms(const unsigned shaderID, const std::vector<Uniform>& uniforms);
|
||||
void uploadUniforms(const unsigned shaderID,
|
||||
const std::vector<Uniform> &uniforms);
|
||||
|
||||
unsigned uboMatrices;
|
||||
|
||||
|
|
@ -61,6 +51,7 @@ private:
|
|||
std::unique_ptr<ScreenQuad> screenQuad;
|
||||
|
||||
std::shared_ptr<ResourceManager> resourceManager;
|
||||
std::shared_ptr<GLWindow> glWindow;
|
||||
|
||||
void initFrameBuffers();
|
||||
void initUniformBuffers();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ AI::AI(GameActor* actor, std::unique_ptr<Raycaster> raycaster)
|
|||
lastGCTime(std::chrono::high_resolution_clock::now()), GCTimeout(3)
|
||||
{}
|
||||
|
||||
/*
|
||||
* The behavior script works off of three different states, idle, patrol and alert.
|
||||
* When the script is idle, this is */
|
||||
void AI::attachBehaviourScript(std::unique_ptr<AIScript> behaviour)
|
||||
{
|
||||
// passing out instance of raycaster and this AI into our scripting api
|
||||
|
|
@ -25,6 +28,8 @@ void AI::attachBehaviourScript(std::unique_ptr<AIScript> behaviour)
|
|||
void AI::update()
|
||||
{
|
||||
try {
|
||||
// If our ai doesn't have a reference to the actor it's controlling it will do nothing.
|
||||
// If our ai script does have an actor but no target, it will default to its idle state.
|
||||
if (actor && target) {
|
||||
switch (state)
|
||||
{
|
||||
|
|
@ -35,7 +40,7 @@ void AI::update()
|
|||
if (!result.valid())
|
||||
{
|
||||
sol::error err = result;
|
||||
std::cerr << "lua error: " << err.what() << std::endl;
|
||||
LOG(ERROR, "Lua error: {}", err.what(), NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -46,7 +51,7 @@ void AI::update()
|
|||
if (!result.valid())
|
||||
{
|
||||
sol::error err = result;
|
||||
std::cerr << "lua error: " << err.what() << std::endl;
|
||||
LOG(ERROR, "Lua error: {}", err.what(), NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -57,12 +62,25 @@ void AI::update()
|
|||
if (!result.valid())
|
||||
{
|
||||
sol::error err = result;
|
||||
std::cerr << "lua error: " << err.what() << std::endl;
|
||||
LOG(ERROR, "Lua error: {}", err.what(), NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (actor) {
|
||||
switch (state)
|
||||
{
|
||||
case AIState::Idle:
|
||||
if (idleFunc.valid()) {
|
||||
auto result = idleFunc(actor, nullptr);
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
LOG(ERROR, "Lua Error: {}", err.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Collect garbage just to be sure.
|
||||
std::chrono::high_resolution_clock::time_point curTime = std::chrono::high_resolution_clock::now();
|
||||
if (curTime - lastGCTime >= GCTimeout)
|
||||
{
|
||||
|
|
@ -71,13 +89,14 @@ void AI::update()
|
|||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Error during AI update: " << e.what() << std::endl;
|
||||
LOG(ERROR, "Problem occured during AI update: {}", e.what());
|
||||
state = AIState::Idle;
|
||||
}
|
||||
}
|
||||
|
||||
AI::~AI()
|
||||
{
|
||||
// Just set all of the references to null, given they are smart pointers, they are freed when no longer used.
|
||||
behaviour->lua["raycaster"] = sol::nil;
|
||||
behaviour->lua["ai"] = sol::nil;
|
||||
behaviour->lua["idle"] = sol::nil;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "gameplay/camera.h"
|
||||
|
||||
// follow our target set using the setTarget. If there is no target set the camera will not move.
|
||||
void Camera::update(double deltaTime)
|
||||
{
|
||||
if (target == nullptr)
|
||||
|
|
@ -19,6 +20,7 @@ glm::mat4 Camera::getProjectionMatrix()
|
|||
return glm::ortho(0.f, viewPortW, viewPortH, 0.f);
|
||||
}
|
||||
|
||||
// The local coordinates are the corrdinates relative to the camera.
|
||||
const glm::vec3 Camera::worldToLocal(const glm::vec3& worldCoordinates)
|
||||
{
|
||||
//return worldCoordinates - position;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ void Entity::flip()
|
|||
flipped = !flipped;
|
||||
}
|
||||
|
||||
// Add physics component implies more than one can be attached to an entity...
|
||||
void Entity::addPhysicsComponent(const std::shared_ptr<PhysicsComponent>& physics)
|
||||
{
|
||||
this->physics = physics;
|
||||
|
|
@ -39,6 +40,8 @@ void Entity::addPhysicsComponent(const std::shared_ptr<PhysicsComponent>& physic
|
|||
|
||||
void Entity::update(double deltaTime)
|
||||
{
|
||||
// If our entity has a physics component attached and that they're moving,
|
||||
// we will update the entity position to match the rigidBody position.
|
||||
if (physics && physics->rigidBody.velocity != glm::vec2(0.0f))
|
||||
{
|
||||
position = glm::vec3(physics->rigidBody.position, 0.f);
|
||||
|
|
@ -47,21 +50,24 @@ void Entity::update(double deltaTime)
|
|||
}
|
||||
else if (!physics)
|
||||
{
|
||||
// In the case that the entity does not have a physics component we will handle movement on the entity itself.
|
||||
position += deltaPosition * 1.f;
|
||||
updateModelMatrix();
|
||||
deltaPosition = glm::vec3(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
// The entity will only need to update its model matrix and the flipped flag on its attached shader.
|
||||
// The shader and sprite component will handle the drawing.
|
||||
void Entity::draw()
|
||||
{
|
||||
//glm::mat4 mvp = camera->getProjectionMatrix() * camera->getViewMatrix() * modelMatrix;
|
||||
editUniform("model", modelMatrix);
|
||||
editUniform("flip", flipped);
|
||||
}
|
||||
|
||||
void Entity::updateModelMatrix()
|
||||
{
|
||||
// Quick sanity check to make sure our Z position is zero. Since we are in 2D
|
||||
position.z = 0.f;
|
||||
glm::mat4 rotationMat = (isRotatable) ? glm::rotate(glm::mat4(1.f), glm::radians(rotation), glm::vec3(0.0f, 0.0f, 1.0f)) : glm::mat4(1.0f);
|
||||
glm::mat4 translation = glm::translate(glm::mat4(1.f), position);
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
#include "gameplay/game.h"
|
||||
#include "gameplay/input.h"
|
||||
#include "gameplay/scene.h"
|
||||
/*due for possible removal!*/
|
||||
#include "gameplay/gameactor.h"
|
||||
#include "gameplay/weapons/weapon.h"
|
||||
/*-------------------------*/
|
||||
|
||||
#include "utility/command.h"
|
||||
#include "utility/resourcemanager.h"
|
||||
#include "utility/ftfont.h"
|
||||
#include "utility/logger.h"
|
||||
#include "utility/resourcemanager.h"
|
||||
|
||||
#include "graphics/glwindow.h"
|
||||
|
||||
|
|
@ -17,12 +13,10 @@
|
|||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <utility/events.h>
|
||||
|
||||
bool Game::init()
|
||||
{
|
||||
window = std::make_shared<GLWindow>("Yupple Mayham", 800, 600);
|
||||
bool Game::init() {
|
||||
window = std::make_shared<GLWindow>("Yupple Mayham", 1024, 768);
|
||||
|
||||
if (!window->Init())
|
||||
ERROR_LOG("Failed to init GLWindow: {}", SDL_GetError());
|
||||
|
|
@ -37,27 +31,31 @@ bool Game::init()
|
|||
#endif
|
||||
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
glViewport(0, 0, window->width(), window->height());
|
||||
glViewport(0, 0, window->Width(), window->Height());
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// For now we'll init default bindings, but as we move forward controls will be set by the player and saved in controls.xml
|
||||
// For now we'll init default bindings, but as we move forward controls will
|
||||
// be set by the player and saved in controls.xml
|
||||
inputHandler = std::make_shared<InputHandler>();
|
||||
inputHandler->bindKeyCommand(SDLK_w, 0, std::make_unique<MoveUpCommand>());
|
||||
inputHandler->bindKeyCommand(SDLK_a, 0, std::make_unique<MoveLeftCommand>());
|
||||
inputHandler->bindKeyCommand(SDLK_s, 0, std::make_unique<MoveDownCommand>());
|
||||
inputHandler->bindKeyCommand(SDLK_d, 0, std::make_unique<MoveRightCommand>());
|
||||
|
||||
inputHandler->bindMouseCommand(MOUSE_BUTTON_LEFT, 100, std::make_unique<ShootCommand>());
|
||||
inputHandler->bindMouseCommand(MOUSE_BUTTON_LEFT, 100,
|
||||
std::make_unique<ShootCommand>());
|
||||
inputHandler->bindMouseMotion(std::make_unique<FollowMouseCommand>());
|
||||
inputHandler->bindMouseScroll(std::make_unique<CycleCommand>());
|
||||
|
||||
game_state |= GAME_RUNNING;
|
||||
globalEventManager = std::make_shared<EventManager>();
|
||||
resourceManager = std::make_shared<ResourceManager>();
|
||||
renderer = std::make_shared<Renderer>(resourceManager);
|
||||
renderer = std::make_shared<Renderer>(resourceManager, window);
|
||||
audioEngine = std::make_shared<AudioEngine>(resourceManager);
|
||||
camera = std::make_unique<Camera>(static_cast<float>(window->Width()),
|
||||
static_cast<float>(window->Height()));
|
||||
audioEngine->hookEventManager(globalEventManager);
|
||||
/* Testing */
|
||||
audioEngine->pushMusic("music/short_song.ogg");
|
||||
|
|
@ -72,65 +70,56 @@ bool Game::init()
|
|||
return true;
|
||||
}
|
||||
|
||||
const unsigned Game::getWindowWidth() const { return window->width(); }
|
||||
const unsigned Game::getWindowHeight() const { return window->height(); }
|
||||
const unsigned Game::getWindowWidth() const { return window->Width(); }
|
||||
const unsigned Game::getWindowHeight() const { return window->Height(); }
|
||||
|
||||
bool Game::loadDebugScene()
|
||||
{
|
||||
currentScene = std::make_shared<Scene>(SCENE_SHOOTER, resourceManager, globalEventManager);
|
||||
bool Game::loadDebugScene() {
|
||||
currentScene = std::make_shared<Scene>(SCENE_SHOOTER, resourceManager,
|
||||
globalEventManager);
|
||||
currentScene->init();
|
||||
audioEngine->hookSceneManager(currentScene->getEventManager());
|
||||
if (currentScene->getPlayer() == nullptr)
|
||||
return false;
|
||||
inputHandler->setActor(currentScene->getPlayer().get());
|
||||
camera->setTarget(currentScene->getPlayer().get());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Game::captureInput(SDL_Event& e)
|
||||
{
|
||||
inputHandler->captureInput(e);
|
||||
}
|
||||
void Game::captureInput(SDL_Event &e) { inputHandler->captureInput(e); }
|
||||
|
||||
void Game::executeInputs()
|
||||
{
|
||||
void Game::executeInputs() {
|
||||
inputHandler->handleInput();
|
||||
inputHandler->executeCommands();
|
||||
}
|
||||
|
||||
void Game::update(double deltaTime)
|
||||
{
|
||||
void Game::update(double deltaTime) {
|
||||
if (currentScene) {
|
||||
currentScene->update(deltaTime);
|
||||
if (auto player = currentScene->getPlayer())
|
||||
if (auto player = currentScene->getPlayer()) {
|
||||
audioEngine->updateListener(player->getPosition());
|
||||
player->setLocalPosition(camera->worldToLocal(player->getPosition()));
|
||||
}
|
||||
}
|
||||
camera->update(deltaTime);
|
||||
audioEngine->poll();
|
||||
}
|
||||
|
||||
void Game::render()
|
||||
{
|
||||
void Game::render() {
|
||||
glClearColor(0.05f, 0.25f, 0.05f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
renderer->setProjAndViewMatrix(camera->getProjectionMatrix(),
|
||||
camera->getViewMatrix());
|
||||
|
||||
if (currentScene)
|
||||
{
|
||||
currentScene->render(renderer);
|
||||
/*Debug ammo indicator*/
|
||||
textHandler->DrawText("comic.ttf", std::to_string(currentScene->getPlayer()->getHeldWeapon()->getMagazine()), glm::vec2(10, 10), 0.5f);
|
||||
textHandler->DrawText("comic.ttf", "/", glm::vec2(50, 10), 0.5f);
|
||||
textHandler->DrawText("comic.ttf", std::to_string(currentScene->getPlayer()->getHeldWeapon()->getAmmo()), glm::vec2(90, 10), 0.5f);
|
||||
}
|
||||
|
||||
window->swap();
|
||||
}
|
||||
|
||||
void Game::quit()
|
||||
{
|
||||
game_state = GAME_QUITTING;
|
||||
}
|
||||
void Game::quit() { game_state = GAME_QUITTING; }
|
||||
|
||||
Game::~Game()
|
||||
{
|
||||
Game::~Game() {
|
||||
if (audioEngine) {
|
||||
audioEngine->killMusic();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,30 @@
|
|||
#include "gameplay/scene.h"
|
||||
#include "gameplay/camera.h"
|
||||
#include "gameplay/ai.h"
|
||||
#include "gameplay/gameactor.h"
|
||||
#include "gameplay/weapons/weapons.h"
|
||||
#include "gameplay/weapons/bulletmanager.h"
|
||||
#include "gameplay/map.h"
|
||||
#include "gameplay/physics.h"
|
||||
#include "gameplay/ai.h"
|
||||
#include "gameplay/weapons/bulletmanager.h"
|
||||
#include "gameplay/weapons/weapons.h"
|
||||
|
||||
#include "graphics/sprite.h"
|
||||
#include "graphics/animation.h"
|
||||
#include "graphics/background.h"
|
||||
#include "graphics/sprite.h"
|
||||
|
||||
#include "utility/script.h"
|
||||
#include "utility/component.h"
|
||||
#include "utility/ftfont.h"
|
||||
#include "utility/xmlloader.h"
|
||||
#include "utility/resourcemanager.h"
|
||||
#include "utility/events.h"
|
||||
#include "utility/raycaster.h"
|
||||
#include "utility/debugdraw.h"
|
||||
#include "utility/events.h"
|
||||
#include "utility/ftfont.h"
|
||||
#include "utility/raycaster.h"
|
||||
#include "utility/resourcemanager.h"
|
||||
#include "utility/script.h"
|
||||
#include "utility/xmlloader.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <execution>
|
||||
|
||||
// Scene xml files, should contain a node called <player> that holds the sprite location
|
||||
// Scene xml files, should contain a node called <player> that holds the sprite
|
||||
// location
|
||||
/*
|
||||
like this:
|
||||
<player sprite="sprites/player2Atlas.png" frameSize=64.0>
|
||||
|
|
@ -33,33 +33,35 @@ like this:
|
|||
</player>
|
||||
*/
|
||||
|
||||
Scene::Scene(SceneType sceneType, std::shared_ptr<ResourceManager> resources, std::weak_ptr<EventManager> globalEvents)
|
||||
: type(sceneType), resourceManager(resources), globalEventManager(globalEvents)
|
||||
{
|
||||
camera = std::make_shared<Camera>(800.f, 600.f);
|
||||
Scene::Scene(SceneType sceneType, std::shared_ptr<ResourceManager> resources,
|
||||
std::weak_ptr<EventManager> globalEvents)
|
||||
: type(sceneType), resourceManager(resources),
|
||||
globalEventManager(globalEvents) {
|
||||
physicsEngine = std::make_shared<PhysicsEngine>();
|
||||
eventManager = std::make_shared<EventManager>();
|
||||
}
|
||||
|
||||
void Scene::init()
|
||||
{
|
||||
void Scene::init() {
|
||||
physicsEngine->hookEventManager(eventManager);
|
||||
// if (sceneType == SCENE_SHOOTER)
|
||||
loadDebugShooterScene();
|
||||
}
|
||||
|
||||
// This function is full of hardcoded values and test sprites, NOT for use with final product
|
||||
void Scene::loadDebugShooterScene()
|
||||
{
|
||||
// This function is full of hardcoded values and test sprites, NOT for use with
|
||||
// final product
|
||||
void Scene::loadDebugShooterScene() {
|
||||
hookSceneEvents();
|
||||
sceneData = resourceManager->loadScene("000");
|
||||
if (!sceneData)
|
||||
return;
|
||||
EntityData playerData = sceneData->entities[0];
|
||||
auto mapData = sceneData->map;
|
||||
auto playerShader = resourceManager->loadShader("GL_player", "shaders/GL_player.vert", "shaders/GL_player.frag");
|
||||
auto bubbleShader = resourceManager->loadShader("GL_bubble", "shaders/GL_bubble.vert", "shaders/GL_bubble.frag");
|
||||
auto weaponShader = resourceManager->loadShader("GL_pistol", "shaders/GL_pistol.vert", "shaders/GL_pistol.frag");
|
||||
auto playerShader = resourceManager->loadShader(
|
||||
"GL_player", "shaders/GL_player.vert", "shaders/GL_player.frag");
|
||||
auto bubbleShader = resourceManager->loadShader(
|
||||
"GL_bubble", "shaders/GL_bubble.vert", "shaders/GL_bubble.frag");
|
||||
auto weaponShader = resourceManager->loadShader(
|
||||
"GL_pistol", "shaders/GL_pistol.vert", "shaders/GL_pistol.frag");
|
||||
|
||||
if (!sceneData->bgFile.empty()) {
|
||||
LOG(INFO, "Found background loading '{}'", sceneData->bgFile);
|
||||
|
|
@ -67,57 +69,54 @@ void Scene::loadDebugShooterScene()
|
|||
}
|
||||
|
||||
// creating map from scene
|
||||
auto tileShader = resourceManager->loadShader("GL_tile", "shaders/GL_tile.vert", "shaders/GL_tile.frag");
|
||||
auto tileShader = resourceManager->loadShader(
|
||||
"GL_tile", "shaders/GL_tile.vert", "shaders/GL_tile.frag");
|
||||
map = std::make_shared<Map>(mapData, tileShader, resourceManager);
|
||||
|
||||
for (EntityData entityData : sceneData->entities)
|
||||
{
|
||||
for (EntityData entityData : sceneData->entities) {
|
||||
auto entity = std::make_shared<GameActor>(this, playerShader);
|
||||
// Directional is the kind of sprite sheet we are using, in this case for directional, I have the sprite sheet handle the rotations
|
||||
// instead of just rotating the object, this makes it look quite a bit better from the end user perspective.
|
||||
if (entityData.animated)
|
||||
{
|
||||
auto entityAnimation = resourceManager->loadAnimationSet(entityData.graphic, entity->getEntityID());
|
||||
// because we don't want to have the engine rotate the object based on the entities rotation,
|
||||
// we set the this value to false so we no longer rotate the object.
|
||||
// Directional is the kind of sprite sheet we are using, in this case for
|
||||
// directional, I have the sprite sheet handle the rotations instead of just
|
||||
// rotating the object, this makes it look quite a bit better from the end
|
||||
// user perspective.
|
||||
if (entityData.animated) {
|
||||
auto entityAnimation = resourceManager->loadAnimationSet(
|
||||
entityData.graphic, entity->getEntityID());
|
||||
// because we don't want to have the engine rotate the object based on the
|
||||
// entities rotation, we set the this value to false so we no longer
|
||||
// rotate the object.
|
||||
if (entityAnimation->getDirectional())
|
||||
entity->setRotatable(false);
|
||||
entity->addComponent(std::make_unique<AnimationComponent>(entityAnimation, eventManager));
|
||||
}
|
||||
else
|
||||
{
|
||||
entity->addComponent(
|
||||
std::make_unique<AnimationComponent>(entityAnimation, eventManager));
|
||||
} else {
|
||||
auto entitySprite = resourceManager->loadSpriteStatic(entityData.graphic);
|
||||
entity->addComponent(std::make_unique<SpriteComponent>(entitySprite));
|
||||
}
|
||||
auto defaultWeapon = resourceManager->loadWeapon("gun/pistol", weaponShader, bubbleShader);
|
||||
auto entityWeapon = resourceManager->loadWeapon(entityData.weapon, weaponShader, bubbleShader);
|
||||
auto defaultWeapon =
|
||||
resourceManager->loadWeapon("gun/pistol", weaponShader, bubbleShader);
|
||||
auto entityWeapon = resourceManager->loadWeapon(entityData.weapon,
|
||||
weaponShader, bubbleShader);
|
||||
|
||||
entity->pickupWeapon(std::move(defaultWeapon));
|
||||
entity->pickupWeapon(std::move(entityWeapon));
|
||||
entity->setPosition(glm::vec3(entityData.x * mapData->tileSize, entityData.y * mapData->tileSize, 0.f));
|
||||
entity->setPosition(glm::vec3(entityData.x * mapData->tileSize,
|
||||
entityData.y * mapData->tileSize, 0.f));
|
||||
entity->setScale(glm::vec3(mapData->tileSize, mapData->tileSize, 1.f));
|
||||
|
||||
entity->addPhysicsComponent(
|
||||
physicsEngine->createObject(entity->getEntityID(),
|
||||
entity->getPosition(),
|
||||
49.0,
|
||||
entity->addPhysicsComponent(physicsEngine->createObject(
|
||||
entity->getEntityID(), entity->getPosition(), 49.0,
|
||||
PhysicsComponent::Collider::Shape::Circle,
|
||||
glm::vec3(mapData->tileSize / 2))
|
||||
);
|
||||
glm::vec3(mapData->tileSize / 2)));
|
||||
|
||||
if (entityData.isPlayer)
|
||||
{
|
||||
if (entityData.isPlayer) {
|
||||
player = entity;
|
||||
camera->setTarget(entity.get());
|
||||
entity->setLocalPosition(camera->worldToLocal(entity->getPosition()));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// attach ai
|
||||
if (!entityData.script.empty())
|
||||
{
|
||||
if (!entityData.script.empty()) {
|
||||
auto behaviour = resourceManager->loadAIScript(entityData.script);
|
||||
auto rayCaster = std::make_unique<Raycaster>(40.f, 300.f, map->getCollisionMap(), mapData->tileSize);
|
||||
auto rayCaster = std::make_unique<Raycaster>(
|
||||
40.f, 300.f, map->getCollisionMap(), mapData->tileSize);
|
||||
auto ai = std::make_shared<AI>(entity.get(), std::move(rayCaster));
|
||||
ai->setTarget(player.get());
|
||||
ai->attachBehaviourScript(std::move(behaviour));
|
||||
|
|
@ -133,36 +132,28 @@ void Scene::loadDebugShooterScene()
|
|||
// Setup map and other entities...
|
||||
}
|
||||
|
||||
std::shared_ptr<GameActor> Scene::getPlayer() const
|
||||
{
|
||||
std::shared_ptr<GameActor> Scene::getPlayer() const {
|
||||
return (!player) ? nullptr : player;
|
||||
}
|
||||
|
||||
void Scene::update(double deltaTime)
|
||||
{
|
||||
void Scene::update(double deltaTime) {
|
||||
|
||||
for (const auto& [id, e] : entities)
|
||||
{
|
||||
for (const auto &[id, e] : entities) {
|
||||
e->update(deltaTime);
|
||||
if (camera->getTarget() == e.get())
|
||||
e->setLocalPosition(camera->worldToLocal(e->getPosition()));
|
||||
}
|
||||
physicsEngine->update(deltaTime);
|
||||
camera->update(deltaTime);
|
||||
}
|
||||
|
||||
void Scene::render(std::shared_ptr<Renderer> renderer)
|
||||
{
|
||||
void Scene::render(std::shared_ptr<Renderer> renderer) {
|
||||
renderer->clear();
|
||||
|
||||
renderer->setProjAndViewMatrix(camera->getProjectionMatrix(), camera->getViewMatrix());
|
||||
renderer->addDrawable(RenderLayer::Map, map.get());
|
||||
if (background) {
|
||||
renderer->addDrawable(RenderLayer::Background, static_cast<Drawable*>(background));
|
||||
renderer->addDrawable(RenderLayer::Background,
|
||||
static_cast<Drawable *>(background));
|
||||
}
|
||||
// map->draw();
|
||||
for (auto& [id, e] : entities)
|
||||
{
|
||||
for (auto &[id, e] : entities) {
|
||||
// e->draw();
|
||||
renderer->addDrawable(RenderLayer::GameObjects, e.get());
|
||||
if (e->getHeldWeapon()) {
|
||||
|
|
@ -178,13 +169,13 @@ void Scene::render(std::shared_ptr<Renderer> renderer)
|
|||
|
||||
renderer->render();
|
||||
/*
|
||||
for (const auto& bullet : player->getHeldWeapon()->getBulletManager()->getBullets()) {
|
||||
DebugDrawer::getInstance().addLine(player->getCenter(), bullet->getCenter(), glm::vec4(1.f, 0.f, 0.f, 0.f));
|
||||
DEBUG_TEXT(
|
||||
for (const auto& bullet :
|
||||
player->getHeldWeapon()->getBulletManager()->getBullets()) {
|
||||
DebugDrawer::getInstance().addLine(player->getCenter(),
|
||||
bullet->getCenter(), glm::vec4(1.f, 0.f, 0.f, 0.f)); DEBUG_TEXT(
|
||||
glm::vec3(camera.get()->worldToLocal(bullet->getCenter()).x,
|
||||
camera.get()->worldToLocal(bullet->getCenter()).y, 0.f),
|
||||
glm::vec4(1.f, 0.f, 0.f, 1.f),
|
||||
0.2f,
|
||||
camera.get()->worldToLocal(bullet->getCenter()).y,
|
||||
0.f), glm::vec4(1.f, 0.f, 0.f, 1.f), 0.2f,
|
||||
"( {}, {}, {} )",
|
||||
bullet->getCenter().x,
|
||||
bullet->getCenter().y,
|
||||
|
|
@ -192,35 +183,35 @@ void Scene::render(std::shared_ptr<Renderer> renderer)
|
|||
);
|
||||
DEBUG_TEXT(
|
||||
glm::vec3(camera.get()->worldToLocal(bullet->getCenter()).x,
|
||||
camera.get()->worldToLocal(bullet->getCenter()).y + 10.f, 0.f),
|
||||
glm::vec4(1.f, 1.f, 0.f, 1.f),
|
||||
0.2f,
|
||||
camera.get()->worldToLocal(bullet->getCenter()).y
|
||||
+ 10.f, 0.f), glm::vec4(1.f, 1.f, 0.f, 1.f), 0.2f,
|
||||
"( {}, {} )",
|
||||
bullet->getPhysicsComponent()->rigidBody.position.x,
|
||||
bullet->getPhysicsComponent()->rigidBody.position.y
|
||||
);
|
||||
DEBUG_TEXT(
|
||||
glm::vec3(camera.get()->worldToLocal(bullet->getCenter()).x,
|
||||
camera.get()->worldToLocal(bullet->getCenter()).y + 20.f, 0.f),
|
||||
glm::vec4(0.f, 1.f, 1.f, 1.f),
|
||||
0.2f,
|
||||
camera.get()->worldToLocal(bullet->getCenter()).y
|
||||
+ 20.f, 0.f), glm::vec4(0.f, 1.f, 1.f, 1.f), 0.2f,
|
||||
"( {}, {} )",
|
||||
bullet->getPhysicsComponent()->rigidBody.velocity.x,
|
||||
bullet->getPhysicsComponent()->rigidBody.velocity.y);
|
||||
}
|
||||
*/
|
||||
DebugDrawer::getInstance().draw(camera->getProjectionMatrix() * camera->getViewMatrix());
|
||||
|
||||
DEBUG_TEXT(glm::vec3(10.f, 10.f, 0.f), glm::vec4(0.f, 0.f, 0.f, 1.f), 0.5f,
|
||||
"{} / {}", getPlayer()->getHeldWeapon()->getMagazine(),
|
||||
getPlayer()->getHeldWeapon()->getAmmo());
|
||||
}
|
||||
|
||||
void Scene::unloadScene()
|
||||
{
|
||||
void Scene::unloadScene() {
|
||||
// xmlLoader.reset();
|
||||
}
|
||||
|
||||
void Scene::hookSceneEvents()
|
||||
{
|
||||
void Scene::hookSceneEvents() {
|
||||
std::weak_ptr<Scene> weakSelf = shared_from_this();
|
||||
eventManager->subscribe<BulletCollideEvent>([weakSelf](const BulletCollideEvent& e) {
|
||||
eventManager->subscribe<BulletCollideEvent>(
|
||||
[weakSelf](const BulletCollideEvent &e) {
|
||||
if (auto self = weakSelf.lock()) {
|
||||
GameActor *shooter = self->getGameActorByID(e.ownerID);
|
||||
GameActor *target = self->getGameActorByID(e.victimID);
|
||||
|
|
@ -231,16 +222,14 @@ void Scene::hookSceneEvents()
|
|||
});
|
||||
}
|
||||
|
||||
GameActor* Scene::getGameActorByID(const unsigned int ID)
|
||||
{
|
||||
GameActor *Scene::getGameActorByID(const unsigned int ID) {
|
||||
auto iterator = entities.find(ID);
|
||||
if (iterator == entities.end())
|
||||
return nullptr;
|
||||
return iterator->second.get();
|
||||
}
|
||||
|
||||
std::span<std::weak_ptr<GameActor>> Scene::getAllEntities() const
|
||||
{
|
||||
std::span<std::weak_ptr<GameActor>> Scene::getAllEntities() const {
|
||||
entityCache.clear();
|
||||
for (const auto &[_, entity] : entities) {
|
||||
entityCache.push_back(entity);
|
||||
|
|
|
|||
22
YuppleMayham/src/graphics/glwindow.cpp
Normal file
22
YuppleMayham/src/graphics/glwindow.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "graphics/glwindow.h"
|
||||
#include <SDL_error.h>
|
||||
|
||||
bool GLWindow::Init() {
|
||||
window = SDL_CreateWindow(name, SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED, w, h, SDL_WINDOW_OPENGL);
|
||||
if (!window) {
|
||||
LOG(ERROR, "Failed to create window! {}", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
glContext = SDL_GL_CreateContext(window);
|
||||
if (!glContext) {
|
||||
LOG(ERROR, "Failed to create opengl context! {}", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
GLWindow::~GLWindow() {
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
|
|
@ -1,44 +1,39 @@
|
|||
#include "graphics/renderer.h"
|
||||
#include "graphics/shader.h"
|
||||
#include "utility/resourcemanager.h"
|
||||
#include "utility/logger.h"
|
||||
#include "utility/events.h"
|
||||
#include "utility/logger.h"
|
||||
#include "utility/resourcemanager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <graphics/postprocess.h>
|
||||
#include <memory>
|
||||
|
||||
Renderer::Renderer(const std::shared_ptr<ResourceManager>& r)
|
||||
: resourceManager(r)
|
||||
{
|
||||
Renderer::Renderer(const std::shared_ptr<ResourceManager> &r,
|
||||
const std::shared_ptr<GLWindow> &w)
|
||||
: resourceManager(r), glWindow(w) {
|
||||
initFrameBuffers();
|
||||
initUniformBuffers();
|
||||
screenQuad = std::make_unique<ScreenQuad>();
|
||||
postProcessor = std::make_unique<Postprocessor>(r);
|
||||
}
|
||||
|
||||
void Renderer::hookEventManager(std::weak_ptr<EventManager> eventManager)
|
||||
{
|
||||
void Renderer::hookEventManager(std::weak_ptr<EventManager> eventManager) {
|
||||
if (auto e = eventManager.lock()) {
|
||||
e->subscribe<ScreenShakeEvent>([this](const ScreenShakeEvent &event) {
|
||||
postProcessor->ApplyEffect(Postprocessor::SHAKE,
|
||||
event.intensity,
|
||||
event.duration
|
||||
);
|
||||
postProcessor->ApplyEffect(Postprocessor::SHAKE, event.intensity,
|
||||
event.duration);
|
||||
});
|
||||
e->subscribe<ScreenBlurEvent>([this](const ScreenBlurEvent &event) {
|
||||
postProcessor->ApplyEffect(Postprocessor::BLUR,
|
||||
event.intensity,
|
||||
event.duration
|
||||
);
|
||||
postProcessor->ApplyEffect(Postprocessor::BLUR, event.intensity,
|
||||
event.duration);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the framebuffers used by the renderer to allow for post-processing effects
|
||||
void Renderer::initFrameBuffers()
|
||||
{
|
||||
// Initialize the framebuffers used by the renderer to allow for post-processing
|
||||
// effects
|
||||
void Renderer::initFrameBuffers() {
|
||||
glGenFramebuffers(1, &worldBuffer.frame);
|
||||
glGenFramebuffers(1, &hudBuffer.frame);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, worldBuffer.frame);
|
||||
|
|
@ -46,17 +41,21 @@ void Renderer::initFrameBuffers()
|
|||
// World buffer creation
|
||||
glGenTextures(1, &worldBuffer.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, worldBuffer.texture);
|
||||
// !!! NEED TO CREATE STATIC WINDOW SIZING !!!
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glWindow->Width(), glWindow->Height(),
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
// Attaching empty texture as color buffer for framebuffer
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, worldBuffer.texture, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
worldBuffer.texture, 0);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LOG(ERROR, "Failed to complete world framebuffer: {}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
LOG(ERROR, "Failed to complete world framebuffer: {}",
|
||||
glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
assert(1 == 0); // force crash
|
||||
}
|
||||
|
||||
|
|
@ -68,15 +67,18 @@ void Renderer::initFrameBuffers()
|
|||
|
||||
glGenTextures(1, &hudBuffer.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, hudBuffer.texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glWindow->Width(), glWindow->Height(),
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hudBuffer.texture, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
hudBuffer.texture, 0);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
LOG(ERROR, "Failed to complete hud framebuffer: {}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
LOG(ERROR, "Failed to complete hud framebuffer: {}",
|
||||
glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
assert(1 == 0); // force crash
|
||||
}
|
||||
|
||||
|
|
@ -86,8 +88,7 @@ void Renderer::initFrameBuffers()
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void Renderer::initUniformBuffers()
|
||||
{
|
||||
void Renderer::initUniformBuffers() {
|
||||
glGenBuffers(1, &uboMatrices);
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
|
||||
|
|
@ -95,39 +96,38 @@ void Renderer::initUniformBuffers()
|
|||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboMatrices);
|
||||
//glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));
|
||||
// glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 *
|
||||
// sizeof(glm::mat4));
|
||||
}
|
||||
|
||||
void Renderer::setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view)
|
||||
{
|
||||
void Renderer::setProjAndViewMatrix(const glm::mat4 &proj,
|
||||
const glm::mat4 &view) {
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(proj));
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4),
|
||||
glm::value_ptr(proj));
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4),
|
||||
glm::value_ptr(view));
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
}
|
||||
|
||||
void Renderer::addDrawable(RenderLayer renderLayer, Drawable *drawable)
|
||||
{
|
||||
void Renderer::addDrawable(RenderLayer renderLayer, Drawable *drawable) {
|
||||
if (renderLayer == RenderLayer::HUD || renderLayer == RenderLayer::Menu)
|
||||
HUDLayerPool[renderLayer].push_back(drawable);
|
||||
else
|
||||
worldLayerPool[renderLayer].push_back(drawable);
|
||||
}
|
||||
|
||||
void Renderer::removeDrawable(RenderLayer renderLayer, Drawable *drawable)
|
||||
{
|
||||
void Renderer::removeDrawable(RenderLayer renderLayer, Drawable *drawable) {
|
||||
auto erase = [&](auto &pool) {
|
||||
pool.erase(std::remove(pool.begin(), pool.end(), drawable), pool.end());
|
||||
};
|
||||
if (renderLayer == RenderLayer::HUD || renderLayer == RenderLayer::Menu) {
|
||||
erase(HUDLayerPool[renderLayer]);
|
||||
}
|
||||
else
|
||||
} else
|
||||
erase(worldLayerPool[renderLayer]);
|
||||
}
|
||||
|
||||
void Renderer::render()
|
||||
{
|
||||
void Renderer::render() {
|
||||
// Bind the world frame buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, worldBuffer.frame);
|
||||
// clear color and depth buffer
|
||||
|
|
@ -147,12 +147,11 @@ void Renderer::render()
|
|||
screenQuad->draw();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, hudBuffer.texture);
|
||||
postProcessor->applyPostProcess(1);
|
||||
// postProcessor->applyPostProcess(1);
|
||||
screenQuad->draw();
|
||||
}
|
||||
|
||||
void Renderer::renderPool(auto& layerPool)
|
||||
{
|
||||
void Renderer::renderPool(auto &layerPool) {
|
||||
sortLayerPool(layerPool);
|
||||
Shader *curShader = nullptr;
|
||||
for (const auto &layer : renderingOrder) {
|
||||
|
|
@ -175,43 +174,40 @@ void Renderer::renderPool(auto& layerPool)
|
|||
}
|
||||
}
|
||||
|
||||
void Renderer::clear()
|
||||
{
|
||||
void Renderer::clear() {
|
||||
worldLayerPool.clear();
|
||||
HUDLayerPool.clear();
|
||||
}
|
||||
|
||||
void Renderer::uploadUniforms(const unsigned shaderID, const std::vector<Uniform>& uniforms)
|
||||
{
|
||||
void Renderer::uploadUniforms(const unsigned shaderID,
|
||||
const std::vector<Uniform> &uniforms) {
|
||||
Shader *shader = resourceManager->getShaderByID(shaderID);
|
||||
if (shader == nullptr) {
|
||||
LOG(ERROR, "No shader found with id {} !", shaderID);
|
||||
return;
|
||||
}
|
||||
for (const auto &uniform : uniforms) {
|
||||
std::visit([&](auto&& arg) {
|
||||
std::visit(
|
||||
[&](auto &&arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
shader->setBool(uniform.name, arg);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, int>) {
|
||||
} else if constexpr (std::is_same_v<T, int>) {
|
||||
shader->setInt(uniform.name, arg);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, float>) {
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
shader->setFloat(uniform.name, arg);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, glm::vec2>) {
|
||||
} else if constexpr (std::is_same_v<T, glm::vec2>) {
|
||||
shader->setVec2(uniform.name, glm::value_ptr(arg));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, glm::mat4>) {
|
||||
} else if constexpr (std::is_same_v<T, glm::mat4>) {
|
||||
shader->setMatrix4f(uniform.name, glm::value_ptr(arg));
|
||||
}
|
||||
}, uniform.value);
|
||||
},
|
||||
uniform.value);
|
||||
}
|
||||
}
|
||||
void Renderer::sortLayerPool(auto& layerPool)
|
||||
{
|
||||
// Sort by shader id, this works to batch shaders together to avoid shader switching too much
|
||||
void Renderer::sortLayerPool(auto &layerPool) {
|
||||
// Sort by shader id, this works to batch shaders together to avoid shader
|
||||
// switching too much
|
||||
for (auto &[_, pool] : layerPool) {
|
||||
std::sort(pool.begin(), pool.end(),
|
||||
[](const Drawable *a, const Drawable *b) {
|
||||
|
|
|
|||
|
|
@ -1,28 +1,22 @@
|
|||
#undef GLM_FORCE_FAST_MATH
|
||||
#define GLM_FORCE_PURE
|
||||
#define GLM_FORCE_CTOR_INIT
|
||||
#define GLM_FORCE_COLUMN_MAJOR
|
||||
#include <SDL.h>
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_image.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// TODO: Fix circular dependency issues, mostly with input.h needing gameactor.h and command.h
|
||||
#include "gameplay/game.h"
|
||||
|
||||
const float vertices[] = {
|
||||
0.0f, 0.5f, 0.0f,
|
||||
-0.5f, -0.5f, 0.0f,
|
||||
0.5f, -0.5f, 0.0f
|
||||
};
|
||||
#include "utility/logger.h"
|
||||
|
||||
int main(int argc, char* args[])
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
LOG(ERROR, "Failed to initialize SDL!", NULL);
|
||||
return -1;
|
||||
if (IMG_Init(IMG_INIT_PNG) < 0)
|
||||
}
|
||||
if (IMG_Init(IMG_INIT_PNG) < 0) {
|
||||
LOG(ERROR, "Could not initialize png library", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
|
|
@ -31,13 +25,13 @@ int main(int argc, char* args[])
|
|||
Game* game = new Game();
|
||||
if (!game->init())
|
||||
{
|
||||
std::cout << "Failed to init game!" << std::endl;
|
||||
LOG(ERROR, "Failed to init game!", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!game->loadDebugScene())
|
||||
{
|
||||
std::cout << "Failed to load debug scene!" << std::endl;
|
||||
LOG(ERROR, "Failed to load debug scene!", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue