added instancing, and plenty of little things, fixed lots of bugs
This commit is contained in:
parent
e536a76577
commit
d2df3a998f
@ -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}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
1772
src/glxew.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,9 +6,9 @@
|
||||
|
||||
struct Image
|
||||
{
|
||||
int depth;
|
||||
int width;
|
||||
int height;
|
||||
int depth;
|
||||
void* pixels;
|
||||
|
||||
Image() : pixels(NULL) {}
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
81
src/mesh.cpp
81
src/mesh.cpp
@ -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];
|
||||
|
37
src/mesh.h
37
src/mesh.h
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef SPARROWRENDERER_H
|
||||
#define SPARROWRENDERER_H
|
||||
|
||||
#include "glew.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <glm/vec3.hpp>
|
||||
|
Loading…
x
Reference in New Issue
Block a user