Mesh is now the only mesh class, and is very generic

This commit is contained in:
Anselme 2015-07-18 16:51:29 +02:00
parent c20ad01d73
commit 6bfb5fed60
31 changed files with 370 additions and 825 deletions

View File

@ -1,30 +0,0 @@
#include "bumpmappedmesh.h"
#include "glassert.h"
void BumpMappedMesh::addVertex(const SRFVertex& v)
{
if(!locked)
vertices.push_back(v);
}
void BumpMappedMesh::setAttribPointer()
{
glAssert(glBindVertexArray(vao));
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_BUFFER]));
// position attribute
glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(SRFVertex), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(0));
// normal attribute
glAssert(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(SRFVertex), BUFFER_OFFSET(sizeof(glm::vec3))));
glAssert(glEnableVertexAttribArray(1));
// texCoord attribute
glAssert(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(SRFVertex), BUFFER_OFFSET(2*sizeof(glm::vec3))));
glAssert(glEnableVertexAttribArray(2));
// normal attribute
glAssert(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(SRFVertex), BUFFER_OFFSET(2*sizeof(glm::vec3)+sizeof(glm::vec2))));
glAssert(glEnableVertexAttribArray(3));
// texCoord attribute
glAssert(glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(SRFVertex), BUFFER_OFFSET(3*sizeof(glm::vec3)+sizeof(glm::vec2))));
glAssert(glEnableVertexAttribArray(4));
}

View File

@ -1,34 +0,0 @@
#ifndef BUMPMAPPEDMESH_H
#define BUMPMAPPEDMESH_H
#include "vertex.h"
#include "mesh.h"
class BumpMappedMesh : public Mesh
{
protected:
std::vector<SRFVertex> vertices;
virtual int getNbVertices()
{
return vertices.size();
}
virtual int getSizeofVertexType()
{
return sizeof(SRFVertex);
}
virtual void* getVertexData()
{
return (void*)(vertices.data());
}
virtual void setAttribPointer();
public:
void addVertex(const SRFVertex& v);
};
#endif // BUMPMAPPEDMESH_H

View File

@ -2,9 +2,9 @@
#include "shader.h"
#include <glm/glm.hpp>
#include "material.h"
#include "standardmesh.h"
#include "mesh.h"
Entity::Entity(StandardMesh* myMesh, Material* myMat) : mesh(myMesh), mat(myMat) {}
Entity::Entity(Mesh* myMesh, Material* myMat) : mesh(myMesh), mat(myMat) {}
void Entity::draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix)
{

View File

@ -4,18 +4,18 @@
#include "glm/mat4x4.hpp"
#include <vector>
class StandardMesh;
class Mesh;
class Material;
class Shader;
class Entity
{
protected:
StandardMesh* mesh;
Mesh* mesh;
Material* mat;
glm::mat4 modelMatrix;
public:
Entity(StandardMesh* myMesh, Material* myMat);
Entity(Mesh* myMesh, Material* myMat);
virtual void draw(const glm::mat4 viewMatrix, const glm::mat4 projectionMatrix);
glm::mat4* getTransform();
Shader* getShader();

View File

@ -1,50 +0,0 @@
#include "focuscontroller.h"
#include "camera.h"
#include <glm/ext.hpp>
void FocusController::setFocus(glm::vec3* object)
{
track = object;
dist = glm::distance2(*track, camera->getPosition());
}
void FocusController::mouseMove(int dx, int dy)
{
bool needUpdate = false;
if(dist < 0)
dist = glm::distance2(*track, camera->getPosition());
if(grabbed & 1)
{
camera->rotate(glm::vec2(dx*0.01f, dy*0.01f));
needUpdate = true;
}
if(grabbed & 4)
{
dist += dy*0.02f;
needUpdate = true;
}
if(needUpdate)
updateCamera();
}
void FocusController::mouseWheelEvent(int scrollCount)
{
if(dist < 0)
dist = glm::distance2(*track, camera->getPosition());
dist += scrollCount/600.0f;
updateCamera();
}
void FocusController::updateCamera()
{
glm::vec2 rot = camera->getRotation();
glm::vec3 pos = glm::vec3(std::sin(-rot.x)*std::cos(rot.y),
std::sin(rot.y),
std::cos(-rot.x)*std::cos(rot.y));
camera->moveTo(*track + dist*pos);
}

View File

@ -1,23 +0,0 @@
#ifndef FOCUSCONTROLLER_H
#define FOCUSCONTROLLER_H
#include "scenecontroller.h"
#include <glm/fwd.hpp>
class FocusController : public SceneController
{
glm::vec3* track;
float dist;
void updateCamera();
public:
FocusController(glm::vec3* object) : track(object), dist(-1) {}
void setFocus(glm::vec3* object);
virtual void mouseMove(int dx, int dy);
virtual void mouseWheelEvent(int scrollCount);
};
#endif // FOCUSCONTROLLER_H

View File

@ -1,42 +1,42 @@
#include "gridmesh.h"
GridMesh::GridMesh(int width, int height, bool alternate) : StandardMesh(), m_width(width), m_height(height)
GridMesh::GridMesh(int width, int height, bool alternate)
{
for(int i=0; i<=width; ++i)
{
for(int j=0; j<=height; ++j)
{
TexturedVertex v;
v.position = glm::vec3((float)i/(float)width, (float)j/(float)height, 0);
v.normal = glm::vec3(0, 0, 1);
v.texCoord = glm::vec2(v.position.x, v.position.y);
addVertex(v);
float x = (float)i/(float)width;
float y = (float)j/(float)height;
addPosition(x, y, 0);
addNormal(0, 0, 1);
addTexCoord(x, y);
if(i > 0 && j > 0)
{
if(alternate && (i+j)%2)
{
addFace(getVertexId(i, j),
getVertexId(i-1, j),
getVertexId(i, j-1));
addFace(getVertexId(i-1, j-1),
getVertexId(i, j-1),
getVertexId(i-1, j));
addTriangle(getVertexId(i, j, height),
getVertexId(i-1, j, height),
getVertexId(i, j-1, height));
addTriangle(getVertexId(i-1, j-1, height),
getVertexId(i, j-1, height),
getVertexId(i-1, j, height));
}
else
{
addFace(getVertexId(i, j),
getVertexId(i-1, j),
getVertexId(i-1, j-1));
addFace(getVertexId(i, j),
getVertexId(i-1, j-1),
getVertexId(i, j-1));
addTriangle(getVertexId(i, j, height),
getVertexId(i-1, j, height),
getVertexId(i-1, j-1, height));
addTriangle(getVertexId(i, j, height),
getVertexId(i-1, j-1, height),
getVertexId(i, j-1, height));
}
}
}
}
}
int GridMesh::getVertexId(int i, int j)
int GridMesh::getVertexId(int i, int j, int height)
{
return i*(m_height+1) + j;
return i*(height+1) + j;
}

View File

@ -1,16 +1,14 @@
#ifndef GRIDMESH_H
#define GRIDMESH_H
#include "standardmesh.h"
#include "meshbuilder.h"
class GridMesh : public StandardMesh
class GridMesh : public MeshBuilder
{
public:
GridMesh(int width, int height, bool alternate);
private:
int m_width;
int m_height;
int getVertexId(int i, int j);
int getVertexId(int i, int j, int height);
};
#endif // GRIDMESH_H

28
image.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef IMAGE
#define IMAGE
#include <cstddef>
struct Image
{
int depth;
int width;
int height;
void* pixels;
Image() : pixels(NULL) {}
~Image()
{
if(pixels != NULL)
delete[] (char*)pixels;
}
void allocate(int size)
{
pixels = new char[size];
}
};
#endif // IMAGE

139
imesh.cpp
View File

@ -1,139 +0,0 @@
#include "imesh.h"
#include "glassert.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
IMesh::~IMesh()
{
destroyGL();
}
void IMesh::addVertex(float x, float y, float z)
{
addVertex((glm::vec3(x, y, z));
}
void IMesh::addVertex(glm::vec3 &position)
{
positions.push_back(position);
}
void IMesh::addVertex(glm::vec3 &position, glm::vec3 &normal)
{
addVertex(position);
normals.push_back(normal);
}
void IMesh::addVertex(glm::vec3 &position, glm::vec2 &texCoord)
{
addVertex(position);
texCoords.push_back(texCoord);
}
void IMesh::addVertex(glm::vec3 &position, glm::vec3 &normal, glm::vec2 &texCoord)
{
addVertex(position, normal);
texCoords.push_back(texCoord);
}
void IMesh::addFace(int i1, int i2, int i3)
{
if(!locked)
{
indices.push_back(i1);
indices.push_back(i2);
indices.push_back(i3);
}
}
void IMesh::computeFaceNormals()
{
}
void IMesh::computeVertexNormals()
{
}
void IMesh::computeTangents()
{
}
bool IMesh::hasNormals()
{
return normals.size() != 0;
}
bool IMesh::hasTexCoords()
{
return texCoords.size() != 0;
}
bool IMesh::hasTangents()
{
return tangents.size() != 0;
}
void IMesh::initGL(bool isDynamic)
{
if(locked)
destroyGL();
GLenum buffer_type = isDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
// create VAO
glAssert(glGenVertexArrays(1, &vao));
glAssert(glBindVertexArray(vao));
// create VBOs
glAssert(glGenBuffers(NB_BUFFERS, vbo));
// 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));
// init normals vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), normals.data(), buffer_type));
// init texCoords vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, texCoords.size() * sizeof(glm::vec2), texCoords.data(), buffer_type));
// init tangents vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, tangents.size() * sizeof(glm::vec3)*2, tangents.data(), buffer_type));
// init indices vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[INDICES_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), buffer_type));
// unbind vao
glAssert(glBindVertexArray(0));
locked = true;
}
void IMesh::destroyGL()
{
if(locked)
{
locked = false;
glAssert(glDeleteVertexArrays(1, &vao));
glAssert(glDeleteBuffers(2, vbo));
}
}
void IMesh::draw()
{
if(locked)
{
glAssert(glBindVertexArray(vao));
glAssert(glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, indices.data()));
}
}

59
imesh.h
View File

@ -1,59 +0,0 @@
#ifndef IMESH_H
#define IMESH_H
#include <glew/glew.h>
#include <vector>
#include <glm/vec3.hpp>
#include <glm/vec2.hpp>
class IMesh
{
protected:
enum {POSITION_BUFFER, NORMAL_BUFFER, TEXCOORD_BUFFER, TANGENT_BUFFER, INDICES_BUFFER, NB_BUFFERS};
typedef struct
{
glm::vec3 tangent;
glm::vec3 bitangent;
} Tangents;
std::vector<glm::vec3> positions;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> texCoords;
std::vector<Tangents> tangents;
std::vector<unsigned int> indices;
GLuint vao;
GLuint vbo[NB_BUFFERS];
bool locked;
public:
~IMesh();
void addTriangle(int i1, int i2, int i3);
void addVertex(float x, float y, float z);
void addVertex(glm::vec3 &position);
void addVertex(glm::vec3 &position, glm::vec3 &normal);
void addVertex(glm::vec3 &position, glm::vec2 &texCoord);
void addVertex(glm::vec3 &position, glm::vec3 &normal, glm::vec2 &texCoord);
void computeFaceNormals();
void computeVertexNormals();
void computeTangents();
bool hasNormals();
bool hasTexCoords();
bool hasTangents();
/*
* When the mesh is locked, addFace and addVertex do nothing, but the mesh can be drawn
* initGL locks the mesh
* destroyGL unlocks the mesh
*/
void initGL(bool isDynamic = false);
void destroyGL();
void draw();
bool isLocked(){return locked;}
};
#endif // IMESH_H

View File

@ -1,5 +1,5 @@
#include "mesh.h"
#include <glm/ext.hpp>
#include "glassert.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
@ -9,39 +9,71 @@ Mesh::~Mesh()
destroyGL();
}
void Mesh::addFace(int i1, int i2, int i3)
bool Mesh::hasNormals()
{
if(!locked)
{
indices.push_back(i1);
indices.push_back(i2);
indices.push_back(i3);
}
return normals.size() != 0;
}
void Mesh::initGL()
bool Mesh::hasTexCoords()
{
return texCoords.size() != 0;
}
bool Mesh::hasTangents()
{
return tangents.size() != 0;
}
void Mesh::initGL(bool isDynamic)
{
if(locked)
destroyGL();
GLenum buffer_type = isDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
// create VAO
glAssert(glGenVertexArrays(1, &vao));
glAssert(glBindVertexArray(vao));
int nb_buffers = 2;
if(hasNormals())
++nb_buffers;
if(hasTexCoords())
++nb_buffers;
if(hasTangents())
++nb_buffers;
// create VBOs
glAssert(glGenBuffers(NB_BUFFERS, vbo));
int size = getSizeofVertexType();
// init vertex vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, getNbVertices() * size, getVertexData(), GL_STATIC_DRAW));
setAttribPointer();
glAssert(glGenBuffers(nb_buffers, vbo));
// init indices vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[INDICES_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW));
glAssert(glBufferData(GL_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), buffer_type));
// 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));
if(hasNormals())
{
// init normals vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), normals.data(), buffer_type));
}
if(hasNormals())
{
// init texCoords vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, texCoords.size() * sizeof(glm::vec2), texCoords.data(), buffer_type));
}
if(hasTangents())
{
// init tangents vbo
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
glAssert(glBufferData(GL_ARRAY_BUFFER, tangents.size() * sizeof(glm::vec3)*2, tangents.data(), buffer_type));
}
// unbind vao
glAssert(glBindVertexArray(0));
@ -64,6 +96,30 @@ void Mesh::draw()
if(locked)
{
glAssert(glBindVertexArray(vao));
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[POSITION_BUFFER]));
glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(0));
if(hasNormals())
{
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[NORMAL_BUFFER]));
glAssert(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(1));
}
if(hasTexCoords())
{
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TEXCOORD_BUFFER]));
glAssert(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(2));
}
if(hasTangents())
{
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[TANGENT_BUFFER]));
glAssert(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Tangents), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(3));
glAssert(glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Tangents), BUFFER_OFFSET(sizeof(glm::vec3))));
glAssert(glEnableVertexAttribArray(4));
}
glAssert(glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, indices.data()));
}
}

49
mesh.h
View File

@ -3,27 +3,50 @@
#include <glew/glew.h>
#include <vector>
#include <glm/vec3.hpp>
#include <glm/vec2.hpp>
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
class Mesh{
class Mesh
{
protected:
enum {VERTEX_BUFFER, INDICES_BUFFER, NB_BUFFERS};
enum {
// required buffers
INDICES_BUFFER, POSITION_BUFFER,
// optionnal buffers :
NORMAL_BUFFER, TEXCOORD_BUFFER, TANGENT_BUFFER,
NB_BUFFERS
};
typedef struct
{
glm::vec3 tangent;
glm::vec3 binormal;
} Tangents;
std::vector<glm::vec3> positions;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> texCoords;
std::vector<Tangents> tangents;
std::vector<unsigned int> indices;
GLuint vao;
GLuint vbo[2];
bool locked;
virtual int getNbVertices() = 0;
virtual int getSizeofVertexType() = 0;
virtual void* getVertexData() = 0;
virtual void setAttribPointer() = 0;
GLuint vao;
GLuint vbo[NB_BUFFERS];
bool locked;
public:
~Mesh();
void addFace(int i1, int i2, int i3);
void initGL();
bool hasNormals();
bool hasTexCoords();
bool hasTangents();
/*
* When the mesh is locked, addFace and addVertex do nothing, but the mesh can be drawn
* initGL locks the mesh
* destroyGL unlocks the mesh
*/
void initGL(bool isDynamic = false);
void destroyGL();
void draw();
bool isLocked(){return locked;}

123
meshbuilder.cpp Normal file
View File

@ -0,0 +1,123 @@
#include "meshbuilder.h"
void MeshBuilder::addPosition(float x, float y, float z)
{
addPosition(glm::vec3(x, y, z));
}
void MeshBuilder::addPosition(const glm::vec3 &position)
{
positions.push_back(position);
}
void MeshBuilder::addNormal(float x, float y, float z)
{
addNormal(glm::vec3(x, y, z));
}
void MeshBuilder::addNormal(const glm::vec3 &normal)
{
normals.push_back(normal);
}
void MeshBuilder::addTexCoord(float u, float v)
{
addTexCoord(glm::vec2(u, v));
}
void MeshBuilder::addTexCoord(const glm::vec2 &texCoord)
{
texCoords.push_back(texCoord);
}
void MeshBuilder::addVertex(glm::vec3 &position, glm::vec3 &normal)
{
addPosition(position);
addNormal(normal);
}
void MeshBuilder::addVertex(glm::vec3 &position, glm::vec2 &texCoord)
{
addPosition(position);
addTexCoord(texCoord);
}
void MeshBuilder::addVertex(glm::vec3 &position, glm::vec3 &normal, glm::vec2 &texCoord)
{
addVertex(position, normal);
addTexCoord(texCoord);
}
void MeshBuilder::addTriangle(int i1, int i2, int i3)
{
if(!locked)
{
indices.push_back(i1);
indices.push_back(i2);
indices.push_back(i3);
}
}
void MeshBuilder::computeTangents()
{
if(!hasTexCoords())
return;
tangents = std::vector<Tangents>(positions.size());
for (int i=0; i < indices.size(); i += 3)
{
const glm::vec3 &v1 = positions[i];
const glm::vec3 &v2 = positions[i+1];
const glm::vec3 &v3 = positions[i+2];
const glm::vec2& w1 = texCoords[i];
const glm::vec2& w2 = texCoords[i+1];
const glm::vec2& w3 = texCoords[i+2];
float x1 = v2.x - v1.x;
float x2 = v3.x - v1.x;
float y1 = v2.y - v1.y;
float y2 = v3.y - v1.y;
float z1 = v2.z - v1.z;
float z2 = v3.z - v1.z;
float s1 = w2.x - w1.x;
float s2 = w3.x - w1.x;
float t1 = w2.y - w1.y;
float t2 = w3.y - w1.y;
float r = 1.0f / (s1 * t2 - s2 * t1);
glm::vec3 sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
(t2 * z1 - t1 * z2) * r);
glm::vec3 tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
(s1 * z2 - s2 * z1) * r);
Tangents& tan1 = tangents[i];
Tangents& tan2 = tangents[i+1];
Tangents& tan3 = tangents[i+2];
tan1.tangent += sdir;
tan2.tangent += sdir;
tan3.tangent += sdir;
tan1.binormal += tdir;
tan2.binormal += tdir;
tan3.binormal += tdir;
}
// building tangent matrix
/*
for (long a = 0; a < vertexCount; a++)
{
const Vector3D& n = normal[a];
const Vector3D& t = tan1[a];
// Gram-Schmidt orthogonalize
tangent[a] = (t - n * Dot(n, t)).Normalize();
// Calculate handedness
tangent[a].w = (Dot(Cross(n, t), tan2[a]) < 0.0F) ? -1.0F : 1.0F;
}*/
}

26
meshbuilder.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef MESHBUILDER_H
#define MESHBUILDER_H
#include "mesh.h";
class MeshBuilder : public Mesh
{
public:
void addTriangle(int i1, int i2, int i3);
void addPosition(float x, float y, float z);
void addPosition(const glm::vec3 &position);
void addNormal(float x, float y, float z);
void addNormal(const glm::vec3 &normal);
void addTexCoord(float u, float v);
void addTexCoord(const glm::vec2 &texCoord);
void addVertex(glm::vec3 &position, glm::vec3 &normal);
void addVertex(glm::vec3 &position, glm::vec2 &texCoord);
void addVertex(glm::vec3 &position, glm::vec3 &normal, glm::vec2 &texCoord);
// require normals and texCoord
void computeTangents();
};
#endif // MESHBUILDER_H

View File

@ -1,5 +1,7 @@
#include "phongmodule.h"
#include "lights.h"
#include "shader.h"
#include "resourcebase.h"
PhongModule::PhongModule(Lights* myDirLights, Lights* myPointLights) :
BasicModule(ResourceBase::getShader("phong")), dirLights(myDirLights), pointLights(myPointLights)

View File

@ -3,8 +3,6 @@
#include <glew/glew.h>
#include "basicmodule.h"
#include "phongmaterial.h"
#include "standardmesh.h"
class Lights;

View File

@ -1,7 +1,7 @@
#include "resourcebase.h"
ResourceBase::DataBase<Texture> ResourceBase::textures;
ResourceBase::DataBase<StandardMesh> ResourceBase::meshes;
ResourceBase::DataBase<Mesh> ResourceBase::meshes;
ResourceBase::DataBase<Material> ResourceBase::materials;
ResourceBase::DataBase<Shader> ResourceBase::shaders;
ResourceBase::DataBase<Entity> ResourceBase::entities;
@ -12,7 +12,7 @@ void ResourceBase::setTexture(const std::string &textureName, Texture* myTexture
textures.add(textureName, myTexture);
}
void ResourceBase::setMesh(const std::string &meshName, StandardMesh* myMesh )
void ResourceBase::setMesh(const std::string &meshName, Mesh* myMesh )
{
meshes.add(meshName, myMesh);
}
@ -43,7 +43,7 @@ Texture* ResourceBase::getTexture(const std::string &textureName)
return textures.get(textureName);
}
StandardMesh* ResourceBase::getMesh(const std::string &meshName)
Mesh* ResourceBase::getMesh(const std::string &meshName)
{
return meshes.get(meshName);
}

View File

@ -2,7 +2,7 @@
#define RESOURCEBASE_H
class Texture;
class StandardMesh;
class Mesh;
class Material;
class Shader;
class Entity;
@ -17,14 +17,14 @@ class ResourceBase
{
public:
static void setTexture(const std::string &textureName, Texture* myTexture);
static void setMesh(const std::string &meshName, StandardMesh* myMesh);
static void setMesh(const std::string &meshName, Mesh* myMesh);
static void setMaterial(const std::string &materialName, Material* myMaterial);
static void setShader(const std::string &shaderName, Shader* myShader);
static void setEntity(const std::string &entityName, Entity* myEntity);
static void setLights(const std::string &lightsName, Lights* myLights);
static Texture* getTexture(const std::string &textureName);
static StandardMesh* getMesh(const std::string &meshName);
static Mesh* getMesh(const std::string &meshName);
static Material* getMaterial(const std::string &materialName);
static Shader* getShader(const std::string &shaderName);
static Entity* getEntity(const std::string &entityName);
@ -57,7 +57,7 @@ protected:
};
static DataBase<Texture> textures;
static DataBase<StandardMesh> meshes;
static DataBase<Mesh> meshes;
static DataBase<Material> materials;
static DataBase<Shader> shaders;
static DataBase<Entity> entities;

View File

@ -1,26 +0,0 @@
#include "scenecontroller.h"
#include "camera.h"
#include <QObject>
void SceneController::setCamera(Camera* myCamera)
{
camera = myCamera;
}
void SceneController::mouseEvent(int button, bool state)
{
switch (button) {
case Qt::LeftButton:
grabbed += state ? 1 : -1;
break;
case Qt::RightButton:
grabbed += state ? 2 : -2;
break;
case Qt::MiddleButton:
grabbed += state ? 4 : -4;
break;
default:
break;
}
}

View File

@ -1,23 +0,0 @@
#ifndef SCENECONTROLLER_H
#define SCENECONTROLLER_H
#include <cstddef>
class Camera;
class SceneController
{
protected:
Camera* camera;
int grabbed;
public:
SceneController() : camera(NULL), grabbed(0) {}
void setCamera(Camera* myCamera);
virtual void mouseMove(int dx, int dy) {}
virtual void mouseEvent(int button, bool state);
virtual void keyEvent(int key, bool state) {}
virtual void mouseWheelEvent(int scrollCount) {}
};
#endif // SCENECONTROLLER_H

View File

@ -4,8 +4,7 @@
#
#-------------------------------------------------
QT += core gui opengl widgets
QT -= core gui
Debug:TARGET = sparrowRendererDebug
Release:TARGET = sparrowRenderer
@ -29,22 +28,17 @@ SOURCES += shader.cpp \
gridmesh.cpp \
texture.cpp \
phongmaterial.cpp \
scenecontroller.cpp \
sphere.cpp \
entity.cpp \
utils.cpp \
entity.cpp \
lights.cpp \
sparrowrenderer.cpp \
resourcebase.cpp \
focuscontroller.cpp \
phongmodule.cpp \
skyboxmodule.cpp \
basicmodule.cpp \
framebuffer.cpp \
standardmesh.cpp \
mesh.cpp \
bumpmappedmesh.cpp \
imesh.cpp
meshbuilder.cpp \
mesh.cpp
HEADERS += shader.h \
camera.h \
@ -52,26 +46,21 @@ HEADERS += shader.h \
material.h \
gridmesh.h \
texture.h \
phongmaterial.h \
scenecontroller.h \
phongmaterial.h \
sphere.h \
entity.h \
utils.h \
entity.h \
lights.h \
sparrowrenderer.h \
resourcebase.h \
focuscontroller.h \
resourcebase.h \
phongmodule.h \
skyboxmodule.h \
basicmodule.h \
module.h \
resource.h \
framebuffer.h \
standardmesh.h \
meshbuilder.h \
mesh.h \
bumpmappedmesh.h \
vertex.h \
imesh.h
image.h
OTHER_FILES += *.frag *.vert *.glsl *.todo

View File

@ -24,17 +24,17 @@ Sphere::Sphere(int n)
int bottom = 7;
int offset = (i+1)%5;
// top cap
addFace(0, top+i, top+offset);
addTriangle(0, top+i, top+offset);
// bottom cap
addFace(6, bottom+offset, bottom+i);
addTriangle(6, bottom+offset, bottom+i);
// middle ribbon
addFace(top+i, bottom+i, top+offset);
addFace(top+offset, bottom+i, bottom+offset);
addTriangle(top+i, bottom+i, top+offset);
addTriangle(top+offset, bottom+i, bottom+offset);
}
// geodesic subdivisions :
for(int i=0; i<n; i++){
edges = new Edge[vertices.size()-1];
edges = new Edge[positions.size()-1];
int nb_triangles = indices.size()/3;
for(int j=0; j<nb_triangles; j++)
{
@ -48,8 +48,8 @@ Sphere::Sphere(int n)
vid[k] = getEdge(a, b);
}
for(int k=0; k<3; k++)
addFace(indices[j*3 + k], vid[k], vid[(k+2)%3]);
addFace(vid[0], vid[1], vid[2]);
addTriangle(indices[j*3 + k], vid[k], vid[(k+2)%3]);
addTriangle(vid[0], vid[1], vid[2]);
}
delete[](edges);
indices.erase(indices.begin(), indices.begin()+nb_triangles*3);
@ -66,22 +66,19 @@ int Sphere::getEdge(int a, int b)
vid = current->vertex;
else if(current->next == NULL)
{
// creating subdivision vertex
TexturedVertex v;
TexturedVertex v0 = vertices[a];
TexturedVertex v1 = vertices[b];
v.position = glm::normalize((v0.position + v1.position)/2.f);
v.normal = v.position;
vid = positions.size();
// creating subdivision vertex
glm::vec3 pos = glm::normalize(positions[a] + positions[b] / 2.f);
addPosition(pos);
addNormal(pos);
// u/v sphériques, cohérents sur toute la sphère sauf des artefacts au niveau des u==0
float newU = (v.position.x < 0 ? 1.5f : 1.f) + atan(v.position.z/v.position.x)/(2*M_PI);
float newV = acos(v.position.y)/M_PI;
v.texCoord = glm::vec2(newU - floor(newU), newV);
float newU = (pos.x < 0 ? 1.5f : 1.f) + atan(pos.z/pos.x)/(2*M_PI);
float newV = acos(pos.y)/M_PI;
addTexCoord(newU - floor(newU), newV);
// alternative, u/v moyennés :
//v.texCoord = (v0.texCoord + v1.texCoord)/2.f;
vid = vertices.size();
addVertex(v);
// inserting the new vertex in the edge collection
if(current->b == -1)
{
@ -99,11 +96,10 @@ int Sphere::getEdge(int a, int b)
void Sphere::createVertex(float u, float v)
{
TexturedVertex vert;
vert.position = glm::vec3(cos(u*2*M_PI)*sin(v*M_PI),
cos(v*M_PI),
sin(u*2*M_PI)*sin(v*M_PI));
vert.normal = vert.position;
vert.texCoord = glm::vec2(u, v);
addVertex(vert);
glm::vec3 pos(cos(u*2*M_PI)*sin(v*M_PI),
cos(v*M_PI),
sin(u*2*M_PI)*sin(v*M_PI));
addPosition(pos);
addNormal(pos);
addTexCoord(u, v);
}

View File

@ -1,9 +1,9 @@
#ifndef SPHERE_H
#define SPHERE_H
#include "standardmesh.h"
#include "meshbuilder.h"
class Sphere : public StandardMesh
class Sphere : public MeshBuilder
{
private:
class Edge{

View File

@ -1,24 +0,0 @@
#include "standardmesh.h"
#include "glassert.h"
void StandardMesh::addVertex(const TexturedVertex& v)
{
if(!locked)
vertices.push_back(v);
}
void StandardMesh::setAttribPointer()
{
glAssert(glBindVertexArray(vao));
glAssert(glBindBuffer(GL_ARRAY_BUFFER, vbo[VERTEX_BUFFER]));
// position attribute
glAssert(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), BUFFER_OFFSET(0)));
glAssert(glEnableVertexAttribArray(0));
// normal attribute
glAssert(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), BUFFER_OFFSET(sizeof(glm::vec3))));
glAssert(glEnableVertexAttribArray(1));
// texCoord attribute
glAssert(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), BUFFER_OFFSET(2*sizeof(glm::vec3))));
glAssert(glEnableVertexAttribArray(2));
}

View File

@ -1,34 +0,0 @@
#ifndef STANDARDMESH_H
#define STANDARDMESH_H
#include "vertex.h"
#include "mesh.h"
class StandardMesh : public Mesh{
protected:
std::vector<TexturedVertex> vertices;
virtual int getNbVertices()
{
return vertices.size();
}
virtual int getSizeofVertexType()
{
return sizeof(TexturedVertex);
}
virtual void* getVertexData()
{
return (void*)(vertices.data());
}
virtual void setAttribPointer();
public:
void addVertex(const TexturedVertex& v);
};
#endif // STANDARDMESH_H

View File

@ -1,6 +1,6 @@
#include "texture.h"
#include "glassert.h"
#include "utils.h"
#include "image.h"
#include <glm/gtc/noise.hpp>
@ -13,17 +13,17 @@ Texture::Texture() : type(GL_TEXTURE_2D)
setFiltering(GL_LINEAR);
}
Texture::Texture(const std::string filename) : type(GL_TEXTURE_2D)
Texture::Texture(Image* myImage) : type(GL_TEXTURE_2D)
{
glAssert(glGenTextures(1, &texId));
glAssert(glBindTexture(type, texId));
createTexture(filename, GL_TEXTURE_2D);
createTexture(myImage, GL_TEXTURE_2D);
setWrap(GL_REPEAT);
setFiltering(GL_LINEAR);
}
Texture::Texture(const std::string filename[6]) : type(GL_TEXTURE_CUBE_MAP)
Texture::Texture(Image* myCubemapImages[6]) : type(GL_TEXTURE_CUBE_MAP)
{
glAssert(glActiveTexture(GL_TEXTURE0));
glAssert(glGenTextures(1, &texId));
@ -31,7 +31,7 @@ Texture::Texture(const std::string filename[6]) : type(GL_TEXTURE_CUBE_MAP)
for(int i=0; i<6; ++i)
{
createTexture(filename[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
createTexture(myCubemapImages[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
setWrap(GL_CLAMP_TO_EDGE);
setFiltering(GL_LINEAR);
}
@ -75,12 +75,11 @@ void Texture::createNoiseTexture(GLenum textureSlot, int width, int height, floa
glAssert(glTexImage2D(textureSlot, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
}
void Texture::createTexture(std::string filename, GLenum textureSlot)
void Texture::createTexture(Image* myImage, GLenum textureSlot)
{
Utils::Image img(filename);
int bpp = (img.depth() == 32) ? GL_RGBA : GL_RGB;
int format = (img.depth() == 32) ? GL_BGRA : GL_BGR;
glAssert(glTexImage2D(textureSlot, 0, bpp, img.width(), img.height(), 0, format, GL_UNSIGNED_BYTE, img.pixels()));
int bpp = (myImage->depth == 32) ? GL_RGBA : GL_RGB;
int format = (myImage->depth == 32) ? GL_BGRA : GL_BGR;
glAssert(glTexImage2D(textureSlot, 0, bpp, myImage->width, myImage->height, 0, format, GL_UNSIGNED_BYTE, myImage->pixels));
}
void Texture::setWrap(GLint wrap)

View File

@ -4,7 +4,7 @@
#include <glew/glew.h>
#include <string>
class QImage;
class Image;
class Texture
{
@ -13,16 +13,16 @@ private:
GLenum type;
void createNoiseTexture(GLenum textureSlot, int width, int height, float frequency, float myScale);
void createTexture(std::string filename, GLenum textureSlot);
void createTexture(Image* myImage, GLenum textureSlot);
void setWrap(GLint wrap);
void setFiltering(GLint filter);
public:
// creates a 2D texture from perlin noise
Texture();
// creates a standard texture from an image
Texture(const std::string filename);
Texture(Image* myImage);
// creates a cubeMap from 6 images
Texture(const std::string filename[6]);
Texture(Image* myCubemapImages[6]);
~Texture();
void bind(int slot);

193
utils.cpp
View File

@ -1,193 +0,0 @@
#include "utils.h"
#include "standardmesh.h"
#include <QFile>
#include <QTextStream>
#include <QImage>
#include <vector>
std::string Utils::fileToString(const std::string &filename)
{
QFile f(QString(filename.c_str()));
if(!f.open(QFile::ReadOnly | QFile::Text))
return NULL;
QTextStream in(&f);
return in.readAll().toStdString();
}
/*void Utils::loadOBJ(const std::string &filename)
{
// loadOBJ
// mtllib -> loadMTL
// g -> resourcebase.addMesh(new Mesh())
// -> resourcebase.addEntity(new Entity())
// end -> resourcebase.addEntity(new Entity())
std::vector<glm::vec3> pos;
std::vector<glm::vec3> norm;
std::vector<glm::vec2> tex;
QString line;
QStringList list;
QFile f(QString(filename.c_str()));
if(!f.open(QFile::ReadOnly | QFile::Text))
return NULL;
QTextStream in(&f);
line = in.readLine();
while(!line.isNull())
{
if(line.isEmpty())
{
line = in.readLine();
continue;
}
switch(line.at(0).toLatin1())
{
case 'v':
//vertex attribute
list = line.split(QChar(' '));
switch(line.at(1).toLatin1())
{
case ' ':
// vertex position
pos.push_back(glm::vec3(list[1].toFloat(), list[2].toFloat(), list[3].toFloat()));
break;
case 't':
// texCoord
tex.push_back(glm::vec2(list[1].toFloat(), list[2].toFloat()));
break;
case 'n':
// normal
norm.push_back(glm::vec3(list[1].toFloat(), list[2].toFloat(), list[3].toFloat()));
break;
}
break;
case 'f':
// face
break;
case 'u':
// usemtl
break;
default:
case 'm':
// mtllib
break;
default:
case '#':
// comment
break;
}
line = in.readLine();
}
f.close();
}*/
void Utils::loadMTL(const std::string &filename)
{
// loadMTL
// newmtl -> resourcebase.addMaterial(new Material())
}
StandardMesh* Utils::loadOBJ(const std::string &filename)
{
StandardMesh* mesh = new StandardMesh();
std::vector<glm::vec3> pos;
std::vector<glm::vec3> norm;
std::vector<glm::vec2> tex;
QString line;
QStringList list;
QStringList faceList;
TexturedVertex v;
int nb_vertices = 0;
QFile f(QString(filename.c_str()));
if(!f.open(QFile::ReadOnly | QFile::Text))
return NULL;
QTextStream in(&f);
line = in.readLine();
while(!line.isNull())
{
if(line.isEmpty())
{
line = in.readLine();
continue;
}
switch(line.at(0).toLatin1())
{
case 'v':
//vertex attribute
list = line.split(QChar(' '));
switch(line.at(1).toLatin1())
{
case ' ':
// vertex position
pos.push_back(glm::vec3(list[1].toFloat(), list[2].toFloat(), list[3].toFloat()));
break;
case 't':
// texCoord
tex.push_back(glm::vec2(list[1].toFloat(), list[2].toFloat()));
break;
case 'n':
// normal
norm.push_back(glm::vec3(list[1].toFloat(), list[2].toFloat(), list[3].toFloat()));
break;
}
break;
case 'f':
// face
list = line.split(QChar(' '));
mesh->addFace(nb_vertices, nb_vertices+1, nb_vertices+2);
for(int i=0; i<3; ++i)
{
faceList = list[i+1].split(QChar('/'));
v.position = pos[faceList[0].toInt()];
v.texCoord= tex[faceList[1].toInt()];
v.normal = norm[faceList[2].toInt()];
mesh->addVertex(v);
}
nb_vertices += 3;
break;
case 'u':
// usemtl
break;
default:
case '#':
// comment
break;
}
line = in.readLine();
}
return mesh;
}
Utils::Image::Image(std::string filename)
{
img = new QImage(QString(filename.c_str()));
}
Utils::Image::~Image()
{
delete(img);
}
int Utils::Image::depth()
{
return img->depth();
}
int Utils::Image::width()
{
return img->width();
}
int Utils::Image::height()
{
return img->height();
}
void* Utils::Image::pixels()
{
return (void*)img->bits();
}

29
utils.h
View File

@ -1,29 +0,0 @@
#ifndef UTILS_H
#define UTILS_H
#include <string>
class QImage;
class StandardMesh;
class Utils
{
public:
static std::string fileToString(const std::string &filename);
static StandardMesh* loadOBJ(const std::string &filename);
//static void loadOBJ(const std::string &filename);
static void loadMTL(const std::string &filename);
class Image
{
private:
QImage* img;
public:
Image(std::string filename);
~Image();
int depth();
int width();
int height();
void* pixels();
};
};
#endif // UTILS_H

View File

@ -1,29 +0,0 @@
#ifndef VERTEX_H
#define VERTEX_H
#include "glm/vec3.hpp"
#include "glm/vec2.hpp"
struct Vertex
{
glm::vec3 position;
};
struct BasicVertex : public Vertex
{
glm::vec3 normal;
};
struct TexturedVertex : public BasicVertex
{
glm::vec2 texCoord;
};
struct SRFVertex : public TexturedVertex
{
glm::vec3 tangent;
glm::vec3 bitangent;
};
#endif // VERTEX_H