finished light and forward refactoring
This commit is contained in:
parent
0273b76bdf
commit
72466f7ef7
@ -16,4 +16,6 @@ endif()
|
|||||||
|
|
||||||
file(GLOB RESOURCES_FILES src/*.h shaders/*.glsl)
|
file(GLOB RESOURCES_FILES src/*.h shaders/*.glsl)
|
||||||
|
|
||||||
include(../cmaketemplate/template.cmake)
|
set(CMAKE_TEMPLATE_PATH "../cmaketemplate")
|
||||||
|
|
||||||
|
include(${CMAKE_TEMPLATE_PATH}/template.cmake)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
GLenum Buffer<T>::getGLEnum(BufferType type)
|
GLenum TBuffer<T>::getGLEnum(BufferType type)
|
||||||
{
|
{
|
||||||
GLenum typeEnum;
|
GLenum typeEnum;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ GLenum Buffer<T>::getGLEnum(BufferType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Buffer<T>::BufferEditor::BufferEditor(Buffer *b)
|
TBuffer<T>::BufferEditor::BufferEditor(TBuffer *b)
|
||||||
{
|
{
|
||||||
if(b->isDynamic())
|
if(b->isDynamic())
|
||||||
{
|
{
|
||||||
@ -41,14 +41,14 @@ Buffer<T>::BufferEditor::BufferEditor(Buffer *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Buffer<T>::BufferEditor::~BufferEditor()
|
TBuffer<T>::BufferEditor::~BufferEditor()
|
||||||
{
|
{
|
||||||
glUnmapBuffer(m_typeEnum);
|
glUnmapBuffer(m_typeEnum);
|
||||||
glBindBuffer(m_typeEnum, 0);
|
glBindBuffer(m_typeEnum, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Buffer<T>::Buffer(const std::vector<T> &data, BufferType type, bool isDynamic) :
|
TBuffer<T>::TBuffer(const std::vector<T> &data, BufferType type, bool isDynamic) :
|
||||||
m_type(type),
|
m_type(type),
|
||||||
m_isDynamic(isDynamic)
|
m_isDynamic(isDynamic)
|
||||||
{
|
{
|
||||||
@ -62,7 +62,7 @@ Buffer<T>::Buffer(const std::vector<T> &data, BufferType type, bool isDynamic) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Buffer<T>::setVertexAttrib(int location, int nbComponents, int offset, int instanceDivisor)
|
void TBuffer<T>::setVertexAttrib(int location, int nbComponents, int offset, int instanceDivisor)
|
||||||
{
|
{
|
||||||
if(m_type == VBO && SparrowRenderer::isModernOpenGLAvailable())
|
if(m_type == VBO && SparrowRenderer::isModernOpenGLAvailable())
|
||||||
{
|
{
|
||||||
@ -76,19 +76,19 @@ void Buffer<T>::setVertexAttrib(int location, int nbComponents, int offset, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Buffer<T>::bind()
|
void TBuffer<T>::bind()
|
||||||
{
|
{
|
||||||
glBindBuffer(getGLEnum(m_type), m_id);
|
glBindBuffer(getGLEnum(m_type), m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Buffer<T>::unbind()
|
void TBuffer<T>::unbind()
|
||||||
{
|
{
|
||||||
glBindBuffer(getGLEnum(m_type), 0);
|
glBindBuffer(getGLEnum(m_type), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Buffer<T>::~Buffer()
|
TBuffer<T>::~TBuffer()
|
||||||
{
|
{
|
||||||
glDeleteBuffers(1, m_id);
|
glDeleteBuffers(1, m_id);
|
||||||
}
|
}
|
||||||
|
22
src/buffer.h
22
src/buffer.h
@ -6,9 +6,17 @@
|
|||||||
|
|
||||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Buffer
|
class Buffer
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Buffer();
|
||||||
|
virtual void bind() = 0;
|
||||||
|
virtual void unbind() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TBuffer : public Buffer
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
enum BufferType
|
enum BufferType
|
||||||
{
|
{
|
||||||
@ -23,19 +31,19 @@ public:
|
|||||||
T *ptr;
|
T *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BufferEditor(Buffer *b);
|
BufferEditor(TBuffer *b);
|
||||||
~BufferEditor();
|
~BufferEditor();
|
||||||
|
|
||||||
T* getPointer();
|
T* getPointer();
|
||||||
};
|
};
|
||||||
|
|
||||||
Buffer(const std::vector<T> &data, BufferType type, bool isDynamic = false);
|
TBuffer(const std::vector<T> &data, BufferType type, bool isDynamic = false);
|
||||||
~Buffer();
|
~TBuffer();
|
||||||
|
|
||||||
void setVertexAttrib(int location, int nbComponents, int offset = 0, int instanceDivisor = 0);
|
virtual void setVertexAttrib(int location, int nbComponents, int offset = 0, int instanceDivisor = 0);
|
||||||
|
|
||||||
void bind();
|
virtual void bind();
|
||||||
void unbind();
|
virtual void unbind();
|
||||||
|
|
||||||
GLuint getId() {return m_id;}
|
GLuint getId() {return m_id;}
|
||||||
BufferType getType() {return m_type;}
|
BufferType getType() {return m_type;}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
|
#include "phongmaterial.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
@ -15,90 +15,59 @@ void ForwardModule::renderGL(Camera* myCamera, Scene* scene)
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
|
|
||||||
// render ambient lighting
|
for(const Pass &p : passes)
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
|
|
||||||
lightPass(myCamera, scene, NULL);
|
|
||||||
|
|
||||||
// render directionnal lighting and point lighting
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_ONE, GL_ONE);
|
|
||||||
glDepthMask(GL_FALSE);
|
|
||||||
|
|
||||||
for(SceneIterator<Light*>* lightIt = scene->getLights(); lightIt->isValid(); lightIt->next())
|
|
||||||
lightPass(myCamera, scene, lightIt->getItem());
|
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
glDepthMask(GL_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
|
|
||||||
{
|
|
||||||
if(isWireframe){
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
||||||
}else{
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
}
|
|
||||||
// loop over all types of geometry
|
|
||||||
for(std::size_t i=0; i<geometryFlagList.size(); ++i)
|
|
||||||
{
|
{
|
||||||
std::size_t j;
|
for(Light *light : p.lights)
|
||||||
for(j=0; j<lightFlagList.size(); ++j)
|
|
||||||
if(lightFlagList[j] == light->getFlags())
|
|
||||||
break;
|
|
||||||
if(j == lightFlagList.size())
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "WARNING : missing shader for the light");
|
if(light->getFlags() & Light::AMBIENT_FLAG)
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Shader* shader = shaders[i*lightFlagList.size() + j];
|
|
||||||
shader->bind();
|
|
||||||
|
|
||||||
// bind light attributes
|
|
||||||
switch(light->getType())
|
|
||||||
{
|
|
||||||
case Light::AMBIENT:
|
|
||||||
shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); // add attribute, and setter for ambient lighting
|
|
||||||
break;
|
|
||||||
case Light::DIRECTIONNAL:
|
|
||||||
shader->bindVec3(shader->getLocation("dirLight"), -light->getDir());
|
|
||||||
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
|
|
||||||
if(light->isShadowCaster())
|
|
||||||
{
|
{
|
||||||
light->getShadowMap()->bind(PhongMaterial::NB_PHONG_SLOTS); // NB_PHONG_SLOTS has the value of the first available slot after the phong material texture slots
|
// render ambient lighting (opaque)
|
||||||
shader->bindInteger(shader->getLocation("shadowMap"), PhongMaterial::NB_PHONG_SLOTS);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(GL_LESS);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case Light::POINT:
|
|
||||||
shader->bindVec3(shader->getLocation("pointLight"), light->getPos());
|
|
||||||
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
|
|
||||||
shader->bindFloat(shader->getLocation("attenuation"), light->getAttenuation());
|
|
||||||
break;
|
|
||||||
case Light::SPOT:
|
|
||||||
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
|
|
||||||
// TODO add cutoff and attenuation
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
unsigned int id = 2;
|
|
||||||
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
|
||||||
geometryIt->isValid(); geometryIt->next())
|
|
||||||
{
|
|
||||||
GeometryNode* node = geometryIt->getItem();
|
|
||||||
shader->bindUnsignedInteger(shader->getLocation("object_identifier"), id);
|
|
||||||
if(node->mesh->hasInstances())
|
|
||||||
id += node->mesh->instances_offsets.size();
|
|
||||||
else
|
else
|
||||||
++id;
|
|
||||||
Material* mat = node->mesh->material;
|
|
||||||
unsigned int flags = mat->getFlags();
|
|
||||||
if(node->mesh->hasInstances())
|
|
||||||
flags |= INSTANCING_FLAG;
|
|
||||||
if(flags == geometryFlagList[i]) // if flag matches material
|
|
||||||
{
|
{
|
||||||
|
// render directionnal lighting and point lighting (additive light)
|
||||||
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
}
|
||||||
|
Shader *shader = p.shader;
|
||||||
|
shader->bind();
|
||||||
|
switch(light->getType())
|
||||||
|
{
|
||||||
|
case Light::AMBIENT:
|
||||||
|
shader->bindVec3(shader->getLocation("lightColor"), light->getColor()); // add attribute, and setter for ambient lighting
|
||||||
|
break;
|
||||||
|
case Light::DIRECTIONNAL:
|
||||||
|
shader->bindVec3(shader->getLocation("dirLight"), -light->getDir());
|
||||||
|
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
|
||||||
|
if(light->isShadowCaster())
|
||||||
|
{
|
||||||
|
light->getShadowMap()->bind(PhongMaterial::NB_PHONG_SLOTS); // NB_PHONG_SLOTS has the value of the first available slot after the phong material texture slots
|
||||||
|
shader->bindInteger(shader->getLocation("shadowMap"), PhongMaterial::NB_PHONG_SLOTS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Light::POINT:
|
||||||
|
shader->bindVec3(shader->getLocation("pointLight"), light->getPos());
|
||||||
|
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
|
||||||
|
shader->bindFloat(shader->getLocation("attenuation"), light->getAttenuation());
|
||||||
|
break;
|
||||||
|
case Light::SPOT:
|
||||||
|
shader->bindVec3(shader->getLocation("lightColor"), light->getColor());
|
||||||
|
// TODO add cutoff and attenuation
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
unsigned int id = 2;
|
||||||
|
for(GeometryNode *node : p.geometry)
|
||||||
|
{
|
||||||
|
shader->bindUnsignedInteger(shader->getLocation("object_identifier"), id);
|
||||||
|
if(node->mesh->instances_offsets.empty())
|
||||||
|
++id;
|
||||||
|
else
|
||||||
|
id += node->mesh->instances_offsets.size();
|
||||||
// compute matrix attributes
|
// compute matrix attributes
|
||||||
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
|
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
|
||||||
glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix;
|
glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix;
|
||||||
@ -116,9 +85,11 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// modern opengl methods
|
glDisable(GL_BLEND);
|
||||||
|
glDepthFunc(GL_LESS);
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
void ForwardModule::setShaderSource(ShaderSource* source)
|
void ForwardModule::setShaderSource(ShaderSource* source)
|
||||||
{
|
{
|
||||||
@ -129,72 +100,44 @@ void ForwardModule::setShaderSource(ShaderSource* source)
|
|||||||
|
|
||||||
void ForwardModule::compileShaders(Scene* scene)
|
void ForwardModule::compileShaders(Scene* scene)
|
||||||
{
|
{
|
||||||
geometryFlagList.clear();
|
for(Pass &p : passes)
|
||||||
lightFlagList.clear();
|
delete(p.shader);
|
||||||
for(Shader* s : shaders)
|
passes.clear();
|
||||||
delete(s);
|
// list all geometry types
|
||||||
shaders.clear();
|
geometry.clear();
|
||||||
|
|
||||||
// get material flags
|
|
||||||
const int nb_geometry_flags = 1 << NB_FLAGS;
|
|
||||||
bool geometryFlags[nb_geometry_flags];
|
|
||||||
for(int i=0; i<nb_geometry_flags; ++i)
|
|
||||||
geometryFlags[i] = false;
|
|
||||||
|
|
||||||
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
||||||
geometryIt->isValid(); geometryIt->next())
|
geometryIt->isValid(); geometryIt->next())
|
||||||
{
|
{
|
||||||
Mesh* m = geometryIt->getItem()->mesh;
|
GeometryNode* n = geometryIt->getItem();
|
||||||
unsigned int flags = m->material->getFlags();
|
geometry[n->mesh->getFlags()].push_back(n);
|
||||||
if(m->hasInstances())
|
|
||||||
flags |= INSTANCING_FLAG;
|
|
||||||
geometryFlags[flags] = true;
|
|
||||||
}
|
}
|
||||||
for(int i=0; i<nb_geometry_flags; ++i)
|
// list all light types
|
||||||
{
|
lights.clear();
|
||||||
if(geometryFlags[i])
|
lights[ambientLight.getFlags()].push_back(&ambientLight);
|
||||||
geometryFlagList.push_back(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get light flags
|
|
||||||
const int nb_light_flags = 1 << Light::NB_LIGHT_FLAGS;
|
|
||||||
bool lightFlags[nb_light_flags];
|
|
||||||
for(int i=0; i<nb_light_flags; ++i)
|
|
||||||
lightFlags[i] = false;
|
|
||||||
|
|
||||||
// ambient light
|
|
||||||
lightFlags[Light::getFlags(NULL)] = true;
|
|
||||||
// scene lights
|
|
||||||
for(SceneIterator<Light*>* lightIt = scene->getLights();
|
for(SceneIterator<Light*>* lightIt = scene->getLights();
|
||||||
lightIt->isValid(); lightIt->next())
|
lightIt->isValid(); lightIt->next())
|
||||||
{
|
{
|
||||||
Light* l = lightIt->getItem();
|
Light* l = lightIt->getItem();
|
||||||
lightFlags[Light::getFlags(l)] = true;
|
lights[l->getFlags()].push_back(l);
|
||||||
}
|
}
|
||||||
for(int i=0; i<nb_light_flags; ++i)
|
// compile shaders and add the pass for the ambient light first
|
||||||
|
unsigned int ambientFlags = ambientLight.getFlags();
|
||||||
|
for(const auto &geomIt : geometry)
|
||||||
{
|
{
|
||||||
if(lightFlags[i])
|
unsigned int geomFlags = geomIt.first;
|
||||||
lightFlagList.push_back(i);
|
passes.push_back(Pass(shaderSources->compile(geomFlags, ambientFlags), geomIt.second, lights[ambientFlags]));
|
||||||
}
|
}
|
||||||
|
// compile a shader for each combination of a geometry flag and a light flag
|
||||||
// shader compilation
|
for(const auto &lightIt : lights)
|
||||||
for(int i : geometryFlagList)
|
|
||||||
{
|
{
|
||||||
std::vector<const char*> defines;
|
unsigned int lightFlags = lightIt.first;
|
||||||
|
if(lightFlags != ambientFlags) // ambient shaders are already ready
|
||||||
std::size_t boundary = defines.size();
|
|
||||||
for(int j : lightFlagList)
|
|
||||||
{
|
{
|
||||||
while(defines.size() > boundary)
|
for(const auto &geomIt : geometry)
|
||||||
defines.pop_back();
|
|
||||||
// set light defines
|
|
||||||
for(int k=0; k<Light::NB_LIGHT_FLAGS; ++k)
|
|
||||||
{
|
{
|
||||||
if(j & (1 << k))
|
unsigned int geomFlags = geomIt.first;
|
||||||
defines.push_back(Light::flagStr[k]);
|
passes.push_back(Pass(shaderSources->compile(geomFlags, lightFlags), geomIt.second, lightIt.second));
|
||||||
}
|
}
|
||||||
// compilation
|
|
||||||
shaders.push_back(shaderSources->compile(defines.size(), defines.data()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,10 @@
|
|||||||
#include "shadersource.h"
|
#include "shadersource.h"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
#include "framebuffer.h"
|
#include "framebuffer.h"
|
||||||
|
#include "light.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
class Light;
|
class GeometryNode;
|
||||||
class Scene;
|
class Scene;
|
||||||
class PhongEntity;
|
class PhongEntity;
|
||||||
|
|
||||||
@ -20,9 +22,10 @@ public:
|
|||||||
ForwardModule() :
|
ForwardModule() :
|
||||||
shaderSources(NULL),
|
shaderSources(NULL),
|
||||||
renderTarget(FrameBuffer::screen),
|
renderTarget(FrameBuffer::screen),
|
||||||
isWireframe(false),
|
|
||||||
clearBeforeDrawing(false)
|
clearBeforeDrawing(false)
|
||||||
{}
|
{
|
||||||
|
ambientLight.initAmbientLight();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void renderGL(Camera* myCamera, Scene* scene);
|
virtual void renderGL(Camera* myCamera, Scene* scene);
|
||||||
virtual bool requiresModernOpenGL() {return true;}
|
virtual bool requiresModernOpenGL() {return true;}
|
||||||
@ -34,23 +37,36 @@ public:
|
|||||||
void compileShaders(Scene* scene);
|
void compileShaders(Scene* scene);
|
||||||
|
|
||||||
void setRenderTarget(const FrameBuffer* target);
|
void setRenderTarget(const FrameBuffer* target);
|
||||||
void setWireframe(bool wireframe) {isWireframe = wireframe;}
|
|
||||||
void setClearBeforeDrawing(bool clear) {clearBeforeDrawing = clear;}
|
void setClearBeforeDrawing(bool clear) {clearBeforeDrawing = clear;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Pass
|
||||||
|
{
|
||||||
|
Shader* shader;
|
||||||
|
const std::vector<GeometryNode*> &geometry;
|
||||||
|
const std::vector<Light*> &lights;
|
||||||
|
|
||||||
|
Pass(Shader *myShader,
|
||||||
|
const std::vector<GeometryNode*> &geomIt,
|
||||||
|
const std::vector<Light*> &lightIt) :
|
||||||
|
shader(myShader),
|
||||||
|
geometry(geomIt),
|
||||||
|
lights(lightIt)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<unsigned int, std::vector<GeometryNode*>> geometry;
|
||||||
|
std::unordered_map<unsigned int, std::vector<Light*>> lights;
|
||||||
|
Light ambientLight;
|
||||||
|
std::vector<Pass> passes;
|
||||||
ShaderSource* shaderSources;
|
ShaderSource* shaderSources;
|
||||||
std::set<Shader*> shaders;
|
|
||||||
std::vector<unsigned int> geometryFlagList;
|
|
||||||
std::vector<unsigned int> lightFlagList;
|
|
||||||
const FrameBuffer* renderTarget;
|
const FrameBuffer* renderTarget;
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
bool isWireframe;
|
|
||||||
bool clearBeforeDrawing;
|
bool clearBeforeDrawing;
|
||||||
|
|
||||||
void lightPass(Camera* myCamera, Scene* scene, Light* light);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FORWARDMODULE_H
|
#endif // FORWARDMODULE_H
|
||||||
|
@ -28,7 +28,7 @@ Light::Light()
|
|||||||
initPointLight();
|
initPointLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::initAmbientLight(glm::vec3 lightColor = glm::vec3(0.1f))
|
void Light::initAmbientLight(glm::vec3 lightColor)
|
||||||
{
|
{
|
||||||
type = AMBIENT;
|
type = AMBIENT;
|
||||||
position = glm::vec3(0);
|
position = glm::vec3(0);
|
||||||
@ -99,10 +99,8 @@ void Light::initShadowMap(int resWidth, int resHeight, glm::vec3 dim)
|
|||||||
ShaderSource source;
|
ShaderSource source;
|
||||||
source.setSource(shadowVertSource, ShaderSource::VERTEX);
|
source.setSource(shadowVertSource, ShaderSource::VERTEX);
|
||||||
source.setSource(shadowFragSource, ShaderSource::FRAGMENT);
|
source.setSource(shadowFragSource, ShaderSource::FRAGMENT);
|
||||||
std::vector<const char*> defines;
|
shaders[0] = source.compile(Mesh::MESH_3D, getFlags());
|
||||||
shaders[0] = source.compile(defines.size(), defines.data());
|
shaders[1] = source.compile(Mesh::MESH_3D & Mesh::MATERIAL_ALPHA_MASK, getFlags());
|
||||||
defines.push_back("ALPHA_MASK");
|
|
||||||
shaders[1] = source.compile(defines.size(), defines.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Light::generateShadowMap(Scene* scene)
|
void Light::generateShadowMap(Scene* scene)
|
||||||
@ -119,26 +117,14 @@ void Light::generateShadowMap(Scene* scene)
|
|||||||
geometryIt->isValid(); geometryIt->next())
|
geometryIt->isValid(); geometryIt->next())
|
||||||
{
|
{
|
||||||
GeometryNode* node = geometryIt->getItem();
|
GeometryNode* node = geometryIt->getItem();
|
||||||
Material* mat = node->mesh->material;
|
if(node->mesh->getFlags() & Mesh::MESH_SHADOWED)
|
||||||
if(((PhongMaterial*)mat)->castShadow)
|
|
||||||
{
|
{
|
||||||
// compute matrix attributes
|
// compute matrix attributes
|
||||||
glm::mat4 lightMVP = getProjectionMatrix() * (getViewMatrix() * node->modelMatrix);
|
glm::mat4 lightMVP = getProjectionMatrix() * (getViewMatrix() * node->modelMatrix);
|
||||||
if(mat->getFlags() & ALPHA_MASK_FLAG)
|
int hasAlpha = (node->mesh->getFlags() & Mesh::MATERIAL_ALPHA_MASK) > 0;
|
||||||
{
|
shaders[hasAlpha]->bind();
|
||||||
PhongMaterial* pmat = (PhongMaterial*)mat;
|
shaders[hasAlpha]->bindMat4(shaders[hasAlpha]->getLocation("MVP"), lightMVP);
|
||||||
shaders[1]->bind();
|
node->mesh->draw(shaders[hasAlpha], false, hasAlpha, false);
|
||||||
pmat->alpha_mask->bind(ALPHA_MASK);
|
|
||||||
shaders[1]->bindMat4(shaders[1]->getLocation("MVP"), lightMVP);
|
|
||||||
shaders[1]->bindInteger(shaders[1]->getLocation("alphaMask"), ALPHA_MASK);
|
|
||||||
node->mesh->draw(shaders[1], false, true, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shaders[0]->bind();
|
|
||||||
shaders[0]->bindMat4(shaders[1]->getLocation("MVP"), lightMVP);
|
|
||||||
node->mesh->draw(shaders[0], false, false, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
@ -158,7 +144,7 @@ void Light::setPosition(glm::vec3 new_pos)
|
|||||||
unsigned int Light::getFlags()
|
unsigned int Light::getFlags()
|
||||||
{
|
{
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
switch(l->getType())
|
switch(type)
|
||||||
{
|
{
|
||||||
case AMBIENT :
|
case AMBIENT :
|
||||||
flags = 1 << AMBIENT_FLAG;
|
flags = 1 << AMBIENT_FLAG;
|
||||||
@ -173,7 +159,7 @@ unsigned int Light::getFlags()
|
|||||||
flags = 1 << SPOT_FLAG;
|
flags = 1 << SPOT_FLAG;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(l->isShadowCaster())
|
if(shadowCaster)
|
||||||
flags |= 1 << SHADOWMAP_FLAG;
|
flags |= 1 << SHADOWMAP_FLAG;
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
POINT_FLAG,
|
POINT_FLAG,
|
||||||
SPOT_FLAG,
|
SPOT_FLAG,
|
||||||
SHADOWMAP_FLAG,
|
SHADOWMAP_FLAG,
|
||||||
NB_LIGHT_FLAGS
|
NB_FLAGS
|
||||||
};
|
};
|
||||||
static const char* flagStr[];
|
static const char* flagStr[];
|
||||||
static const glm::mat4 biasMatrix;
|
static const glm::mat4 biasMatrix;
|
||||||
|
16
src/mesh.cpp
16
src/mesh.cpp
@ -17,6 +17,7 @@ const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
|
|||||||
|
|
||||||
"TANGENT_SPACE",
|
"TANGENT_SPACE",
|
||||||
"BILLBOARD",
|
"BILLBOARD",
|
||||||
|
"SHADOWED"
|
||||||
|
|
||||||
"COLOR_TEXTURE",
|
"COLOR_TEXTURE",
|
||||||
"ALPHA_MASK",
|
"ALPHA_MASK",
|
||||||
@ -34,6 +35,7 @@ Mesh::Mesh() :
|
|||||||
material(NULL),
|
material(NULL),
|
||||||
isDoubleSided(false),
|
isDoubleSided(false),
|
||||||
isBillboard(false),
|
isBillboard(false),
|
||||||
|
isShadowCaster(true),
|
||||||
depth(0),
|
depth(0),
|
||||||
vao(0),
|
vao(0),
|
||||||
primitive_type(GL_TRIANGLES)
|
primitive_type(GL_TRIANGLES)
|
||||||
@ -74,21 +76,21 @@ void Mesh::initGL()
|
|||||||
// init positions VBO
|
// init positions VBO
|
||||||
if(!positions3D.empty())
|
if(!positions3D.empty())
|
||||||
{
|
{
|
||||||
b = new Buffer(positions3D, Buffer::VBO);
|
b = new TBuffer(positions3D, TBuffer::VBO);
|
||||||
b->setVertexAttrib(0, 3);
|
b->setVertexAttrib(0, 3);
|
||||||
addBuffer(b, POSITION_BUFFER);
|
addBuffer(b, POSITION_BUFFER);
|
||||||
|
|
||||||
// init normals vbo
|
// init normals vbo
|
||||||
if(!normals.empty())
|
if(!normals.empty())
|
||||||
{
|
{
|
||||||
b = new Buffer(normals, Buffer::VBO);
|
b = new TBuffer(normals, TBuffer::VBO);
|
||||||
b->setVertexAttrib(1, 3);
|
b->setVertexAttrib(1, 3);
|
||||||
addBuffer(b, NORMAL_BUFFER);
|
addBuffer(b, NORMAL_BUFFER);
|
||||||
}
|
}
|
||||||
// init tangents vbo
|
// init tangents vbo
|
||||||
if(!tangents.empty())
|
if(!tangents.empty())
|
||||||
{
|
{
|
||||||
b = new Buffer(tangents, Buffer::VBO);
|
b = new TBuffer(tangents, TBuffer::VBO);
|
||||||
b->setVertexAttrib(3, 3);
|
b->setVertexAttrib(3, 3);
|
||||||
b->setVertexAttrib(4, 3);
|
b->setVertexAttrib(4, 3);
|
||||||
addBuffer(b, TANGENT_BUFFER);
|
addBuffer(b, TANGENT_BUFFER);
|
||||||
@ -96,7 +98,7 @@ void Mesh::initGL()
|
|||||||
}
|
}
|
||||||
else if(!positions2D.empty())
|
else if(!positions2D.empty())
|
||||||
{
|
{
|
||||||
b = new Buffer(positions2D, Buffer::VBO);
|
b = new TBuffer(positions2D, TBuffer::VBO);
|
||||||
b->setVertexAttrib(0, 2);
|
b->setVertexAttrib(0, 2);
|
||||||
addBuffer(b, POSITION_BUFFER);
|
addBuffer(b, POSITION_BUFFER);
|
||||||
}
|
}
|
||||||
@ -108,7 +110,7 @@ void Mesh::initGL()
|
|||||||
// init texCoords vbo
|
// init texCoords vbo
|
||||||
if(!texCoords.empty())
|
if(!texCoords.empty())
|
||||||
{
|
{
|
||||||
b = new Buffer(texCoords, Buffer::VBO);
|
b = new TBuffer(texCoords, TBuffer::VBO);
|
||||||
b->setVertexAttrib(2, 2);
|
b->setVertexAttrib(2, 2);
|
||||||
addBuffer(b, TEXCOORD_BUFFER);
|
addBuffer(b, TEXCOORD_BUFFER);
|
||||||
}
|
}
|
||||||
@ -116,7 +118,7 @@ void Mesh::initGL()
|
|||||||
// init instances vbo
|
// init instances vbo
|
||||||
if(!instances_offsets.empty())
|
if(!instances_offsets.empty())
|
||||||
{
|
{
|
||||||
b = new Buffer(instances_offsets, Buffer::VBO);
|
b = new TBuffer(instances_offsets, TBuffer::VBO);
|
||||||
b->setVertexAttrib(5, 3, 0, 1);
|
b->setVertexAttrib(5, 3, 0, 1);
|
||||||
addBuffer(b, INSTANCE_BUFFER);
|
addBuffer(b, INSTANCE_BUFFER);
|
||||||
}
|
}
|
||||||
@ -124,7 +126,7 @@ void Mesh::initGL()
|
|||||||
// init EBO
|
// init EBO
|
||||||
if(!indices.empty())
|
if(!indices.empty())
|
||||||
{
|
{
|
||||||
b = new Buffer(indices, Buffer::EBO);
|
b = new TBuffer(indices, TBuffer::EBO);
|
||||||
addBuffer(b, INDICES_BUFFER);
|
addBuffer(b, INDICES_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
// 3D Geometric properties
|
// 3D Geometric properties
|
||||||
MESH_TANGENT_SPACE,
|
MESH_TANGENT_SPACE,
|
||||||
MESH_BILLBOARD,
|
MESH_BILLBOARD,
|
||||||
|
MESH_SHADOWED,
|
||||||
|
|
||||||
// simple material (no lighting)
|
// simple material (no lighting)
|
||||||
MATERIAL_COLOR_TEXTURE,
|
MATERIAL_COLOR_TEXTURE,
|
||||||
@ -146,6 +147,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setIsBillboard(bool val) {isBillboard = val;}
|
void setIsBillboard(bool val) {isBillboard = val;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief setIsShadowCaster allows to enable or disable,
|
||||||
|
* rendering of this mesh in the shadowmaps
|
||||||
|
*/
|
||||||
|
void setIsShadowCaster(bool val) {isShadowCaster = val;}
|
||||||
|
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
/* 3D MESH TOOLS */
|
/* 3D MESH TOOLS */
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
@ -196,6 +203,7 @@ protected:
|
|||||||
Material* material;
|
Material* material;
|
||||||
bool isDoubleSided;
|
bool isDoubleSided;
|
||||||
bool isBillboard;
|
bool isBillboard;
|
||||||
|
bool isShadowCaster;
|
||||||
float depth;
|
float depth;
|
||||||
|
|
||||||
GLenum primitive_type;
|
GLenum primitive_type;
|
||||||
|
@ -9,16 +9,6 @@ class Texture;
|
|||||||
class PhongMaterial : public Material
|
class PhongMaterial : public Material
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
enum TextureSlots
|
|
||||||
{
|
|
||||||
DIFFUSE_SLOT,
|
|
||||||
AMBIENT_SLOT,
|
|
||||||
NORMALS_SLOT,
|
|
||||||
SPECULAR_SLOT,
|
|
||||||
ALPHA_SLOT,
|
|
||||||
NB_PHONG_SLOTS
|
|
||||||
};
|
|
||||||
|
|
||||||
glm::vec3 ambient;
|
glm::vec3 ambient;
|
||||||
glm::vec3 diffuse;
|
glm::vec3 diffuse;
|
||||||
glm::vec3 specular;
|
glm::vec3 specular;
|
||||||
@ -31,6 +21,15 @@ private:
|
|||||||
Texture* alpha_mask;
|
Texture* alpha_mask;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum TextureSlots
|
||||||
|
{
|
||||||
|
DIFFUSE_SLOT,
|
||||||
|
AMBIENT_SLOT,
|
||||||
|
NORMALS_SLOT,
|
||||||
|
SPECULAR_SLOT,
|
||||||
|
ALPHA_SLOT,
|
||||||
|
NB_PHONG_SLOTS
|
||||||
|
};
|
||||||
|
|
||||||
PhongMaterial() :
|
PhongMaterial() :
|
||||||
ambient(0),
|
ambient(0),
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
|
#include "light.h"
|
||||||
|
|
||||||
ShaderSource::ShaderSource()
|
ShaderSource::ShaderSource()
|
||||||
{
|
{
|
||||||
@ -31,11 +32,19 @@ void ShaderSource::setSource(const char *source, SourceType type)
|
|||||||
Shader* ShaderSource::compile(unsigned int geomFlags, unsigned int lightFlags)
|
Shader* ShaderSource::compile(unsigned int geomFlags, unsigned int lightFlags)
|
||||||
{
|
{
|
||||||
std::string header = "#version 330 core";
|
std::string header = "#version 330 core";
|
||||||
for(int i=0; i<NB_FLAGS; ++i)
|
|
||||||
|
for(int i=0; i<Mesh::NB_FLAGS; ++i)
|
||||||
{
|
{
|
||||||
if((geomFlags >> i) & 0x00000001)
|
if((geomFlags >> i) & 0x00000001)
|
||||||
header += "\n#define "+std::string(flagStr[i]);
|
header += "\n#define "+std::string(Mesh::flagStr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<Light::NB_FLAGS; ++i)
|
||||||
|
{
|
||||||
|
if((lightFlags >> i) & 0x00000001)
|
||||||
|
header += "\n#define "+std::string(Light::flagStr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
header += "\n#line 1\n";
|
header += "\n#line 1\n";
|
||||||
|
|
||||||
if(sources[VERTEX] == NULL || sources[FRAGMENT] == NULL)
|
if(sources[VERTEX] == NULL || sources[FRAGMENT] == NULL)
|
||||||
|
@ -21,7 +21,7 @@ public:
|
|||||||
|
|
||||||
void setSource(const char *source, SourceType type);
|
void setSource(const char *source, SourceType type);
|
||||||
|
|
||||||
Shader* compile(int nbDefines = 0, const char** defines = NULL);
|
Shader* compile(unsigned int geomFlags, unsigned int lightFlags);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string* sources[NB_TYPES];
|
std::string* sources[NB_TYPES];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user