Deferred lighting is working, currently adding forward redering as a comparison, also working on the sceneswapping and light manipulation tools

This commit is contained in:
Hurlu 2019-06-16 23:52:49 +09:00
parent 284650a034
commit 937c23c1d7
14 changed files with 343 additions and 181 deletions

View File

@ -32,7 +32,11 @@ void main()
// diffuse // diffuse
vec3 lightDir = normalize(lights[i].Position - FragPos); vec3 lightDir = normalize(lights[i].Position - FragPos);
vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Albedo * lights[i].Color; vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Albedo * lights[i].Color;
lighting += diffuse; // specular
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = pow(max(dot(Normal, halfwayDir), 0.0), 16.0);
vec3 specular = lights[i].Color * spec * Specular;
lighting += diffuse + specular;
} }
FragColor = vec4(lighting, 1.0); FragColor = vec4(lighting, 1.0);

View File

@ -21,3 +21,10 @@ Light::Light() : location(glm::vec4(0)), intensity(glm::vec3(1))
Light::~Light() Light::~Light()
{ {
} }
std::string Light::toString()
{
return "(" + std::to_string(location.x) + ", " +
std::to_string(location.y) + ", " +
std::to_string(location.z) + ")";
}

View File

@ -2,6 +2,7 @@
#include "glm/vec3.hpp" #include "glm/vec3.hpp"
#include "glm/vec4.hpp" #include "glm/vec4.hpp"
#include <string>
class Light class Light
{ {
@ -18,6 +19,8 @@ public:
float spot_exponent, glm::vec4 lookAt); float spot_exponent, glm::vec4 lookAt);
~Light(); ~Light();
std::string toString();
bool activated = true; bool activated = true;
LightType type; LightType type;
glm::vec3 intensity; glm::vec3 intensity;

View File

@ -297,8 +297,9 @@ void Mesh::MeshEntry::render(SceneContext &ctx, Shader &shd) {
/** /**
* Mesh constructor, loads the specified filename if supported by Assimp * Mesh constructor, loads the specified filename if supported by Assimp
**/ **/
Mesh::Mesh(const char *filename, std::string vert_shd, std::string frag_shd) : shader(vert_shd, frag_shd) Mesh::Mesh(const char *filename, std::string vert_shd, std::string frag_shd)
{ {
shader = std::make_shared<Shader>(vert_shd, frag_shd);
std::string fullname; std::string fullname;
fullname = std::string("./Models/")+ std::string(filename); fullname = std::string("./Models/")+ std::string(filename);
directory = fullname; directory = fullname;
@ -336,8 +337,9 @@ Mesh::Mesh(const char *filename, std::string vert_shd, std::string frag_shd) : s
} }
} }
Mesh::Mesh(Dataset &set, std::string vert_shd, std::string frag_shd) : shader(vert_shd, frag_shd) Mesh::Mesh(Dataset &set, std::string vert_shd, std::string frag_shd)
{ {
shader = std::make_shared<Shader>(vert_shd, frag_shd);
meshEntries.push_back(new Mesh::MeshEntry(set, this)); meshEntries.push_back(new Mesh::MeshEntry(set, this));
} }
@ -355,7 +357,7 @@ Mesh::~Mesh(void)
void Mesh::draw(SceneContext &ctx) { void Mesh::draw(SceneContext &ctx) {
shader.enable(); shader->enable();
for (unsigned int i = 0; i < meshEntries.size(); ++i) { for (unsigned int i = 0; i < meshEntries.size(); ++i) {
MeshEntry * m = meshEntries[i]; MeshEntry * m = meshEntries[i];
@ -371,21 +373,24 @@ void Mesh::draw(SceneContext &ctx) {
ctx.modelViewMatrix = ctx.viewMatrix * ctx.modelMatrix; ctx.modelViewMatrix = ctx.viewMatrix * ctx.modelMatrix;
ctx.normalMatrix = glm::transpose(glm::inverse(glm::mat3(ctx.modelMatrix))); ctx.normalMatrix = glm::transpose(glm::inverse(glm::mat3(ctx.modelMatrix)));
shader.addUniform("mvp", ctx.mvpMatrix); shader->addUniform("mvp", ctx.mvpMatrix);
shader.addUniform("NormalMatrix", ctx.normalMatrix); shader->addUniform("NormalMatrix", ctx.normalMatrix);
shader.addUniform("ModelMatrix", ctx.modelMatrix); if (ctx.renderMode == FORWARD_LIGHT)
shader->addUniform("ModelViewMatrix", ctx.modelViewMatrix);
else
shader->addUniform("ModelMatrix", ctx.modelMatrix);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures["0"].tex_ref); glBindTexture(GL_TEXTURE_2D, textures["0"].tex_ref);
meshEntries.at(i)->render(ctx, shader); meshEntries.at(i)->render(ctx, *shader);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
model.glPopMatrix(); model.glPopMatrix();
} }
shader.disable(); shader->disable();
} }
void Mesh::effectTransformations() void Mesh::effectTransformations()

View File

@ -61,9 +61,7 @@ public:
~MeshEntry(); ~MeshEntry();
Mesh * parent; Mesh * parent;
void render(SceneContext &ctx, Shader &shd); void render(SceneContext &ctx, Shader &shd);
private:
void textureBinding(Shader *shd);
void textureUnbinding();
}; };
public: public:
@ -77,10 +75,6 @@ public:
private: private:
std::vector<std::pair<glm::vec4, Transformation>> _transformations; std::vector<std::pair<glm::vec4, Transformation>> _transformations;
void enableCulling();
void textureBinding(Shader *shd);
void textureUnbinding();
void disableCulling();
public: public:
Model model; Model model;
CullFace cullMode = NONE; CullFace cullMode = NONE;
@ -97,8 +91,7 @@ public:
void removeLastTransformations(int n); void removeLastTransformations(int n);
glm::vec3 getPosition(); glm::vec3 getPosition();
Shader shader; std::shared_ptr<Shader> shader;
void draw(SceneContext &ctx); void draw(SceneContext &ctx);
void assignTexture(Texture &texture);
}; };

View File

@ -66,30 +66,45 @@ void Multipass::enableFrameBufferTexture(const std::string tex_name)
glBindFramebuffer(GL_FRAMEBUFFER, _fboId); glBindFramebuffer(GL_FRAMEBUFFER, _fboId);
} }
void Multipass::gBufferSetup(SceneContext &scnctx) void Multipass::gBufferSetup(SceneContext &scnctx, std::map<std::string, Mesh *> &meshes)
{ {
if (shader != nullptr)
delete(shader); delete(shader);
shader = new Shader("textureViewer.vert", "textureViewer.frag"); shader = new Shader("textureViewer.vert", "textureViewer.frag");
shader->addUniform("tex", 0);
for (auto mesh : meshes)
mesh.second->shader = std::make_shared<Shader>("DSGeometryPass.vert", "DSGeometryPass.frag");
scnctx.firstRedraw = false; scnctx.firstRedraw = false;
} }
void Multipass::deferredLightSetup(SceneContext &scnctx) void Multipass::recomputeDeferredLights(SceneContext &scnctx)
{ {
int i = 0;
for (auto light : scnctx.lights)
{
shader->addUniform("lights[" + std::to_string(i) + "].Position", glm::vec3(light.location));
shader->addUniform("lights[" + std::to_string(i) + "].Color", light.intensity);
i++;
}
shader->addUniform("NLights", (int)scnctx.lights.size());
}
void Multipass::deferredLightSetup(SceneContext &scnctx, std::map<std::string, Mesh *> &meshes)
{
if (shader != nullptr)
delete(shader);
shader = new Shader("DSLightPass.vert", "DSLightPass.frag"); shader = new Shader("DSLightPass.vert", "DSLightPass.frag");
shader->addUniform("pos_tex", 0); shader->addUniform("pos_tex", 0);
shader->addUniform("normal_tex", 1); shader->addUniform("normal_tex", 1);
shader->addUniform("color_tex", 2); shader->addUniform("color_tex", 2);
int i = 0; for (auto mesh : meshes)
for (auto light : scnctx.lights) mesh.second->shader = std::make_shared<Shader>("DSGeometryPass.vert", "DSGeometryPass.frag");
{
shader->addUniform("lights[" + std::to_string(i) + "].Position", glm::vec3(light.second.location)); recomputeDeferredLights(scnctx);
shader->addUniform("lights[" + std::to_string(i) + "].Color", light.second.intensity);
i++;
}
shader->addUniform("NLights", (int)scnctx.lights.size());
scnctx.firstRedraw = false; scnctx.firstRedraw = false;
} }
@ -133,6 +148,20 @@ void Multipass::drawDeferredLightToScreen(SceneContext &scnctx)
shader->disable(); shader->disable();
} }
void Multipass::forwardLightSetup(SceneContext &scnctx, std::map<std::string, Mesh *> &meshes)
{
if (shader != nullptr)
delete(shader);
shader = nullptr;
for (auto mesh : meshes)
{
mesh.second->shader = std::make_shared<Shader>("tex_base_light.vert", "tex_base_light.frag");
mesh.second->shader->addUniform("tex", 0);
}
scnctx.firstRedraw = false;
}
void Multipass::drawGBufferToScreen(SceneContext & scnctx) void Multipass::drawGBufferToScreen(SceneContext & scnctx)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -144,7 +173,6 @@ void Multipass::drawGBufferToScreen(SceneContext & scnctx)
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _pass_textures[_current_tex]); glBindTexture(GL_TEXTURE_2D, _pass_textures[_current_tex]);
shader->addUniform("tex", 0);
glBindVertexArray(_quad_vao); glBindVertexArray(_quad_vao);
glBindBuffer(GL_ARRAY_BUFFER, _quad_vbo); glBindBuffer(GL_ARRAY_BUFFER, _quad_vbo);

View File

@ -3,6 +3,7 @@
#include <map> #include <map>
#include <GL/glew.h> #include <GL/glew.h>
#include "Shader.h" #include "Shader.h"
#include "Models/Mesh.h"
#include "SceneContext.h" #include "SceneContext.h"
class Multipass class Multipass
@ -21,11 +22,13 @@ public:
void enableFrameBufferTexture(const std::string tex_name); void enableFrameBufferTexture(const std::string tex_name);
void gBufferSetup(SceneContext & scnctx); void gBufferSetup(SceneContext &scnctx, std::map<std::string, Mesh *> &meshes);
void recomputeDeferredLights(SceneContext &scnctx);
void drawGBufferToScreen(SceneContext &scnctx); void drawGBufferToScreen(SceneContext &scnctx);
void deferredLightSetup(SceneContext &scnctx); void deferredLightSetup(SceneContext &scnctx, std::map<std::string, Mesh *> &meshes);
void drawDeferredLightToScreen(SceneContext &scnctx); void drawDeferredLightToScreen(SceneContext &scnctx);
void forwardLightSetup(SceneContext &scnctx, std::map<std::string, Mesh *> &meshes);

View File

@ -41,8 +41,8 @@ MyGlWindow::MyGlWindow(int w, int h) :
m_width = w; m_width = w;
m_height = h; m_height = h;
_scnctx.height = m_height; scnctx.height = m_height;
_scnctx.width = m_width; scnctx.width = m_width;
setup(); setup();
} }
@ -54,15 +54,17 @@ MyGlWindow::~MyGlWindow()
void MyGlWindow::draw() void MyGlWindow::draw()
{ {
if (_scnctx.renderMode == GBUF_DEBUG) if (scnctx.renderMode == GBUF_DEBUG)
drawDebugGBuffer(); drawDebugGBuffer();
else if (_scnctx.renderMode == DEFERRED_LIGHT) else if (scnctx.renderMode == DEFERRED_LIGHT)
drawDeferredLight(); drawDeferredLight();
else if (scnctx.renderMode == FORWARD_LIGHT)
drawForwardLight();
} }
void MyGlWindow::setBgColor(float bgColor[3]) void MyGlWindow::setBgColor(float bgColor[3])
{ {
_scnctx.bg = glm::vec4(bgColor[0], bgColor[1], bgColor[2], 1); scnctx.bg = glm::vec4(bgColor[0], bgColor[1], bgColor[2], 1);
} }
void MyGlWindow::textureSetup() void MyGlWindow::textureSetup()
@ -72,39 +74,39 @@ void MyGlWindow::textureSetup()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
_scnctx.textures.emplace("BrickTex", Texture("brick1.jpg")); scnctx.textures.emplace("BrickTex", Texture("brick1.jpg"));
_scnctx.textures.emplace("MossTex", Texture("moss.png")); scnctx.textures.emplace("MossTex", Texture("moss.png"));
_scnctx.textures.emplace("EarthTex", Texture("earth.jpg")); scnctx.textures.emplace("EarthTex", Texture("earth.jpg"));
_scnctx.textures.emplace("OgreTex", Texture("Models/ogre/ogre_diffuse.png")); scnctx.textures.emplace("OgreTex", Texture("Models/ogre/ogre_diffuse.png"));
_scnctx.textures["OgreTex"].mat.shininess = 3.0f; scnctx.textures["OgreTex"].mat.shininess = 3.0f;
_scnctx.textures["OgreTex"].mat.ks = glm::vec3(0.1f, 0.1f, 0.1f); scnctx.textures["OgreTex"].mat.ks = glm::vec3(0.1f, 0.1f, 0.1f);
_scnctx.textures["OgreTex"].mat.ka = glm::vec3(0.3f, 0.3f, 0.3f); scnctx.textures["OgreTex"].mat.ka = glm::vec3(0.3f, 0.3f, 0.3f);
_scnctx.textures["OgreTex"].mat.enabled = true; scnctx.textures["OgreTex"].mat.enabled = true;
_scnctx.textures.emplace("OgreNmap", Texture("Models/ogre/ogre_normalmap.png")); scnctx.textures.emplace("OgreNmap", Texture("Models/ogre/ogre_normalmap.png"));
_scnctx.textures["OgreNmap"].isNmap = true; scnctx.textures["OgreNmap"].isNmap = true;
_scnctx.textures.emplace("CubeTex", Texture("Models/cube/color_map.jpg")); scnctx.textures.emplace("CubeTex", Texture("Models/cube/color_map.jpg"));
_scnctx.textures["CubeTex"].mat.shininess = 3.0f; scnctx.textures["CubeTex"].mat.shininess = 3.0f;
_scnctx.textures["CubeTex"].mat.ks = glm::vec3(0.1f, 0.1f, 0.1f); scnctx.textures["CubeTex"].mat.ks = glm::vec3(0.1f, 0.1f, 0.1f);
_scnctx.textures["CubeTex"].mat.ka = glm::vec3(0.3f, 0.3f, 0.3f); scnctx.textures["CubeTex"].mat.ka = glm::vec3(0.3f, 0.3f, 0.3f);
_scnctx.textures["CubeTex"].mat.enabled = true; scnctx.textures["CubeTex"].mat.enabled = true;
_scnctx.textures.emplace("CubeNmap", Texture("Models/cube/normal_map.jpg")); scnctx.textures.emplace("CubeNmap", Texture("Models/cube/normal_map.jpg"));
_scnctx.textures["CubeNmap"].isNmap = true; scnctx.textures["CubeNmap"].isNmap = true;
} }
void MyGlWindow::multipassSetup() void MyGlWindow::multipassSetup()
{ {
_multipassManager.addTexture("position_buffer", GL_NEAREST, GL_RGB16F, GL_RGB, GL_FLOAT, false, _scnctx); multipassManager.addTexture("position_buffer", GL_NEAREST, GL_RGB16F, GL_RGB, GL_FLOAT, false, scnctx);
_multipassManager.addTexture("normal_buffer", GL_NEAREST, GL_RGB16F, GL_RGB, GL_UNSIGNED_BYTE, false, _scnctx); multipassManager.addTexture("normal_buffer", GL_NEAREST, GL_RGB16F, GL_RGB, GL_UNSIGNED_BYTE, false, scnctx);
_multipassManager.addTexture("color_buffer", GL_NEAREST, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, false, _scnctx); multipassManager.addTexture("color_buffer", GL_NEAREST, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, false, scnctx);
_multipassManager.addTexture("depth_tex", GL_LINEAR, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT, true, _scnctx); multipassManager.addTexture("depth_tex", GL_LINEAR, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_FLOAT, true, scnctx);
_multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, "position_buffer"); multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, "position_buffer");
_multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, "normal_buffer"); multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, "normal_buffer");
_multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, "color_buffer"); multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, "color_buffer");
_multipassManager.bindToFrameBuffer(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, "depth_tex"); multipassManager.bindToFrameBuffer(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, "depth_tex");
_multipassManager.setDrawBuffers(); multipassManager.setDrawBuffers();
} }
void MyGlWindow::setup() void MyGlWindow::setup()
@ -113,7 +115,7 @@ void MyGlWindow::setup()
glEnable(GL_DEPTH_BUFFER); glEnable(GL_DEPTH_BUFFER);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
_scnctx.bg = glm::vec4(0.7, 0.7, 0.9, 1); scnctx.bg = glm::vec4(0.7, 0.7, 0.9, 1);
textureSetup(); textureSetup();
multipassSetup(); multipassSetup();
@ -126,102 +128,128 @@ void MyGlWindow::setup()
meshes.emplace("mountain", mountain); meshes.emplace("mountain", mountain);
_scnctx.lights.emplace("RandLight", scnctx.lights.emplace_back(glm::vec3(1, 1, 1), glm::vec4(0, 2, 0, 1));
Light(glm::vec3(1, 1, 1), glm::vec4(0, 2, 0, 1)));
//Scene for light testing //Scene for light testing
moddata.simpleCube(); //moddata.simpleCube();
//Hardcoded seed for easy scene replication //Hardcoded seed for easy scene replication
/*std::srand(18); //std::srand(18);
int zob = std::rand(); //int zob = std::rand();
for (int i = 0; i < 64; i++) //for (int i = 0; i < 20; i++)
{ //{
std::string cube_name = "Cube" + std::to_string(i); // //std::string cube_name = "Cube" + std::to_string(i);
meshes.emplace(cube_name, new Mesh(moddata, "DSGeometryPass.vert", "DSGeometryPass.frag")); // //meshes.emplace(cube_name, new Mesh(moddata, "DSGeometryPass.vert", "DSGeometryPass.frag"));
meshes[cube_name]->textures["0"] = _scnctx.textures["BrickTex"]; // //meshes[cube_name]->textures["0"] = _scnctx.textures["BrickTex"];
// //
// float pos_x = std::rand() % 100 - 50;
// float pos_z = std::rand() % 100 - 50;
float pos_x = std::rand() % 100 - 50; // //meshes[cube_name]->addStartTranslation(glm::vec4(0, 1, 0, 0));
float pos_z = std::rand() % 100 - 50; // //meshes[cube_name]->addStartTranslation(glm::vec4(pos_x, 0, 0, 0));
// //meshes[cube_name]->addStartTranslation(glm::vec4(0, 0, pos_z, 0));
meshes[cube_name]->addStartTranslation(glm::vec4(0, 1, 0, 0)); // //meshes[cube_name]->addStartRotation(glm::vec4(1, 0, 0, std::rand() % 360));
meshes[cube_name]->addStartTranslation(glm::vec4(pos_x, 0, 0, 0)); // //meshes[cube_name]->addStartRotation(glm::vec4(0, 1, 0, std::rand() % 360));
meshes[cube_name]->addStartTranslation(glm::vec4(0, 0, pos_z, 0)); // //meshes[cube_name]->addStartRotation(glm::vec4(0, 0, 1, std::rand() % 360));
meshes[cube_name]->addStartRotation(glm::vec4(1, 0, 0, std::rand() % 360)); //
meshes[cube_name]->addStartRotation(glm::vec4(0, 1, 0, std::rand() % 360)); // float light_r = (40 + std::rand() % 60) / 100.f;
meshes[cube_name]->addStartRotation(glm::vec4(0, 0, 1, std::rand() % 360)); // float light_g = (40 + std::rand() % 60) / 100.f;
// float light_b = (40 + std::rand() % 60) / 100.f;
float light_r = (40 + std::rand() % 60) / 100.f; //
float light_g = (40 + std::rand() % 60) / 100.f; // scnctx.lights.emplace_back(glm::vec3(light_r, light_g, light_b), glm::vec4(pos_x, 2, pos_z, 1));
float light_b = (40 + std::rand() % 60) / 100.f; //}
_scnctx.lights.emplace("RandLight" + i,
Light(glm::vec3(light_r, light_g, light_b), glm::vec4(pos_x, 2, pos_z, 1)));
}*/
} }
void MyGlWindow::drawDeferredLight() void MyGlWindow::drawDeferredLight()
{ {
if (_scnctx.firstRedraw) if (scnctx.firstRedraw)
_multipassManager.deferredLightSetup(_scnctx); multipassManager.deferredLightSetup(scnctx, meshes);
_scnctx.height = m_height; scnctx.height = m_height;
_scnctx.width = m_width; scnctx.width = m_width;
glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z); glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z);
glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z); glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z);
glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z); glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z);
glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer
glm::mat4 projection = perspective(45.0f, (float)_scnctx.width / (float)_scnctx.height, 0.1f, 1000.0f); glm::mat4 projection = perspective(45.0f, (float)scnctx.width / (float)scnctx.height, 0.1f, 1000.0f);
_scnctx.camPos = eye; scnctx.camPos = eye;
_scnctx.viewMatrix = view; scnctx.viewMatrix = view;
_scnctx.projectionMatrix = projection; scnctx.projectionMatrix = projection;
glClearColor(_scnctx.bg.r, _scnctx.bg.g, _scnctx.bg.b, _scnctx.bg.a); glClearColor(scnctx.bg.r, scnctx.bg.g, scnctx.bg.b, scnctx.bg.a);
glViewport(0, 0, _scnctx.width, _scnctx.height); glViewport(0, 0, scnctx.width, scnctx.height);
_multipassManager.enableFrameBufferTexture(_scnctx.fboDisplayName); multipassManager.enableFrameBufferTexture(scnctx.fboDisplayName);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (auto it = meshes.begin(); it != meshes.end(); it++) for (auto it = meshes.begin(); it != meshes.end(); it++)
(*it).second->draw(_scnctx); (*it).second->draw(scnctx);
_multipassManager.drawDeferredLightToScreen(_scnctx); multipassManager.drawDeferredLightToScreen(scnctx);
} }
void MyGlWindow::drawDebugGBuffer() void MyGlWindow::drawDebugGBuffer()
{ {
if (_scnctx.firstRedraw) if (scnctx.firstRedraw)
_multipassManager.gBufferSetup(_scnctx); multipassManager.gBufferSetup(scnctx, meshes);
_scnctx.height = m_height; scnctx.height = m_height;
_scnctx.width = m_width; scnctx.width = m_width;
glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z); glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z);
glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z); glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z);
glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z); glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z);
glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer
glm::mat4 projection = perspective(45.0f, (float)_scnctx.width / (float)_scnctx.height, 0.1f, 1000.0f); glm::mat4 projection = perspective(45.0f, (float)scnctx.width / (float)scnctx.height, 0.1f, 1000.0f);
_scnctx.camPos = eye; scnctx.camPos = eye;
_scnctx.viewMatrix = view; scnctx.viewMatrix = view;
_scnctx.projectionMatrix = projection; scnctx.projectionMatrix = projection;
glClearColor(_scnctx.bg.r, _scnctx.bg.g, _scnctx.bg.b, _scnctx.bg.a); glClearColor(scnctx.bg.r, scnctx.bg.g, scnctx.bg.b, scnctx.bg.a);
glViewport(0, 0, _scnctx.width, _scnctx.height); glViewport(0, 0, scnctx.width, scnctx.height);
_multipassManager.enableFrameBufferTexture(_scnctx.fboDisplayName); multipassManager.enableFrameBufferTexture(scnctx.fboDisplayName);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (auto it = meshes.begin(); it != meshes.end(); it++) for (auto it = meshes.begin(); it != meshes.end(); it++)
(*it).second->draw(_scnctx); (*it).second->draw(scnctx);
_multipassManager.drawGBufferToScreen(_scnctx); multipassManager.drawGBufferToScreen(scnctx);
}
void MyGlWindow::drawForwardLight()
{
if (scnctx.firstRedraw)
multipassManager.forwardLightSetup(scnctx, meshes);
scnctx.height = m_height;
scnctx.width = m_width;
glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z);
glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z);
glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z);
glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer
glm::mat4 projection = perspective(45.0f, (float)scnctx.width / (float)scnctx.height, 0.1f, 1000.0f);
scnctx.camPos = eye;
scnctx.viewMatrix = view;
scnctx.projectionMatrix = projection;
glClearColor(scnctx.bg.r, scnctx.bg.g, scnctx.bg.b, scnctx.bg.a);
glViewport(0, 0, scnctx.width, scnctx.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (auto it = meshes.begin(); it != meshes.end(); it++)
(*it).second->draw(scnctx);
} }

View File

@ -32,19 +32,21 @@ public:
void resize(int w, int h); void resize(int w, int h);
Viewer viewer; Viewer viewer;
SceneContext _scnctx; SceneContext scnctx;
Multipass multipassManager;
private: private:
int m_width; int m_width;
int m_height; int m_height;
float _bgColor[3]; float _bgColor[3];
Multipass _multipassManager;
GLuint _vaoHandle; GLuint _vaoHandle;
GLuint _iboHandle; GLuint _iboHandle;
void drawDebugGBuffer(); void drawDebugGBuffer();
void drawForwardLight();
void drawDeferredLight(); void drawDeferredLight();
void textureSetup(); void textureSetup();
void multipassSetup(); void multipassSetup();

View File

@ -9,12 +9,13 @@
enum RenderMode enum RenderMode
{ {
GBUF_DEBUG, GBUF_DEBUG,
DEFERRED_LIGHT DEFERRED_LIGHT,
FORWARD_LIGHT
}; };
struct SceneContext struct SceneContext
{ {
std::map<std::string, Light> lights; std::vector<Light> lights;
std::map<std::string, float> floatValues; std::map<std::string, float> floatValues;
glm::mat4x4 viewMatrix; glm::mat4x4 viewMatrix;
@ -43,10 +44,10 @@ struct SceneContext
{ {
for (auto it : lights) for (auto it : lights)
{ {
if (it.second.type == Light::SPOT) if (it.type == Light::SPOT)
{ {
it.second.location = it.second.location * viewMatrix; it.location = it.location * viewMatrix;
it.second.direction = (viewMatrix * it.second.lookAt - it.second.location * viewMatrix); it.direction = (viewMatrix * it.lookAt - it.location * viewMatrix);
} }
} }
} }

View File

@ -155,68 +155,11 @@ bool createWindow(GLFWwindow **window)
return true; return true;
} }
int loop(GLFWwindow *window) void FPSDisplay(int width)
{ {
std::printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION)); static int frameCount = 0;
static int fps = 60;
int width; static double previousTime = glfwGetTime();
int heigth;
glfwGetWindowSize(window, &width, &heigth);
MyGlWindow glWin(width, heigth);
int frameCount = 0;
int fps = 60;
double previousTime = glfwGetTime();
glWin._scnctx.fboDisplayName = "position_buffer";
bool is_selected = false;
glWin._scnctx.renderMode = GBUF_DEBUG;
glWin._scnctx.firstRedraw = true;
while (!glfwWindowShouldClose(window))
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
if (ImGui::Begin("Scene settings"))
{
if (ImGui::BeginCombo("Debug Buffer", glWin._scnctx.fboDisplayName.c_str()))
{
if (ImGui::Selectable("Position buffer", &is_selected, 0, ImVec2(120, 10)))
glWin._scnctx.fboDisplayName = "position_buffer";
if (ImGui::Selectable("Normal buffer", &is_selected, 0, ImVec2(120, 10)))
glWin._scnctx.fboDisplayName = "normal_buffer";
if (ImGui::Selectable("Color buffer", &is_selected, 0, ImVec2(120, 10)))
glWin._scnctx.fboDisplayName = "color_buffer";
ImGui::EndCombo();
}
if (ImGui::BeginCombo("Render Mode",
(glWin._scnctx.renderMode == DEFERRED_LIGHT)? "Deferred Lights" : "Debug GBuffers"))
{
if (ImGui::Selectable("Draw Debug GBuffers", &is_selected, 0, ImVec2(120, 10)))
{
glWin._scnctx.renderMode = GBUF_DEBUG;
glWin._scnctx.firstRedraw = true;
}
if (ImGui::Selectable("Draw with Deferred Lights", &is_selected, 0, ImVec2(120, 10)))
{
glWin._scnctx.renderMode = DEFERRED_LIGHT;
glWin._scnctx.firstRedraw = true;
}
ImGui::EndCombo();
}
ImGui::SetWindowPos(ImVec2(20, 20));
}
ImGui::End();
double currentTime = glfwGetTime(); double currentTime = glfwGetTime();
frameCount++; frameCount++;
@ -228,13 +171,137 @@ int loop(GLFWwindow *window)
previousTime = currentTime; previousTime = currentTime;
} }
if (ImGui::Begin("FPSCounterOutline1", false,
ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing))
ImGui::TextColored(ImVec4(0, 0, 0, 1), std::to_string(fps).c_str());
ImGui::End();
if (ImGui::Begin("FPSCounterOutline2", false,
ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing))
ImGui::TextColored(ImVec4(0, 0, 0, 1), std::to_string(fps).c_str());
ImGui::End();
if (ImGui::Begin("FPSCounterOutline3", false,
ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing))
ImGui::TextColored(ImVec4(0, 0, 0, 1), std::to_string(fps).c_str());
ImGui::End();
if (ImGui::Begin("FPSCounterOutline4", false,
ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing))
ImGui::TextColored(ImVec4(0, 0, 0, 1), std::to_string(fps).c_str());
ImGui::End();
if (ImGui::Begin("FPSCounter", false, if (ImGui::Begin("FPSCounter", false,
ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing)) ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing))
ImGui::TextColored(ImVec4(1, 1, 0, 1), std::to_string(fps).c_str()); ImGui::TextColored(ImVec4(1, 1, 1, 1), std::to_string(fps).c_str());
ImGui::End(); ImGui::End();
ImGui::SetWindowPos("FPSCounter", ImVec2(width - 50, 20), ImGuiCond_Once); ImGui::SetWindowPos("FPSCounterOutline1", ImVec2(width - 49.f, 20.f), ImGuiCond_Once);
ImGui::SetWindowPos("FPSCounterOutline2", ImVec2(width - 51.f, 20.f), ImGuiCond_Once);
ImGui::SetWindowPos("FPSCounterOutline3", ImVec2(width - 50.f, 19.f), ImGuiCond_Once);
ImGui::SetWindowPos("FPSCounterOutline4", ImVec2(width - 50.f, 21.f), ImGuiCond_Once);
ImGui::SetWindowPos("FPSCounter", ImVec2(width - 50.f, 20.f), ImGuiCond_Once);
}
int loop(GLFWwindow *window)
{
std::printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION));
int width;
int heigth;
glfwGetWindowSize(window, &width, &heigth);
MyGlWindow glWin(width, heigth);
glWin.scnctx.fboDisplayName = "position_buffer";
bool is_selected = false;
glWin.scnctx.renderMode = GBUF_DEBUG;
glWin.scnctx.firstRedraw = true;
std::vector<std::string> lights_strs;
char const **strings = nullptr;
int current_light = 0;
while (!glfwWindowShouldClose(window))
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
if (ImGui::Begin("Scene settings"))
{
if (ImGui::BeginCombo("Debug Buffer", glWin.scnctx.fboDisplayName.c_str()))
{
if (ImGui::Selectable("Position buffer", &is_selected, 0, ImVec2(120, 10)))
glWin.scnctx.fboDisplayName = "position_buffer";
if (ImGui::Selectable("Normal buffer", &is_selected, 0, ImVec2(120, 10)))
glWin.scnctx.fboDisplayName = "normal_buffer";
if (ImGui::Selectable("Color buffer", &is_selected, 0, ImVec2(120, 10)))
glWin.scnctx.fboDisplayName = "color_buffer";
ImGui::EndCombo();
}
if (ImGui::BeginCombo("Render Mode",
(glWin.scnctx.renderMode == DEFERRED_LIGHT) ? "Deferred Lights" : (
(glWin.scnctx.renderMode == FORWARD_LIGHT) ? "Forward Lights" : "Debug GBuffers")))
{
if (ImGui::Selectable("Draw Debug GBuffers", &is_selected, 0, ImVec2(120, 10)))
{
glWin.scnctx.renderMode = GBUF_DEBUG;
glWin.scnctx.firstRedraw = true;
}
if (ImGui::Selectable("Draw with Deferred Lights", &is_selected, 0, ImVec2(120, 10)))
{
glWin.scnctx.renderMode = DEFERRED_LIGHT;
glWin.scnctx.firstRedraw = true;
}
if (ImGui::Selectable("Draw with Forward Lights", &is_selected, 0, ImVec2(120, 10)))
{
glWin.scnctx.renderMode = FORWARD_LIGHT;
glWin.scnctx.firstRedraw = true;
}
ImGui::EndCombo();
}
ImGui::SetWindowPos(ImVec2(20, 20));
}
ImGui::End();
if (ImGui::Begin("Light management"))
{
lights_strs.clear();
for (auto light : glWin.scnctx.lights)
lights_strs.push_back(light.toString());
std::free(strings);
strings = (char const **)std::malloc(sizeof(char *) * (lights_strs.size() + 1));
std::memset((void *)strings, 0, sizeof(char *) * (lights_strs.size() + 1));
for (int i = 0; i < lights_strs.size(); i++)
strings[i] = lights_strs[i].c_str();
ImGui::ListBox("Lights", &current_light, strings, lights_strs.size());
if (ImGui::SliderFloat("Selected light X", &glWin.scnctx.lights[current_light].location.x, -10, 10)
&& glWin.scnctx.renderMode != GBUF_DEBUG)
glWin.multipassManager.recomputeDeferredLights(glWin.scnctx);
if (ImGui::SliderFloat("Selected light Y", &glWin.scnctx.lights[current_light].location.y, -10, 10)
&& glWin.scnctx.renderMode != GBUF_DEBUG)
glWin.multipassManager.recomputeDeferredLights(glWin.scnctx);
if (ImGui::SliderFloat("Selected light Z", &glWin.scnctx.lights[current_light].location.z, -10, 10)
&& glWin.scnctx.renderMode != GBUF_DEBUG)
glWin.multipassManager.recomputeDeferredLights(glWin.scnctx);
}
ImGui::End();
FPSDisplay(width);
glfwSwapBuffers(window); glfwSwapBuffers(window);
glWin.draw(); glWin.draw();

View File

@ -58,3 +58,33 @@ Pos=20,20
Size=309,85 Size=309,85
Collapsed=0 Collapsed=0
[Window][FPSCounterOutline]
Pos=1031,21
Size=32,32
Collapsed=0
[Window][FPSCounterOutline4]
Pos=1030,21
Size=32,32
Collapsed=0
[Window][FPSCounterOutline3]
Pos=1030,19
Size=32,32
Collapsed=0
[Window][FPSCounterOutline2]
Pos=1029,20
Size=32,32
Collapsed=0
[Window][FPSCounterOutline1]
Pos=1031,20
Size=32,32
Collapsed=0
[Window][Light management]
Pos=12,120
Size=410,449
Collapsed=0

View File

@ -8,52 +8,43 @@ uniform vec3 Ka;
uniform vec3 Ks; uniform vec3 Ks;
uniform float Shininess; uniform float Shininess;
struct LightInfo { struct Light {
vec4 Position; vec4 Position;
vec3 Intensity; vec3 Color;
}; };
uniform LightInfo Light[64]; uniform Light lights[64];
uniform int LightCount; uniform int NLights;
in vec3 fNormal; in vec3 fNormal;
in vec3 pos; in vec3 pos;
in vec2 texCoord; in vec2 texCoord;
uniform int TexCount; uniform sampler2D tex;
uniform sampler2D tex[32];
void main() void main()
{ {
vec3 finalColor; vec3 finalColor;
vec3 diffuse_sum; vec3 diffuse_sum;
vec3 specular_sum; vec3 specular_sum;
vec3 ambient; vec3 ambient;
ambient = Ka * Light[0].Intensity; ambient = Ka * lights[0].Color;
for (int i=0; i<LightCount; i++) for (int i = 0; i < NLights; i++)
{ {
vec3 L = normalize(Light[i].Position.xyz - pos); vec3 L = normalize(lights[i].Position.xyz - pos);
vec3 N = fNormal; vec3 N = fNormal;
vec3 V = normalize(-pos); vec3 V = normalize(-pos);
vec3 H = normalize(V + L); vec3 H = normalize(V + L);
vec3 diffuse = Kd * Light[i].Intensity * max(dot(L, N), 0.0); vec3 diffuse = Kd * lights[i].Color * max(dot(L, N), 0.0);
vec3 specular = Ks * Light[i].Intensity * pow(max(dot(H, N), 0.0), Shininess); vec3 specular = Ks * lights[i].Color * pow(max(dot(H, N), 0.0), Shininess);
diffuse_sum += diffuse; diffuse_sum += diffuse;
specular_sum += specular; specular_sum += specular;
} }
vec4 texColor = texture(tex[0], texCoord); vec4 texColor = texture(tex, texCoord);
for (int i=1; i < TexCount; i++)
{
vec4 new_tex = texture(tex[i], texCoord);
texColor = mix(new_tex, texColor, new_tex.a);
}
FragColors = (vec4(diffuse_sum + ambient, 1) * texColor + vec4(specular_sum, 1.0)); FragColors = (vec4(diffuse_sum + ambient, 1) * texColor + vec4(specular_sum, 1.0));
FragColors = texColor + (FragColors * 0.01);
} }