Mesh is now the only mesh class, and is very generic
This commit is contained in:
parent
c20ad01d73
commit
6bfb5fed60
@ -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));
|
||||
}
|
@ -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
|
@ -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)
|
||||
{
|
||||
|
6
entity.h
6
entity.h
@ -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();
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
40
gridmesh.cpp
40
gridmesh.cpp
@ -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;
|
||||
}
|
||||
|
@ -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
28
image.h
Normal 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
139
imesh.cpp
@ -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
59
imesh.h
@ -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
|
94
mesh.cpp
94
mesh.cpp
@ -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
49
mesh.h
@ -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
123
meshbuilder.cpp
Normal 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
26
meshbuilder.h
Normal 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
|
@ -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)
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#include <glew/glew.h>
|
||||
#include "basicmodule.h"
|
||||
#include "phongmaterial.h"
|
||||
#include "standardmesh.h"
|
||||
|
||||
class Lights;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
@ -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
|
||||
|
||||
|
46
sphere.cpp
46
sphere.cpp
@ -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);
|
||||
}
|
||||
|
4
sphere.h
4
sphere.h
@ -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{
|
||||
|
@ -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));
|
||||
}
|
@ -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
|
19
texture.cpp
19
texture.cpp
@ -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)
|
||||
|
@ -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
193
utils.cpp
@ -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
29
utils.h
@ -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
|
29
vertex.h
29
vertex.h
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user