added forward module, and modifications to materials

This commit is contained in:
anselme 2015-11-29 19:31:57 +01:00
parent 09afb90dd4
commit 2381318a09
14 changed files with 408 additions and 55 deletions

View File

@ -12,8 +12,6 @@ else(WIN32)
endif(WIN32)
set(LIB_SRC_LIST
asciientity.cpp
asciimodule.cpp
framebuffer.cpp
gbuffer.cpp
lights.cpp

84
forward.frag Normal file
View File

@ -0,0 +1,84 @@
#version 330 core
uniform vec3 lightColor;
uniform float materialNs;
uniform int objectId;
#ifdef ALPHA_MASK
uniform sampler2D alphaMask;
#endif
#ifdef AMBIENT_TEXTURE
uniform sampler2D ambientTexture;
#else
uniform vec3 materialKa;
#endif
#ifdef DIFFUSE_TEXTURE
uniform sampler2D diffuseTexture;
#else
uniform vec3 materialKd;
#endif
#ifdef SPECULAR_TEXTURE
uniform sampler2D specularTexture;
#else
uniform vec3 materialKs;
#endif
#ifdef NORMAL_MAP
uniform sampler2D normalMap;
in mat3 tangentSpace;
#else
in vec3 varNormal;
#endif
in vec2 varTexCoord;
in vec3 lightDirInView;
in vec3 halfVecInView;
layout(location = 0)out vec4 outColor;
vec3 phongLighting(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 normal, in vec3 lightDir, in vec3 halfVec){
float diffuseComponent = max(dot(normal, lightDir), 0);
float specularComponent = max(dot(halfVec, normal), 0);
return color*diffuseComponent*(kd+ks*pow(specularComponent, ns));
}
void main(void) {
#ifdef
#ifdef ALPHA_MASK
if(texture(alphaMask, varTexCoord).r < 0.5)
discard;
#endif
#ifdef NORMAL_MAP
vec3 normal = normalize(texture(normalMap, varTexCoord).xyz * tangentSpace);
#else
vec3 normal = normalize(varNormal);
#endif
#ifdef AMBIENT_TEXTURE
vec3 ambient = texture(ambientTexture, varTexCoord).rgb;
#else
vec3 ambient = materialKa;
#endif
#ifdef DIFFUSE_TEXTURE
vec3 diffuse = texture(diffuseTexture, varTexCoord).rgb;
#else
vec3 diffuse = materialKd;
#endif
#ifdef SPECULAR_TEXTURE
vec3 specular = texture(specularTexture, varTexCoord).rgb;
#else
vec3 specular = materialKs;
#endif
vec3 light = phongLighting(diffuse, specular, materialNs, lightColor, normal, lightDirInView, halfVecInView);
outColor = vec4(ambient + light, 1);
}

61
forward.vert Normal file
View File

@ -0,0 +1,61 @@
#version 330 core
uniform mat4 modelViewMatrix;
uniform mat4 MVP;
uniform mat4 viewMatrix;
uniform mat3 normalMatrix;
#ifdef NORMAL_MAP
out mat3 tangentSpace;
#else
out vec3 varNormal;
#endif
out vec2 varTexCoord;
#ifdef DIRECTIONNAL_LIGHT
uniform vec3 dirLight;
#endif
#ifdef POINT_LIGHT
uniform vec3 pointLight;
#endif
layout(location = 0)in vec3 inPosition;
layout(location = 1)in vec2 inTexCoord;
layout(location = 2)in vec3 inNormal;
#ifdef NORMAL_MAP
layout(location = 3)in vec3 inTangent;
layout(location = 4)in vec3 inBinormal;
#endif
#ifndef AMBIENT_LIGHT
out vec3 lightDirInView;
out vec3 halfVecInView;
#endif
void main(void) {
vec3 posInView = vec3(modelViewMatrix*vec4(inPosition, 1.0));
#ifdef DIRECTIONNAL_LIGHT
lightDirInView = normalize(mat3(viewMatrix)*dirLight);
halfVecInView = normalize(lightDirInView - normalize(posInView));
#endif
#ifdef POINT_LIGHT
lightDirInView = normalize(mat3(viewMatrix)*pointLight - posInView);
halfVecInView = normalize(lightDirInView - posInView);
#endif
#ifdef NORMAL_MAP
tangentSpace = mat3(normalize(normalMatrix*inNormal),
normalize(normalMatrix*inTangent),
normalize(normalMatrix*inBinormal));
#else
varNormal = normalize(normalMatrix*inNormal);
#endif
varTexCoord = inTexCoord.xy;
gl_Position = MVP * vec4(inPosition, 1.0);
}

View File

@ -2,19 +2,86 @@
#include "scene.h"
#include "phongentity.h"
#include "mesh.h"
#include "material.h"
#include "shader.h"
#include "light.h"
#include <glm/ext.hpp>
const char* const ForwardModule::flagStr[ForwardModule::NB_FLAGS] =
const char* const ForwardModule::flagStr[] =
{
"NORMAL_MAP",
"AMBIENT_TEXTURE",
"DIFFUSE_TEXTURE",
"SPECULAR_TEXTURE",
"ALPHA_MASK"
};
const char* const ForwardModule::lightStr[] =
{
"AMBIENT_LIGHT",
"DIRECTIONNAL_LIGHT",
"POINT_LIGHT"
};
void ForwardModule::renderGL(Camera* myCamera, Scene* scene)
{
// render ambient lighting
lightPass(NULL, myCamera, scene, AMBIENT_LIGHT);
// render directionnal lighting and point lighting
for(SceneIterator<Light*>* lightIt = scene->getLights();
lightIt->isValid(); lightIt->next())
{
Light* l = lightIt->getItem();
unsigned int type = l->isDirectionnal() ? DIRECTIONNAL_LIGHT : POINT_LIGHT;
lightPass(l, myCamera, scene, type);
}
}
void ForwardModule::lightPass(Light* light, Camera* myCamera, Scene* scene, unsigned int type)
{
// loop over all types of geometry
for(int i=0; i<flags.size(); ++i)
{
// bind shader
Shader* shader = shaders[i*NB_LIGHT_FLAGS + type];
shader->bind();
// bind light attributes
if(type == DIRECTIONNAL_LIGHT)
shader->bindVec3(shader->getLocation("dirLight"), light->getDir());
if(type == POINT_LIGHT)
shader->bindVec3(shader->getLocation("pointLight"), light->getPos());
glm::vec3 color;
if(type == AMBIENT_LIGHT)
color = glm::vec3(0.1f); // add attribute, and setter for ambient lighting
else
color = light->getColor();
shader->bindVec3(shader->getLocation("lightColor"), color);
for(SceneIterator<PhongEntity*>* entityIt = scene->getGeometry();
entityIt->isValid(); entityIt->next())
{
// compute matrix attributes
PhongEntity* entity = entityIt->getItem();
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * entity->modelMatrix;
glm::mat4 mvp = myCamera->getProjectionMatrix() * modelViewMatrix;
glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix));
// loop over material groups
for(int j=0; j<entity->getMesh()->indiceGroups.size(); ++j)
{
Material* mat = entity->getMesh()->indiceGroups[i].material;
if(mat->getFlags() == flags[i])
{
// bind material attributes
mat->bindAttributes(shader);
shader->bindMatrix(shader->getLocation("viewMatrix"), myCamera->getViewMatrix());
shader->bindMatrix(shader->getLocation("modelViewMatrix"), modelViewMatrix);
shader->bindMatrix(shader->getLocation("normalMatrix"), normalMatrix);
shader->bindMatrix(shader->getLocation("MVP"), mvp);
// draw geometry
entity->drawGroup(j);
}
}
}
}
}
// modern opengl methods
@ -26,13 +93,45 @@ void ForwardModule::setShaderSource(ShaderSource* source)
void ForwardModule::compileShaders(Scene* scene)
{
int size = 1 << NB_FLAGS;
bool geometryFlags[size];
for(int i=0; i<size; ++i)
geometryFlags[i] = false;
for(SceneIterator<PhongEntity*>* EntityIt = scene->getGeometry();
EntityIt->isValid(); EntityIt->next())
{
Mesh* m = EntityIt->getItem()->getMesh();
for(Mesh::Group &g : m->indiceGroups)
{
geometryFlags[g.material->getFlags()] = true;
}
for(int i=0; i<size; ++i)
{
if(geometryFlags[i])
{
std::vector<const char*> defines;
defines.push_back(lightStr[AMBIENT_LIGHT]);
if(i & NORMAL_MAP_FLAG)
defines.push_back(flagStr[NORMAL_MAP]);
if(i & AMBIENT_TEXTURE_FLAG)
defines.push_back(flagStr[AMBIENT_TEXTURE]);
if(i & DIFFUSE_TEXTURE_FLAG)
defines.push_back(flagStr[DIFFUSE_TEXTURE]);
if(i & SPECULAR_TEXTURE_FLAG)
defines.push_back(flagStr[SPECULAR_TEXTURE]);
// for each geometry flag, 3 shaders are compiled, one for each kind of lighting
flags.push_back(i);
// ambient
shaders.push_back(shaderSources->compile(defines.size(), defines.data()));
// directionnal
defines[0] = lightStr[DIRECTIONNAL_LIGHT];
shaders.push_back(shaderSources->compile(defines.size(), defines.data()));
// point
defines[0] = lightStr[POINT_LIGHT];
shaders.push_back(shaderSources->compile(defines.size(), defines.data()));
}
}
}

View File

@ -6,7 +6,9 @@
#include <cstddef>
#include <glew/glew.h>
#include "shadersource.h"
#include "material.h"
class Light;
class Scene;
class PhongEntity;
@ -25,17 +27,22 @@ public:
private:
enum {
NORMAL_MAP,
DIFFUSE_TEXTURE,
SPECULAR_TEXTURE,
ALPHA_MASK,
NB_FLAGS
// light flags
AMBIENT_LIGHT,
DIRECTIONNAL_LIGHT,
POINT_LIGHT,
// count
NB_LIGHT_FLAGS
};
static const char* const flagStr[NB_FLAGS];
static const char* const lightStr[NB_LIGHT_FLAGS];
ShaderSource* shaderSources;
Shader* shaders[1 << NB_FLAGS];
std::vector<Shader*> shaders;
std::vector<unsigned int> flags;
void lightPass(Light* light, Camera* myCamera, Scene* scene, unsigned int type);
};
#endif // FORWARDMODULE_H

View File

@ -7,14 +7,21 @@ Light::Light()
void Light::initDirectionnalLight(glm::vec3 dir, glm::vec3 lightColor, bool isShadowCaster)
{
initSpotLight(glm::vec3(0), dir, -1, lightColor, isShadowCaster);
direction = dir;
color = lightColor;
shadowCaster = isShadowCaster;
isDir = true;
}
void Light::initPointLight(glm::vec3 pos, glm::vec3 lightColor, bool isShadowCaster)
{
initSpotLight(pos, glm::vec3(0), 360, lightColor, isShadowCaster);
position = pos;
angle = 360;
color = lightColor;
shadowCaster = isShadowCaster;
isDir = false;
}
/*
void Light::initSpotLight(glm::vec3 pos, glm::vec3 dir, float spotAngle, glm::vec3 lightColor, bool isShadowCaster)
{
position = pos;
@ -22,4 +29,10 @@ void Light::initSpotLight(glm::vec3 pos, glm::vec3 dir, float spotAngle, glm::ve
angle = spotAngle;
color = lightColor;
shadowCaster = isShadowCaster;
isDir = false;
}
*/
bool Light::isDirectionnal()
{
return isDir;
}

12
light.h
View File

@ -9,9 +9,11 @@ private:
// standard attributes
glm::vec3 position;
glm::vec3 direction;
float angle;
float angle; // spotlight not supported yet
glm::vec3 color;
bool isDir;
// shadowmap attributes
bool shadowCaster;
// Shadowmap fbo
@ -19,7 +21,13 @@ public:
Light();
void initDirectionnalLight(glm::vec3 dir = glm::vec3(1, 0, 0), glm::vec3 lightColor = glm::vec3(1), bool isShadowCaster = false);
void initPointLight(glm::vec3 pos = glm::vec3(0), glm::vec3 lightColor = glm::vec3(1), bool isShadowCaster = false);
void initSpotLight(glm::vec3 pos = glm::vec3(0), glm::vec3 dir = glm::vec3(1, 0, 0), float spotAngle = 360, glm::vec3 lightColor = glm::vec3(1), bool isShadowCaster = false);
// spotlight not supported yet
//void initSpotLight(glm::vec3 pos = glm::vec3(0), glm::vec3 dir = glm::vec3(1, 0, 0), float spotAngle = 360, glm::vec3 lightColor = glm::vec3(1), bool isShadowCaster = false);
bool isDirectionnal();
glm::vec3 getDir() {return direction;}
glm::vec3 getPos() {return position;}
glm::vec3 getColor() {return color;}
};
#endif // LIGHT_H

View File

@ -1,28 +1,39 @@
#ifndef MATERIAL_H
#define MATERIAL_H
#include "shader.h"
#include "glm/fwd.hpp"
enum {
// Geometry Flags
NORMAL_MAP,
AMBIENT_TEXTURE,
DIFFUSE_TEXTURE,
SPECULAR_TEXTURE,
ALPHA_MASK,
NB_FLAGS
};
enum {
// Geometry Flags
NORMAL_MAP = 1 << 0,
DIFFUSE_TEXTURE = 1 << 1,
SPECULAR_TEXTURE = 1 << 2,
ALPHA_MASK = 1 << 3,
NORMAL_MAP_FLAG = 1 << NORMAL_MAP,
AMBIENT_TEXTURE_FLAG = 1 << AMBIENT_TEXTURE,
DIFFUSE_TEXTURE_FLAG = 1 << DIFFUSE_TEXTURE,
SPECULAR_TEXTURE_FLAG = 1 << SPECULAR_TEXTURE,
ALPHA_MASK_FLAG = 1 << ALPHA_MASK,
};
class Shader;
class Material
{
public:
Material(Shader* myShader = NULL) : shader(myShader) {}
Shader* getShader() {return shader;}
/**
* deprecated, you should use bindAttributes(Shader*) instead
*/
virtual void bindAttributes() = 0;
virtual void bindAttributes(Shader*) = 0;
virtual unsigned int getFlags() = 0;
protected:
Shader* shader;
};
#endif // MATERIAL_H

View File

@ -33,7 +33,7 @@ void PhongEntity::modernDraw(const glm::mat4 &viewMatrix, const glm::mat4 &proje
glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix));
for(int i=0; i<mesh->indiceGroups.size(); ++i)
{
Material* mat = mesh->indiceGroups[i].material;
PhongMaterial* mat = (PhongMaterial*)mesh->indiceGroups[i].material;
mat->bindAttributes();
Shader* shader = mat->getShader();
shader->bindMatrix(shader->getLocation("viewMatrix"), viewMatrix);

View File

@ -31,7 +31,6 @@ protected:
GLuint* vbo;
void modernInit(bool isDynamic);
void drawGroup(int groupId);
void modernDraw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights);
// old opengl :
@ -50,6 +49,7 @@ public:
PhongEntity(Mesh* myMesh);
void draw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights);
void drawGroup(int groupId); // temporarily public
void initGL(bool isDynamic = false);
void destroyGL();

View File

@ -3,10 +3,9 @@
#include "phongmodule.h"
#include "sparrowrenderer.h"
#include "glassert.h"
#include "shader.h"
#include <glm/ext.hpp>
#define TEX_ID 0
void PhongMaterial::updateShader()
{
shader = PhongModule::getShader(diffuse_texture == NULL ? PhongModule::PHONG_COLOR : PhongModule::PHONG_TEXTURE);
@ -17,27 +16,82 @@ void PhongMaterial::bindAttributes()
if(SparrowRenderer::isModernOpenGLAvailable())
{
shader->bind();
shader->bindVec3(shader->getLocation("materialAmbient"), emission);
shader->bindVec3(shader->getLocation("materialAmbient"), ambient);
shader->bindVec3(shader->getLocation("materialKd"), diffuse);
shader->bindVec3(shader->getLocation("materialKs"), specular);
shader->bindFloat(shader->getLocation("materialNs"), shininess);
if(diffuse_texture != NULL)
{
diffuse_texture->bind(TEX_ID);
shader->bindInteger(shader->getLocation("baseTexture"), TEX_ID);
diffuse_texture->bind(DIFFUSE_TEXTURE);
shader->bindInteger(shader->getLocation("baseTexture"), DIFFUSE_TEXTURE);
}
}
else
{
glAssert(glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, glm::value_ptr(glm::vec4(emission, 1))));
glAssert(glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, glm::value_ptr(glm::vec4(ambient, 1))));
glAssert(glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glm::value_ptr(glm::vec4(diffuse, 1))));
glAssert(glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, glm::value_ptr(glm::vec4(specular, 1))));
glAssert(glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess));
if(diffuse_texture != NULL)
diffuse_texture->bind(TEX_ID);
diffuse_texture->bind(DIFFUSE_TEXTURE);
else
{
GLenum texSlot = GL_TEXTURE0+TEX_ID;
GLenum texSlot = GL_TEXTURE0+DIFFUSE_TEXTURE;
glAssert(glActiveTexture(texSlot));
glAssert(glBindTexture(GL_TEXTURE_2D, 0));
}
}
}
void PhongMaterial::bindAttributes(Shader* myShader)
{
if(SparrowRenderer::isModernOpenGLAvailable())
{
// TODO store the attributes location (in the shader class maybe)
myShader->bindFloat(myShader->getLocation("materialNs"), shininess);
if(normal_map != NULL)
{
normal_map->bind(NORMAL_MAP);
myShader->bindInteger(myShader->getLocation("normalMap"), NORMAL_MAP);
}
if(ambient_texture != NULL)
{
ambient_texture->bind(AMBIENT_TEXTURE);
myShader->bindInteger(myShader->getLocation("ambientTexture"), AMBIENT_TEXTURE);
}
else
myShader->bindVec3(myShader->getLocation("materialKa"), ambient);
if(diffuse_texture != NULL)
{
diffuse_texture->bind(DIFFUSE_TEXTURE);
myShader->bindInteger(myShader->getLocation("diffuseTexture"), DIFFUSE_TEXTURE);
}
else
myShader->bindVec3(myShader->getLocation("materialKd"), diffuse);
if(specular_texture != NULL)
{
specular_texture->bind(SPECULAR_TEXTURE);
myShader->bindInteger(myShader->getLocation("specularTexture"), SPECULAR_TEXTURE);
}
else
myShader->bindVec3(myShader->getLocation("materialKs"), specular);
}
else
{
// Crappy rendering code
glAssert(glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, glm::value_ptr(glm::vec4(ambient, 1))));
glAssert(glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glm::value_ptr(glm::vec4(diffuse, 1))));
glAssert(glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, glm::value_ptr(glm::vec4(specular, 1))));
glAssert(glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess));
if(diffuse_texture != NULL)
diffuse_texture->bind(DIFFUSE_TEXTURE);
else
{
GLenum texSlot = GL_TEXTURE0+DIFFUSE_TEXTURE;
glAssert(glActiveTexture(texSlot));
glAssert(glBindTexture(GL_TEXTURE_2D, 0));
}
@ -48,33 +102,38 @@ unsigned int PhongMaterial::getFlags()
{
unsigned int flags = 0;
if(normal_map != NULL)
flags |= NORMAL_MAP;
flags |= NORMAL_MAP_FLAG;
if(ambient_texture != NULL)
flags |= AMBIENT_TEXTURE_FLAG;
if(diffuse_texture != NULL)
flags |= DIFFUSE_TEXTURE;
flags |= DIFFUSE_TEXTURE_FLAG;
if(specular_texture != NULL)
flags |= SPECULAR_TEXTURE;
flags |= SPECULAR_TEXTURE_FLAG;
return flags;
}
void PhongMaterial::setTexture(Texture* myTexture)
{
setDiffuseTexture(myTexture);
updateShader();
}
void PhongMaterial::setAmbientTexture(Texture* myTexture)
{
ambient_texture = myTexture;
}
void PhongMaterial::setDiffuseTexture(Texture* myTexture)
{
diffuse_texture = myTexture;
updateShader();
}
void PhongMaterial::setSpecularTexture(Texture* myTexture)
{
specular_texture = myTexture;
updateShader();
}
void PhongMaterial::setNormalMap(Texture* myNormalMap)
{
normal_map = myNormalMap;
updateShader();
}

View File

@ -9,48 +9,62 @@ class Texture;
class PhongMaterial : public Material
{
public:
glm::vec3 emission;
glm::vec3 ambient;
glm::vec3 diffuse;
glm::vec3 specular;
float shininess;
Texture* ambient_texture;
Texture* diffuse_texture;
Texture* specular_texture;
Texture* normal_map;
PhongMaterial() :
emission(0),
ambient(0),
diffuse(0.5f),
specular(0.5f),
shininess(10),
ambient_texture(NULL),
diffuse_texture(NULL),
specular_texture(NULL),
normal_map(NULL)
{
updateShader();
}
PhongMaterial(glm::vec3 myKd, glm::vec3 myKs, float myNs) :
emission(0),
ambient(0),
diffuse(myKd),
specular(myKs),
shininess(myNs),
diffuse_texture(NULL),
ambient_texture(NULL),
diffuse_texture(NULL),
specular_texture(NULL),
normal_map(NULL)
{
updateShader();
}
virtual void bindAttributes();
virtual unsigned int getFlags();
void crappyBindAttributes();
// deprecated, you should use setDiffuseTexture instead
virtual void bindAttributes();
virtual void bindAttributes(Shader* myShader);
virtual unsigned int getFlags();
Shader* getShader() {return shader;}
/**
* deprecated, you should use setDiffuseTexture instead
*/
void setTexture(Texture* myTexture);
void setAmbientTexture(Texture* myTexture);
void setDiffuseTexture(Texture* myTexture);
void setSpecularTexture(Texture* myTexture);
void setNormalMap(Texture* myNormalMap);
void updateShader();
private:
Shader* shader;
};
#endif // PHONGMATERIAL_H

View File

@ -46,7 +46,9 @@ class ArrayScene : public Scene
std::vector<Light*> lights;
std::vector<PhongEntity*> entities;
public:
void clearScene() {lights.clear(); entities.clear();}
void clearLights() {lights.clear();}
void clearEntities() {entities.clear();}
void clearScene() {clearLights(); clearEntities();}
void addEntity(PhongEntity* myEntity) {entities.push_back(myEntity);}
void addLight(Light* myLight) {lights.push_back(myLight);}

View File

@ -22,9 +22,6 @@ layout(location = 3)in vec3 inTangent;
layout(location = 4)in vec3 inBinormal;
#endif
out vec3 varNormal;
out vec2 varTexCoord;
void main(void)
{
#ifdef NORMAL_MAP