changed scene to hold a pipeline, renderer does not handle modules anymore, material flags are handled by the mesh
This commit is contained in:
parent
0d4914c1d7
commit
4dcef0d4e3
@ -7,22 +7,13 @@
|
||||
#include "texture.h"
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
const char* const ForwardModule::flagStr[] =
|
||||
{
|
||||
"DIFFUSE_TEXTURE",
|
||||
"AMBIENT_TEXTURE",
|
||||
"SPECULAR_TEXTURE",
|
||||
"NORMAL_MAP",
|
||||
"ALPHA_MASK",
|
||||
"INSTANCING"
|
||||
};
|
||||
|
||||
void ForwardModule::renderGL(Camera* myCamera, Scene* scene)
|
||||
{
|
||||
// bind target
|
||||
renderTarget->bindFBO();
|
||||
if(clearBeforeDrawing)
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glAssert(glViewport(0, 0, width, height));
|
||||
|
||||
// render ambient lighting
|
||||
glAssert(glEnable(GL_DEPTH_TEST));
|
||||
|
@ -23,8 +23,9 @@ public:
|
||||
clearBeforeDrawing(false)
|
||||
{}
|
||||
|
||||
void renderGL(Camera* myCamera, Scene* scene);
|
||||
bool requiresModernOpenGL() {return true;} // write some compatibility code to change that to false
|
||||
virtual void renderGL(Camera* myCamera, Scene* scene);
|
||||
virtual bool requiresModernOpenGL() {return true;}
|
||||
virtual void resize(int w, int h) {width = w; height = h;}
|
||||
|
||||
// modern opengl methods
|
||||
|
||||
@ -36,14 +37,15 @@ public:
|
||||
void setClearBeforeDrawing(bool clear) {clearBeforeDrawing = clear;}
|
||||
|
||||
private:
|
||||
static const char* const flagStr[NB_FLAGS];
|
||||
|
||||
ShaderSource* shaderSources;
|
||||
std::vector<Shader*> shaders;
|
||||
std::vector<unsigned int> geometryFlagList;
|
||||
std::vector<unsigned int> lightFlagList;
|
||||
const FrameBuffer* renderTarget;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
bool isWireframe;
|
||||
bool clearBeforeDrawing;
|
||||
|
||||
|
@ -1,34 +1,19 @@
|
||||
#ifndef MATERIAL_H
|
||||
#define MATERIAL_H
|
||||
|
||||
enum {
|
||||
// Geometry Flags
|
||||
DIFFUSE_TEXTURE, // must stay first for crappy rendering
|
||||
AMBIENT_TEXTURE,
|
||||
SPECULAR_TEXTURE,
|
||||
NORMAL_MAP,
|
||||
ALPHA_MASK,
|
||||
INSTANCING,
|
||||
NB_FLAGS
|
||||
};
|
||||
|
||||
enum {
|
||||
// Geometry Flags
|
||||
DIFFUSE_TEXTURE_FLAG = 1 << DIFFUSE_TEXTURE,
|
||||
AMBIENT_TEXTURE_FLAG = 1 << AMBIENT_TEXTURE,
|
||||
SPECULAR_TEXTURE_FLAG = 1 << SPECULAR_TEXTURE,
|
||||
NORMAL_MAP_FLAG = 1 << NORMAL_MAP,
|
||||
ALPHA_MASK_FLAG = 1 << ALPHA_MASK,
|
||||
INSTANCING_FLAG = 1 << INSTANCING
|
||||
};
|
||||
|
||||
class Shader;
|
||||
|
||||
class Material
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief bindAttributes should send the material attribute to the specified shader as a uniform
|
||||
* if the shader is NULL, we can assume that modern opengl is not available and try to apply the material differently (glMaterial)
|
||||
*/
|
||||
virtual void bindAttributes(Shader*) = 0;
|
||||
|
||||
virtual unsigned int getFlags() = 0;
|
||||
|
||||
virtual ~Material(){}
|
||||
};
|
||||
|
||||
|
104
src/mesh.cpp
104
src/mesh.cpp
@ -7,6 +7,29 @@
|
||||
|
||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||
|
||||
const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
|
||||
{
|
||||
"INDEXED",
|
||||
"TEXTURABLE",
|
||||
"INSTANCED",
|
||||
|
||||
"MESH_3D",
|
||||
"MESH_2D",
|
||||
|
||||
"TANGENT_SPACE",
|
||||
"BILLBOARD",
|
||||
|
||||
"COLOR_TEXTURE",
|
||||
"ALPHA_MASK",
|
||||
|
||||
"DIFFUSE_TEXTURE",
|
||||
"AMBIENT_TEXTURE",
|
||||
"SPECULAR_TEXTURE",
|
||||
"NORMAL_MAP",
|
||||
|
||||
"BUMP_MAP"
|
||||
};
|
||||
|
||||
Mesh::Mesh() :
|
||||
material(NULL),
|
||||
isDoubleSided(false),
|
||||
@ -39,7 +62,7 @@ void Mesh::initGL(bool isDynamic)
|
||||
|
||||
// init positions vbo
|
||||
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_BUFFER]));
|
||||
glAssert(glBufferData(GL_ARRAY_BUFFER, positions.size() * sizeof(glm::vec3), positions.data(), buffer_type));
|
||||
glAssert(glBufferData(GL_ARRAY_BUFFER, positions3D.size() * sizeof(glm::vec3), positions3D.data(), buffer_type));
|
||||
|
||||
if(hasNormals())
|
||||
{
|
||||
@ -182,6 +205,51 @@ void Mesh::endUpdateBuffer()
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
unsigned int Mesh::getFlags()
|
||||
{
|
||||
unsigned int flags = material->getFlags() << MESH_NB_FLAGS;
|
||||
|
||||
if(!indices.empty())
|
||||
flags |= 1 << MESH_INDEXED;
|
||||
if(!texCoords.empty())
|
||||
flags |= 1 << MESH_TEXTURABLE;
|
||||
if(!instances_offsets.empty())
|
||||
flags |= 1 << MESH_INSTANCED;
|
||||
|
||||
if(!positions3D.empty())
|
||||
{
|
||||
flags |= 1 << MESH_3D;
|
||||
|
||||
if(!tangents.empty())
|
||||
flags |= 1 << MESH_TANGENT_SPACE;
|
||||
if(isBillboard)
|
||||
flags |= 1 << MESH_BILLBOARD;
|
||||
}
|
||||
else
|
||||
flags |= 1 << MESH_2D;
|
||||
|
||||
|
||||
return flags;
|
||||
|
||||
// Mesh type
|
||||
MESH_3D,
|
||||
MESH_2D,
|
||||
|
||||
// 3D Geometric properties
|
||||
MESH_TANGENT_SPACE,
|
||||
MESH_BILLBOARD,
|
||||
|
||||
// simple textures properties
|
||||
MATERIAL_DIFFUSE_TEXTURE,
|
||||
MATERIAL_ALPHA_MASK,
|
||||
|
||||
// 3D phong-like materials :
|
||||
MATERIAL_AMBIENT_TEXTURE,
|
||||
MATERIAL_SPECULAR_TEXTURE,
|
||||
MATERIAL_NORMAL_MAP,
|
||||
MATERIAL_BUMP_MAP,
|
||||
}
|
||||
|
||||
struct VertexComparator
|
||||
{
|
||||
// c'est plutot crade mais j'ai pas trouve d'autre moyen pour le moment
|
||||
@ -190,12 +258,12 @@ struct VertexComparator
|
||||
|
||||
bool operator() (const int& vertId1, const int& vertId2) const
|
||||
{
|
||||
if(mesh->positions[vertId1].x != mesh->positions[vertId2].x)
|
||||
return (mesh->positions[vertId1].x < mesh->positions[vertId2].x);
|
||||
if(mesh->positions[vertId1].y != mesh->positions[vertId2].y)
|
||||
return (mesh->positions[vertId1].y < mesh->positions[vertId2].y);
|
||||
if(mesh->positions[vertId1].z != mesh->positions[vertId2].z)
|
||||
return (mesh->positions[vertId1].z < mesh->positions[vertId2].z);
|
||||
if(mesh->positions3D[vertId1].x != mesh->positions3D[vertId2].x)
|
||||
return (mesh->positions3D[vertId1].x < mesh->positions3D[vertId2].x);
|
||||
if(mesh->positions3D[vertId1].y != mesh->positions3D[vertId2].y)
|
||||
return (mesh->positions3D[vertId1].y < mesh->positions3D[vertId2].y);
|
||||
if(mesh->positions3D[vertId1].z != mesh->positions3D[vertId2].z)
|
||||
return (mesh->positions3D[vertId1].z < mesh->positions3D[vertId2].z);
|
||||
if(mesh->hasTexCoords())
|
||||
{
|
||||
if(mesh->texCoords[vertId1].x != mesh->texCoords[vertId2].x)
|
||||
@ -220,8 +288,8 @@ Mesh* VertexComparator::mesh = NULL;
|
||||
|
||||
void Mesh::mergeVertices()
|
||||
{
|
||||
bool *deleted = new bool[positions.size()];
|
||||
int *offsets = new int[positions.size()];
|
||||
bool *deleted = new bool[positions3D.size()];
|
||||
int *offsets = new int[positions3D.size()];
|
||||
std::set<int, VertexComparator> vertexSet;
|
||||
VertexComparator::setMesh(this);
|
||||
|
||||
@ -241,7 +309,7 @@ void Mesh::mergeVertices()
|
||||
}
|
||||
int offset = 0;
|
||||
int pos = 0;
|
||||
for(std::size_t i=0; i<positions.size(); ++i)
|
||||
for(std::size_t i=0; i<positions3D.size(); ++i)
|
||||
{
|
||||
if(deleted[i])
|
||||
++offset;
|
||||
@ -250,7 +318,7 @@ void Mesh::mergeVertices()
|
||||
offsets[i] = offset;
|
||||
if(offset != 0)
|
||||
{
|
||||
positions[pos] = positions[i];
|
||||
positions3D[pos] = positions3D[i];
|
||||
if(hasTexCoords())
|
||||
texCoords[pos] = texCoords[i];
|
||||
if(hasNormals())
|
||||
@ -264,7 +332,7 @@ void Mesh::mergeVertices()
|
||||
for(std::size_t i=0; i<indices.size(); ++i)
|
||||
indices[i] -= offsets[indices[i]];
|
||||
|
||||
positions.resize(positions.size()-offset);
|
||||
positions3D.resize(positions3D.size()-offset);
|
||||
if(hasTexCoords())
|
||||
texCoords.resize(texCoords.size()-offset);
|
||||
if(hasNormals())
|
||||
@ -280,14 +348,14 @@ void Mesh::mergeVertices()
|
||||
|
||||
void Mesh::computeNormals()
|
||||
{
|
||||
normals.resize(positions.size());
|
||||
normals.resize(positions3D.size());
|
||||
std::memset(normals.data(), 0, normals.size());
|
||||
for (std::size_t i=0; i < indices.size(); i += 3)
|
||||
{
|
||||
int v0 = indices[i];
|
||||
int v1 = indices[i+1];
|
||||
int v2 = indices[i+2];
|
||||
glm::vec3 n = glm::cross(positions[v1] - positions[v0], positions[v2] - positions[v0]);
|
||||
glm::vec3 n = glm::cross(positions3D[v1] - positions3D[v0], positions3D[v2] - positions3D[v0]);
|
||||
normals[v0] += n;
|
||||
normals[v1] += n;
|
||||
normals[v2] += n;
|
||||
@ -300,7 +368,7 @@ void Mesh::computeTangents()
|
||||
{
|
||||
if(!hasTexCoords())
|
||||
return;
|
||||
tangents = std::vector<Tangents>(positions.size());
|
||||
tangents = std::vector<Tangents>(positions3D.size());
|
||||
|
||||
for (std::size_t j=0; j < indices.size(); j += 3)
|
||||
{
|
||||
@ -308,9 +376,9 @@ void Mesh::computeTangents()
|
||||
int vertexId1 = indices[j+1];
|
||||
int vertexId2 = indices[j+2];
|
||||
|
||||
const glm::vec3 &v1 = positions[vertexId0];
|
||||
const glm::vec3 &v2 = positions[vertexId1];
|
||||
const glm::vec3 &v3 = positions[vertexId2];
|
||||
const glm::vec3 &v1 = positions3D[vertexId0];
|
||||
const glm::vec3 &v2 = positions3D[vertexId1];
|
||||
const glm::vec3 &v3 = positions3D[vertexId2];
|
||||
|
||||
const glm::vec2& w1 = texCoords[vertexId0];
|
||||
const glm::vec2& w2 = texCoords[vertexId1];
|
||||
|
95
src/mesh.h
95
src/mesh.h
@ -9,11 +9,48 @@
|
||||
class Material;
|
||||
class Shader;
|
||||
|
||||
|
||||
|
||||
struct Mesh
|
||||
{
|
||||
public: // TODO : see if there is a way to set this protected
|
||||
// geometry data
|
||||
public:
|
||||
|
||||
// Mesh properties
|
||||
enum {
|
||||
// Geometric properties
|
||||
MESH_INDEXED,
|
||||
MESH_TEXTURABLE,
|
||||
MESH_INSTANCED,
|
||||
|
||||
// Mesh type
|
||||
MESH_3D,
|
||||
MESH_2D,
|
||||
|
||||
// 3D Geometric properties
|
||||
MESH_TANGENT_SPACE,
|
||||
MESH_BILLBOARD,
|
||||
|
||||
// simple material (no lighting)
|
||||
MATERIAL_COLOR_TEXTURE,
|
||||
MATERIAL_ALPHA_MASK,
|
||||
|
||||
// 3D phong material
|
||||
MATERIAL_PHONG_DIFFUSE_TEXTURE,
|
||||
MATERIAL_PHONG_AMBIENT_TEXTURE,
|
||||
MATERIAL_PHONG_SPECULAR_TEXTURE,
|
||||
MATERIAL_PHONG_NORMAL_MAP,
|
||||
|
||||
// 3D Beckman-like materials
|
||||
MATERIAL_BACKMANN_BUMP_MAP,
|
||||
// TODO
|
||||
|
||||
NB_FLAGS
|
||||
};
|
||||
|
||||
// define strings associated to the properties
|
||||
static const char* const flagStr[NB_FLAGS];
|
||||
|
||||
// geometry data
|
||||
typedef struct
|
||||
{
|
||||
glm::vec3 tangent;
|
||||
@ -23,8 +60,11 @@ public: // TODO : see if there is a way to set this protected
|
||||
|
||||
Material* material;
|
||||
bool isDoubleSided;
|
||||
bool isBillboard;
|
||||
float depth;
|
||||
|
||||
std::vector<glm::vec3> positions;
|
||||
std::vector<glm::vec3> positions3D;
|
||||
std::vector<glm::vec2> positions2D;
|
||||
std::vector<glm::vec3> normals;
|
||||
std::vector<glm::vec2> texCoords;
|
||||
std::vector<glm::vec3> instances_offsets;
|
||||
@ -62,9 +102,20 @@ public:
|
||||
void draw(Shader* shader = NULL, bool drawNormals = true, bool drawTexCoord = true, bool drawTangents = true);
|
||||
void destroyGL();
|
||||
|
||||
/**
|
||||
* @brief beginUpdateBuffer can be used to change the contents of a VBO dynamically
|
||||
* @return a pointer to the buffer's data
|
||||
*
|
||||
* endUpdateBuffer() must be called when the modifications are over
|
||||
*/
|
||||
glm::vec3* beginUpdateBuffer(int buffer);
|
||||
void endUpdateBuffer();
|
||||
|
||||
/**
|
||||
* @brief getFlags returns the flags that defines the specificities of the mesh and his material
|
||||
*/
|
||||
unsigned int getFlags();
|
||||
|
||||
/**
|
||||
* this class is intended to be used with the default GL_TRIANGLES primitive,
|
||||
* the methods mergeVertices, computeNormals, and computeTangents will probably have
|
||||
@ -72,33 +123,25 @@ public:
|
||||
*/
|
||||
void setPrimitiveType(GLenum type) {primitive_type = type;}
|
||||
|
||||
// merge same vertices
|
||||
/**
|
||||
* @brief mergeVertices simplifies an indexed mesh by merging all vertices that
|
||||
* have exactly the same position, texcoord, and normals, the tangents will be averaged.
|
||||
*/
|
||||
void mergeVertices();
|
||||
bool operator() (const int& vertId1, const int& vertId2) const;
|
||||
// require positions and indices
|
||||
/**
|
||||
* compute normals from an indexed mesh (positions + indices)
|
||||
*/
|
||||
void computeNormals();
|
||||
// require normals and texCoord
|
||||
|
||||
/**
|
||||
* compute tangent space from a textured indexed mesh (positions + normals + texcoords + indices)
|
||||
*/
|
||||
void computeTangents();
|
||||
|
||||
bool hasNormals() const
|
||||
{
|
||||
return normals.size() != 0;
|
||||
}
|
||||
|
||||
bool hasTexCoords() const
|
||||
{
|
||||
return texCoords.size() != 0;
|
||||
}
|
||||
|
||||
bool hasTangents() const
|
||||
{
|
||||
return tangents.size() != 0;
|
||||
}
|
||||
|
||||
bool hasInstances() const
|
||||
{
|
||||
return instances_offsets.size() != 0;
|
||||
}
|
||||
bool hasNormals() const {return !normals.empty();}
|
||||
bool hasTexCoords() const {return !texCoords.empty();}
|
||||
bool hasTangents() const {return !tangents.empty();}
|
||||
bool hasInstances() const {return !instances_offsets.empty();}
|
||||
};
|
||||
|
||||
#endif // MESH_H
|
||||
|
@ -7,7 +7,7 @@ void MeshBuilder::addPosition(float x, float y, float z)
|
||||
|
||||
void MeshBuilder::addPosition(const glm::vec3 &position)
|
||||
{
|
||||
positions.push_back(position);
|
||||
positions3D.push_back(position);
|
||||
}
|
||||
|
||||
void MeshBuilder::addNormal(float x, float y, float z)
|
||||
|
@ -40,7 +40,7 @@ Sphere::Sphere(Material* mat, int n, float myRadius) :
|
||||
for(int i=0; i<n; i++)
|
||||
subdivide();
|
||||
|
||||
for(glm::vec3 &vertex : positions)
|
||||
for(glm::vec3 &vertex : positions3D)
|
||||
vertex *= radius;
|
||||
}
|
||||
|
||||
@ -54,9 +54,9 @@ int Sphere::getEdge(int a, int b)
|
||||
vid = current->vertex;
|
||||
else if(current->next == NULL)
|
||||
{
|
||||
vid = positions.size();
|
||||
vid = positions3D.size();
|
||||
// creating subdivision vertex
|
||||
glm::vec3 pos = glm::normalize(positions[a] + positions[b] / 2.f);
|
||||
glm::vec3 pos = glm::normalize(positions3D[a] + positions3D[b] / 2.f);
|
||||
addPosition(pos);
|
||||
addNormal(pos);
|
||||
|
||||
@ -84,7 +84,7 @@ int Sphere::getEdge(int a, int b)
|
||||
|
||||
void Sphere::subdivide()
|
||||
{
|
||||
edges = new Edge[positions.size()-1];
|
||||
edges = new Edge[positions3D.size()-1];
|
||||
int nb_triangles = indices.size()/3;
|
||||
for(int j=0; j<nb_triangles; j++)
|
||||
{
|
||||
|
@ -37,4 +37,6 @@ private:
|
||||
int getVertexId(int i, int j, int height);
|
||||
};
|
||||
|
||||
// TODO TextMesh (with glyph map)
|
||||
|
||||
#endif // PARAMETRIC_MESH_H
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "sparrowrenderer.h"
|
||||
#include "glassert.h"
|
||||
#include "shader.h"
|
||||
#include "mesh.h"
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
void PhongMaterial::bindAttributes(Shader* myShader)
|
||||
@ -14,38 +15,38 @@ void PhongMaterial::bindAttributes(Shader* myShader)
|
||||
|
||||
if(normal_map != NULL)
|
||||
{
|
||||
normal_map->bind(NORMAL_MAP);
|
||||
myShader->bindInteger(myShader->getLocation("normalMap"), NORMAL_MAP);
|
||||
normal_map->bind(NORMALS_SLOT);
|
||||
myShader->bindInteger(myShader->getLocation("normalMap"), NORMALS_SLOT);
|
||||
}
|
||||
|
||||
if(ambient_texture != NULL)
|
||||
{
|
||||
ambient_texture->bind(AMBIENT_TEXTURE);
|
||||
myShader->bindInteger(myShader->getLocation("ambientTexture"), AMBIENT_TEXTURE);
|
||||
ambient_texture->bind(AMBIENT_SLOT);
|
||||
myShader->bindInteger(myShader->getLocation("ambientTexture"), AMBIENT_SLOT);
|
||||
}
|
||||
else
|
||||
myShader->bindVec3(myShader->getLocation("materialKa"), ambient);
|
||||
|
||||
if(diffuse_texture != NULL)
|
||||
{
|
||||
diffuse_texture->bind(DIFFUSE_TEXTURE);
|
||||
myShader->bindInteger(myShader->getLocation("diffuseTexture"), DIFFUSE_TEXTURE);
|
||||
diffuse_texture->bind(DIFFUSE_SLOT);
|
||||
myShader->bindInteger(myShader->getLocation("diffuseTexture"), DIFFUSE_SLOT);
|
||||
}
|
||||
else
|
||||
myShader->bindVec3(myShader->getLocation("materialKd"), diffuse);
|
||||
|
||||
if(specular_texture != NULL)
|
||||
{
|
||||
specular_texture->bind(SPECULAR_TEXTURE);
|
||||
myShader->bindInteger(myShader->getLocation("specularTexture"), SPECULAR_TEXTURE);
|
||||
specular_texture->bind(SPECULAR_SLOT);
|
||||
myShader->bindInteger(myShader->getLocation("specularTexture"), SPECULAR_SLOT);
|
||||
}
|
||||
else
|
||||
myShader->bindVec3(myShader->getLocation("materialKs"), specular);
|
||||
|
||||
if(alpha_mask != NULL)
|
||||
{
|
||||
alpha_mask->bind(ALPHA_MASK);
|
||||
myShader->bindInteger(myShader->getLocation("alphaMask"), ALPHA_MASK);
|
||||
alpha_mask->bind(ALPHA_SLOT);
|
||||
myShader->bindInteger(myShader->getLocation("alphaMask"), ALPHA_SLOT);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -56,11 +57,10 @@ void PhongMaterial::bindAttributes(Shader* myShader)
|
||||
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);
|
||||
diffuse_texture->bind(0);
|
||||
else
|
||||
{
|
||||
GLenum texSlot = GL_TEXTURE0+DIFFUSE_TEXTURE;
|
||||
glAssert(glActiveTexture(texSlot));
|
||||
glAssert(glActiveTexture(0));
|
||||
glAssert(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
}
|
||||
}
|
||||
@ -70,15 +70,15 @@ unsigned int PhongMaterial::getFlags()
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
if(normal_map != NULL)
|
||||
flags |= NORMAL_MAP_FLAG;
|
||||
flags |= Mesh::MATERIAL_PHONG_NORMAL_MAP;
|
||||
if(ambient_texture != NULL)
|
||||
flags |= AMBIENT_TEXTURE_FLAG;
|
||||
flags |= Mesh::MATERIAL_PHONG_AMBIENT_TEXTURE;
|
||||
if(diffuse_texture != NULL)
|
||||
flags |= DIFFUSE_TEXTURE_FLAG;
|
||||
flags |= Mesh::MATERIAL_PHONG_DIFFUSE_TEXTURE;
|
||||
if(specular_texture != NULL)
|
||||
flags |= SPECULAR_TEXTURE_FLAG;
|
||||
flags |= Mesh::MATERIAL_PHONG_SPECULAR_TEXTURE;
|
||||
if(alpha_mask != NULL)
|
||||
flags |= ALPHA_MASK_FLAG;
|
||||
flags |= Mesh::MATERIAL_ALPHA_MASK;
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,16 @@ class Texture;
|
||||
|
||||
class PhongMaterial : public Material
|
||||
{
|
||||
public:
|
||||
private:
|
||||
enum TextureSlots
|
||||
{
|
||||
DIFFUSE_SLOT,
|
||||
AMBIENT_SLOT,
|
||||
NORMALS_SLOT,
|
||||
SPECULAR_SLOT,
|
||||
ALPHA_SLOT,
|
||||
};
|
||||
|
||||
glm::vec3 ambient;
|
||||
glm::vec3 diffuse;
|
||||
glm::vec3 specular;
|
||||
@ -20,6 +29,8 @@ public:
|
||||
Texture* normal_map;
|
||||
Texture* alpha_mask;
|
||||
|
||||
public:
|
||||
|
||||
PhongMaterial() :
|
||||
ambient(0),
|
||||
diffuse(0.5f),
|
||||
@ -33,14 +44,11 @@ public:
|
||||
alpha_mask(NULL)
|
||||
{}
|
||||
|
||||
void bindAttributes(Shader* myShader = NULL);
|
||||
virtual ~PhongMaterial() {}
|
||||
|
||||
unsigned int getFlags();
|
||||
virtual void bindAttributes(Shader* myShader = NULL);
|
||||
|
||||
/**
|
||||
* deprecated, you should use setDiffuseTexture instead
|
||||
*/
|
||||
void setTexture(Texture* myTexture);
|
||||
virtual unsigned int getFlags();
|
||||
|
||||
void setAmbientTexture(Texture* myTexture);
|
||||
void setDiffuseTexture(Texture* myTexture);
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "shadersource.h"
|
||||
#include "sparrowrenderer.h"
|
||||
#include "scene.h"
|
||||
#include "camera.h"
|
||||
#include "glassert.h"
|
||||
|
||||
Pipeline::~Pipeline()
|
||||
{
|
||||
@ -13,8 +15,12 @@ Pipeline::~Pipeline()
|
||||
|
||||
SimplePipeline::SimplePipeline(ShaderSource *forwardSource)
|
||||
{
|
||||
isCrappy = forwardSource != NULL && SparrowRenderer::isModernOpenGLAvailable();
|
||||
if(!isCrappy)
|
||||
glAssert(glEnable(GL_DEPTH_TEST));
|
||||
glAssert(glEnable(GL_CULL_FACE));
|
||||
glAssert(glEnable(GL_TEXTURE_2D));
|
||||
|
||||
m_isCrappy = forwardSource != NULL && SparrowRenderer::isModernOpenGLAvailable();
|
||||
if(!m_isCrappy)
|
||||
{
|
||||
ForwardModule *forward = new ForwardModule();
|
||||
forward->setShaderSource(forwardSource);
|
||||
@ -25,16 +31,50 @@ SimplePipeline::SimplePipeline(ShaderSource *forwardSource)
|
||||
modules.push_back(new CrappyModule());
|
||||
}
|
||||
|
||||
void SimplePipeline::renderGL(Scene *scene)
|
||||
{
|
||||
glAssert(glClearColor(m_clearColor.r, m_clearColor.g, m_clearColor.b, 1));
|
||||
glAssert(glClearDepth(1.0));
|
||||
glAssert(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||
for(Module *m : modules)
|
||||
{
|
||||
glAssert(glFinish());
|
||||
m->renderGL(m_camera, scene);
|
||||
}
|
||||
}
|
||||
|
||||
void SimplePipeline::resizeGL(int w, int h)
|
||||
{
|
||||
if(m_camera != NULL)
|
||||
m_camera->resize(w, h);
|
||||
for(Module *m : modules)
|
||||
m->resize(w, h);
|
||||
}
|
||||
|
||||
void SimplePipeline::refreshScene(Scene *scene)
|
||||
{
|
||||
if(!isCrappy)
|
||||
if(!m_isCrappy)
|
||||
{
|
||||
ForwardModule *forward = (ForwardModule*)(modules[0]);
|
||||
forward->compileShaders(scene);
|
||||
}
|
||||
}
|
||||
|
||||
DefaultPipeline::DefaultPipeline(const Settings &mySettings, const SourcePack &mySourcePack)
|
||||
StandardPipeline::StandardPipeline(const Settings &mySettings, const SourcePack &mySourcePack)
|
||||
{
|
||||
glAssert(glEnable(GL_DEPTH_TEST));
|
||||
glAssert(glEnable(GL_CULL_FACE));
|
||||
glAssert(glEnable(GL_TEXTURE_2D));
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void StandardPipeline::renderGL(Scene *scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StandardPipeline::resizeGL(int w, int h)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -4,10 +4,12 @@
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <glm/vec3.hpp>
|
||||
|
||||
class ShaderSource;
|
||||
class Module;
|
||||
class Scene;
|
||||
class Camera;
|
||||
|
||||
class Pipeline
|
||||
{
|
||||
@ -18,10 +20,8 @@ protected:
|
||||
std::vector<Module*> modules;
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief getModules is a getter used by the renderer to access the pipeline modules
|
||||
*/
|
||||
std::vector<Module*>& getModules() {return modules;}
|
||||
virtual void renderGL(Scene *scene) = 0;
|
||||
virtual void resizeGL(int w, int h) {}
|
||||
|
||||
/**
|
||||
* the destructor deletes all the modules
|
||||
@ -35,16 +35,30 @@ public:
|
||||
*/
|
||||
class SimplePipeline : public Pipeline
|
||||
{
|
||||
bool isCrappy;
|
||||
bool m_isCrappy;
|
||||
Camera *m_camera;
|
||||
glm::vec3 m_clearColor;
|
||||
|
||||
public:
|
||||
SimplePipeline(ShaderSource *forwardSource = NULL);
|
||||
|
||||
virtual void renderGL(Scene *scene);
|
||||
virtual void resizeGL(int w, int h);
|
||||
|
||||
void refreshScene(Scene *scene);
|
||||
|
||||
void setCamera(Camera *camera) {m_camera = camera;}
|
||||
void setClearColor(glm::vec3 clearColor) {m_clearColor = clearColor;}
|
||||
};
|
||||
|
||||
class DefaultPipeline : public Pipeline
|
||||
/**
|
||||
* @brief The DefaultPipeline class -> WORK IN PROGRESS
|
||||
*/
|
||||
class StandardPipeline : public Pipeline
|
||||
{
|
||||
Camera *m_camera;
|
||||
glm::vec3 m_clearColor;
|
||||
|
||||
public:
|
||||
struct Settings
|
||||
{
|
||||
@ -71,9 +85,15 @@ public:
|
||||
std::string reduction_frag;
|
||||
};
|
||||
|
||||
DefaultPipeline(const Settings &mySettings, const SourcePack &mySourcePack);
|
||||
StandardPipeline(const Settings &mySettings, const SourcePack &mySourcePack);
|
||||
|
||||
virtual void renderGL(Scene *scene);
|
||||
virtual void resizeGL(int w, int h);
|
||||
|
||||
void refreshScene(Scene *scene);
|
||||
|
||||
void setCamera(Camera *camera) {m_camera = camera;}
|
||||
void setClearColor(glm::vec3 clearColor) {m_clearColor = clearColor;}
|
||||
};
|
||||
|
||||
#endif // PIPELINE_H
|
||||
|
@ -1 +1,17 @@
|
||||
#include "scene.h"
|
||||
#include "mesh.h"
|
||||
#include <set>
|
||||
|
||||
std::vector<unsigned int> getMeshTypes()
|
||||
{
|
||||
std::set<unsigned int> typesSet;
|
||||
std::vector<unsigned int> types;
|
||||
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
|
||||
geometryIt->isValid(); geometryIt->next())
|
||||
{
|
||||
typesSet.emplace(geometryIt->getItem()->mesh->getFlags());
|
||||
}
|
||||
for(unsigned int type : typesSet)
|
||||
types.push_back(type);
|
||||
return types;
|
||||
}
|
||||
|
15
src/scene.h
15
src/scene.h
@ -2,10 +2,11 @@
|
||||
#define SCENE_H
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include "camera.h"
|
||||
#include <vector>
|
||||
#include "light.h"
|
||||
|
||||
class Camera;
|
||||
class Pipeline;
|
||||
class Mesh;
|
||||
|
||||
// Scene interface :
|
||||
@ -30,18 +31,20 @@ struct GeometryNode
|
||||
class Scene
|
||||
{
|
||||
protected:
|
||||
Camera *m_camera;
|
||||
Pipeline *m_pipeline;
|
||||
|
||||
public:
|
||||
Scene() : m_camera(NULL) {}
|
||||
Scene() : m_pipeline(NULL) {}
|
||||
|
||||
Camera* getCamera() {return m_camera;}
|
||||
Pipeline* getPipeline() {return m_pipeline;}
|
||||
|
||||
virtual SceneIterator<Light*>* getLights() = 0;
|
||||
virtual SceneIterator<GeometryNode*>* getGeometry() = 0;
|
||||
|
||||
std::vector<unsigned int> getMeshTypes();
|
||||
};
|
||||
|
||||
// Some basic implementations :
|
||||
// A basic implementation :
|
||||
|
||||
template <class T>
|
||||
class ArraySceneIterator : public SceneIterator<T>
|
||||
@ -63,6 +66,8 @@ protected:
|
||||
public:
|
||||
ArrayScene() : Scene() {}
|
||||
|
||||
void setPipeline(Pipeline *pipeline) {m_pipeline = pipeline;}
|
||||
|
||||
void clearLights() {lights.clear();}
|
||||
void clearEntities() {geometry.clear();}
|
||||
void clearScene() {clearLights(); clearEntities();}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include "shader.h"
|
||||
#include "mesh.h"
|
||||
|
||||
ShaderSource::ShaderSource()
|
||||
{
|
||||
@ -27,16 +28,23 @@ void ShaderSource::setSource(const char *source, SourceType type)
|
||||
sources[type] = new std::string(source);
|
||||
}
|
||||
|
||||
Shader* ShaderSource::compile(int nbDefines, const char** defines)
|
||||
Shader* ShaderSource::compile(unsigned int geomFlags, unsigned int lightFlags)
|
||||
{
|
||||
std::string header = "#version 330 core";
|
||||
for(int i=0; i<NB_FLAGS; ++i)
|
||||
{
|
||||
if((geomFlags >> i) & 0x00000001)
|
||||
header += "\n#define "+std::string(flagStr[i]);
|
||||
}
|
||||
header += "\n#line 1\n";
|
||||
|
||||
if(sources[VERTEX] == NULL || sources[FRAGMENT] == NULL)
|
||||
return NULL;
|
||||
std::string compiledSources[NB_TYPES];
|
||||
for(int i=0; i<NB_TYPES; ++i)
|
||||
{
|
||||
if(sources[i] == NULL)
|
||||
continue;
|
||||
compiledSources[i] = preprocess(*(sources[i]), nbDefines, defines);
|
||||
if(sources[i] != NULL)
|
||||
compiledSources[i] = header + *(sources[i]);
|
||||
}
|
||||
if(sources[GEOMETRY] != NULL)
|
||||
return new Shader(compiledSources[VERTEX], compiledSources[GEOMETRY], compiledSources[FRAGMENT]);
|
||||
@ -44,10 +52,3 @@ Shader* ShaderSource::compile(int nbDefines, const char** defines)
|
||||
return new Shader(compiledSources[VERTEX], compiledSources[FRAGMENT]);
|
||||
}
|
||||
|
||||
std::string ShaderSource::preprocess(std::string source, int nbDefines, const char** defines, const char* version)
|
||||
{
|
||||
std::string header = "#version "+std::string(version);
|
||||
for(int i=0; i<nbDefines; ++i)
|
||||
header += "\n#define "+std::string(defines[i]);
|
||||
return header+"\n#line 1\n"+source;
|
||||
}
|
||||
|
@ -25,8 +25,6 @@ public:
|
||||
|
||||
private:
|
||||
std::string* sources[NB_TYPES];
|
||||
|
||||
std::string preprocess(std::string source, int nbDefines, const char** defines, const char* version = "330 core");
|
||||
};
|
||||
|
||||
#endif // SHADERSOURCE_H
|
||||
|
@ -44,6 +44,7 @@ SkyboxModule::~SkyboxModule()
|
||||
|
||||
void SkyboxModule::renderGL(Camera* myCamera, Scene* scene)
|
||||
{
|
||||
glAssert(glViewport(0, 0, width, height));
|
||||
glm::mat4 viewMatrix = glm::mat4(glm::mat3(myCamera->getViewMatrix()));
|
||||
glm::mat4 projectionMatrix = myCamera->getProjectionMatrix();
|
||||
glAssert(glDisable(GL_CULL_FACE));
|
||||
|
@ -16,6 +16,9 @@ class SkyboxModule : public Module
|
||||
static const std::string vertSource;
|
||||
static const std::string fragSource;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
// modern opengl variables
|
||||
GLuint vao;
|
||||
GLuint vbos[2];
|
||||
@ -30,6 +33,7 @@ public:
|
||||
~SkyboxModule();
|
||||
virtual void renderGL(Camera* myCamera, Scene* scene = NULL);
|
||||
virtual bool requiresModernOpenGL() {return false;}
|
||||
virtual void resize(int w, int h) {width = w; height = h;}
|
||||
void setRenderTarget(const FrameBuffer* target);
|
||||
};
|
||||
|
||||
|
@ -44,9 +44,6 @@ void SparrowRenderer::initGL(int w, int h, bool forceCrappy)
|
||||
std::cout << "Renderer " << glGetString(GL_RENDERER) << std::endl;
|
||||
std::cout << "Vendor " << glGetString(GL_VENDOR) << std::endl;
|
||||
|
||||
glAssert(glEnable(GL_DEPTH_TEST));
|
||||
glAssert(glEnable(GL_CULL_FACE));
|
||||
glAssert(glEnable(GL_TEXTURE_2D));
|
||||
resizeGL(w, h);
|
||||
}
|
||||
|
||||
@ -54,28 +51,18 @@ void SparrowRenderer::resizeGL(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
if(scene != NULL && scene->getCamera() != NULL)
|
||||
scene->getCamera()->resize(width, height);
|
||||
if(modules != NULL)
|
||||
if(m_scene != NULL)
|
||||
{
|
||||
for(Module *m : *modules)
|
||||
m->resize(w, h);
|
||||
if(m_scene->getPipeline() != NULL)
|
||||
m_scene->getPipeline()->resizeGL(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
void SparrowRenderer::renderGL()
|
||||
{
|
||||
glAssert(glViewport(0, 0, width, height));
|
||||
glAssert(glClearColor(clearColor.r, clearColor.g, clearColor.b, 1));
|
||||
glAssert(glClearDepth(1.0));
|
||||
|
||||
if(modules != NULL)
|
||||
if(m_scene != NULL && m_scene->getPipeline() != NULL)
|
||||
{
|
||||
for(Module *m : *modules)
|
||||
{
|
||||
glFinish();
|
||||
m->renderGL(scene == NULL ? NULL : scene->getCamera(), scene);
|
||||
}
|
||||
m_scene->getPipeline()->renderGL(m_scene);
|
||||
}
|
||||
glFinish();
|
||||
}
|
||||
@ -85,26 +72,14 @@ bool SparrowRenderer::isModernOpenGLAvailable()
|
||||
return modernOpenglAvailable;
|
||||
}
|
||||
|
||||
// pipeline methods
|
||||
|
||||
void SparrowRenderer::setPipeline(Pipeline* pipeline)
|
||||
{
|
||||
if(pipeline != NULL)
|
||||
modules = &(pipeline->getModules());
|
||||
else
|
||||
modules = NULL;
|
||||
}
|
||||
|
||||
// scene methods
|
||||
|
||||
void SparrowRenderer::setScene(Scene* myScene)
|
||||
{
|
||||
scene = myScene;
|
||||
}
|
||||
|
||||
Scene* SparrowRenderer::getScene()
|
||||
{
|
||||
return scene;
|
||||
m_scene = myScene;
|
||||
if(m_scene == NULL || m_scene->getPipeline() == NULL)
|
||||
fprintf(stderr, "WARNING : incomplete scene class, rendering may not work properly.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -15,9 +15,7 @@ class SparrowRenderer
|
||||
{
|
||||
public:
|
||||
SparrowRenderer() :
|
||||
scene(NULL),
|
||||
modules(NULL),
|
||||
clearColor(0)
|
||||
m_scene(NULL)
|
||||
{}
|
||||
|
||||
// main methods
|
||||
@ -26,25 +24,17 @@ public:
|
||||
void renderGL();
|
||||
|
||||
static bool isModernOpenGLAvailable();
|
||||
void setClearColor(glm::vec3 color) {clearColor=color;}
|
||||
|
||||
// pipeline methods
|
||||
void setPipeline(Pipeline* pipeline);
|
||||
|
||||
// scene methods
|
||||
void setScene(Scene* myScene);
|
||||
Scene* getScene();
|
||||
|
||||
protected:
|
||||
int width;
|
||||
int height;
|
||||
|
||||
Scene* scene;
|
||||
std::vector<Module*> *modules;
|
||||
Scene* m_scene;
|
||||
|
||||
static bool modernOpenglAvailable;
|
||||
|
||||
glm::vec3 clearColor;
|
||||
};
|
||||
|
||||
#endif // SPARROWRENDERER_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user