sphere and grid are now in the same file : parametricmesh
This commit is contained in:
parent
124ef6ec2e
commit
9c2c8315b0
@ -15,8 +15,7 @@ set(LIB_SRC_LIST
|
|||||||
asciientity.cpp
|
asciientity.cpp
|
||||||
asciimodule.cpp
|
asciimodule.cpp
|
||||||
framebuffer.cpp
|
framebuffer.cpp
|
||||||
gbuffermodule.cpp
|
gbuffermodule.cpp
|
||||||
gridmesh.cpp
|
|
||||||
lights.cpp
|
lights.cpp
|
||||||
meshbuilder.cpp
|
meshbuilder.cpp
|
||||||
phongentity.cpp
|
phongentity.cpp
|
||||||
@ -25,7 +24,7 @@ set(LIB_SRC_LIST
|
|||||||
shader.cpp
|
shader.cpp
|
||||||
skyboxmodule.cpp
|
skyboxmodule.cpp
|
||||||
sparrowrenderer.cpp
|
sparrowrenderer.cpp
|
||||||
sphere.cpp
|
parametricmesh.cpp
|
||||||
texture.cpp
|
texture.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
43
gridmesh.cpp
43
gridmesh.cpp
@ -1,43 +0,0 @@
|
|||||||
#include "gridmesh.h"
|
|
||||||
|
|
||||||
GridMesh::GridMesh(Material* mat, int width, int height, bool alternate)
|
|
||||||
{
|
|
||||||
addGroup(mat);
|
|
||||||
for(int i=0; i<=width; ++i)
|
|
||||||
{
|
|
||||||
for(int j=0; j<=height; ++j)
|
|
||||||
{
|
|
||||||
float x = (float)i/(float)width;
|
|
||||||
float y = (float)j/(float)height;
|
|
||||||
addPosition(x-0.5f, 0, y-0.5f);
|
|
||||||
addNormal(0, 1, 0);
|
|
||||||
addTexCoord(x, y);
|
|
||||||
if(i > 0 && j > 0)
|
|
||||||
{
|
|
||||||
if(alternate && (i+j)%2)
|
|
||||||
{
|
|
||||||
addTriangle(getVertexId(i, j, height),
|
|
||||||
getVertexId(i, j-1, height),
|
|
||||||
getVertexId(i-1, j, height));
|
|
||||||
addTriangle(getVertexId(i-1, j-1, height),
|
|
||||||
getVertexId(i-1, j, height),
|
|
||||||
getVertexId(i, j-1, height));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
addTriangle(getVertexId(i, j, height),
|
|
||||||
getVertexId(i-1, j-1, height),
|
|
||||||
getVertexId(i-1, j, height));
|
|
||||||
addTriangle(getVertexId(i, j, height),
|
|
||||||
getVertexId(i, j-1, height),
|
|
||||||
getVertexId(i-1, j-1, height));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int GridMesh::getVertexId(int i, int j, int height)
|
|
||||||
{
|
|
||||||
return i*(height+1) + j;
|
|
||||||
}
|
|
14
gridmesh.h
14
gridmesh.h
@ -1,14 +0,0 @@
|
|||||||
#ifndef GRIDMESH_H
|
|
||||||
#define GRIDMESH_H
|
|
||||||
|
|
||||||
#include "meshbuilder.h"
|
|
||||||
|
|
||||||
class GridMesh : public MeshBuilder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GridMesh(Material* mat, int width, int height, bool alternate = true);
|
|
||||||
private:
|
|
||||||
int getVertexId(int i, int j, int height);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // GRIDMESH_H
|
|
3
mesh.h
3
mesh.h
@ -7,9 +7,8 @@
|
|||||||
|
|
||||||
class Material;
|
class Material;
|
||||||
|
|
||||||
class Mesh
|
struct Mesh
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
glm::vec3 tangent;
|
glm::vec3 tangent;
|
||||||
|
154
parametricmesh.cpp
Normal file
154
parametricmesh.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
#include "parametricmesh.h"
|
||||||
|
#include "glm/ext.hpp"
|
||||||
|
#include "phongmaterial.h"
|
||||||
|
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#define MAGIC_RATIO 0.37139f
|
||||||
|
|
||||||
|
Sphere::Sphere(Material* mat, int n)
|
||||||
|
{
|
||||||
|
// icosahedron :
|
||||||
|
addGroup(mat);
|
||||||
|
Group* group = &(indiceGroups[0]);
|
||||||
|
|
||||||
|
// top cap
|
||||||
|
createVertex(0, 1);
|
||||||
|
for(int i=0; i<5; i++)
|
||||||
|
createVertex(i/5.f, 1-MAGIC_RATIO);
|
||||||
|
|
||||||
|
// bottom cap
|
||||||
|
createVertex(0, 0);
|
||||||
|
for(int i=0; i<5; i++)
|
||||||
|
createVertex((i+0.5f)/5.f, MAGIC_RATIO);
|
||||||
|
|
||||||
|
// Compute faces
|
||||||
|
for(int i=0; i<5; i++){
|
||||||
|
int top = 1;
|
||||||
|
int bottom = 7;
|
||||||
|
int offset = (i+1)%5;
|
||||||
|
// top cap
|
||||||
|
addTriangle(0, top+i, top+offset);
|
||||||
|
// bottom cap
|
||||||
|
addTriangle(6, bottom+offset, bottom+i);
|
||||||
|
// middle ribbon
|
||||||
|
addTriangle(top+i, bottom+i, top+offset);
|
||||||
|
addTriangle(top+offset, bottom+i, bottom+offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// geodesic subdivisions :
|
||||||
|
for(int i=0; i<n; i++)
|
||||||
|
subdivide(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Sphere::getEdge(int a, int b)
|
||||||
|
{
|
||||||
|
Edge* current = edges+a;
|
||||||
|
int vid = -1;
|
||||||
|
while(vid == -1)
|
||||||
|
{
|
||||||
|
if(current->b == b)
|
||||||
|
vid = current->vertex;
|
||||||
|
else if(current->next == NULL)
|
||||||
|
{
|
||||||
|
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 = (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;
|
||||||
|
|
||||||
|
// inserting the new vertex in the edge collection
|
||||||
|
if(current->b == -1)
|
||||||
|
{
|
||||||
|
current->vertex = vid;
|
||||||
|
current->b = b;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
current->next = new Edge(b, vid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
return vid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sphere::subdivide(Group* group)
|
||||||
|
{
|
||||||
|
edges = new Edge[positions.size()-1];
|
||||||
|
int nb_triangles = group->indices.size()/3;
|
||||||
|
for(int j=0; j<nb_triangles; j++)
|
||||||
|
{
|
||||||
|
int vid[3];
|
||||||
|
for(int k=0; k<3; k++)
|
||||||
|
{
|
||||||
|
int idA = group->indices[j*3 + k];
|
||||||
|
int idB = group->indices[j*3 + (k+1)%3];
|
||||||
|
int a = idA < idB ? idA : idB;
|
||||||
|
int b = idA > idB ? idA : idB;
|
||||||
|
vid[k] = getEdge(a, b);
|
||||||
|
}
|
||||||
|
for(int k=0; k<3; k++)
|
||||||
|
addTriangle(group->indices[j*3 + k], vid[k], vid[(k+2)%3]);
|
||||||
|
addTriangle(vid[0], vid[1], vid[2]);
|
||||||
|
}
|
||||||
|
delete[](edges);
|
||||||
|
group->indices.erase(group->indices.begin(), group->indices.begin()+nb_triangles*3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sphere::createVertex(float u, float v)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
GridMesh::GridMesh(Material* mat, int width, int height, bool alternate)
|
||||||
|
{
|
||||||
|
addGroup(mat);
|
||||||
|
for(int i=0; i<=width; ++i)
|
||||||
|
{
|
||||||
|
for(int j=0; j<=height; ++j)
|
||||||
|
{
|
||||||
|
float x = (float)i/(float)width;
|
||||||
|
float y = (float)j/(float)height;
|
||||||
|
addPosition(x-0.5f, 0, y-0.5f);
|
||||||
|
addNormal(0, 1, 0);
|
||||||
|
addTexCoord(x, y);
|
||||||
|
if(i > 0 && j > 0)
|
||||||
|
{
|
||||||
|
if(alternate && (i+j)%2)
|
||||||
|
{
|
||||||
|
addTriangle(getVertexId(i, j, height),
|
||||||
|
getVertexId(i, j-1, height),
|
||||||
|
getVertexId(i-1, j, height));
|
||||||
|
addTriangle(getVertexId(i-1, j-1, height),
|
||||||
|
getVertexId(i-1, j, height),
|
||||||
|
getVertexId(i, j-1, height));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addTriangle(getVertexId(i, j, height),
|
||||||
|
getVertexId(i-1, j-1, height),
|
||||||
|
getVertexId(i-1, j, height));
|
||||||
|
addTriangle(getVertexId(i, j, height),
|
||||||
|
getVertexId(i, j-1, height),
|
||||||
|
getVertexId(i-1, j-1, height));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GridMesh::getVertexId(int i, int j, int height)
|
||||||
|
{
|
||||||
|
return i*(height+1) + j;
|
||||||
|
}
|
38
parametricmesh.h
Normal file
38
parametricmesh.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef PARAMETRIC_MESH_H
|
||||||
|
#define PARAMETRIC_MESH_H
|
||||||
|
|
||||||
|
#include "meshbuilder.h"
|
||||||
|
|
||||||
|
class Sphere : public MeshBuilder
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
class Edge{
|
||||||
|
public:
|
||||||
|
int b;
|
||||||
|
int vertex;
|
||||||
|
Edge* next;
|
||||||
|
Edge(int myB = -1, int myVertex = -1) :
|
||||||
|
b(myB),
|
||||||
|
vertex(myVertex),
|
||||||
|
next(NULL)
|
||||||
|
{}
|
||||||
|
~Edge(){ if(next != NULL) delete(next); }
|
||||||
|
};
|
||||||
|
|
||||||
|
Edge* edges;
|
||||||
|
int getEdge(int a, int b);
|
||||||
|
void createVertex(float u, float v);
|
||||||
|
void subdivide(Group* group);
|
||||||
|
public:
|
||||||
|
Sphere(Material* mat, int n = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
class GridMesh : public MeshBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GridMesh(Material* mat, int width, int height, bool alternate = true);
|
||||||
|
private:
|
||||||
|
int getVertexId(int i, int j, int height);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PARAMETRIC_MESH_H
|
@ -9,7 +9,14 @@
|
|||||||
|
|
||||||
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
||||||
|
|
||||||
PhongEntity::PhongEntity(Mesh* myMesh) : mesh(myMesh) {}
|
PhongEntity::PhongEntity(Mesh* myMesh) :
|
||||||
|
mesh(myMesh),
|
||||||
|
vao(0),
|
||||||
|
nb_buffers(0),
|
||||||
|
vbo(NULL),
|
||||||
|
displayList(0),
|
||||||
|
modelMatrix()
|
||||||
|
{}
|
||||||
|
|
||||||
void PhongEntity::draw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights)
|
void PhongEntity::draw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights)
|
||||||
{
|
{
|
||||||
@ -143,6 +150,7 @@ void PhongEntity::destroyGL()
|
|||||||
glAssert(glDeleteVertexArrays(1, &vao));
|
glAssert(glDeleteVertexArrays(1, &vao));
|
||||||
glAssert(glDeleteBuffers(nb_buffers, vbo));
|
glAssert(glDeleteBuffers(nb_buffers, vbo));
|
||||||
delete[] vbo;
|
delete[] vbo;
|
||||||
|
vbo = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
glAssert(glDeleteLists(displayList, 1));
|
glAssert(glDeleteLists(displayList, 1));
|
||||||
@ -177,3 +185,12 @@ void PhongEntity::drawGroup(int groupId)
|
|||||||
glAssert(glDrawElements(GL_TRIANGLES, mesh->indiceGroups[groupId].indices.size(), GL_UNSIGNED_INT, mesh->indiceGroups[groupId].indices.data()));
|
glAssert(glDrawElements(GL_TRIANGLES, mesh->indiceGroups[groupId].indices.size(), GL_UNSIGNED_INT, mesh->indiceGroups[groupId].indices.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhongEntity* PhongEntity::clone()
|
||||||
|
{
|
||||||
|
PhongEntity* myClone = new PhongEntity(mesh);
|
||||||
|
myClone->modelMatrix = modelMatrix;
|
||||||
|
myClone->displayList = displayList;
|
||||||
|
myClone->nb_buffers = nb_buffers;
|
||||||
|
myClone->vao = vao;
|
||||||
|
myClone->vbo = vbo;
|
||||||
|
}
|
||||||
|
@ -42,6 +42,9 @@ protected:
|
|||||||
void crappyDraw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights);
|
void crappyDraw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief the model matrix is public, so the user can manipulate it in any way he desires.
|
||||||
|
*/
|
||||||
glm::mat4 modelMatrix;
|
glm::mat4 modelMatrix;
|
||||||
|
|
||||||
PhongEntity(Mesh* myMesh);
|
PhongEntity(Mesh* myMesh);
|
||||||
@ -52,6 +55,12 @@ public:
|
|||||||
void destroyGL();
|
void destroyGL();
|
||||||
|
|
||||||
Mesh* getMesh() {return mesh;}
|
Mesh* getMesh() {return mesh;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief this method returns a clone of the current entity.
|
||||||
|
* The same VAO will be used to render both, so there is no need to call initGL on the clone
|
||||||
|
*/
|
||||||
|
PhongEntity* clone();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PHONGENTITY_H
|
#endif // PHONGENTITY_H
|
||||||
|
108
sphere.cpp
108
sphere.cpp
@ -1,108 +0,0 @@
|
|||||||
#include "sphere.h"
|
|
||||||
#include "glm/ext.hpp"
|
|
||||||
#include "phongmaterial.h"
|
|
||||||
|
|
||||||
#define M_PI 3.14159265358979323846
|
|
||||||
#define MAGIC_RATIO 0.37139f
|
|
||||||
|
|
||||||
Sphere::Sphere(Material* mat, int n)
|
|
||||||
{
|
|
||||||
// icosahedron :
|
|
||||||
addGroup(mat);
|
|
||||||
Group* group = &(indiceGroups[0]);
|
|
||||||
|
|
||||||
// top cap
|
|
||||||
createVertex(0, 1);
|
|
||||||
for(int i=0; i<5; i++)
|
|
||||||
createVertex(i/5.f, 1-MAGIC_RATIO);
|
|
||||||
|
|
||||||
// bottom cap
|
|
||||||
createVertex(0, 0);
|
|
||||||
for(int i=0; i<5; i++)
|
|
||||||
createVertex((i+0.5f)/5.f, MAGIC_RATIO);
|
|
||||||
|
|
||||||
// Compute faces
|
|
||||||
for(int i=0; i<5; i++){
|
|
||||||
int top = 1;
|
|
||||||
int bottom = 7;
|
|
||||||
int offset = (i+1)%5;
|
|
||||||
// top cap
|
|
||||||
addTriangle(0, top+i, top+offset);
|
|
||||||
// bottom cap
|
|
||||||
addTriangle(6, bottom+offset, bottom+i);
|
|
||||||
// middle ribbon
|
|
||||||
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[positions.size()-1];
|
|
||||||
int nb_triangles = group->indices.size()/3;
|
|
||||||
for(int j=0; j<nb_triangles; j++)
|
|
||||||
{
|
|
||||||
int vid[3];
|
|
||||||
for(int k=0; k<3; k++)
|
|
||||||
{
|
|
||||||
int idA = group->indices[j*3 + k];
|
|
||||||
int idB = group->indices[j*3 + (k+1)%3];
|
|
||||||
int a = idA < idB ? idA : idB;
|
|
||||||
int b = idA > idB ? idA : idB;
|
|
||||||
vid[k] = getEdge(a, b);
|
|
||||||
}
|
|
||||||
for(int k=0; k<3; k++)
|
|
||||||
addTriangle(group->indices[j*3 + k], vid[k], vid[(k+2)%3]);
|
|
||||||
addTriangle(vid[0], vid[1], vid[2]);
|
|
||||||
}
|
|
||||||
delete[](edges);
|
|
||||||
group->indices.erase(group->indices.begin(), group->indices.begin()+nb_triangles*3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Sphere::getEdge(int a, int b)
|
|
||||||
{
|
|
||||||
Edge* current = edges+a;
|
|
||||||
int vid = -1;
|
|
||||||
while(vid == -1)
|
|
||||||
{
|
|
||||||
if(current->b == b)
|
|
||||||
vid = current->vertex;
|
|
||||||
else if(current->next == NULL)
|
|
||||||
{
|
|
||||||
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 = (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;
|
|
||||||
|
|
||||||
// inserting the new vertex in the edge collection
|
|
||||||
if(current->b == -1)
|
|
||||||
{
|
|
||||||
current->vertex = vid;
|
|
||||||
current->b = b;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
current->next = new Edge(b, vid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
return vid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sphere::createVertex(float u, float v)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
25
sphere.h
25
sphere.h
@ -1,25 +0,0 @@
|
|||||||
#ifndef SPHERE_H
|
|
||||||
#define SPHERE_H
|
|
||||||
|
|
||||||
#include "meshbuilder.h"
|
|
||||||
|
|
||||||
class Sphere : public MeshBuilder
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
class Edge{
|
|
||||||
public:
|
|
||||||
int b;
|
|
||||||
int vertex;
|
|
||||||
Edge* next;
|
|
||||||
Edge(int myB = -1, int myVertex = -1):b(myB),vertex(myVertex),next(NULL){}
|
|
||||||
~Edge(){ if(next != NULL) delete(next); }
|
|
||||||
};
|
|
||||||
|
|
||||||
Edge* edges;
|
|
||||||
int getEdge(int a, int b);
|
|
||||||
void createVertex(float u, float v);
|
|
||||||
public:
|
|
||||||
Sphere(Material* mat, int n = 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // SPHERE_H
|
|
Loading…
x
Reference in New Issue
Block a user