finished light and forward refactoring

This commit is contained in:
Anselme 2016-04-25 17:36:26 +02:00
parent 0273b76bdf
commit 72466f7ef7
12 changed files with 177 additions and 204 deletions

View File

@ -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)

View File

@ -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);
} }

View File

@ -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;}

View File

@ -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,50 +15,27 @@ 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)
{
for(Light *light : p.lights)
{
if(light->getFlags() & Light::AMBIENT_FLAG)
{
// render ambient lighting (opaque)
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS); glDepthFunc(GL_LESS);
glDisable(GL_BLEND); glDisable(GL_BLEND);
}
lightPass(myCamera, scene, NULL); else
{
// render directionnal lighting and point lighting // render directionnal lighting and point lighting (additive light)
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
glDepthMask(GL_FALSE); 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 Shader *shader = p.shader;
for(std::size_t i=0; i<geometryFlagList.size(); ++i)
{
std::size_t j;
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");
continue;
}
Shader* shader = shaders[i*lightFlagList.size() + j];
shader->bind(); shader->bind();
// bind light attributes
switch(light->getType()) switch(light->getType())
{ {
case Light::AMBIENT: case Light::AMBIENT:
@ -84,21 +61,13 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
break; break;
} }
unsigned int id = 2; unsigned int id = 2;
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry(); for(GeometryNode *node : p.geometry)
geometryIt->isValid(); geometryIt->next())
{ {
GeometryNode* node = geometryIt->getItem();
shader->bindUnsignedInteger(shader->getLocation("object_identifier"), id); shader->bindUnsignedInteger(shader->getLocation("object_identifier"), id);
if(node->mesh->hasInstances()) if(node->mesh->instances_offsets.empty())
id += node->mesh->instances_offsets.size();
else
++id; ++id;
Material* mat = node->mesh->material; else
unsigned int flags = mat->getFlags(); id += node->mesh->instances_offsets.size();
if(node->mesh->hasInstances())
flags |= INSTANCING_FLAG;
if(flags == geometryFlagList[i]) // if flag matches material
{
// 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()));
} }
} }
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);
} }

View File

@ -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;

View File

@ -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),

View File

@ -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)

View File

@ -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];