Added framebuffers for world and hud for postprocessing. Also fixed a nagging NDC issue
This commit is contained in:
parent
f7f68e500b
commit
5501a13488
29 changed files with 388 additions and 135 deletions
13
.vscode/settings.json
vendored
13
.vscode/settings.json
vendored
|
|
@ -1,5 +1,16 @@
|
||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"memory": "cpp"
|
"memory": "cpp",
|
||||||
|
"execution": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"charconv": "cpp",
|
||||||
|
"format": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"xhash": "cpp",
|
||||||
|
"xlocnum": "cpp",
|
||||||
|
"xmemory": "cpp",
|
||||||
|
"cassert": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,8 +32,8 @@
|
||||||
"scale": 0.75,
|
"scale": 0.75,
|
||||||
"selectedLayer": 2,
|
"selectedLayer": 2,
|
||||||
"viewCenter": {
|
"viewCenter": {
|
||||||
"x": 989.3333333333334,
|
"x": 1440,
|
||||||
"y": 665.3333333333334
|
"y": 872
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"newmap.tmx": {
|
"newmap.tmx": {
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
"selectedLayer": 1,
|
"selectedLayer": 1,
|
||||||
"viewCenter": {
|
"viewCenter": {
|
||||||
"x": 930,
|
"x": 930,
|
||||||
"y": 621
|
"y": 620
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shooterWorldOneAtlas.tsx": {
|
"shooterWorldOneAtlas.tsx": {
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@ uniform sampler2D sprite;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
FragColor = texture(sprite, texCoord) * vec4(1.0, 0.8, 1.0, 1.0);
|
FragColor = texture(sprite, texCoord);
|
||||||
}
|
}
|
||||||
16
Resources/shaders/GL_pp_hud.frag
Normal file
16
Resources/shaders/GL_pp_hud.frag
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
uniform sampler2D screenTexture;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
//FragColor = texture(screenTexture, texCoord);
|
||||||
|
vec4 color = texture(screenTexture, texCoord);
|
||||||
|
if (color.rgb == vec3(0.0, 0.0, 0.0))
|
||||||
|
FragColor = vec4(0.0, 0.0, 1.0, 1.0);
|
||||||
|
else
|
||||||
|
FragColor = color;
|
||||||
|
}
|
||||||
11
Resources/shaders/GL_pp_hud.vert
Normal file
11
Resources/shaders/GL_pp_hud.vert
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec2 aTexCoord;
|
||||||
|
|
||||||
|
out vec2 texCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
texCoord = aTexCoord;
|
||||||
|
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
|
||||||
|
}
|
||||||
12
Resources/shaders/GL_pp_world.frag
Normal file
12
Resources/shaders/GL_pp_world.frag
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in vec2 texCoord;
|
||||||
|
|
||||||
|
uniform sampler2D world_color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
//FragColor = vec4(0.0, 1.0, 1.0, 1.0);
|
||||||
|
FragColor = mix(texture(world_color, texCoord), vec4(0.4, 0.2, 0.2, 1.0), 0.2);
|
||||||
|
}
|
||||||
11
Resources/shaders/GL_pp_world.vert
Normal file
11
Resources/shaders/GL_pp_world.vert
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec2 aTexCoord;
|
||||||
|
|
||||||
|
out vec2 texCoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
texCoord = aTexCoord;
|
||||||
|
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
@ -58,6 +58,7 @@ add_executable (YuppleMayham
|
||||||
"include/gameplay/scene.h"
|
"include/gameplay/scene.h"
|
||||||
|
|
||||||
"include/graphics/texture.h"
|
"include/graphics/texture.h"
|
||||||
|
"src/graphics/quad.cpp"
|
||||||
|
|
||||||
"include/utility/resourcemanager.h"
|
"include/utility/resourcemanager.h"
|
||||||
"include/utility/xmlloader.h"
|
"include/utility/xmlloader.h"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ class Camera
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Camera(float viewPortW, float viewPortH) :
|
Camera(float viewPortW, float viewPortH) :
|
||||||
position(glm::vec3(0.0f, 0.0f, 1.0f)),
|
position(glm::vec3(0.0f, 0.0f, 0.0f)),
|
||||||
front(glm::vec3(0.0f, 0.0f, -1.0f)),
|
front(glm::vec3(0.0f, 0.0f, -1.0f)),
|
||||||
up(glm::vec3(0.0f, 1.0f, 0.0f)),
|
up(glm::vec3(0.0f, 1.0f, 0.0f)),
|
||||||
viewPortW(viewPortW),
|
viewPortW(viewPortW),
|
||||||
|
|
@ -22,9 +22,9 @@ public:
|
||||||
void unsetTarget() { target = nullptr; }
|
void unsetTarget() { target = nullptr; }
|
||||||
bool isTargeting() { return (target != nullptr); }
|
bool isTargeting() { return (target != nullptr); }
|
||||||
|
|
||||||
void update(float deltaTime);
|
void update(double deltaTime);
|
||||||
|
|
||||||
const glm::vec3 worldToLocal(const glm::vec3& worldCoordinates) const;
|
const glm::vec3 worldToLocal(const glm::vec3& worldCoordinates);
|
||||||
|
|
||||||
glm::mat4 getViewMatrix();
|
glm::mat4 getViewMatrix();
|
||||||
glm::mat4 getProjectionMatrix();
|
glm::mat4 getProjectionMatrix();
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ public:
|
||||||
const float getRotation() const { return this->rotation; }
|
const float getRotation() const { return this->rotation; }
|
||||||
const bool isFlipped() const { return flipped; }
|
const bool isFlipped() const { return flipped; }
|
||||||
const glm::vec2 getFacingDir() const { return glm::vec2(cos(glm::radians(rotation)), sin(glm::radians(rotation))); }
|
const glm::vec2 getFacingDir() const { return glm::vec2(cos(glm::radians(rotation)), sin(glm::radians(rotation))); }
|
||||||
const glm::vec3 getCenter() const { return glm::vec3(position.x + (0.5f * scale.x), position.y + (0.5f * scale.y), 0.0f); }
|
const glm::vec3 getCenter() const { return glm::vec3(position.x, position.y, 0.0f); }
|
||||||
|
//const glm::vec3 getCenter() const { return glm::vec3(position.x + (0.5f * scale.x), position.y + (0.5f * scale.y), 0.0f); }
|
||||||
const bool getIsMoving() const { return isMoving; }
|
const bool getIsMoving() const { return isMoving; }
|
||||||
const int getEntityID() const { return entityid; }
|
const int getEntityID() const { return entityid; }
|
||||||
const std::shared_ptr<PhysicsComponent> getPhysicsComponent() const { return physics; }
|
const std::shared_ptr<PhysicsComponent> getPhysicsComponent() const { return physics; }
|
||||||
|
|
@ -59,6 +60,7 @@ protected:
|
||||||
|
|
||||||
int entityid;
|
int entityid;
|
||||||
|
|
||||||
|
// Should consider move to using unique pointers for this.
|
||||||
std::shared_ptr<PhysicsComponent> physics;
|
std::shared_ptr<PhysicsComponent> physics;
|
||||||
|
|
||||||
bool isMoving = false;
|
bool isMoving = false;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ public:
|
||||||
void loadCollisionMap(const std::vector<std::vector<int>>&, float tileSize);
|
void loadCollisionMap(const std::vector<std::vector<int>>&, float tileSize);
|
||||||
void addObject(const std::shared_ptr<PhysicsComponent>&);
|
void addObject(const std::shared_ptr<PhysicsComponent>&);
|
||||||
void removeObject(const std::shared_ptr<PhysicsComponent>&);
|
void removeObject(const std::shared_ptr<PhysicsComponent>&);
|
||||||
void update(float deltaTime);
|
void update(double deltaTime);
|
||||||
private:
|
private:
|
||||||
void resolveWorldCollision(const std::shared_ptr<PhysicsComponent>&);
|
void resolveWorldCollision(const std::shared_ptr<PhysicsComponent>&);
|
||||||
void resolvePossibleCollisions();
|
void resolvePossibleCollisions();
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ private:
|
||||||
std::string animName;
|
std::string animName;
|
||||||
std::string animType;
|
std::string animType;
|
||||||
|
|
||||||
std::shared_ptr<SpriteAtlas> spriteAtlas;
|
SpriteAtlas* spriteAtlas;
|
||||||
|
|
||||||
Uint32 elapsedTime = 0;
|
Uint32 elapsedTime = 0;
|
||||||
Uint32 lastFrameTick = 0;
|
Uint32 lastFrameTick = 0;
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,10 @@ private:
|
||||||
TextureArray* textures = nullptr;
|
TextureArray* textures = nullptr;
|
||||||
float vertices[20] = {
|
float vertices[20] = {
|
||||||
// vertex
|
// vertex
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
|
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
|
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
|
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
|
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
55
YuppleMayham/include/graphics/quad.h
Normal file
55
YuppleMayham/include/graphics/quad.h
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef _H_QUAD_H
|
||||||
|
#define _H_QUAD_H
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
class Quad
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void draw();
|
||||||
|
~Quad();
|
||||||
|
protected:
|
||||||
|
Quad(const float* vertexData);
|
||||||
|
private:
|
||||||
|
unsigned indices[6] = {
|
||||||
|
0, 1, 2,
|
||||||
|
3, 2, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vertex Array, Vertex Buffer, Element Buffer
|
||||||
|
unsigned VAO, VBO, EBO;
|
||||||
|
|
||||||
|
float vertices[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
class UnitQuad : public Quad
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnitQuad() : Quad(vertices) {}
|
||||||
|
private:
|
||||||
|
// simple rectangle. Most scales will be done based on this generic vertex data.
|
||||||
|
static constexpr float vertices[20] = {
|
||||||
|
// vertex texturecoords
|
||||||
|
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||||
|
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||||
|
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
|
||||||
|
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // top left
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScreenQuad : public Quad
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScreenQuad() : Quad(vertices) {}
|
||||||
|
private:
|
||||||
|
// simple rectangle. Most scales will be done based on this generic vertex data.
|
||||||
|
static constexpr float vertices[20] = {
|
||||||
|
// vertex texturecoords
|
||||||
|
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left
|
||||||
|
1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right
|
||||||
|
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
|
||||||
|
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _H_QUAD_H
|
||||||
|
|
@ -8,7 +8,10 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "graphics/quad.h"
|
||||||
|
|
||||||
class ResourceManager;
|
class ResourceManager;
|
||||||
|
class Shader;
|
||||||
|
|
||||||
enum class RenderLayer {
|
enum class RenderLayer {
|
||||||
Background,
|
Background,
|
||||||
|
|
@ -64,6 +67,7 @@ class Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Renderer(const std::shared_ptr<ResourceManager>&);
|
Renderer(const std::shared_ptr<ResourceManager>&);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view);
|
void setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view);
|
||||||
|
|
@ -73,7 +77,8 @@ public:
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<RenderLayer, std::vector<std::shared_ptr<Drawable>>> layerPool;
|
std::unordered_map<RenderLayer, std::vector<std::shared_ptr<Drawable>>> worldLayerPool;
|
||||||
|
std::unordered_map<RenderLayer, std::vector<std::shared_ptr<Drawable>>> HUDLayerPool;
|
||||||
std::vector<RenderLayer> renderingOrder = {
|
std::vector<RenderLayer> renderingOrder = {
|
||||||
RenderLayer::Background,
|
RenderLayer::Background,
|
||||||
RenderLayer::Map,
|
RenderLayer::Map,
|
||||||
|
|
@ -88,7 +93,23 @@ private:
|
||||||
glm::mat4 projMat;
|
glm::mat4 projMat;
|
||||||
glm::mat4 viewMat;
|
glm::mat4 viewMat;
|
||||||
|
|
||||||
|
union FrameBuffer {
|
||||||
|
unsigned int frame;
|
||||||
|
unsigned int texture;
|
||||||
|
}worldBuffer, hudBuffer;
|
||||||
|
|
||||||
|
std::unique_ptr<ScreenQuad> screenQuad;
|
||||||
|
|
||||||
std::shared_ptr<ResourceManager> resourceManager;
|
std::shared_ptr<ResourceManager> resourceManager;
|
||||||
|
|
||||||
|
void initFrameBuffers();
|
||||||
|
void loadPostProcessShaders();
|
||||||
|
|
||||||
|
Shader* postProcess_World;
|
||||||
|
Shader* postProcess_HUD;
|
||||||
|
|
||||||
|
void sortLayerPool(auto& layerPool);
|
||||||
|
void renderPool(auto& layerPool);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
enum class TileType;
|
enum class TileType;
|
||||||
class Texture;
|
class Texture;
|
||||||
class EventManager;
|
class EventManager;
|
||||||
|
class UnitQuad;
|
||||||
|
|
||||||
class Sprite
|
class Sprite
|
||||||
{
|
{
|
||||||
|
|
@ -49,19 +50,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupSprite();
|
void setupSprite();
|
||||||
|
UnitQuad* quad;
|
||||||
// Vertex Array, Vertex Buffer, Element Buffer
|
|
||||||
unsigned VAO, VBO, EBO;
|
|
||||||
|
|
||||||
// simple rectangle. Most scales will be done based on this generic vertex data.
|
|
||||||
float vertices[20] = {
|
|
||||||
// vertex texturecoords
|
|
||||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
|
|
||||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
|
|
||||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
|
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpriteAtlas : public Sprite
|
class SpriteAtlas : public Sprite
|
||||||
|
|
@ -74,6 +63,7 @@ public:
|
||||||
SpriteAtlas(const char* textureAtlasPath, float frameSize, bool isDirectional = false);
|
SpriteAtlas(const char* textureAtlasPath, float frameSize, bool isDirectional = false);
|
||||||
~SpriteAtlas();
|
~SpriteAtlas();
|
||||||
|
|
||||||
|
// bind the frame VAO before drawing
|
||||||
void bindFrame(VertexIDs* f);
|
void bindFrame(VertexIDs* f);
|
||||||
// draw current frame
|
// draw current frame
|
||||||
void draw() override;
|
void draw() override;
|
||||||
|
|
@ -96,8 +86,6 @@ private:
|
||||||
unsigned EBO;
|
unsigned EBO;
|
||||||
bool isDirectional;
|
bool isDirectional;
|
||||||
|
|
||||||
VertexIDs* curFrame;
|
|
||||||
|
|
||||||
VertexIDs singleFrame(int index) const {
|
VertexIDs singleFrame(int index) const {
|
||||||
return (index < 0 || index >= singleIDs.size()) ? singleIDs[0] : singleIDs[index];
|
return (index < 0 || index >= singleIDs.size()) ? singleIDs[0] : singleIDs[index];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ private:
|
||||||
class SpriteComponent : public Component
|
class SpriteComponent : public Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpriteComponent(std::shared_ptr<Sprite> sprite) : sprite(sprite), Component(nullptr) {}
|
SpriteComponent(Sprite* sprite) : sprite(sprite), Component(nullptr) {}
|
||||||
|
|
||||||
void bind() override {
|
void bind() override {
|
||||||
if (sprite) sprite->bind();
|
if (sprite) sprite->bind();
|
||||||
|
|
@ -62,12 +62,12 @@ public:
|
||||||
void play() override { /*unused*/ }
|
void play() override { /*unused*/ }
|
||||||
void idle() override { /*unused*/ }
|
void idle() override { /*unused*/ }
|
||||||
|
|
||||||
std::shared_ptr<Sprite>& getSprite() { return sprite; }
|
Sprite* getSprite() { return sprite; }
|
||||||
|
|
||||||
~SpriteComponent() { /*sprite->~Sprite();*/ }
|
~SpriteComponent() { /*sprite->~Sprite();*/ }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Sprite> sprite;
|
Sprite* sprite;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnimationComponent : public Component
|
class AnimationComponent : public Component
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,9 @@
|
||||||
|
|
||||||
#include "utility/xmlloader.h"
|
#include "utility/xmlloader.h"
|
||||||
#include "graphics/shader.h"
|
#include "graphics/shader.h"
|
||||||
|
#include "graphics/sprite.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
class Sprite;
|
|
||||||
class SpriteAtlas;
|
|
||||||
class Weapon;
|
class Weapon;
|
||||||
class Script;
|
class Script;
|
||||||
class AnimationSet;
|
class AnimationSet;
|
||||||
|
|
@ -32,8 +31,8 @@ public:
|
||||||
xmlLoader->loadScenes("scenes");
|
xmlLoader->loadScenes("scenes");
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<SpriteAtlas> loadSpriteAtlas (const std::string& path, float frameSize, bool isDirectional = false);
|
SpriteAtlas* loadSpriteAtlas (const std::string& path, float frameSize, bool isDirectional = false);
|
||||||
std::shared_ptr<Sprite> loadSpriteStatic (const std::string& path);
|
Sprite* loadSpriteStatic (const std::string& path);
|
||||||
std::shared_ptr<AIScript> loadAIScript (const std::string& path);
|
std::shared_ptr<AIScript> loadAIScript (const std::string& path);
|
||||||
std::shared_ptr<WeaponScript> loadWeaponScript (const std::string& path);
|
std::shared_ptr<WeaponScript> loadWeaponScript (const std::string& path);
|
||||||
|
|
||||||
|
|
@ -52,7 +51,7 @@ public:
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, std::unique_ptr<Shader>> shaders;
|
std::unordered_map<std::string, std::unique_ptr<Shader>> shaders;
|
||||||
std::unordered_map<unsigned, Shader*> shaderIDs;
|
std::unordered_map<unsigned, Shader*> shaderIDs;
|
||||||
std::unordered_map<std::string, std::shared_ptr<Sprite>> sprites;
|
std::unordered_map<std::string, std::unique_ptr<Sprite>> sprites;
|
||||||
std::unordered_map<std::string, std::shared_ptr<Weapon>> weapons;
|
std::unordered_map<std::string, std::shared_ptr<Weapon>> weapons;
|
||||||
std::unordered_map<std::string, std::shared_ptr<Script>> scripts;
|
std::unordered_map<std::string, std::shared_ptr<Script>> scripts;
|
||||||
std::unordered_map<std::string, std::shared_ptr<TileSetData>>tileSets;
|
std::unordered_map<std::string, std::shared_ptr<TileSetData>>tileSets;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
#include "gameplay/camera.h"
|
#include "gameplay/camera.h"
|
||||||
|
|
||||||
void Camera::update(float deltaTime)
|
void Camera::update(double deltaTime)
|
||||||
{
|
{
|
||||||
if (target == nullptr)
|
if (target == nullptr)
|
||||||
return;
|
return;
|
||||||
float smoothingFactor = 5.0f;
|
float smoothingFactor = 5.0f;
|
||||||
//if (glm::distance(target->getCenter(), getCenterPos()) > 20.f)
|
//if (glm::distance(target->getCenter(), getCenterPos()) > 20.f)
|
||||||
position += (target->getCenter() - getCenterPos()) * smoothingFactor * deltaTime;
|
position += (target->getCenter() - getCenterPos()) * smoothingFactor * static_cast<float>(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Camera::getViewMatrix()
|
glm::mat4 Camera::getViewMatrix()
|
||||||
|
|
@ -19,7 +19,8 @@ glm::mat4 Camera::getProjectionMatrix()
|
||||||
return glm::ortho(0.f, viewPortW, viewPortH, 0.f);
|
return glm::ortho(0.f, viewPortW, viewPortH, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
const glm::vec3 Camera::worldToLocal(const glm::vec3& worldCoordinates) const
|
const glm::vec3 Camera::worldToLocal(const glm::vec3& worldCoordinates)
|
||||||
{
|
{
|
||||||
return worldCoordinates - position;
|
//return worldCoordinates - position;
|
||||||
|
return glm::vec3(getViewMatrix() * glm::vec4(worldCoordinates, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,12 +63,10 @@ void Entity::draw()
|
||||||
|
|
||||||
void Entity::updateModelMatrix()
|
void Entity::updateModelMatrix()
|
||||||
{
|
{
|
||||||
glm::mat4 origin = glm::translate(glm::mat4(1.f), -0.5f * scale);
|
|
||||||
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 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 + 0.5f * scale);
|
glm::mat4 translation = glm::translate(glm::mat4(1.f), position);
|
||||||
modelMatrix =
|
modelMatrix =
|
||||||
translation *
|
translation *
|
||||||
rotationMat *
|
rotationMat *
|
||||||
origin *
|
|
||||||
glm::scale(glm::mat4(1.0f), scale);
|
glm::scale(glm::mat4(1.0f), scale);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "graphics/texture.h"
|
#include "graphics/texture.h"
|
||||||
#include "utility/xmlloader.h"
|
#include "utility/xmlloader.h"
|
||||||
#include "utility/resourcemanager.h"
|
#include "utility/resourcemanager.h"
|
||||||
|
#include "utility/logger.h"
|
||||||
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
|
@ -33,7 +34,7 @@ Map::Map(std::shared_ptr<MapData> mapData, const unsigned shaderID, std::shared_
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#include <glm/ext.hpp>
|
||||||
void Map::loadMap()
|
void Map::loadMap()
|
||||||
{
|
{
|
||||||
tileData.resize(tileIds.size());
|
tileData.resize(tileIds.size());
|
||||||
|
|
@ -47,7 +48,6 @@ void Map::loadMap()
|
||||||
glm::translate(glm::mat4(1.f), glm::vec3(x * mapData->tileSize, y * mapData->tileSize, 0.0f)) *
|
glm::translate(glm::mat4(1.f), glm::vec3(x * mapData->tileSize, y * mapData->tileSize, 0.0f)) *
|
||||||
glm::scale(glm::mat4(1.f), glm::vec3(mapData->tileSize, mapData->tileSize, 1.0f));
|
glm::scale(glm::mat4(1.f), glm::vec3(mapData->tileSize, mapData->tileSize, 1.0f));
|
||||||
|
|
||||||
|
|
||||||
int textureIndex = getTileSetIndex(tileIds[layer][y][x]);
|
int textureIndex = getTileSetIndex(tileIds[layer][y][x]);
|
||||||
glm::vec2 originalSize = (textureIndex != -1) ?
|
glm::vec2 originalSize = (textureIndex != -1) ?
|
||||||
glm::vec2(tileSetData[textureIndex]->width, tileSetData[textureIndex]->height) :
|
glm::vec2(tileSetData[textureIndex]->width, tileSetData[textureIndex]->height) :
|
||||||
|
|
@ -115,7 +115,7 @@ int Map::getTileSetIndex(int id) const
|
||||||
{
|
{
|
||||||
// work from the bottom, break if ID > startID
|
// work from the bottom, break if ID > startID
|
||||||
// If we get a textureIndex of -1 then we are on an empty tile
|
// If we get a textureIndex of -1 then we are on an empty tile
|
||||||
int tileSetIndex = mapData->tileSets.size() - 1;
|
size_t tileSetIndex = mapData->tileSets.size() - 1;
|
||||||
for (; tileSetIndex != -1; --tileSetIndex)
|
for (; tileSetIndex != -1; --tileSetIndex)
|
||||||
{
|
{
|
||||||
if (id >= mapData->tileSets[tileSetIndex].startID)
|
if (id >= mapData->tileSets[tileSetIndex].startID)
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,8 @@ void PhysicsEngine::removeObject(const std::shared_ptr<PhysicsComponent>& compon
|
||||||
|
|
||||||
int PhysicsEngine::getTileCollider(const glm::vec3& position)
|
int PhysicsEngine::getTileCollider(const glm::vec3& position)
|
||||||
{
|
{
|
||||||
int x = static_cast<int>(position.x / tileSize);
|
int x = static_cast<int>((position.x + 0.5f * tileSize) / tileSize);
|
||||||
int y = static_cast<int>(position.y / tileSize);
|
int y = static_cast<int>((position.y + 0.5f * tileSize) / tileSize);
|
||||||
if (y >= 0 && y < collisionMap.size())
|
if (y >= 0 && y < collisionMap.size())
|
||||||
{
|
{
|
||||||
if (x >= 0 && x < collisionMap[y].size())
|
if (x >= 0 && x < collisionMap[y].size())
|
||||||
|
|
@ -150,34 +150,32 @@ void PhysicsEngine::resolveWorldCollision(const std::shared_ptr<PhysicsComponent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int tileY = static_cast<int>((position.y) / tileSize);
|
||||||
|
int tileX = static_cast<int>((position.x) / tileSize);
|
||||||
if (topTile)
|
if (topTile)
|
||||||
{
|
{
|
||||||
//obj->rigidBody.velocity.y = -obj->rigidBody.velocity.y;
|
//obj->rigidBody.velocity.y = -obj->rigidBody.velocity.y;
|
||||||
int tileY = static_cast<int>((position.y - radius) / tileSize);
|
obj->rigidBody.position.y = (tileY+1) * tileSize + obj->collider.offset.y;
|
||||||
obj->rigidBody.position.y = (tileY) * tileSize + radius + obj->collider.offset.y;
|
|
||||||
}
|
}
|
||||||
if (bottomTile)
|
if (bottomTile)
|
||||||
{
|
{
|
||||||
//obj->rigidBody.velocity.y = -obj->rigidBody.velocity.y;
|
//obj->rigidBody.velocity.y = -obj->rigidBody.velocity.y;
|
||||||
int tileY = static_cast<int>((position.y + radius) / tileSize);
|
obj->rigidBody.position.y = (tileY) * tileSize - obj->collider.offset.y;
|
||||||
obj->rigidBody.position.y = tileY * tileSize - radius - obj->collider.offset.y;
|
|
||||||
}
|
}
|
||||||
if (leftTile)
|
if (leftTile)
|
||||||
{
|
{
|
||||||
//obj->rigidBody.velocity.x = -obj->rigidBody.velocity.x;
|
//obj->rigidBody.velocity.x = -obj->rigidBody.velocity.x;
|
||||||
int tileX = static_cast<int>((position.x - radius) / tileSize);
|
obj->rigidBody.position.x = (tileX + 1) * tileSize + obj->collider.offset.x;
|
||||||
obj->rigidBody.position.x = (tileX) * tileSize + radius + obj->collider.offset.x;
|
|
||||||
}
|
}
|
||||||
if (rightTile)
|
if (rightTile)
|
||||||
{
|
{
|
||||||
//obj->rigidBody.velocity.x = -obj->rigidBody.velocity.x;
|
//obj->rigidBody.velocity.x = -obj->rigidBody.velocity.x;
|
||||||
int tileX = static_cast<int>((position.x + radius) / tileSize);
|
obj->rigidBody.position.x = (tileX) * tileSize - obj->collider.offset.x;
|
||||||
obj->rigidBody.position.x = tileX * tileSize - radius - obj->collider.offset.x;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsEngine::update(float deltaTime)
|
void PhysicsEngine::update(double deltaTime)
|
||||||
{
|
{
|
||||||
for (auto& obj : objects)
|
for (auto& obj : objects)
|
||||||
{
|
{
|
||||||
|
|
@ -205,7 +203,7 @@ void PhysicsEngine::update(float deltaTime)
|
||||||
// check map collisions
|
// check map collisions
|
||||||
resolveWorldCollision(obj);
|
resolveWorldCollision(obj);
|
||||||
}
|
}
|
||||||
obj->rigidBody.position += obj->rigidBody.velocity * deltaTime;
|
obj->rigidBody.position += obj->rigidBody.velocity * static_cast<float>(deltaTime);
|
||||||
}
|
}
|
||||||
getPossibleCollisions();
|
getPossibleCollisions();
|
||||||
if (!objCollisions.empty())
|
if (!objCollisions.empty())
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,7 @@ void Scene::loadDebugShooterScene()
|
||||||
entity->getPosition(),
|
entity->getPosition(),
|
||||||
49.0,
|
49.0,
|
||||||
PhysicsComponent::Collider::Shape::Circle,
|
PhysicsComponent::Collider::Shape::Circle,
|
||||||
glm::vec3(mapData->tileSize / 2),
|
glm::vec3(mapData->tileSize / 2))
|
||||||
glm::abs(entity->getCenter() - entity->getPosition()))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (entityData.isPlayer)
|
if (entityData.isPlayer)
|
||||||
|
|
@ -159,9 +158,8 @@ void Scene::render(std::shared_ptr<Renderer> renderer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugDrawer::getInstance().draw(camera->getProjectionMatrix() * camera->getViewMatrix());
|
|
||||||
|
|
||||||
renderer->render();
|
renderer->render();
|
||||||
|
DebugDrawer::getInstance().draw(camera->getProjectionMatrix() * camera->getViewMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::unloadScene()
|
void Scene::unloadScene()
|
||||||
|
|
|
||||||
|
|
@ -194,8 +194,8 @@ void Weapon::adjustWeapon()
|
||||||
0.0f
|
0.0f
|
||||||
);
|
);
|
||||||
glm::vec3 origin = wielder->getCenter() + offset;
|
glm::vec3 origin = wielder->getCenter() + offset;
|
||||||
origin.x -= (weaponSize.x) * 0.5f;
|
//origin.x += (weaponSize.x) * 0.25f;
|
||||||
origin.y -= (weaponSize.y) * 0.5f;
|
//origin.y += (weaponSize.y) * 0.25f;
|
||||||
|
|
||||||
// Flip the texture if the weapon is facing upwards or downwards
|
// Flip the texture if the weapon is facing upwards or downwards
|
||||||
Direction d = getDirectionFromRotation(glm::degrees(rotation));
|
Direction d = getDirectionFromRotation(glm::degrees(rotation));
|
||||||
|
|
|
||||||
46
YuppleMayham/src/graphics/quad.cpp
Normal file
46
YuppleMayham/src/graphics/quad.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "graphics/quad.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
Quad::Quad(const float* vertexData)
|
||||||
|
{
|
||||||
|
std::memcpy(vertices, vertexData, sizeof(vertices));
|
||||||
|
VAO = 0, VBO = 0, EBO = 0;
|
||||||
|
|
||||||
|
// Assigning vertex data
|
||||||
|
glGenVertexArrays(1, &VAO);
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
glGenBuffers(1, &EBO);
|
||||||
|
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||||
|
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Position
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||||
|
// Texture Coordinates
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quad::draw()
|
||||||
|
{
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Quad::~Quad()
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &VBO);
|
||||||
|
glDeleteBuffers(1, &EBO);
|
||||||
|
glDeleteVertexArrays(1, &VAO);
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,74 @@ Renderer::Renderer(const std::shared_ptr<ResourceManager>& r)
|
||||||
{
|
{
|
||||||
projMat = glm::mat4(0.f);
|
projMat = glm::mat4(0.f);
|
||||||
viewMat = glm::mat4(0.f);
|
viewMat = glm::mat4(0.f);
|
||||||
|
|
||||||
|
initFrameBuffers();
|
||||||
|
loadPostProcessShaders();
|
||||||
|
screenQuad = std::make_unique<ScreenQuad>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
LOG(ERROR, "Failed to complete world framebuffer: {}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||||
|
assert(1 == 0); // force crash
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
// same thing is done for the hud texture
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, hudBuffer.frame);
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
LOG(ERROR, "Failed to complete hud framebuffer: {}", glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||||
|
assert(1 == 0); // force crash
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::loadPostProcessShaders()
|
||||||
|
{
|
||||||
|
postProcess_World = resourceManager->getShaderByID(resourceManager->loadShader("GL_pp_world-DEFAULT", "shaders/GL_pp_world.vert", "shaders/GL_pp_world.frag"));
|
||||||
|
if (postProcess_World == nullptr) {
|
||||||
|
LOG(ERROR, "Failed to load world shader: GL_pp_world!");
|
||||||
|
assert(1 == 0); // force crash
|
||||||
|
}
|
||||||
|
postProcess_HUD = resourceManager->getShaderByID(resourceManager->loadShader("GL_pp_hud-DEFAULT", "shaders/GL_pp_hud.vert", "shaders/GL_pp_hud.frag"));
|
||||||
|
if (postProcess_HUD == nullptr) {
|
||||||
|
LOG(ERROR, "Failed to load hud shader: GL_pp_hud!");
|
||||||
|
assert(1 == 0); // force crash
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view)
|
void Renderer::setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view)
|
||||||
|
|
@ -20,24 +88,52 @@ void Renderer::setProjAndViewMatrix(const glm::mat4& proj, const glm::mat4& view
|
||||||
|
|
||||||
void Renderer::addDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable)
|
void Renderer::addDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable)
|
||||||
{
|
{
|
||||||
layerPool[renderLayer].push_back(drawable);
|
if (renderLayer == RenderLayer::HUD || renderLayer == RenderLayer::Menu)
|
||||||
|
HUDLayerPool[renderLayer].push_back(drawable);
|
||||||
|
else
|
||||||
|
worldLayerPool[renderLayer].push_back(drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::removeDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable)
|
void Renderer::removeDrawable(RenderLayer renderLayer, std::shared_ptr<Drawable> drawable)
|
||||||
{
|
{
|
||||||
auto& pool = layerPool[renderLayer];
|
auto erase = [&](auto& pool) {
|
||||||
pool.erase(std::remove(pool.begin(), pool.end(), drawable));
|
pool.erase(std::remove(pool.begin(), pool.end(), drawable), pool.end());
|
||||||
|
};
|
||||||
|
if (renderLayer == RenderLayer::HUD || renderLayer == RenderLayer::Menu) {
|
||||||
|
erase(HUDLayerPool[renderLayer]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
erase(worldLayerPool[renderLayer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::render()
|
void Renderer::render()
|
||||||
{
|
{
|
||||||
// Sort by shader id, this works to batch shaders together to avoid shader switching too much
|
// Bind the world frame buffer
|
||||||
for (auto& [_,pool] : layerPool) {
|
glBindFramebuffer(GL_FRAMEBUFFER, worldBuffer.frame);
|
||||||
std::sort(pool.begin(), pool.end(),
|
// clear color and depth buffer
|
||||||
[](const std::shared_ptr<Drawable>& a, const std::shared_ptr<Drawable>& b) {
|
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
return a->getShaderID() < b->getShaderID();
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
});
|
renderPool(worldLayerPool);
|
||||||
}
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, hudBuffer.frame);
|
||||||
|
glClearColor(0.0f, 1.0f, 0.0f, 0.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
renderPool(HUDLayerPool);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, worldBuffer.texture);
|
||||||
|
postProcess_World->use();
|
||||||
|
screenQuad->draw();
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, hudBuffer.texture);
|
||||||
|
postProcess_HUD->use();
|
||||||
|
screenQuad->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::renderPool(auto& layerPool)
|
||||||
|
{
|
||||||
|
sortLayerPool(layerPool);
|
||||||
Shader* curShader = nullptr;
|
Shader* curShader = nullptr;
|
||||||
for (const auto& layer : renderingOrder) {
|
for (const auto& layer : renderingOrder) {
|
||||||
unsigned curShaderID = static_cast<unsigned>(-1);
|
unsigned curShaderID = static_cast<unsigned>(-1);
|
||||||
|
|
@ -69,7 +165,8 @@ void Renderer::render()
|
||||||
|
|
||||||
void Renderer::clear()
|
void Renderer::clear()
|
||||||
{
|
{
|
||||||
layerPool.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)
|
||||||
|
|
@ -99,4 +196,14 @@ void Renderer::uploadUniforms(const unsigned shaderID, const std::vector<Uniform
|
||||||
}
|
}
|
||||||
}, 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
|
||||||
|
for (auto& [_,pool] : layerPool) {
|
||||||
|
std::sort(pool.begin(), pool.end(),
|
||||||
|
[](const std::shared_ptr<Drawable>& a, const std::shared_ptr<Drawable>& b) {
|
||||||
|
return a->getShaderID() < b->getShaderID();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
#include "graphics/shader.h"
|
#include "graphics/shader.h"
|
||||||
|
|
||||||
|
#include "utility/logger.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
||||||
{
|
{
|
||||||
std::string vertexSource;
|
std::string vertexSource;
|
||||||
|
|
@ -27,8 +30,8 @@ Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
||||||
}
|
}
|
||||||
catch(std::exception e)
|
catch(std::exception e)
|
||||||
{
|
{
|
||||||
std::cout << "failed to open shader files " << e.what() << std::endl;
|
LOG(ERROR, "failed to open shader files '{}', '{}' error: {}", vertexPath, fragmentPath, e.what());
|
||||||
return;
|
assert(1 == 0); // force crash
|
||||||
}
|
}
|
||||||
const char* vSource = vertexSource.c_str();
|
const char* vSource = vertexSource.c_str();
|
||||||
const char* fSource = fragmentSource.c_str();
|
const char* fSource = fragmentSource.c_str();
|
||||||
|
|
@ -46,7 +49,7 @@ Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
glGetShaderInfoLog(vertexid, 512, NULL, infoLog);
|
glGetShaderInfoLog(vertexid, 512, NULL, infoLog);
|
||||||
std::cout << "VERTEX SHADER COMPILE ERROR\n" << infoLog << std::endl;
|
LOG(ERROR, "VERTEX SHADER '{}' COMPILE ERROR\n{}", vertexPath, infoLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
//compile fragment shader
|
//compile fragment shader
|
||||||
|
|
@ -58,7 +61,7 @@ Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
glGetShaderInfoLog(fragmentid, 512, NULL, infoLog);
|
glGetShaderInfoLog(fragmentid, 512, NULL, infoLog);
|
||||||
std::cout << "FRAGMENT SHADER COMPILE ERROR\n" << infoLog << std::endl;
|
LOG(ERROR, "FRAGMENT SHADER '{}' COMPILE ERROR\n{}", fragmentPath, infoLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
//create and link program with compiled shaders
|
//create and link program with compiled shaders
|
||||||
|
|
@ -71,7 +74,7 @@ Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
glGetProgramInfoLog(ID, 512, NULL, infoLog);
|
glGetProgramInfoLog(ID, 512, NULL, infoLog);
|
||||||
std::cout << "PROGRAM LINKER ERROR\n" << infoLog << std::endl;
|
LOG(ERROR, "PROGRAM LINKER ERROR\n{}", infoLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDeleteShader(vertexid);
|
glDeleteShader(vertexid);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "graphics/sprite.h"
|
#include "graphics/sprite.h"
|
||||||
#include "graphics/texture.h"
|
#include "graphics/texture.h"
|
||||||
|
#include "graphics/quad.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utility/events.h"
|
#include "utility/events.h"
|
||||||
|
|
||||||
|
|
@ -7,7 +8,6 @@ bool Sprite::loaded() const { return (texture != nullptr); }
|
||||||
|
|
||||||
SpriteStatic::SpriteStatic(const char* texturePath)
|
SpriteStatic::SpriteStatic(const char* texturePath)
|
||||||
{
|
{
|
||||||
EBO = 0, VBO = 0, VAO = 0;
|
|
||||||
texture = new Texture();
|
texture = new Texture();
|
||||||
texture->loadTexture(texturePath);
|
texture->loadTexture(texturePath);
|
||||||
if (texture)
|
if (texture)
|
||||||
|
|
@ -18,28 +18,7 @@ SpriteStatic::SpriteStatic(const char* texturePath)
|
||||||
|
|
||||||
void SpriteStatic::setupSprite()
|
void SpriteStatic::setupSprite()
|
||||||
{
|
{
|
||||||
// Assigning vertex data
|
quad = new UnitQuad();
|
||||||
glGenVertexArrays(1, &VAO);
|
|
||||||
glGenBuffers(1, &VBO);
|
|
||||||
glGenBuffers(1, &EBO);
|
|
||||||
|
|
||||||
glBindVertexArray(VAO);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
|
||||||
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
// Position
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
|
||||||
// Texture Coordinates
|
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::bind()
|
void Sprite::bind()
|
||||||
|
|
@ -50,20 +29,16 @@ void Sprite::bind()
|
||||||
|
|
||||||
void SpriteStatic::draw()
|
void SpriteStatic::draw()
|
||||||
{
|
{
|
||||||
glBindVertexArray(VAO);
|
quad->draw();
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteStatic::~SpriteStatic()
|
SpriteStatic::~SpriteStatic()
|
||||||
{
|
{
|
||||||
delete texture;
|
delete texture;
|
||||||
glDeleteBuffers(1, &VBO);
|
delete quad;
|
||||||
glDeleteBuffers(1, &EBO);
|
|
||||||
glDeleteVertexArrays(1, &VAO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteAtlas::SpriteAtlas(const char* textureAtlasPath, float frameSize, bool isDirectional) : isDirectional(isDirectional), curFrame(nullptr)
|
SpriteAtlas::SpriteAtlas(const char* textureAtlasPath, float frameSize, bool isDirectional) : isDirectional(isDirectional)
|
||||||
{
|
{
|
||||||
EBO = 0;
|
EBO = 0;
|
||||||
texture = new Texture();
|
texture = new Texture();
|
||||||
|
|
@ -97,10 +72,10 @@ void SpriteAtlas::Setup(float frameSize)
|
||||||
float bottom = (row) * (frameSize / height);
|
float bottom = (row) * (frameSize / height);
|
||||||
float top = (row + 1) * (frameSize / height);
|
float top = (row + 1) * (frameSize / height);
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
0.0f, 0.0f, 0.0f, left, bottom, // bottom left
|
-0.5f, -0.5f, 0.0f, left, bottom, // bottom left
|
||||||
1.0f, 0.0f, 0.0f, right, bottom, // bottom right
|
0.5f, -0.5f, 0.0f, right, bottom, // bottom right
|
||||||
1.0f, 1.0f, 0.0f, right, top, // top right
|
0.5f, 0.5f, 0.0f, right, top, // top right
|
||||||
0.0f, 1.0f, 0.0f, left, top // top left
|
-0.5f, 0.5f, 0.0f, left, top // top left
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned VAO, VBO;
|
unsigned VAO, VBO;
|
||||||
|
|
@ -128,12 +103,11 @@ void SpriteAtlas::Setup(float frameSize)
|
||||||
|
|
||||||
void SpriteAtlas::bindFrame(VertexIDs* f)
|
void SpriteAtlas::bindFrame(VertexIDs* f)
|
||||||
{
|
{
|
||||||
curFrame = f;
|
glBindVertexArray(f->VAO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteAtlas::draw()
|
void SpriteAtlas::draw()
|
||||||
{
|
{
|
||||||
glBindVertexArray(curFrame->VAO);
|
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
@ -162,8 +136,8 @@ void SpriteAtlas::SetupDirectional(float frameSize)
|
||||||
{
|
{
|
||||||
int width = texture->getWidth();
|
int width = texture->getWidth();
|
||||||
int height = texture->getHeight();
|
int height = texture->getHeight();
|
||||||
int frameRows = height / frameSize;
|
int frameRows = static_cast<int>(height / frameSize);
|
||||||
int frameCols = width / frameSize;
|
int frameCols = static_cast<int>(width / frameSize);
|
||||||
|
|
||||||
glGenBuffers(1, &EBO);
|
glGenBuffers(1, &EBO);
|
||||||
|
|
||||||
|
|
@ -182,10 +156,10 @@ void SpriteAtlas::SetupDirectional(float frameSize)
|
||||||
float bottom = (row) * (frameSize / height);
|
float bottom = (row) * (frameSize / height);
|
||||||
float top = (row + 1) * (frameSize / height);
|
float top = (row + 1) * (frameSize / height);
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
0.0f, 0.0f, 0.0f, left, bottom, // bottom left
|
-0.5f, -0.5f, 0.0f, left, bottom, // bottom left
|
||||||
1.0f, 0.0f, 0.0f, right, bottom, // bottom right
|
0.5f, -0.5f, 0.0f, right, bottom, // bottom right
|
||||||
1.0f, 1.0f, 0.0f, right, top, // top right
|
0.5f, 0.5f, 0.0f, right, top, // top right
|
||||||
0.0f, 1.0f, 0.0f, left, top // top left
|
-0.5f, 0.5f, 0.0f, left, top // top left
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned VAO, VBO;
|
unsigned VAO, VBO;
|
||||||
|
|
|
||||||
|
|
@ -6,26 +6,27 @@
|
||||||
#include "graphics/animation.h"
|
#include "graphics/animation.h"
|
||||||
#include "gameplay/weapons/weapons.h"
|
#include "gameplay/weapons/weapons.h"
|
||||||
|
|
||||||
std::shared_ptr<SpriteAtlas> ResourceManager::loadSpriteAtlas(const std::string& path, float frameSize, bool isDirectional)
|
SpriteAtlas* ResourceManager::loadSpriteAtlas(const std::string& path, float frameSize, bool isDirectional)
|
||||||
{
|
{
|
||||||
auto iterator = sprites.find(path);
|
auto iterator = sprites.find(path);
|
||||||
if (iterator != sprites.end())
|
if (iterator != sprites.end())
|
||||||
return std::dynamic_pointer_cast<SpriteAtlas>(iterator->second);
|
return static_cast<SpriteAtlas*>(iterator->second.get());
|
||||||
auto sprite = std::make_shared<SpriteAtlas>(path.c_str(), frameSize, isDirectional);
|
auto sprite = std::make_unique<SpriteAtlas>(path.c_str(), frameSize, isDirectional);
|
||||||
sprites[path] = sprite;
|
sprites[path] = std::move(sprite);
|
||||||
return sprite;
|
SpriteAtlas& l = static_cast<SpriteAtlas&>(*sprites[path].get());
|
||||||
|
return static_cast<SpriteAtlas*>(sprites[path].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Sprite> ResourceManager::loadSpriteStatic(const std::string& path)
|
Sprite* ResourceManager::loadSpriteStatic(const std::string& path)
|
||||||
{
|
{
|
||||||
auto iterator = sprites.find(path);
|
auto iterator = sprites.find(path);
|
||||||
if (iterator != sprites.end())
|
if (iterator != sprites.end())
|
||||||
return iterator->second;
|
return iterator->second.get();
|
||||||
auto sprite = std::make_shared<SpriteStatic>(path.c_str());
|
auto sprite = std::make_unique<SpriteStatic>(path.c_str());
|
||||||
if (!sprite->loaded())
|
if (!sprite->loaded())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
sprites[path] = sprite;
|
sprites[path] = std::move(sprite);
|
||||||
return sprite;
|
return sprites[path].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AIScript> ResourceManager::loadAIScript(const std::string& path)
|
std::shared_ptr<AIScript> ResourceManager::loadAIScript(const std::string& path)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue