From 9c2c8315b02b457db39d8ff0d1a7950e3076a994 Mon Sep 17 00:00:00 2001 From: Anselme Date: Tue, 13 Oct 2015 22:46:57 +0200 Subject: [PATCH] sphere and grid are now in the same file : parametricmesh --- CMakeLists.txt | 5 +- gridmesh.cpp | 43 ------------- gridmesh.h | 14 ----- mesh.h | 3 +- parametricmesh.cpp | 154 +++++++++++++++++++++++++++++++++++++++++++++ parametricmesh.h | 38 +++++++++++ phongentity.cpp | 19 +++++- phongentity.h | 9 +++ sphere.cpp | 108 ------------------------------- sphere.h | 25 -------- 10 files changed, 222 insertions(+), 196 deletions(-) delete mode 100644 gridmesh.cpp delete mode 100644 gridmesh.h create mode 100644 parametricmesh.cpp create mode 100644 parametricmesh.h delete mode 100644 sphere.cpp delete mode 100644 sphere.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bbc45d7..432d0b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,8 +15,7 @@ set(LIB_SRC_LIST asciientity.cpp asciimodule.cpp framebuffer.cpp - gbuffermodule.cpp - gridmesh.cpp + gbuffermodule.cpp lights.cpp meshbuilder.cpp phongentity.cpp @@ -25,7 +24,7 @@ set(LIB_SRC_LIST shader.cpp skyboxmodule.cpp sparrowrenderer.cpp - sphere.cpp + parametricmesh.cpp texture.cpp ) diff --git a/gridmesh.cpp b/gridmesh.cpp deleted file mode 100644 index 728769d..0000000 --- a/gridmesh.cpp +++ /dev/null @@ -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; -} diff --git a/gridmesh.h b/gridmesh.h deleted file mode 100644 index d022afd..0000000 --- a/gridmesh.h +++ /dev/null @@ -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 diff --git a/mesh.h b/mesh.h index 8ca6dbc..e61e3b5 100644 --- a/mesh.h +++ b/mesh.h @@ -7,9 +7,8 @@ class Material; -class Mesh +struct Mesh { -public: typedef struct { glm::vec3 tangent; diff --git a/parametricmesh.cpp b/parametricmesh.cpp new file mode 100644 index 0000000..514e7c9 --- /dev/null +++ b/parametricmesh.cpp @@ -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; ib == 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; jindices[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; +} diff --git a/parametricmesh.h b/parametricmesh.h new file mode 100644 index 0000000..89e421f --- /dev/null +++ b/parametricmesh.h @@ -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 diff --git a/phongentity.cpp b/phongentity.cpp index 0e1820d..a52af2c 100644 --- a/phongentity.cpp +++ b/phongentity.cpp @@ -9,7 +9,14 @@ #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) { @@ -143,6 +150,7 @@ void PhongEntity::destroyGL() glAssert(glDeleteVertexArrays(1, &vao)); glAssert(glDeleteBuffers(nb_buffers, vbo)); delete[] vbo; + vbo = NULL; } else 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())); } +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; +} diff --git a/phongentity.h b/phongentity.h index 8c34e28..d62048b 100644 --- a/phongentity.h +++ b/phongentity.h @@ -42,6 +42,9 @@ protected: void crappyDraw(const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, Lights::Light* dirLight, Lights* pointLights); public: + /** + * @brief the model matrix is public, so the user can manipulate it in any way he desires. + */ glm::mat4 modelMatrix; PhongEntity(Mesh* myMesh); @@ -52,6 +55,12 @@ public: void destroyGL(); 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 diff --git a/sphere.cpp b/sphere.cpp deleted file mode 100644 index 976dfa9..0000000 --- a/sphere.cpp +++ /dev/null @@ -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; iindices.size()/3; - for(int j=0; jindices[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); - } diff --git a/sphere.h b/sphere.h deleted file mode 100644 index b347490..0000000 --- a/sphere.h +++ /dev/null @@ -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