changed scene to hold a pipeline, renderer does not handle modules anymore, material flags are handled by the mesh

This commit is contained in:
Anselme 2016-03-29 07:17:54 +02:00
parent 0d4914c1d7
commit 4dcef0d4e3
20 changed files with 333 additions and 184 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -37,4 +37,6 @@ private:
int getVertexId(int i, int j, int height);
};
// TODO TextMesh (with glyph map)
#endif // PARAMETRIC_MESH_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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