153 lines
5.8 KiB
C++
153 lines
5.8 KiB
C++
#ifndef RENDER_SYSTEM
|
|
#define RENDER_SYSTEM
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <glm/glm.hpp>
|
|
#include "Structures.h"
|
|
const float skyboxVertices[] = {
|
|
-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
|
|
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
|
|
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
|
|
-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
|
|
1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
|
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
|
|
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
|
1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
|
|
-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
|
|
1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,
|
|
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
|
|
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f
|
|
};
|
|
class Camera;
|
|
class Shader;
|
|
class FBO;
|
|
class VBO;
|
|
class VAO;
|
|
class Cubemap;
|
|
class Lighting;
|
|
class Renderable {
|
|
public:
|
|
enum ShaderType {
|
|
RigShader,
|
|
MeshShader,
|
|
ImageBoxShader,
|
|
BoxShader,
|
|
TextShader,
|
|
ParticleShader
|
|
};
|
|
ShaderType shadertype = ShaderType::MeshShader;
|
|
bool opaque = true;
|
|
bool castshadow = false;
|
|
Renderable();
|
|
~Renderable();
|
|
void BindToRenderSystem();
|
|
virtual void Render(Shader& ShaderProgram) {}
|
|
virtual glm::vec3 GetWorldPosition() const { return glm::vec3(0.0f); }
|
|
|
|
// A world space box around everything this draws. Without one it's never culled.
|
|
virtual bool GetWorldBounds(BoundingBox& bounds) const { return false; }
|
|
|
|
// Occlusion culling state, only the render system touches these
|
|
unsigned int occlusionQuery = 0;
|
|
bool occlusionPending = false; // a query was sent and hasn't been read back yet
|
|
bool occluded = false; // the last answered query saw none of it
|
|
};
|
|
struct GraphicsSettings {
|
|
bool bloom = true;
|
|
bool shadows = true; // the sun's shadow map
|
|
bool lightShadows = true; // spot and point light shadows
|
|
bool vsync = true;
|
|
bool culling = true; // frustum and occlusion culling for opaque meshes and characters
|
|
};
|
|
|
|
struct HitboxDebugLine {
|
|
glm::mat4 transform;
|
|
glm::vec3 color;
|
|
};
|
|
|
|
class RenderSystem {
|
|
public:
|
|
Lighting* lighting = nullptr;
|
|
GraphicsSettings graphics;
|
|
FBO* screenfbo = nullptr;
|
|
FBO* shadowdepthmapfbo = nullptr;
|
|
FBO* gBuffer = nullptr;
|
|
unsigned int gPosition = 0;
|
|
unsigned int gNormal = 0;
|
|
unsigned int gAlbedo = 0;
|
|
unsigned int gMaterial = 0;
|
|
unsigned int gDepth = 0;
|
|
unsigned int shadowDebugSampler = 0;
|
|
FBO* localShadowFBO = nullptr;
|
|
unsigned int localShadowAtlas = 0;
|
|
FBO* bloomFBO[2] = { nullptr, nullptr };
|
|
unsigned int bloomTextures[2] = { 0, 0 };
|
|
int bloomWidth = 0;
|
|
int bloomHeight = 0;
|
|
int debugView = 0; // 0 = final image, otherwise a debugMode in gbuffer_debug.frag
|
|
unsigned int depthMaptexture = 0;
|
|
unsigned int textureColorbuffer = 0;
|
|
unsigned int rbo = 0;
|
|
unsigned int SHADOW_RESOLUTION = 0;
|
|
VAO* quadVAO = nullptr; VBO* quadVBO = nullptr;
|
|
VAO* skyboxVAO = nullptr; VBO* skyboxVBO = nullptr;
|
|
Shader* MeshShadowShader = nullptr;
|
|
Shader* RigShadowShader = nullptr;
|
|
Shader* SkyboxShader = nullptr;
|
|
Shader* ScreenShader = nullptr;
|
|
Shader* RigShader = nullptr;
|
|
Shader* MeshShader = nullptr;
|
|
Shader* GeometryShader = nullptr;
|
|
Shader* GeometryRigShader = nullptr;
|
|
Shader* DeferredLightingShader = nullptr;
|
|
Shader* GBufferDebugShader = nullptr;
|
|
Shader* BloomExtractShader = nullptr;
|
|
Shader* BloomBlurShader = nullptr;
|
|
Shader* ImageBoxShader = nullptr;
|
|
Shader* BoxShader = nullptr;
|
|
Shader* Text2DShader = nullptr;
|
|
Shader* ParticleShader = nullptr;
|
|
Shader* HitboxShader = nullptr;
|
|
Cubemap* skybox = nullptr;
|
|
unsigned int hitboxVAO = 0;
|
|
unsigned int hitboxVBO = 0;
|
|
std::vector<HitboxDebugLine> hitboxDebugLines;
|
|
RenderSystem() {}
|
|
void Initialize();
|
|
void Resize(int width, int height);
|
|
void Render(Camera& camera);
|
|
void CycleDebugView();
|
|
void SetHitboxDebugLines(const std::vector<HitboxDebugLine>& lines) { hitboxDebugLines = lines; }
|
|
void AddRenderable(Renderable* r) { renderables.push_back(r); }
|
|
void RemoveRenderable(Renderable* r) {
|
|
for (int i = 0; i < (int)renderables.size(); i++) {
|
|
if (renderables[i] == r) { renderables.erase(renderables.begin() + i); return; }
|
|
}
|
|
std::cout << "didn't find renderable to remove\n";
|
|
}
|
|
void RenderRenderable(Renderable* renderable, Camera& camera);
|
|
std::vector<Renderable*> renderables;
|
|
private:
|
|
void PrepareRigShader(Camera& camera);
|
|
void PrepareMeshShader(Camera& camera);
|
|
void PrepareParticleShader(Camera& camera);
|
|
void PrepareBoxShader(Camera& camera);
|
|
void PrepareImageBoxShader(Camera& camera);
|
|
void PrepareTextShader(Camera& camera);
|
|
void RenderTranslucent(Camera& camera, const glm::mat4& lightSpaceMatrix, const glm::vec3& camPos);
|
|
void RenderHitboxDebug(Camera& camera);
|
|
void AllocateGBuffer(int width, int height);
|
|
void AllocateBloom(int width, int height);
|
|
void RenderBloom();
|
|
void RenderShadowCasters(const glm::mat4& lightSpaceMatrix);
|
|
void RenderLocalShadows();
|
|
void BindGBufferTextures(Shader* shader);
|
|
void RenderGeometryPass(const glm::mat4& proj, const glm::mat4& view, const glm::vec3& camPos);
|
|
bool IsVisible(Renderable* r, const glm::vec4 (&frustum)[6], const glm::vec3& camPos);
|
|
void IssueOcclusionQueries(const glm::mat4& proj, const glm::mat4& view);
|
|
std::vector<Renderable*> occlusionCandidates; // drawn into the queries after the geometry pass
|
|
void RenderLightingPass(const glm::vec3& camPos, const glm::mat4& lightSpaceMatrix);
|
|
void RenderDebugView();
|
|
};
|
|
#endif |