added instancing, and plenty of little things, fixed lots of bugs

This commit is contained in:
Anselme 2016-02-20 14:07:04 +01:00
parent e536a76577
commit d2df3a998f
30 changed files with 2037 additions and 119 deletions

View File

@ -4,25 +4,25 @@ cmake_minimum_required(VERSION 2.8)
find_package(OpenGL REQUIRED)
set(LIB_SRC_LIST
src/glew.c
src/sparrowrenderer.cpp
src/framebuffer.cpp
src/meshbuilder.cpp
src/phongmaterial.cpp
src/crappymodule.cpp
src/shader.cpp
src/skyboxmodule.cpp
src/parametricmesh.cpp
src/texture.cpp
src/scene.cpp
src/deferredmodule.cpp
src/forwardmodule.cpp
src/shadersource.cpp
src/light.cpp
src/posteffectmodule.cpp
src/textureblur.cpp
src/textureredux.cpp
src/mesh.cpp
src/glew.c
src/sparrowrenderer.cpp
src/framebuffer.cpp
src/meshbuilder.cpp
src/phongmaterial.cpp
src/crappymodule.cpp
src/shader.cpp
src/skyboxmodule.cpp
src/parametricmesh.cpp
src/texture.cpp
src/scene.cpp
src/deferredmodule.cpp
src/forwardmodule.cpp
src/shadersource.cpp
src/light.cpp
src/posteffectmodule.cpp
src/textureblur.cpp
src/textureredux.cpp
src/mesh.cpp
)
set(LIBRARY_NAME ${PROJECT_NAME})
@ -35,13 +35,13 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_ROOT}) #for SHARED
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_ROOT}) #for STATIC
if(CMAKE_BUILD_TYPE MATCHES "Debug")
set(CPP_DEFINES -DRENDER_DEBUG)
set(CPP_DEFINES -DRENDER_DEBUG -DGLEW_BUILD -DGLEW_STATIC)
endif()
file(GLOB LIBRARY_RES_FILES src/*.h shaders/*.glsl)
add_library(${LIBRARY_NAME} STATIC ${LIB_SRC_LIST} ${LIBRARY_RES_FILES})
add_definitions(-std=c++11 ${CPP_DEFINES})
add_definitions(-std=c++11 -Wno-comment ${CPP_DEFINES})
include_directories(
${INCLUDE_ROOT}

View File

@ -3,7 +3,11 @@
uniform vec3 lightColor;
uniform float materialNs;
uniform int objectId;
uniform uint objectId;
#ifdef INSTANCING
flat in int instanceId;
#endif
#ifdef ALPHA_MASK
uniform sampler2D alphaMask;
@ -53,6 +57,7 @@ uniform float attenuation;
#endif
layout(location = 0)out vec4 outColor;
layout(location = 1)out vec4 pickData;
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);
@ -73,7 +78,6 @@ void main(void) {
#ifdef NORMAL_MAP
vec3 normal = normalize(texture(normalMap, varTexCoord).xyz * tangentSpace);
//normal = normalize(vec3(0, 0, 1) * tangentSpace);
#else
vec3 normal = normalize(varNormal);
#endif
@ -115,4 +119,14 @@ void main(void) {
vec3 light = phongLighting(diffuse, specular, materialNs, lightColor, normal, lightDirInView, halfVecInView);
outColor = vec4(light*shadow*(1+cos(1.57 + att*1.57)), 1);
#endif
#ifdef INSTANCING
pickData = vec4(gl_FragCoord.z, gl_FragCoord.w, float(int(objectId) + instanceId), 0);
#else
pickData = vec4(gl_FragCoord.z, gl_FragCoord.w, float(objectId), 0);
#endif
#ifndef AMBIENT_LIGHT
pickData = vec4(0);
#endif
}

View File

@ -29,6 +29,12 @@ layout(location = 3)in vec3 inTangent;
layout(location = 4)in vec3 inBinormal;
#endif
#ifdef INSTANCING
layout(location = 5)in vec3 inInstanceOffset;
flat out int instanceId;
#endif
#ifndef AMBIENT_LIGHT
out vec3 lightDirInView;
out vec3 halfVecInView;
@ -44,7 +50,14 @@ out vec4 posInLightSpace;
#endif
void main(void) {
vec3 posInView = vec3(modelViewMatrix*vec4(inPosition, 1.0));
#ifdef INSTANCING
instanceId = gl_InstanceID;
vec4 pos = vec4(inPosition + inInstanceOffset, 1.0);
#else
vec4 pos = vec4(inPosition, 1.0);
#endif
vec3 posInView = vec3(modelViewMatrix*pos);
#ifdef DIRECTIONNAL_LIGHT
lightDirInView = normalize(mat3(viewMatrix)*dirLight);
@ -52,7 +65,7 @@ void main(void) {
#endif
#ifdef SHADOWMAP
posInLightSpace = lightMVP * vec4(inPosition, 1.0);
posInLightSpace = lightMVP * pos;
#endif
#ifdef POINT_LIGHT
@ -72,5 +85,5 @@ void main(void) {
varTexCoord = inTexCoord.xy;
gl_Position = MVP * vec4(inPosition, 1.0);
gl_Position = MVP * pos;
}

View File

@ -4,11 +4,12 @@
#include <glm/mat4x4.hpp>
class Camera{
public:
virtual glm::mat4 getProjectionMatrix() = 0;
virtual glm::mat4 getViewMatrix() = 0;
public:
virtual glm::mat4 getProjectionMatrix() = 0;
virtual glm::mat4 getViewMatrix() = 0;
virtual void resize(int width, int height) = 0;
virtual void resize(int width, int height) = 0;
virtual ~Camera(){}//polymorphism
};
#endif // CAMERA_H

View File

@ -11,7 +11,6 @@
void CrappyModule::renderGL(Camera* myCamera, Scene* scene)
{
glAssert(glEnable(GL_LIGHTING));
glAssert(glClearColor(0, 0.1f, 0.05f, 1.0));
glAssert(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
glLoadIdentity();
glAssert(glEnable(GL_LIGHT0));
@ -28,7 +27,7 @@ void CrappyModule::renderGL(Camera* myCamera, Scene* scene)
glAssert(glEnable(GL_LIGHT0 + i));
glAssert(glLightfv(GL_LIGHT0 + i, GL_AMBIENT, glm::value_ptr(glm::vec4(glm::vec3(0), 1))));
if(l->isDirectionnal()){
glAssert(glLightfv(GL_LIGHT0 + i, GL_POSITION, glm::value_ptr(glm::vec4(l->getDir(), 0))));
glAssert(glLightfv(GL_LIGHT0 + i, GL_POSITION, glm::value_ptr(glm::vec4(-l->getDir(), 0))));
}else{
glAssert(glLightfv(GL_LIGHT0 + i, GL_POSITION, glm::value_ptr(glm::vec4(l->getPos(), 1))));
}
@ -41,12 +40,25 @@ void CrappyModule::renderGL(Camera* myCamera, Scene* scene)
geometryIt->isValid(); geometryIt->next())
{
GeometryNode* node = geometryIt->getItem();
glMatrixMode(GL_MODELVIEW);
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
glLoadMatrixf(glm::value_ptr(modelViewMatrix));
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(myCamera->getProjectionMatrix()));
node->mesh->draw();
glMatrixMode(GL_MODELVIEW);
if(node->mesh->hasInstances())
{
for(const glm::vec3 &pos : node->mesh->instances_offsets)
{
glm::mat4 offsetMatrix = glm::translate(node->modelMatrix, pos);
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * offsetMatrix;
glLoadMatrixf(glm::value_ptr(modelViewMatrix));
node->mesh->draw();
}
}
else
{
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
glLoadMatrixf(glm::value_ptr(modelViewMatrix));
node->mesh->draw();
}
}
glAssert(glDisable(GL_LIGHTING));

View File

@ -8,8 +8,8 @@
class CrappyModule : public Module
{
public:
virtual void renderGL(Camera* myCamera, Scene* scene = NULL);
virtual bool requiresModernOpenGL() {return false;}
void renderGL(Camera* myCamera, Scene* scene = NULL);
bool requiresModernOpenGL() {return false;}
};
#endif // CRAPPYMODULE_H

View File

@ -13,15 +13,19 @@ const char* const ForwardModule::flagStr[] =
"AMBIENT_TEXTURE",
"SPECULAR_TEXTURE",
"NORMAL_MAP",
"ALPHA_MASK"
"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);
// render ambient lighting
glAssert(glEnable(GL_DEPTH_TEST));
glAssert(glDepthFunc(GL_LESS));
glAssert(glDisable(GL_BLEND));
@ -49,9 +53,9 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
glAssert(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
}
// loop over all types of geometry
for(int i=0; i<geometryFlagList.size(); ++i)
for(std::size_t i=0; i<geometryFlagList.size(); ++i)
{
int j;
std::size_t j;
for(j=0; j<lightFlagList.size(); ++j)
if(lightFlagList[j] == Light::getFlags(light))
break;
@ -76,7 +80,7 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
if(light->isShadowCaster())
{
light->getShadowMap()->bind(NB_FLAGS); // NB_FLAGS has the value of the first available slot after the phong material texture slots
shader->bindInteger(shader->getLocation("shadowMap"), NB_FLAGS);
shader->bindUnsignedInteger(shader->getLocation("shadowMap"), NB_FLAGS);
}
break;
case Light::POINT:
@ -90,12 +94,21 @@ void ForwardModule::lightPass(Camera* myCamera, Scene* scene, Light* light)
break;
}
}
unsigned int id = 2;
for(SceneIterator<GeometryNode*>* geometryIt = scene->getGeometry();
geometryIt->isValid(); geometryIt->next())
{
GeometryNode* node = geometryIt->getItem();
shader->bindUnsignedInteger(shader->getLocation("objectId"), id);
if(node->mesh->hasInstances())
id += node->mesh->instances_offsets.size();
else
++id;
Material* mat = node->mesh->material;
if(mat->getFlags() == geometryFlagList[i]) // if flag matches material
unsigned int flags = mat->getFlags();
if(node->mesh->hasInstances())
flags |= INSTANCING_FLAG;
if(flags == geometryFlagList[i]) // if flag matches material
{
// compute matrix attributes
glm::mat4 modelViewMatrix = myCamera->getViewMatrix() * node->modelMatrix;
@ -143,7 +156,10 @@ void ForwardModule::compileShaders(Scene* scene)
geometryIt->isValid(); geometryIt->next())
{
Mesh* m = geometryIt->getItem()->mesh;
geometryFlags[m->material->getFlags()] = true;
unsigned int flags = m->material->getFlags();
if(m->hasInstances())
flags |= INSTANCING_FLAG;
geometryFlags[flags] = true;
}
for(int i=0; i<nb_geometry_flags; ++i)
{
@ -188,8 +204,10 @@ void ForwardModule::compileShaders(Scene* scene)
defines.push_back(flagStr[SPECULAR_TEXTURE]);
if(i & ALPHA_MASK_FLAG)
defines.push_back(flagStr[ALPHA_MASK]);
if(i & INSTANCING_FLAG)
defines.push_back(flagStr[INSTANCING]);
int boundary = defines.size();
std::size_t boundary = defines.size();
for(int j : lightFlagList)
{
while(defines.size() > boundary)

View File

@ -19,11 +19,12 @@ public:
ForwardModule() :
shaderSources(NULL),
renderTarget(FrameBuffer::screen),
isWireframe(false)
isWireframe(false),
clearBeforeDrawing(false)
{}
virtual void renderGL(Camera* myCamera, Scene* scene);
virtual bool requiresModernOpenGL() {return true;} // write some compatibility code to change that to false
void renderGL(Camera* myCamera, Scene* scene);
bool requiresModernOpenGL() {return true;} // write some compatibility code to change that to false
// modern opengl methods
@ -32,6 +33,7 @@ public:
void setRenderTarget(const FrameBuffer* target);
void setWireframe(bool wireframe) {isWireframe = wireframe;}
void setClearBeforeDrawing(bool clear) {clearBeforeDrawing = clear;}
private:
static const char* const flagStr[NB_FLAGS];
@ -43,6 +45,7 @@ private:
const FrameBuffer* renderTarget;
bool isWireframe;
bool clearBeforeDrawing;
void lightPass(Camera* myCamera, Scene* scene, Light* light);
};

View File

@ -4,14 +4,15 @@
const FrameBuffer* FrameBuffer::screen = new FrameBuffer(0);
FrameBuffer::FrameBuffer()
FrameBuffer::FrameBuffer() :
allocated(true)
{
glAssert(glGenFramebuffers(1, &fbo));
}
FrameBuffer::~FrameBuffer()
{
if(fbo != 0)
if(allocated)
glAssert(glDeleteFramebuffers(1, &fbo));
}
@ -29,7 +30,7 @@ void FrameBuffer::addTexture(Texture* tex, GLenum attachment)
else
{
glAssert(glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, tex->getTarget(), tex->getId(), 0));
if(attachment != GL_DEPTH_ATTACHMENT)
if(attachment != GL_DEPTH_ATTACHMENT) // TODO stencil attachment must be tested too
attachments.push_back(attachment);
}
@ -52,6 +53,7 @@ void FrameBuffer::deleteTextures()
{
for(Texture* t : textures)
delete(t);
textures.clear();
}
void FrameBuffer::bindFBO(GLenum target) const

View File

@ -8,17 +8,16 @@ class Texture;
class FrameBuffer
{
private:
FrameBuffer(int id) : fbo(id) {}
bool check();
protected:
bool check();
const bool allocated;
GLuint fbo;
std::vector<Texture*> textures;
std::vector<GLuint> attachments;
public:
FrameBuffer();
FrameBuffer(GLuint id) : allocated(false), fbo(id) {}
~FrameBuffer();
void addTexture(Texture* tex, GLenum attachment);
void initColorAttachments();

View File

@ -35,7 +35,7 @@
#if defined(_WIN32)
# include "wglew.h"
#elif !defined(__ANDROID__) && !defined(__native_client__) && !defined(__HAIKU__) && (!defined(__APPLE__) || defined(GLEW_APPLE_GLX))
# include <GL/glxew.h>
# include "glxew.h"
#endif
#include <stddef.h> /* For size_t */

1772
src/glxew.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -6,9 +6,9 @@
struct Image
{
int depth;
int width;
int height;
int depth;
void* pixels;
Image() : pixels(NULL) {}

View File

@ -120,7 +120,7 @@ void Light::generateShadowMap(Scene* scene)
shaders[1]->bind();
pmat->alpha_mask->bind(ALPHA_MASK);
shaders[1]->bindMat4(shaders[1]->getLocation("MVP"), lightMVP);
shaders[1]->bindInteger(shaders[1]->getLocation("alphaMask"), ALPHA_MASK);
shaders[1]->bindUnsignedInteger(shaders[1]->getLocation("alphaMask"), ALPHA_MASK);
node->mesh->draw(shaders[1], false, true, false);
}
else

View File

@ -53,10 +53,10 @@ public:
void setColor(glm::vec3 new_color) {color = new_color;}
// camera inheritance
virtual glm::mat4 getProjectionMatrix() {return projectionMatrix;}
virtual glm::mat4 getViewMatrix() {return viewMatrix;}
glm::mat4 getProjectionMatrix() {return projectionMatrix;}
glm::mat4 getViewMatrix() {return viewMatrix;}
// does nothing, just required for inheriting Camera
virtual void resize(int width, int height) {}
void resize(int width, int height) {}
static unsigned int getFlags(Light* l);
private:

View File

@ -8,6 +8,7 @@ enum {
SPECULAR_TEXTURE,
NORMAL_MAP,
ALPHA_MASK,
INSTANCING,
NB_FLAGS
};
@ -18,6 +19,7 @@ enum {
SPECULAR_TEXTURE_FLAG = 1 << SPECULAR_TEXTURE,
NORMAL_MAP_FLAG = 1 << NORMAL_MAP,
ALPHA_MASK_FLAG = 1 << ALPHA_MASK,
INSTANCING_FLAG = 1 << INSTANCING
};
class Shader;
@ -27,6 +29,7 @@ class Material
public:
virtual void bindAttributes(Shader*) = 0;
virtual unsigned int getFlags() = 0;
virtual ~Material(){}
};
#endif // MATERIAL_H

View File

@ -9,8 +9,10 @@
Mesh::Mesh() :
material(NULL),
isDoubleSided(false),
vao(0),
nb_buffers(0)
nb_buffers(0),
primitive_type(GL_TRIANGLES)
{}
Mesh::~Mesh()
@ -20,8 +22,7 @@ Mesh::~Mesh()
void Mesh::initGL(bool isDynamic)
{
if(vao != 0)
destroyGL();
destroyGL();
GLenum buffer_type = isDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
@ -61,12 +62,25 @@ void Mesh::initGL(bool isDynamic)
glAssert(glBufferData(GL_ARRAY_BUFFER, tangents.size() * sizeof(glm::vec3)*2, tangents.data(), buffer_type));
}
if(hasInstances() && SparrowRenderer::isModernOpenGLAvailable())
{
// init instances vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[INSTANCE_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, instances_offsets.size() * sizeof(glm::vec3), instances_offsets.data(), GL_DYNAMIC_DRAW));
}
// unbind vao
glAssert(glBindVertexArray(0));
glAssert(glBindBuffer(GL_ARRAY_BUFFER, 0));
glAssert(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
void Mesh::draw(Shader* shader, bool drawNormals, bool drawTexCoord, bool drawTangents)
{
if(isDoubleSided)
{
glAssert(glDisable(GL_CULL_FACE));
}
bool crappy = (shader == NULL);
material->bindAttributes(shader);
glAssert(glBindVertexArray(vao));
@ -78,8 +92,8 @@ void Mesh::draw(Shader* shader, bool drawNormals, bool drawTexCoord, bool drawTa
}
else
{
glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(0));
glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
}
if(hasNormals() && drawNormals)
{
@ -91,8 +105,8 @@ void Mesh::draw(Shader* shader, bool drawNormals, bool drawTexCoord, bool drawTa
}
else
{
glAssert(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(1));
glAssert(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
}
}
if(hasTexCoords() && drawTexCoord)
@ -105,22 +119,33 @@ void Mesh::draw(Shader* shader, bool drawNormals, bool drawTexCoord, bool drawTa
}
else
{
glAssert(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(2));
glAssert(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), BUFFER_OFFSET(0)));
}
}
if(hasTangents() && drawTangents && !crappy)
{
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
glAssert(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(3));
glAssert(glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(sizeof(glm::vec3))));
glAssert(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(4));
glAssert(glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Mesh::Tangents), BUFFER_OFFSET(sizeof(glm::vec3))));
}
glAssert(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDICES_BUFFER]));
glAssert(glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, NULL));
glAssert(glBindVertexArray(0));
if(crappy)
if(!instances_offsets.empty() && !crappy)
{
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[INSTANCE_BUFFER]));
glAssert(glEnableVertexAttribArray(5));
glAssert(glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
glAssert(glVertexAttribDivisor(5, 1));
glAssert(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDICES_BUFFER]));
glAssert(glDrawElementsInstanced(primitive_type, indices.size(), GL_UNSIGNED_INT, NULL, instances_offsets.size()));
}
else
{
glAssert(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[INDICES_BUFFER]));
glAssert(glDrawElements(primitive_type, indices.size(), GL_UNSIGNED_INT, NULL));
}
if(crappy)
{
glAssert(glDisableClientState(GL_VERTEX_ARRAY));
if(hasNormals() && drawNormals)
@ -128,18 +153,35 @@ void Mesh::draw(Shader* shader, bool drawNormals, bool drawTexCoord, bool drawTa
if(hasTexCoords() && drawTexCoord)
glAssert(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
}
glAssert(glBindVertexArray(0));
if(isDoubleSided)
{
glAssert(glEnable(GL_CULL_FACE));
}
}
void Mesh::destroyGL()
{
if(vbo != NULL)
if(vao != 0)
{
glAssert(glDeleteVertexArrays(1, &vao));
glAssert(glDeleteBuffers(NB_BUFFERS, vbo));
glAssert(glDeleteVertexArrays(1, &vao));
vao = 0;
}
}
glm::vec3* Mesh::beginUpdateBuffer(int buffer)
{
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[buffer]));
glAssert(glm::vec3* ptr = (glm::vec3*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
return ptr;
}
void Mesh::endUpdateBuffer()
{
glUnmapBuffer(GL_ARRAY_BUFFER);
}
struct VertexComparator
{
// c'est plutot crade mais j'ai pas trouve d'autre moyen pour le moment
@ -183,7 +225,7 @@ void Mesh::mergeVertices()
std::set<int, VertexComparator> vertexSet;
VertexComparator::setMesh(this);
for(int i=0; i<indices.size(); ++i)
for(std::size_t i=0; i<indices.size(); ++i)
{
std::pair<std::set<int,VertexComparator>::iterator,bool> ret = vertexSet.insert(indices[i]);
deleted[indices[i]] = !ret.second && *(ret.first) != indices[i];
@ -199,7 +241,7 @@ void Mesh::mergeVertices()
}
int offset = 0;
int pos = 0;
for(int i=0; i<positions.size(); ++i)
for(std::size_t i=0; i<positions.size(); ++i)
{
if(deleted[i])
++offset;
@ -219,7 +261,7 @@ void Mesh::mergeVertices()
++pos;
}
}
for(int i=0; i<indices.size(); ++i)
for(std::size_t i=0; i<indices.size(); ++i)
indices[i] -= offsets[indices[i]];
positions.resize(positions.size()-offset);
@ -239,7 +281,8 @@ void Mesh::mergeVertices()
void Mesh::computeNormals()
{
normals.resize(positions.size());
for (int i=0; i < indices.size(); i += 3)
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];
@ -259,7 +302,7 @@ void Mesh::computeTangents()
return;
tangents = std::vector<Tangents>(positions.size());
for (int j=0; j < indices.size(); j += 3)
for (std::size_t j=0; j < indices.size(); j += 3)
{
int vertexId0 = indices[j];
int vertexId1 = indices[j+1];

View File

@ -11,8 +11,6 @@ class Shader;
struct Mesh
{
protected:
public: // TODO : see if there is a way to set this protected
// geometry data
@ -24,16 +22,14 @@ public: // TODO : see if there is a way to set this protected
Material* material;
bool isDoubleSided;
std::vector<glm::vec3> positions;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> texCoords;
std::vector<glm::vec3> instances_offsets;
std::vector<Tangents> tangents;
std::vector<unsigned int> indices;
protected:
// opengl
std::vector<GLuint> indices;
enum {
// required buffers
@ -43,21 +39,39 @@ protected:
// optionnal buffers :
NORMAL_BUFFER, TEXCOORD_BUFFER, TANGENT_BUFFER,
// instanciation buffer
INSTANCE_BUFFER,
NB_BUFFERS
};
GLuint vao;
GLuint vao; // TODO : this is supposed to be protected
protected:
int nb_buffers;
GLuint vbo[NB_BUFFERS];
GLenum primitive_type;
public:
Mesh();
~Mesh();
virtual ~Mesh();
void initGL(bool isDynamic = false);
void draw(Shader* shader = NULL, bool drawNormals = true, bool drawTexCoord = true, bool drawTangents = true);
void destroyGL();
glm::vec3* beginUpdateBuffer(int buffer);
void endUpdateBuffer();
/**
* this class is intended to be used with the default GL_TRIANGLES primitive,
* the methods mergeVertices, computeNormals, and computeTangents will probably have
* unpredictable behavior with other primitive types.
*/
void setPrimitiveType(GLenum type) {primitive_type = type;}
// merge same vertices
void mergeVertices();
bool operator() (const int& vertId1, const int& vertId2) const;
@ -80,6 +94,11 @@ public:
{
return tangents.size() != 0;
}
bool hasInstances() const
{
return instances_offsets.size() != 0;
}
};
#endif // MESH_H

View File

@ -10,6 +10,7 @@ public:
virtual void renderGL(Camera* myCamera, Scene* scene) = 0;
virtual bool requiresModernOpenGL() {return true;}
virtual void resize(int width, int height) {}
virtual ~Module(){}
};
#endif // MODULE

View File

@ -5,8 +5,11 @@
#define M_PI 3.14159265358979323846
#define MAGIC_RATIO 0.37139f
Sphere::Sphere(Material* mat, int n)
Sphere::Sphere(Material* mat, int n, float myRadius) :
radius(myRadius)
{
setMaterial(mat);
// icosahedron :
// top cap
@ -36,6 +39,9 @@ Sphere::Sphere(Material* mat, int n)
// geodesic subdivisions :
for(int i=0; i<n; i++)
subdivide();
for(glm::vec3 &vertex : positions)
vertex *= radius;
}
int Sphere::getEdge(int a, int b)

View File

@ -20,11 +20,13 @@ private:
};
Edge* edges;
float radius;
int getEdge(int a, int b);
void createVertex(float u, float v);
void subdivide();
public:
Sphere(Material* mat, int n = 0);
Sphere(Material* mat, int n = 0, float myRadius = 1.f);
};
class GridMesh : public MeshBuilder

View File

@ -15,13 +15,13 @@ void PhongMaterial::bindAttributes(Shader* myShader)
if(normal_map != NULL)
{
normal_map->bind(NORMAL_MAP);
myShader->bindInteger(myShader->getLocation("normalMap"), NORMAL_MAP);
myShader->bindUnsignedInteger(myShader->getLocation("normalMap"), NORMAL_MAP);
}
if(ambient_texture != NULL)
{
ambient_texture->bind(AMBIENT_TEXTURE);
myShader->bindInteger(myShader->getLocation("ambientTexture"), AMBIENT_TEXTURE);
myShader->bindUnsignedInteger(myShader->getLocation("ambientTexture"), AMBIENT_TEXTURE);
}
else
myShader->bindVec3(myShader->getLocation("materialKa"), ambient);
@ -29,7 +29,7 @@ void PhongMaterial::bindAttributes(Shader* myShader)
if(diffuse_texture != NULL)
{
diffuse_texture->bind(DIFFUSE_TEXTURE);
myShader->bindInteger(myShader->getLocation("diffuseTexture"), DIFFUSE_TEXTURE);
myShader->bindUnsignedInteger(myShader->getLocation("diffuseTexture"), DIFFUSE_TEXTURE);
}
else
myShader->bindVec3(myShader->getLocation("materialKd"), diffuse);
@ -37,7 +37,7 @@ void PhongMaterial::bindAttributes(Shader* myShader)
if(specular_texture != NULL)
{
specular_texture->bind(SPECULAR_TEXTURE);
myShader->bindInteger(myShader->getLocation("specularTexture"), SPECULAR_TEXTURE);
myShader->bindUnsignedInteger(myShader->getLocation("specularTexture"), SPECULAR_TEXTURE);
}
else
myShader->bindVec3(myShader->getLocation("materialKs"), specular);
@ -45,7 +45,7 @@ void PhongMaterial::bindAttributes(Shader* myShader)
if(alpha_mask != NULL)
{
alpha_mask->bind(ALPHA_MASK);
myShader->bindInteger(myShader->getLocation("alphaMask"), ALPHA_MASK);
myShader->bindUnsignedInteger(myShader->getLocation("alphaMask"), ALPHA_MASK);
}
}
else

View File

@ -33,10 +33,9 @@ public:
alpha_mask(NULL)
{}
virtual void bindAttributes(Shader* myShader = NULL);
void bindAttributes(Shader* myShader = NULL);
virtual unsigned int getFlags();
Shader* getShader() {return shader;}
unsigned int getFlags();
/**
* deprecated, you should use setDiffuseTexture instead
@ -48,9 +47,6 @@ public:
void setSpecularTexture(Texture* myTexture);
void setNormalMap(Texture* myNormalMap);
void setAlphaMask(Texture* myAlphaMask);
private:
Shader* shader;
};
#endif // PHONGMATERIAL_H

View File

@ -40,7 +40,7 @@ template <class T>
class ArraySceneIterator : public SceneIterator<T>
{
std::vector<T> &vec;
int id;
unsigned int id;
public:
ArraySceneIterator(std::vector<T> &myVec, int myId=0) : vec(myVec), id(myId) {}
virtual SceneIterator<T>& operator++() {++id; return *this;}
@ -61,8 +61,8 @@ public:
void addLight(Light* myLight) {lights.push_back(myLight);}
Mesh* getMesh(int id) {return geometry[id]->mesh;}
virtual SceneIterator<Light*>* getLights() {return new ArraySceneIterator<Light*>(lights);}
virtual SceneIterator<GeometryNode*>* getGeometry() {return new ArraySceneIterator<GeometryNode*>(geometry);}
SceneIterator<Light*>* getLights() {return new ArraySceneIterator<Light*>(lights);}
SceneIterator<GeometryNode*>* getGeometry() {return new ArraySceneIterator<GeometryNode*>(geometry);}
};
#endif // SCENE_H

View File

@ -1,4 +1,4 @@
#include <glew/glew.h>
#include "glew.h"
#include "shader.h"
#include <iostream>
#include "glassert.h"
@ -104,7 +104,7 @@ GLuint Shader::createShader(const std::string &source, GLenum shaderType)
break;
}
std::cerr << type_str << " shader not compiled : " << std::endl;
std::cout << "Shader source :" << std::endl << source << std::endl;
//std::cout << "Shader source :" << std::endl << source << std::endl;
printShaderInfoLog(shaderId);
return 0;
}
@ -186,7 +186,12 @@ void Shader::bindVec3Array(GLuint location, glm::vec3* vec, int nb_elements)
glAssert(glUniform3fv(location, nb_elements, (GLfloat*)vec));
}
void Shader::bindInteger(GLuint location, GLuint tex_id)
void Shader::bindUnsignedInteger(GLuint location, GLuint unsigned_integer)
{
glAssert(glUniform1i(location, tex_id));
glAssert(glUniform1ui(location, unsigned_integer));
}
void Shader::bindInteger(GLuint location, GLint integer)
{
glAssert(glUniform1i(location, integer));
}

View File

@ -26,7 +26,8 @@ public:
void bindVec3(GLuint location, glm::vec3 vec);
void bindVec4(GLuint location, glm::vec4 vec);
void bindVec3Array(GLuint location, glm::vec3* vec, int nb_elements);
void bindInteger(GLuint location, GLuint tex_id);
void bindUnsignedInteger(GLuint location, GLuint unsigned_integer);
void bindInteger(GLuint location, GLint integer);
};
#endif // SHADER_H

View File

@ -54,6 +54,14 @@ bool isDefined(const std::string &str, int nbDefines, const char** defines)
return false;
}
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;
}
/*
std::string ShaderSource::preprocess(std::string source, int nbDefines, const char** defines)
{
std::string compiled = "";
@ -90,3 +98,4 @@ std::string ShaderSource::preprocess(std::string source, int nbDefines, const ch
}
return compiled;
}
*/

View File

@ -26,7 +26,7 @@ public:
private:
std::string* sources[NB_TYPES];
std::string preprocess(std::string source, int nbDefines, const char** defines);
std::string preprocess(std::string source, int nbDefines, const char** defines, const char* version = "330 core");
};
#endif // SHADERSOURCE_H

View File

@ -1,4 +1,4 @@
#include <glew/glew.h>
#include "glew.h"
#include <GL/gl.h>
#include <GL/glext.h>
#include <cstdio>
@ -8,7 +8,7 @@
#include "framebuffer.h"
#include "module.h"
#include <chrono>
#include <string.h>
// main methods
bool SparrowRenderer::modernOpenglAvailable = false;
@ -21,12 +21,11 @@ void SparrowRenderer::initGL(int w, int h, bool forceCrappy)
fprintf(stderr, "Warning: glewInit failed!\n");
if (!forceCrappy &&
GLEW_ARB_vertex_program &&
GLEW_ARB_fragment_program &&
GLEW_ARB_texture_float &&
GLEW_ARB_draw_buffers &&
GLEW_ARB_framebuffer_object &&
glewIsSupported("GL_VERSION_3_3") &&
GLEW_VERSION_3_3)
GLEW_VERSION_3_3 &&
strcmp("3.30",(const char *)glGetString(GL_SHADING_LANGUAGE_VERSION))<=0)
{
modernOpenglAvailable = true;
printf("Modern OpenGL available.\n");
@ -68,20 +67,20 @@ void SparrowRenderer::resizeGL(int w, int h)
void SparrowRenderer::renderGL()
{
FrameBuffer::screen->bindFBO();
glAssert(glViewport(0, 0, width, height));
glAssert(glClearColor(clearColor.r, clearColor.g, clearColor.b, 1));
glAssert(glClearDepth(1.0));
glAssert(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
for(ModuleNode &m : modules)
{
if(m.isEnabled)
{
glFinish();
std::chrono::high_resolution_clock::time_point t = std::chrono::high_resolution_clock::now();
m.module->renderGL(getCamera(), scene);
m.seconds = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - t).count();
}
}
glFinish();
}
bool SparrowRenderer::isModernOpenGLAvailable()
@ -134,7 +133,6 @@ void SparrowRenderer::setModuleEnabled(std::string module, bool isEnabled)
void SparrowRenderer::setCamera(Camera* myCamera)
{
camera = myCamera;
camera->resize(width, height);
}
Camera* SparrowRenderer::getCamera()

View File

@ -1,6 +1,7 @@
#ifndef SPARROWRENDERER_H
#define SPARROWRENDERER_H
#include "glew.h"
#include <vector>
#include <string>
#include <glm/vec3.hpp>