diff options
Diffstat (limited to 'dev/MinGfx/src/quick_shapes.cc')
-rw-r--r-- | dev/MinGfx/src/quick_shapes.cc | 1454 |
1 files changed, 727 insertions, 727 deletions
diff --git a/dev/MinGfx/src/quick_shapes.cc b/dev/MinGfx/src/quick_shapes.cc index 388aa3d..dbd6c9e 100644 --- a/dev/MinGfx/src/quick_shapes.cc +++ b/dev/MinGfx/src/quick_shapes.cc @@ -1,727 +1,727 @@ -/* - Copyright (c) 2017,2018 Regents of the University of Minnesota. - All Rights Reserved. - See corresponding header file for details. - */ - -#include "quick_shapes.h" -#include "platform.h" - -#include <cmath> -#include <iostream> -#include <string> - - -namespace mingfx { - - - -#define PI 3.14159265359f -#define TWOPI 6.28318530718f - - - -// Helper datastructure for building shapes algorithmically -class Vertex { -public: - Vertex(GLfloat xx, GLfloat yy, GLfloat zz, GLfloat nnx, GLfloat nny, GLfloat nnz) : - x(xx), y(yy), z(zz), nx(nnx), ny(nny), nz(nnz) {} - - GLfloat x; - GLfloat y; - GLfloat z; - GLfloat nx; - GLfloat ny; - GLfloat nz; -}; - - - - -QuickShapes::QuickShapes() { -} - -QuickShapes::~QuickShapes() { -} - - - - -// ------------ CUBE ------------ - - -void QuickShapes::initCube() { - GLfloat vertices[] = { - 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, // v0-v1-v2 (front) - -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // v2-v3-v0 - - 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f,-1.0f,-1.0f, // v0-v3-v4 (right) - 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, // v4-v5-v0 - - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f,-1.0f, // v0-v5-v6 (top) - -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // v6-v1-v0 - - -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, -1.0f,-1.0f,-1.0f, // v1-v6-v7 (left) - -1.0f,-1.0f,-1.0f, -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // v7-v2-v1.0 - - -1.0f,-1.0f,-1.0f, 1.0f,-1.0f,-1.0f, 1.0f,-1.0f, 1.0f, // v7-v4-v3 (bottom) - 1.0f,-1.0f, 1.0f, -1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, // v3-v2-v7 - - 1.0f,-1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, // v4-v7-v6 (back) - -1.0f, 1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f,-1.0f,-1.0f // v6-v5-v4 - }; - - GLfloat normals[] = { - 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2 (front) - 0, 0, 1, 0, 0, 1, 0, 0, 1, // v2-v3-v0 - - 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4 (right) - 1, 0, 0, 1, 0, 0, 1, 0, 0, // v4-v5-v0 - - 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6 (top) - 0, 1, 0, 0, 1, 0, 0, 1, 0, // v6-v1-v0 - - -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7 (left) - -1, 0, 0, -1, 0, 0, -1, 0, 0, // v7-v2-v1 - - 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7-v4-v3 (bottom) - 0,-1, 0, 0,-1, 0, 0,-1, 0, // v3-v2-v7 - - 0, 0,-1, 0, 0,-1, 0, 0,-1, // v4-v7-v6 (back) - 0, 0,-1, 0, 0,-1, 0, 0,-1 // v6-v5-v4 - }; - - cubeMesh_.SetVertices(vertices, 36); - cubeMesh_.SetNormals(normals, 36); - cubeMesh_.UpdateGPUMemory(); -} - - -void QuickShapes::DrawCube(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, const Color &color) -{ - if (cubeMesh_.num_vertices() == 0) { - initCube(); - } - defaultMaterial_.ambient_reflectance = color; - defaultMaterial_.diffuse_reflectance = color; - defaultMaterial_.surface_texture = emptyTex_; - defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &cubeMesh_, defaultMaterial_); -} - - - - -// ------------ SQUARE ------------ - - -void QuickShapes::initSquare() { - GLfloat vertices[] = { - 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,-1.0f, -1.0f, 0.0f,-1.0f, // v0-v5-v6 (top) - -1.0f, 0.0f,-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f // v6-v1-v0 - }; - - GLfloat normals[] = { - 0, 1, 0, 0, 1, 0, 0, 1, 0, - 0, 1, 0, 0, 1, 0, 0, 1, 0 - }; - - GLfloat texcoords[] = { - 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f - }; - - squareMesh_.SetVertices(vertices, 6); - squareMesh_.SetNormals(normals, 6); - squareMesh_.SetTexCoords(0, texcoords, 6); - squareMesh_.UpdateGPUMemory(); -} - - -void QuickShapes::DrawSquare(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, const Color &color) -{ - if (squareMesh_.num_vertices() == 0) { - initSquare(); - } - defaultMaterial_.ambient_reflectance = color; - defaultMaterial_.diffuse_reflectance = color; - defaultMaterial_.surface_texture = emptyTex_; - defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &squareMesh_, defaultMaterial_); -} - - -void QuickShapes::DrawSquare(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, const Color &color, - const Texture2D &tex) -{ - if (squareMesh_.num_vertices() == 0) { - initSquare(); - } - defaultMaterial_.ambient_reflectance = color; - defaultMaterial_.diffuse_reflectance = color; - defaultMaterial_.surface_texture = tex; - defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &squareMesh_, defaultMaterial_); -} - - - - - -// ------------ CYLINDER ------------ - - -void QuickShapes::initCyl() { - - std::vector<Vertex> verts; - - Vertex top(0,1,0, 0,1,0); - Vertex bot(0,-1,0, 0,-1,0); - - const int nslices = 20; - for (int s=1; s<nslices+1; s++) { - int slast = s - 1; - GLfloat xlast = std::cosf(-TWOPI * (float)slast / (float)nslices); - GLfloat zlast = std::sinf(-TWOPI * (float)slast/(float)nslices); - GLfloat xnew = std::cosf(-TWOPI * (float)(s)/(float)nslices); - GLfloat znew = std::sinf(-TWOPI * (float)(s)/(float)nslices); - - // one triangle on the top - verts.push_back(top); - verts.push_back(Vertex(xlast,1,zlast, 0,1,0)); - verts.push_back(Vertex(xnew,1,znew, 0,1,0)); - - // two triangles to create a rect on the side - verts.push_back(Vertex(xlast,1,zlast, xlast,0,zlast)); - verts.push_back(Vertex(xlast,-1,zlast, xlast,0,zlast)); - verts.push_back(Vertex(xnew,1,znew, xnew,0,znew)); - - verts.push_back(Vertex(xnew,-1,znew, xnew,0,znew)); - verts.push_back(Vertex(xnew,1,znew, xnew,0,znew)); - verts.push_back(Vertex(xlast,-1,zlast, xlast,0,zlast)); - - // one triangle on the bottom - verts.push_back(bot); - verts.push_back(Vertex(xnew,-1,znew, 0,-1,0)); - verts.push_back(Vertex(xlast,-1,zlast, 0,-1,0)); - } - - std::vector<Point3> vertices; - std::vector<Vector3> normals; - for (int i=0; i<verts.size(); i++) { - vertices.push_back(Point3(verts[i].x, verts[i].y, verts[i].z)); - normals.push_back(Vector3(verts[i].nx, verts[i].ny, verts[i].nz)); - } - cylMesh_.SetVertices(vertices); - cylMesh_.SetNormals(normals); - cylMesh_.UpdateGPUMemory(); -} - - -void QuickShapes::DrawCylinder(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, const Color &color) -{ - if (cylMesh_.num_vertices() == 0) { - initCyl(); - } - defaultMaterial_.ambient_reflectance = color; - defaultMaterial_.diffuse_reflectance = color; - defaultMaterial_.surface_texture = emptyTex_; - defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &cylMesh_, defaultMaterial_); -} - - - - -// ------------ CONE ------------ - - -void QuickShapes::initCone() { - - std::vector<Vertex> verts; - - Vertex top(0,1,0, 0,1,0); - Vertex bot(0,-1,0, 0,-1,0); - - const int nslices = 20; - for (int s=1; s<nslices+1; s++) { - int slast = s - 1; - GLfloat xlast = std::cosf(-TWOPI * (float)slast/(float)nslices); - GLfloat zlast = std::sinf(-TWOPI * (float)slast/(float)nslices); - GLfloat xnew = std::cosf(-TWOPI * (float)(s)/(float)nslices); - GLfloat znew = std::sinf(-TWOPI * (float)(s)/(float)nslices); - - // one triangle on the side - // normals are a bit more complex than for other shapes... - Vector3 nlast = Vector3(xlast, 2, zlast).ToUnit(); - Vector3 nnew = Vector3(xnew, 2, znew).ToUnit(); - Vector3 ntop = 0.5*(nlast + nnew); - - verts.push_back(Vertex(top.x, top.y, top.z, ntop[0], ntop[1], ntop[2])); - verts.push_back(Vertex(xlast,-1,zlast, nlast[0], nlast[1], nlast[2])); - verts.push_back(Vertex(xnew,-1,znew, nnew[0], nnew[1], nnew[2])); - - // one triangle on the bottom - verts.push_back(bot); - verts.push_back(Vertex(xnew,-1,znew, 0,-1,0)); - verts.push_back(Vertex(xlast,-1,zlast, 0,-1,0)); - } - - std::vector<Point3> vertices; - std::vector<Vector3> normals; - for (int i = 0; i < verts.size(); i++) { - vertices.push_back(Point3(verts[i].x, verts[i].y, verts[i].z)); - normals.push_back(Vector3(verts[i].nx, verts[i].ny, verts[i].nz)); - } - - coneMesh_.SetVertices(vertices); - coneMesh_.SetNormals(normals); - coneMesh_.UpdateGPUMemory(); -} - - -void QuickShapes::DrawCone(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, const Color &color) -{ - if (coneMesh_.num_vertices() == 0) { - initCone(); - } - defaultMaterial_.ambient_reflectance = color; - defaultMaterial_.diffuse_reflectance = color; - defaultMaterial_.surface_texture = emptyTex_; - defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &coneMesh_, defaultMaterial_); -} - - - - - -// ------------ SPHERE ------------ - - -void QuickShapes::initSph() { - - std::vector<Vertex> verts; - - Vertex top(0,1,0, 0,1,0); - Vertex bot(0,-1,0, 0,-1,0); - - const int nslices = 40; - const int nstacks = 40; - for (int s=1; s<nslices+1; s++) { - int slast = s - 1; - GLfloat xlast = std::cosf(-TWOPI * (float)slast/(float)nslices); - GLfloat zlast = std::sinf(-TWOPI * (float)slast/(float)nslices); - GLfloat xnew = std::cosf(-TWOPI * (float)(s)/(float)nslices); - GLfloat znew = std::sinf(-TWOPI * (float)(s)/(float)nslices); - - float stackstep = PI/(float)nstacks; - - // one triangle on the top - verts.push_back(top); - verts.push_back(Vertex(std::sinf(stackstep)*xlast,std::cosf(stackstep),std::sinf(stackstep)*zlast, - std::sinf(stackstep)*xlast,std::cosf(stackstep),std::sinf(stackstep)*zlast)); - verts.push_back(Vertex(std::sinf(stackstep)*xnew,std::cosf(stackstep),std::sinf(stackstep)*znew, - std::sinf(stackstep)*xnew,std::cosf(stackstep),std::sinf(stackstep)*znew)); - - for (int t=2; t<nstacks; t++) { - int tlast = t - 1; - GLfloat ylast = std::cosf(PI*(float)(tlast)/(float)nstacks); - GLfloat ynew = std::cosf(PI*(float)(t)/(float)nstacks); - - GLfloat rlast = std::sinf(PI * (float)(tlast)/(float)nstacks); - GLfloat rnew = std::sinf(PI * (float)(t)/(float)nstacks); - - // two triangles to create a rect on the side - verts.push_back(Vertex(rlast*xlast,ylast,rlast*zlast, rlast*xlast,ylast,rlast*zlast)); - verts.push_back(Vertex(rnew*xlast,ynew,rnew*zlast, rnew*xlast,ynew,rnew*zlast)); - verts.push_back(Vertex(rnew*xnew,ynew,rnew*znew, rnew*xnew,ynew,rnew*znew)); - - verts.push_back(Vertex(rnew*xnew,ynew,rnew*znew, rnew*xnew,ynew,rnew*znew)); - verts.push_back(Vertex(rlast*xnew,ylast,rlast*znew, rlast*xnew,ylast,rlast*znew)); - verts.push_back(Vertex(rlast*xlast,ylast,rlast*zlast, rlast*xlast,ylast,rlast*zlast)); - } - - // one triangle on the bottom - verts.push_back(bot); - verts.push_back(Vertex(std::sinf(stackstep)*xnew,std::cosf(PI-stackstep),std::sinf(stackstep)*znew, - std::sinf(stackstep)*xnew,std::cosf(PI-stackstep),std::sinf(stackstep)*znew)); - verts.push_back(Vertex(std::sinf(stackstep)*xlast,std::cosf(PI-stackstep),std::sinf(stackstep)*zlast, - std::sinf(stackstep)*xlast,std::cosf(PI-stackstep),std::sinf(stackstep)*zlast)); - } - - std::vector<Point3> vertices; - std::vector<Vector3> normals; - for (int i = 0; i < verts.size(); i++) { - vertices.push_back(Point3(verts[i].x, verts[i].y, verts[i].z)); - normals.push_back(Vector3(verts[i].nx, verts[i].ny, verts[i].nz)); - } - sphereMesh_.SetVertices(vertices); - sphereMesh_.SetNormals(normals); - sphereMesh_.UpdateGPUMemory(); -} - - -void QuickShapes::DrawSphere(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, const Color &color) -{ - if (sphereMesh_.num_vertices() == 0) { - initSph(); - } - defaultMaterial_.ambient_reflectance = color; - defaultMaterial_.diffuse_reflectance = color; - defaultMaterial_.surface_texture = emptyTex_; - defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &sphereMesh_, defaultMaterial_); -} - - - - -// ------------ BRUSH ------------ - - -void QuickShapes::initBrush() { - - // Raw vertices -- points that make up the brush geometry - const GLfloat v[19][3] = { - { 0.5f, 0.0f, 0.0f}, // 0 - {-0.5f, 0.0f, 0.0f}, // 1 - - { 0.5f, 0.1f, 0.25f}, // 2 - {-0.5f, 0.1f, 0.25f}, // 3 - { 0.5f, 0.1f, 0.75f}, // 4 - {-0.5f, 0.1f, 0.75f}, // 5 - { 0.1f, 0.06f, 1.0f}, // 6 - {-0.1f, 0.06f, 1.0f}, // 7 - { 0.15f, 0.1f, 1.75f}, // 8 - {-0.15f, 0.1f, 1.75f}, // 9 - - { 0.0f, 0.0f, 1.85f}, // 10 - - { 0.5f, -0.1f, 0.25f}, // 11 - {-0.5f, -0.1f, 0.25f}, // 12 - { 0.5f, -0.1f, 0.75f}, // 13 - {-0.5f, -0.1f, 0.75f}, // 14 - { 0.1f, -0.06f, 1.0f}, // 15 - {-0.1f, -0.06f, 1.0f}, // 16 - { 0.15f, -0.1f, 1.75f}, // 17 - {-0.15f, -0.1f, 1.75f} // 18 - }; - - - // Vertices arranged into triangles - const GLfloat verts[34][3][3] = { - // top - {{v[0][0], v[0][1], v[0][2]}, {v[1][0], v[1][1], v[1][2]}, {v[2][0], v[2][1], v[2][2]}}, - {{v[1][0], v[1][1], v[1][2]}, {v[3][0], v[3][1], v[3][2]}, {v[2][0], v[2][1], v[2][2]}}, - - {{v[2][0], v[2][1], v[2][2]}, {v[3][0], v[3][1], v[3][2]}, {v[4][0], v[4][1], v[4][2]}}, - {{v[3][0], v[3][1], v[3][2]}, {v[5][0], v[5][1], v[5][2]}, {v[4][0], v[4][1], v[4][2]}}, - - {{v[4][0], v[4][1], v[4][2]}, {v[5][0], v[5][1], v[5][2]}, {v[6][0], v[6][1], v[6][2]}}, - {{v[5][0], v[5][1], v[5][2]}, {v[7][0], v[7][1], v[7][2]}, {v[6][0], v[6][1], v[6][2]}}, - - {{v[6][0], v[6][1], v[6][2]}, {v[7][0], v[7][1], v[7][2]}, {v[8][0], v[8][1], v[8][2]}}, - {{v[7][0], v[7][1], v[7][2]}, {v[9][0], v[9][1], v[9][2]}, {v[8][0], v[8][1], v[8][2]}}, - - {{v[8][0], v[8][1], v[8][2]}, {v[9][0], v[9][1], v[9][2]}, {v[10][0], v[10][1], v[10][2]}}, - - // bottom - {{v[0][0], v[0][1], v[0][2]}, {v[12][0], v[12][1], v[12][2]}, {v[1][0], v[1][1], v[1][2]}}, - {{v[11][0], v[11][1], v[11][2]}, {v[12][0], v[12][1], v[12][2]}, {v[0][0], v[0][1], v[0][2]}}, - - {{v[11][0], v[11][1], v[11][2]}, {v[14][0], v[14][1], v[14][2]}, {v[12][0], v[12][1], v[12][2]}}, - {{v[13][0], v[13][1], v[13][2]}, {v[14][0], v[14][1], v[14][2]}, {v[11][0], v[11][1], v[11][2]}}, - - {{v[13][0], v[13][1], v[13][2]}, {v[16][0], v[16][1], v[16][2]}, {v[14][0], v[14][1], v[14][2]}}, - {{v[15][0], v[15][1], v[15][2]}, {v[16][0], v[16][1], v[16][2]}, {v[13][0], v[13][1], v[13][2]}}, - - {{v[15][0], v[15][1], v[15][2]}, {v[18][0], v[18][1], v[18][2]}, {v[16][0], v[16][1], v[16][2]}}, - {{v[17][0], v[17][1], v[17][2]}, {v[18][0], v[18][1], v[18][2]}, {v[15][0], v[15][1], v[15][2]}}, - - {{v[18][0], v[18][1], v[18][2]}, {v[17][0], v[17][1], v[17][2]}, {v[10][0], v[10][1], v[10][2]}}, - - // one side - {{v[11][0], v[11][1], v[11][2]}, {v[0][0], v[0][1], v[0][2]}, {v[2][0], v[2][1], v[2][2]}}, - - {{v[11][0], v[11][1], v[11][2]}, {v[2][0], v[2][1], v[2][2]}, {v[4][0], v[4][1], v[4][2]}}, - {{v[4][0], v[4][1], v[4][2]}, {v[13][0], v[13][1], v[13][2]}, {v[11][0], v[11][1], v[11][2]}}, - - {{v[13][0], v[13][1], v[13][2]}, {v[4][0], v[4][1], v[4][2]}, {v[6][0], v[6][1], v[6][2]}}, - {{v[6][0], v[6][1], v[6][2]}, {v[15][0], v[15][1], v[15][2]}, {v[13][0], v[13][1], v[13][2]}}, - - {{v[15][0], v[15][1], v[15][2]}, {v[6][0], v[6][1], v[6][2]}, {v[8][0], v[8][1], v[8][2]}}, - {{v[8][0], v[8][1], v[8][2]}, {v[17][0], v[17][1], v[17][2]}, {v[15][0], v[15][1], v[15][2]}}, - - {{v[17][0], v[17][1], v[17][2]}, {v[8][0], v[8][1], v[8][2]}, {v[10][0], v[10][1], v[10][2]}}, - - // other side - {{v[3][0], v[3][1], v[3][2]}, {v[1][0], v[1][1], v[1][2]}, {v[12][0], v[12][1], v[12][2]}}, - - {{v[3][0], v[3][1], v[3][2]}, {v[12][0], v[12][1], v[12][2]}, {v[14][0], v[14][1], v[14][2]}}, - {{v[14][0], v[14][1], v[14][2]}, {v[5][0], v[5][1], v[5][2]}, {v[3][0], v[3][1], v[3][2]}}, - - {{v[5][0], v[5][1], v[5][2]}, {v[14][0], v[14][1], v[14][2]}, {v[16][0], v[16][1], v[16][2]}}, - {{v[16][0], v[16][1], v[16][2]}, {v[7][0], v[7][1], v[7][2]}, {v[5][0], v[5][1], v[5][2]}}, - - {{v[7][0], v[7][1], v[7][2]}, {v[16][0], v[16][1], v[16][2]}, {v[18][0], v[18][1], v[18][2]}}, - {{v[18][0], v[18][1], v[18][2]}, {v[9][0], v[9][1], v[9][2]}, {v[7][0], v[7][1], v[7][2]}}, - - {{v[9][0], v[9][1], v[9][2]}, {v[18][0], v[18][1], v[18][2]}, {v[10][0], v[10][1], v[10][2]}} - - }; - - - // Normals defined so as to make each face of the brush a flat surface - const GLfloat norms[34][3][3] = { - // top - {{0.0f, 0.93f, -0.37f}, {0.0f, 0.93f, -0.37f}, {0.0f, 0.93f, -0.37f}}, - {{0.0f, 0.93f, -0.37f}, {0.0f, 0.93f, -0.37f}, {0.0f, 0.93f, -0.37f}}, - - {{0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}}, - {{0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}}, - - {{0.0f, 0.988f, 0.158f}, {0.0f, 0.988f, 0.158f}, {0.0f, 0.988f, 0.158f}}, - {{0.0f, 0.988f, 0.158f}, {0.0f, 0.988f, 0.158f}, {0.0f, 0.988f, 0.158f}}, - - {{0.0f, 0.999f, -0.0533f}, {0.0f, 0.999f, -0.0533f}, {0.0f, 0.999f, -0.0533f}}, - {{0.0f, 0.999f, -0.0533f}, {0.0f, 0.999f, -0.0533f}, {0.0f, 0.999f, -0.0533f}}, - - {{0.0f, 0.709f, 0.709f}, {0.0f, 0.709f, 0.709f}, {0.0f, 0.709f, 0.709f}}, - - // bottom - {{0.0f, -0.93f, -0.37f}, {0.0f, -0.93f, -0.37f}, {0.0f, -0.93f, -0.37f}}, - {{0.0f, -0.93f, -0.37f}, {0.0f, -0.93f, -0.37f}, {0.0f, -0.93f, -0.37f}}, - - {{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}}, - {{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}}, - - {{0.0f, -0.988f, 0.158f}, {0.0f, -0.988f, 0.158f}, {0.0f, -0.988f, 0.158f}}, - {{0.0f, -0.988f, 0.158f}, {0.0f, -0.988f, 0.158f}, {0.0f, -0.988f, 0.158f}}, - - {{0.0f, -0.999f, -0.0533f}, {0.0f, -0.999f, -0.0533f}, {0.0f, -0.999f, -0.0533f}}, - {{0.0f, -0.999f, -0.0533f}, {0.0f, -0.999f, -0.0533f}, {0.0f, -0.999f, -0.0533f}}, - - {{0.0f, -0.709f, 0.709f}, {0.0f, -0.709f, 0.709f}, {0.0f, -0.709f, 0.709f}}, - - // one side - {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}}, - - {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}}, - {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}}, - - {{0.848f, 0.0f, 0.530f}, {0.848f, 0.0f, 0.530f}, {0.848f, 0.0f, 0.530f}}, - {{0.848f, 0.0f, 0.530f}, {0.848f, 0.0f, 0.530f}, {0.848f, 0.0f, 0.530f}}, - - {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}}, - {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}}, - - {{0.709f, 0.0f, 0.709f}, {0.709f, 0.0f, 0.709f}, {0.709f, 0.0f, 0.709f}}, - - // other side - {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}}, - - {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}}, - {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}}, - - {{-0.848f, 0.0f, 0.530f}, {-0.848f, 0.0f, 0.530f}, {-0.848f, 0.0f, 0.530f}}, - {{-0.848f, 0.0f, 0.530f}, {-0.848f, 0.0f, 0.530f}, {-0.848f, 0.0f, 0.530f}}, - - {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}}, - {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}}, - - {{-0.709f, 0.0f, 0.709f}, {-0.709f, 0.0f, 0.709f}, {-0.709f, 0.0f, 0.709f}} - }; - - brushMesh_.SetVertices((float*)verts, 102); - brushMesh_.SetNormals((float*)norms, 102); - brushMesh_.UpdateGPUMemory(); -} - - -void QuickShapes::DrawBrush(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, const Color &color) -{ - if (brushMesh_.num_vertices() == 0) { - initBrush(); - } - defaultMaterial_.ambient_reflectance = color; - defaultMaterial_.diffuse_reflectance = color; - defaultMaterial_.surface_texture = emptyTex_; - defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &brushMesh_, defaultMaterial_); -} - - - -// ---------------- - - -void QuickShapes::DrawLineSegment(const Matrix4 &modelMatrix, - const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, - const Color &color, - const Point3 &p1, - const Point3 &p2, - float radius) -{ - Matrix4 S = Matrix4::Scale(Vector3(radius, 0.5f*(p2-p1).Length(), radius)); - Vector3 y = (p2-p1).ToUnit(); - Vector3 z = Vector3(1,0,0).Cross(y).ToUnit(); - if (z == Vector3(0,0,0)) { - z = Vector3(0,0,1).Cross(y).ToUnit(); - } - Vector3 x = y.Cross(z); - Matrix4 R = Matrix4::FromRowMajorElements( - x[0], y[0], z[0], 0, - x[1], y[1], z[1], 0, - x[2], y[2], z[2], 0, - 0, 0, 0, 1 - ); - Matrix4 T = Matrix4::Translation(0.5 * Vector3(p1[0]+p2[0], p1[1]+p2[1], p1[2]+p2[2])); - - Matrix4 M = T * R * S; - - DrawCylinder(modelMatrix * M, viewMatrix, projectionMatrix, color); -} - - - -void QuickShapes::DrawLines(const Matrix4 &modelMatrix, - const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, - const Color &color, - const std::vector<Point3> &points, - LinesType ltype, - float radius) -{ - if (ltype == LinesType::LINES) { - for (size_t i=0; i<points.size(); i+=2) { - DrawLineSegment(modelMatrix, viewMatrix, projectionMatrix, color, points[i], points[i+1], radius); - } - } - else { - for (size_t i=0; i<points.size()-1; i++) { - DrawLineSegment(modelMatrix, viewMatrix, projectionMatrix, color, points[i], points[i+1], radius); - } - if (ltype == LinesType::LINE_LOOP) { - DrawLineSegment(modelMatrix, viewMatrix, projectionMatrix, color, points[points.size()-1], points[0], radius); - } - } -} - - - -void QuickShapes::DrawArrow(const Matrix4 &modelMatrix, - const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix, - const Color &color, - Point3 p, Vector3 dir, float radius) -{ - float d = dir.Length() - 8.0f*radius; - DrawLineSegment(modelMatrix, viewMatrix, projectionMatrix, color, p, p + d*dir.ToUnit(), radius); - - Matrix4 S = Matrix4::Scale(Vector3(radius*3.0f, radius*4.0f, radius*3.0f)); - Vector3 y = dir.ToUnit(); - Vector3 z = Vector3(1,0,0).Cross(y).ToUnit(); - if (z == Vector3(0,0,0)) { - z = Vector3(0,0,1).Cross(y).ToUnit(); - } - Vector3 x = y.Cross(z); - Matrix4 R = Matrix4::FromRowMajorElements( - x[0], y[0], z[0], 0, - x[1], y[1], z[1], 0, - x[2], y[2], z[2], 0, - 0, 0, 0, 1 - ); - Matrix4 T = Matrix4::Translation((p + d*dir.ToUnit()) - Point3::Origin()); - - Matrix4 M = T * R * S * Matrix4::Translation(Vector3(0,1,0)); - - DrawCone(modelMatrix * M, viewMatrix, projectionMatrix, color); -} - - -void QuickShapes::DrawAxes(const Matrix4 &modelMatrix, - const Matrix4 &viewMatrix, - const Matrix4 &projectionMatrix) -{ - DrawArrow(modelMatrix, viewMatrix, projectionMatrix, Color(1.0f, 0.6f, 0.6f), Point3::Origin(), Vector3::UnitX(), 0.02f); - DrawArrow(modelMatrix, viewMatrix, projectionMatrix, Color(0.6f, 1.0f, 0.6f), Point3::Origin(), Vector3::UnitY(), 0.02f); - DrawArrow(modelMatrix, viewMatrix, projectionMatrix, Color(0.6f, 0.6f, 1.0f), Point3::Origin(), Vector3::UnitZ(), 0.02f); - -} - - -void QuickShapes::initFull() { - GLfloat vertices[] = { - -1, -1, 0, 1, -1, 0, 1, 1, 0, - -1, -1, 0, 1, 1, 0, -1, 1, 0 - }; - - GLfloat normals[] = { - 0, 0, 1, 0, 0, 1, 0, 0, 1, - 0, 0, 1, 0, 0, 1, 0, 0, 1 - }; - - GLfloat texcoords[] = { - 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, - 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f - }; - - fullMesh_.SetVertices(vertices, 6); - fullMesh_.SetNormals(normals, 6); - fullMesh_.SetTexCoords(0, texcoords, 6); - fullMesh_.UpdateGPUMemory(); -} - - -void QuickShapes::DrawFullscreenTexture(const Color &color, const Texture2D &tex) { - if (fullMesh_.num_vertices() == 0) { - initFull(); - } - DrawWithFullscreen(color, &fullMesh_, tex); -} - - - - - -void QuickShapes::DrawWithFullscreen(const Color &color, Mesh *mesh, const Texture2D &tex) { - if (!fullscreenShader_.initialized()) { - fullscreenShader_.AddVertexShaderFromFile(Platform::FindMinGfxShaderFile("fullscreen.vert")); - fullscreenShader_.AddFragmentShaderFromFile(Platform::FindMinGfxShaderFile("fullscreen.frag")); - fullscreenShader_.LinkProgram(); - } - - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - - // Activate the shader program - fullscreenShader_.UseProgram(); - - // Pass uniforms and textures from C++ to the GPU Shader Program - fullscreenShader_.SetUniform("TintColor", color); - fullscreenShader_.BindTexture("SurfaceTexture", tex); - - // Draw the mesh using the shader program - mesh->Draw(); - - // Deactivate the shader program - fullscreenShader_.StopProgram(); - - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); -} - - -DefaultShader* QuickShapes::default_shader() { - return &defaultShader_; -} - - -DefaultShader::MaterialProperties* QuickShapes::material() { - return &defaultMaterial_; -} - - -} // end namespace +/*
+ Copyright (c) 2017,2018 Regents of the University of Minnesota.
+ All Rights Reserved.
+ See corresponding header file for details.
+ */
+
+#include "quick_shapes.h"
+#include "platform.h"
+
+#include <cmath>
+#include <iostream>
+#include <string>
+
+
+namespace mingfx {
+
+
+
+#define PI 3.14159265359f
+#define TWOPI 6.28318530718f
+
+
+
+// Helper datastructure for building shapes algorithmically
+class Vertex {
+public:
+ Vertex(GLfloat xx, GLfloat yy, GLfloat zz, GLfloat nnx, GLfloat nny, GLfloat nnz) :
+ x(xx), y(yy), z(zz), nx(nnx), ny(nny), nz(nnz) {}
+
+ GLfloat x;
+ GLfloat y;
+ GLfloat z;
+ GLfloat nx;
+ GLfloat ny;
+ GLfloat nz;
+};
+
+
+
+
+QuickShapes::QuickShapes() {
+}
+
+QuickShapes::~QuickShapes() {
+}
+
+
+
+
+// ------------ CUBE ------------
+
+
+void QuickShapes::initCube() {
+ GLfloat vertices[] = {
+ 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, // v0-v1-v2 (front)
+ -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // v2-v3-v0
+
+ 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f,-1.0f,-1.0f, // v0-v3-v4 (right)
+ 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, // v4-v5-v0
+
+ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 1.0f,-1.0f, // v0-v5-v6 (top)
+ -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // v6-v1-v0
+
+ -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, -1.0f,-1.0f,-1.0f, // v1-v6-v7 (left)
+ -1.0f,-1.0f,-1.0f, -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, // v7-v2-v1.0
+
+ -1.0f,-1.0f,-1.0f, 1.0f,-1.0f,-1.0f, 1.0f,-1.0f, 1.0f, // v7-v4-v3 (bottom)
+ 1.0f,-1.0f, 1.0f, -1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, // v3-v2-v7
+
+ 1.0f,-1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, // v4-v7-v6 (back)
+ -1.0f, 1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f,-1.0f,-1.0f // v6-v5-v4
+ };
+
+ GLfloat normals[] = {
+ 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0-v1-v2 (front)
+ 0, 0, 1, 0, 0, 1, 0, 0, 1, // v2-v3-v0
+
+ 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4 (right)
+ 1, 0, 0, 1, 0, 0, 1, 0, 0, // v4-v5-v0
+
+ 0, 1, 0, 0, 1, 0, 0, 1, 0, // v0-v5-v6 (top)
+ 0, 1, 0, 0, 1, 0, 0, 1, 0, // v6-v1-v0
+
+ -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1-v6-v7 (left)
+ -1, 0, 0, -1, 0, 0, -1, 0, 0, // v7-v2-v1
+
+ 0,-1, 0, 0,-1, 0, 0,-1, 0, // v7-v4-v3 (bottom)
+ 0,-1, 0, 0,-1, 0, 0,-1, 0, // v3-v2-v7
+
+ 0, 0,-1, 0, 0,-1, 0, 0,-1, // v4-v7-v6 (back)
+ 0, 0,-1, 0, 0,-1, 0, 0,-1 // v6-v5-v4
+ };
+
+ cubeMesh_.SetVertices(vertices, 36);
+ cubeMesh_.SetNormals(normals, 36);
+ cubeMesh_.UpdateGPUMemory();
+}
+
+
+void QuickShapes::DrawCube(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix, const Color &color)
+{
+ if (cubeMesh_.num_vertices() == 0) {
+ initCube();
+ }
+ defaultMaterial_.ambient_reflectance = color;
+ defaultMaterial_.diffuse_reflectance = color;
+ defaultMaterial_.surface_texture = emptyTex_;
+ defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &cubeMesh_, defaultMaterial_);
+}
+
+
+
+
+// ------------ SQUARE ------------
+
+
+void QuickShapes::initSquare() {
+ GLfloat vertices[] = {
+ 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,-1.0f, -1.0f, 0.0f,-1.0f, // v0-v5-v6 (top)
+ -1.0f, 0.0f,-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f // v6-v1-v0
+ };
+
+ GLfloat normals[] = {
+ 0, 1, 0, 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0, 0, 1, 0
+ };
+
+ GLfloat texcoords[] = {
+ 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f
+ };
+
+ squareMesh_.SetVertices(vertices, 6);
+ squareMesh_.SetNormals(normals, 6);
+ squareMesh_.SetTexCoords(0, texcoords, 6);
+ squareMesh_.UpdateGPUMemory();
+}
+
+
+void QuickShapes::DrawSquare(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix, const Color &color)
+{
+ if (squareMesh_.num_vertices() == 0) {
+ initSquare();
+ }
+ defaultMaterial_.ambient_reflectance = color;
+ defaultMaterial_.diffuse_reflectance = color;
+ defaultMaterial_.surface_texture = emptyTex_;
+ defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &squareMesh_, defaultMaterial_);
+}
+
+
+void QuickShapes::DrawSquare(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix, const Color &color,
+ const Texture2D &tex)
+{
+ if (squareMesh_.num_vertices() == 0) {
+ initSquare();
+ }
+ defaultMaterial_.ambient_reflectance = color;
+ defaultMaterial_.diffuse_reflectance = color;
+ defaultMaterial_.surface_texture = tex;
+ defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &squareMesh_, defaultMaterial_);
+}
+
+
+
+
+
+// ------------ CYLINDER ------------
+
+
+void QuickShapes::initCyl() {
+
+ std::vector<Vertex> verts;
+
+ Vertex top(0,1,0, 0,1,0);
+ Vertex bot(0,-1,0, 0,-1,0);
+
+ const int nslices = 20;
+ for (int s=1; s<nslices+1; s++) {
+ int slast = s - 1;
+ GLfloat xlast = std::cosf(-TWOPI * (float)slast / (float)nslices);
+ GLfloat zlast = std::sinf(-TWOPI * (float)slast/(float)nslices);
+ GLfloat xnew = std::cosf(-TWOPI * (float)(s)/(float)nslices);
+ GLfloat znew = std::sinf(-TWOPI * (float)(s)/(float)nslices);
+
+ // one triangle on the top
+ verts.push_back(top);
+ verts.push_back(Vertex(xlast,1,zlast, 0,1,0));
+ verts.push_back(Vertex(xnew,1,znew, 0,1,0));
+
+ // two triangles to create a rect on the side
+ verts.push_back(Vertex(xlast,1,zlast, xlast,0,zlast));
+ verts.push_back(Vertex(xlast,-1,zlast, xlast,0,zlast));
+ verts.push_back(Vertex(xnew,1,znew, xnew,0,znew));
+
+ verts.push_back(Vertex(xnew,-1,znew, xnew,0,znew));
+ verts.push_back(Vertex(xnew,1,znew, xnew,0,znew));
+ verts.push_back(Vertex(xlast,-1,zlast, xlast,0,zlast));
+
+ // one triangle on the bottom
+ verts.push_back(bot);
+ verts.push_back(Vertex(xnew,-1,znew, 0,-1,0));
+ verts.push_back(Vertex(xlast,-1,zlast, 0,-1,0));
+ }
+
+ std::vector<Point3> vertices;
+ std::vector<Vector3> normals;
+ for (int i=0; i<verts.size(); i++) {
+ vertices.push_back(Point3(verts[i].x, verts[i].y, verts[i].z));
+ normals.push_back(Vector3(verts[i].nx, verts[i].ny, verts[i].nz));
+ }
+ cylMesh_.SetVertices(vertices);
+ cylMesh_.SetNormals(normals);
+ cylMesh_.UpdateGPUMemory();
+}
+
+
+void QuickShapes::DrawCylinder(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix, const Color &color)
+{
+ if (cylMesh_.num_vertices() == 0) {
+ initCyl();
+ }
+ defaultMaterial_.ambient_reflectance = color;
+ defaultMaterial_.diffuse_reflectance = color;
+ defaultMaterial_.surface_texture = emptyTex_;
+ defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &cylMesh_, defaultMaterial_);
+}
+
+
+
+
+// ------------ CONE ------------
+
+
+void QuickShapes::initCone() {
+
+ std::vector<Vertex> verts;
+
+ Vertex top(0,1,0, 0,1,0);
+ Vertex bot(0,-1,0, 0,-1,0);
+
+ const int nslices = 20;
+ for (int s=1; s<nslices+1; s++) {
+ int slast = s - 1;
+ GLfloat xlast = std::cosf(-TWOPI * (float)slast/(float)nslices);
+ GLfloat zlast = std::sinf(-TWOPI * (float)slast/(float)nslices);
+ GLfloat xnew = std::cosf(-TWOPI * (float)(s)/(float)nslices);
+ GLfloat znew = std::sinf(-TWOPI * (float)(s)/(float)nslices);
+
+ // one triangle on the side
+ // normals are a bit more complex than for other shapes...
+ Vector3 nlast = Vector3(xlast, 2, zlast).ToUnit();
+ Vector3 nnew = Vector3(xnew, 2, znew).ToUnit();
+ Vector3 ntop = 0.5*(nlast + nnew);
+
+ verts.push_back(Vertex(top.x, top.y, top.z, ntop[0], ntop[1], ntop[2]));
+ verts.push_back(Vertex(xlast,-1,zlast, nlast[0], nlast[1], nlast[2]));
+ verts.push_back(Vertex(xnew,-1,znew, nnew[0], nnew[1], nnew[2]));
+
+ // one triangle on the bottom
+ verts.push_back(bot);
+ verts.push_back(Vertex(xnew,-1,znew, 0,-1,0));
+ verts.push_back(Vertex(xlast,-1,zlast, 0,-1,0));
+ }
+
+ std::vector<Point3> vertices;
+ std::vector<Vector3> normals;
+ for (int i = 0; i < verts.size(); i++) {
+ vertices.push_back(Point3(verts[i].x, verts[i].y, verts[i].z));
+ normals.push_back(Vector3(verts[i].nx, verts[i].ny, verts[i].nz));
+ }
+
+ coneMesh_.SetVertices(vertices);
+ coneMesh_.SetNormals(normals);
+ coneMesh_.UpdateGPUMemory();
+}
+
+
+void QuickShapes::DrawCone(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix, const Color &color)
+{
+ if (coneMesh_.num_vertices() == 0) {
+ initCone();
+ }
+ defaultMaterial_.ambient_reflectance = color;
+ defaultMaterial_.diffuse_reflectance = color;
+ defaultMaterial_.surface_texture = emptyTex_;
+ defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &coneMesh_, defaultMaterial_);
+}
+
+
+
+
+
+// ------------ SPHERE ------------
+
+
+void QuickShapes::initSph() {
+
+ std::vector<Vertex> verts;
+
+ Vertex top(0,1,0, 0,1,0);
+ Vertex bot(0,-1,0, 0,-1,0);
+
+ const int nslices = 40;
+ const int nstacks = 40;
+ for (int s=1; s<nslices+1; s++) {
+ int slast = s - 1;
+ GLfloat xlast = std::cosf(-TWOPI * (float)slast/(float)nslices);
+ GLfloat zlast = std::sinf(-TWOPI * (float)slast/(float)nslices);
+ GLfloat xnew = std::cosf(-TWOPI * (float)(s)/(float)nslices);
+ GLfloat znew = std::sinf(-TWOPI * (float)(s)/(float)nslices);
+
+ float stackstep = PI/(float)nstacks;
+
+ // one triangle on the top
+ verts.push_back(top);
+ verts.push_back(Vertex(std::sinf(stackstep)*xlast,std::cosf(stackstep),std::sinf(stackstep)*zlast,
+ std::sinf(stackstep)*xlast,std::cosf(stackstep),std::sinf(stackstep)*zlast));
+ verts.push_back(Vertex(std::sinf(stackstep)*xnew,std::cosf(stackstep),std::sinf(stackstep)*znew,
+ std::sinf(stackstep)*xnew,std::cosf(stackstep),std::sinf(stackstep)*znew));
+
+ for (int t=2; t<nstacks; t++) {
+ int tlast = t - 1;
+ GLfloat ylast = std::cosf(PI*(float)(tlast)/(float)nstacks);
+ GLfloat ynew = std::cosf(PI*(float)(t)/(float)nstacks);
+
+ GLfloat rlast = std::sinf(PI * (float)(tlast)/(float)nstacks);
+ GLfloat rnew = std::sinf(PI * (float)(t)/(float)nstacks);
+
+ // two triangles to create a rect on the side
+ verts.push_back(Vertex(rlast*xlast,ylast,rlast*zlast, rlast*xlast,ylast,rlast*zlast));
+ verts.push_back(Vertex(rnew*xlast,ynew,rnew*zlast, rnew*xlast,ynew,rnew*zlast));
+ verts.push_back(Vertex(rnew*xnew,ynew,rnew*znew, rnew*xnew,ynew,rnew*znew));
+
+ verts.push_back(Vertex(rnew*xnew,ynew,rnew*znew, rnew*xnew,ynew,rnew*znew));
+ verts.push_back(Vertex(rlast*xnew,ylast,rlast*znew, rlast*xnew,ylast,rlast*znew));
+ verts.push_back(Vertex(rlast*xlast,ylast,rlast*zlast, rlast*xlast,ylast,rlast*zlast));
+ }
+
+ // one triangle on the bottom
+ verts.push_back(bot);
+ verts.push_back(Vertex(std::sinf(stackstep)*xnew,std::cosf(PI-stackstep),std::sinf(stackstep)*znew,
+ std::sinf(stackstep)*xnew,std::cosf(PI-stackstep),std::sinf(stackstep)*znew));
+ verts.push_back(Vertex(std::sinf(stackstep)*xlast,std::cosf(PI-stackstep),std::sinf(stackstep)*zlast,
+ std::sinf(stackstep)*xlast,std::cosf(PI-stackstep),std::sinf(stackstep)*zlast));
+ }
+
+ std::vector<Point3> vertices;
+ std::vector<Vector3> normals;
+ for (int i = 0; i < verts.size(); i++) {
+ vertices.push_back(Point3(verts[i].x, verts[i].y, verts[i].z));
+ normals.push_back(Vector3(verts[i].nx, verts[i].ny, verts[i].nz));
+ }
+ sphereMesh_.SetVertices(vertices);
+ sphereMesh_.SetNormals(normals);
+ sphereMesh_.UpdateGPUMemory();
+}
+
+
+void QuickShapes::DrawSphere(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix, const Color &color)
+{
+ if (sphereMesh_.num_vertices() == 0) {
+ initSph();
+ }
+ defaultMaterial_.ambient_reflectance = color;
+ defaultMaterial_.diffuse_reflectance = color;
+ defaultMaterial_.surface_texture = emptyTex_;
+ defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &sphereMesh_, defaultMaterial_);
+}
+
+
+
+
+// ------------ BRUSH ------------
+
+
+void QuickShapes::initBrush() {
+
+ // Raw vertices -- points that make up the brush geometry
+ const GLfloat v[19][3] = {
+ { 0.5f, 0.0f, 0.0f}, // 0
+ {-0.5f, 0.0f, 0.0f}, // 1
+
+ { 0.5f, 0.1f, 0.25f}, // 2
+ {-0.5f, 0.1f, 0.25f}, // 3
+ { 0.5f, 0.1f, 0.75f}, // 4
+ {-0.5f, 0.1f, 0.75f}, // 5
+ { 0.1f, 0.06f, 1.0f}, // 6
+ {-0.1f, 0.06f, 1.0f}, // 7
+ { 0.15f, 0.1f, 1.75f}, // 8
+ {-0.15f, 0.1f, 1.75f}, // 9
+
+ { 0.0f, 0.0f, 1.85f}, // 10
+
+ { 0.5f, -0.1f, 0.25f}, // 11
+ {-0.5f, -0.1f, 0.25f}, // 12
+ { 0.5f, -0.1f, 0.75f}, // 13
+ {-0.5f, -0.1f, 0.75f}, // 14
+ { 0.1f, -0.06f, 1.0f}, // 15
+ {-0.1f, -0.06f, 1.0f}, // 16
+ { 0.15f, -0.1f, 1.75f}, // 17
+ {-0.15f, -0.1f, 1.75f} // 18
+ };
+
+
+ // Vertices arranged into triangles
+ const GLfloat verts[34][3][3] = {
+ // top
+ {{v[0][0], v[0][1], v[0][2]}, {v[1][0], v[1][1], v[1][2]}, {v[2][0], v[2][1], v[2][2]}},
+ {{v[1][0], v[1][1], v[1][2]}, {v[3][0], v[3][1], v[3][2]}, {v[2][0], v[2][1], v[2][2]}},
+
+ {{v[2][0], v[2][1], v[2][2]}, {v[3][0], v[3][1], v[3][2]}, {v[4][0], v[4][1], v[4][2]}},
+ {{v[3][0], v[3][1], v[3][2]}, {v[5][0], v[5][1], v[5][2]}, {v[4][0], v[4][1], v[4][2]}},
+
+ {{v[4][0], v[4][1], v[4][2]}, {v[5][0], v[5][1], v[5][2]}, {v[6][0], v[6][1], v[6][2]}},
+ {{v[5][0], v[5][1], v[5][2]}, {v[7][0], v[7][1], v[7][2]}, {v[6][0], v[6][1], v[6][2]}},
+
+ {{v[6][0], v[6][1], v[6][2]}, {v[7][0], v[7][1], v[7][2]}, {v[8][0], v[8][1], v[8][2]}},
+ {{v[7][0], v[7][1], v[7][2]}, {v[9][0], v[9][1], v[9][2]}, {v[8][0], v[8][1], v[8][2]}},
+
+ {{v[8][0], v[8][1], v[8][2]}, {v[9][0], v[9][1], v[9][2]}, {v[10][0], v[10][1], v[10][2]}},
+
+ // bottom
+ {{v[0][0], v[0][1], v[0][2]}, {v[12][0], v[12][1], v[12][2]}, {v[1][0], v[1][1], v[1][2]}},
+ {{v[11][0], v[11][1], v[11][2]}, {v[12][0], v[12][1], v[12][2]}, {v[0][0], v[0][1], v[0][2]}},
+
+ {{v[11][0], v[11][1], v[11][2]}, {v[14][0], v[14][1], v[14][2]}, {v[12][0], v[12][1], v[12][2]}},
+ {{v[13][0], v[13][1], v[13][2]}, {v[14][0], v[14][1], v[14][2]}, {v[11][0], v[11][1], v[11][2]}},
+
+ {{v[13][0], v[13][1], v[13][2]}, {v[16][0], v[16][1], v[16][2]}, {v[14][0], v[14][1], v[14][2]}},
+ {{v[15][0], v[15][1], v[15][2]}, {v[16][0], v[16][1], v[16][2]}, {v[13][0], v[13][1], v[13][2]}},
+
+ {{v[15][0], v[15][1], v[15][2]}, {v[18][0], v[18][1], v[18][2]}, {v[16][0], v[16][1], v[16][2]}},
+ {{v[17][0], v[17][1], v[17][2]}, {v[18][0], v[18][1], v[18][2]}, {v[15][0], v[15][1], v[15][2]}},
+
+ {{v[18][0], v[18][1], v[18][2]}, {v[17][0], v[17][1], v[17][2]}, {v[10][0], v[10][1], v[10][2]}},
+
+ // one side
+ {{v[11][0], v[11][1], v[11][2]}, {v[0][0], v[0][1], v[0][2]}, {v[2][0], v[2][1], v[2][2]}},
+
+ {{v[11][0], v[11][1], v[11][2]}, {v[2][0], v[2][1], v[2][2]}, {v[4][0], v[4][1], v[4][2]}},
+ {{v[4][0], v[4][1], v[4][2]}, {v[13][0], v[13][1], v[13][2]}, {v[11][0], v[11][1], v[11][2]}},
+
+ {{v[13][0], v[13][1], v[13][2]}, {v[4][0], v[4][1], v[4][2]}, {v[6][0], v[6][1], v[6][2]}},
+ {{v[6][0], v[6][1], v[6][2]}, {v[15][0], v[15][1], v[15][2]}, {v[13][0], v[13][1], v[13][2]}},
+
+ {{v[15][0], v[15][1], v[15][2]}, {v[6][0], v[6][1], v[6][2]}, {v[8][0], v[8][1], v[8][2]}},
+ {{v[8][0], v[8][1], v[8][2]}, {v[17][0], v[17][1], v[17][2]}, {v[15][0], v[15][1], v[15][2]}},
+
+ {{v[17][0], v[17][1], v[17][2]}, {v[8][0], v[8][1], v[8][2]}, {v[10][0], v[10][1], v[10][2]}},
+
+ // other side
+ {{v[3][0], v[3][1], v[3][2]}, {v[1][0], v[1][1], v[1][2]}, {v[12][0], v[12][1], v[12][2]}},
+
+ {{v[3][0], v[3][1], v[3][2]}, {v[12][0], v[12][1], v[12][2]}, {v[14][0], v[14][1], v[14][2]}},
+ {{v[14][0], v[14][1], v[14][2]}, {v[5][0], v[5][1], v[5][2]}, {v[3][0], v[3][1], v[3][2]}},
+
+ {{v[5][0], v[5][1], v[5][2]}, {v[14][0], v[14][1], v[14][2]}, {v[16][0], v[16][1], v[16][2]}},
+ {{v[16][0], v[16][1], v[16][2]}, {v[7][0], v[7][1], v[7][2]}, {v[5][0], v[5][1], v[5][2]}},
+
+ {{v[7][0], v[7][1], v[7][2]}, {v[16][0], v[16][1], v[16][2]}, {v[18][0], v[18][1], v[18][2]}},
+ {{v[18][0], v[18][1], v[18][2]}, {v[9][0], v[9][1], v[9][2]}, {v[7][0], v[7][1], v[7][2]}},
+
+ {{v[9][0], v[9][1], v[9][2]}, {v[18][0], v[18][1], v[18][2]}, {v[10][0], v[10][1], v[10][2]}}
+
+ };
+
+
+ // Normals defined so as to make each face of the brush a flat surface
+ const GLfloat norms[34][3][3] = {
+ // top
+ {{0.0f, 0.93f, -0.37f}, {0.0f, 0.93f, -0.37f}, {0.0f, 0.93f, -0.37f}},
+ {{0.0f, 0.93f, -0.37f}, {0.0f, 0.93f, -0.37f}, {0.0f, 0.93f, -0.37f}},
+
+ {{0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
+ {{0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
+
+ {{0.0f, 0.988f, 0.158f}, {0.0f, 0.988f, 0.158f}, {0.0f, 0.988f, 0.158f}},
+ {{0.0f, 0.988f, 0.158f}, {0.0f, 0.988f, 0.158f}, {0.0f, 0.988f, 0.158f}},
+
+ {{0.0f, 0.999f, -0.0533f}, {0.0f, 0.999f, -0.0533f}, {0.0f, 0.999f, -0.0533f}},
+ {{0.0f, 0.999f, -0.0533f}, {0.0f, 0.999f, -0.0533f}, {0.0f, 0.999f, -0.0533f}},
+
+ {{0.0f, 0.709f, 0.709f}, {0.0f, 0.709f, 0.709f}, {0.0f, 0.709f, 0.709f}},
+
+ // bottom
+ {{0.0f, -0.93f, -0.37f}, {0.0f, -0.93f, -0.37f}, {0.0f, -0.93f, -0.37f}},
+ {{0.0f, -0.93f, -0.37f}, {0.0f, -0.93f, -0.37f}, {0.0f, -0.93f, -0.37f}},
+
+ {{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}},
+ {{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}},
+
+ {{0.0f, -0.988f, 0.158f}, {0.0f, -0.988f, 0.158f}, {0.0f, -0.988f, 0.158f}},
+ {{0.0f, -0.988f, 0.158f}, {0.0f, -0.988f, 0.158f}, {0.0f, -0.988f, 0.158f}},
+
+ {{0.0f, -0.999f, -0.0533f}, {0.0f, -0.999f, -0.0533f}, {0.0f, -0.999f, -0.0533f}},
+ {{0.0f, -0.999f, -0.0533f}, {0.0f, -0.999f, -0.0533f}, {0.0f, -0.999f, -0.0533f}},
+
+ {{0.0f, -0.709f, 0.709f}, {0.0f, -0.709f, 0.709f}, {0.0f, -0.709f, 0.709f}},
+
+ // one side
+ {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
+
+ {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
+ {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
+
+ {{0.848f, 0.0f, 0.530f}, {0.848f, 0.0f, 0.530f}, {0.848f, 0.0f, 0.530f}},
+ {{0.848f, 0.0f, 0.530f}, {0.848f, 0.0f, 0.530f}, {0.848f, 0.0f, 0.530f}},
+
+ {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
+ {{1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
+
+ {{0.709f, 0.0f, 0.709f}, {0.709f, 0.0f, 0.709f}, {0.709f, 0.0f, 0.709f}},
+
+ // other side
+ {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}},
+
+ {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}},
+ {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}},
+
+ {{-0.848f, 0.0f, 0.530f}, {-0.848f, 0.0f, 0.530f}, {-0.848f, 0.0f, 0.530f}},
+ {{-0.848f, 0.0f, 0.530f}, {-0.848f, 0.0f, 0.530f}, {-0.848f, 0.0f, 0.530f}},
+
+ {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}},
+ {{-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}},
+
+ {{-0.709f, 0.0f, 0.709f}, {-0.709f, 0.0f, 0.709f}, {-0.709f, 0.0f, 0.709f}}
+ };
+
+ brushMesh_.SetVertices((float*)verts, 102);
+ brushMesh_.SetNormals((float*)norms, 102);
+ brushMesh_.UpdateGPUMemory();
+}
+
+
+void QuickShapes::DrawBrush(const Matrix4 &modelMatrix, const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix, const Color &color)
+{
+ if (brushMesh_.num_vertices() == 0) {
+ initBrush();
+ }
+ defaultMaterial_.ambient_reflectance = color;
+ defaultMaterial_.diffuse_reflectance = color;
+ defaultMaterial_.surface_texture = emptyTex_;
+ defaultShader_.Draw(modelMatrix, viewMatrix, projectionMatrix, &brushMesh_, defaultMaterial_);
+}
+
+
+
+// ----------------
+
+
+void QuickShapes::DrawLineSegment(const Matrix4 &modelMatrix,
+ const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix,
+ const Color &color,
+ const Point3 &p1,
+ const Point3 &p2,
+ float radius)
+{
+ Matrix4 S = Matrix4::Scale(Vector3(radius, 0.5f*(p2-p1).Length(), radius));
+ Vector3 y = (p2-p1).ToUnit();
+ Vector3 z = Vector3(1,0,0).Cross(y).ToUnit();
+ if (z == Vector3(0,0,0)) {
+ z = Vector3(0,0,1).Cross(y).ToUnit();
+ }
+ Vector3 x = y.Cross(z);
+ Matrix4 R = Matrix4::FromRowMajorElements(
+ x[0], y[0], z[0], 0,
+ x[1], y[1], z[1], 0,
+ x[2], y[2], z[2], 0,
+ 0, 0, 0, 1
+ );
+ Matrix4 T = Matrix4::Translation(0.5 * Vector3(p1[0]+p2[0], p1[1]+p2[1], p1[2]+p2[2]));
+
+ Matrix4 M = T * R * S;
+
+ DrawCylinder(modelMatrix * M, viewMatrix, projectionMatrix, color);
+}
+
+
+
+void QuickShapes::DrawLines(const Matrix4 &modelMatrix,
+ const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix,
+ const Color &color,
+ const std::vector<Point3> &points,
+ LinesType ltype,
+ float radius)
+{
+ if (ltype == LinesType::LINES) {
+ for (size_t i=0; i<points.size(); i+=2) {
+ DrawLineSegment(modelMatrix, viewMatrix, projectionMatrix, color, points[i], points[i+1], radius);
+ }
+ }
+ else {
+ for (size_t i=0; i<points.size()-1; i++) {
+ DrawLineSegment(modelMatrix, viewMatrix, projectionMatrix, color, points[i], points[i+1], radius);
+ }
+ if (ltype == LinesType::LINE_LOOP) {
+ DrawLineSegment(modelMatrix, viewMatrix, projectionMatrix, color, points[points.size()-1], points[0], radius);
+ }
+ }
+}
+
+
+
+void QuickShapes::DrawArrow(const Matrix4 &modelMatrix,
+ const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix,
+ const Color &color,
+ Point3 p, Vector3 dir, float radius)
+{
+ float d = dir.Length() - 8.0f*radius;
+ DrawLineSegment(modelMatrix, viewMatrix, projectionMatrix, color, p, p + d*dir.ToUnit(), radius);
+
+ Matrix4 S = Matrix4::Scale(Vector3(radius*3.0f, radius*4.0f, radius*3.0f));
+ Vector3 y = dir.ToUnit();
+ Vector3 z = Vector3(1,0,0).Cross(y).ToUnit();
+ if (z == Vector3(0,0,0)) {
+ z = Vector3(0,0,1).Cross(y).ToUnit();
+ }
+ Vector3 x = y.Cross(z);
+ Matrix4 R = Matrix4::FromRowMajorElements(
+ x[0], y[0], z[0], 0,
+ x[1], y[1], z[1], 0,
+ x[2], y[2], z[2], 0,
+ 0, 0, 0, 1
+ );
+ Matrix4 T = Matrix4::Translation((p + d*dir.ToUnit()) - Point3::Origin());
+
+ Matrix4 M = T * R * S * Matrix4::Translation(Vector3(0,1,0));
+
+ DrawCone(modelMatrix * M, viewMatrix, projectionMatrix, color);
+}
+
+
+void QuickShapes::DrawAxes(const Matrix4 &modelMatrix,
+ const Matrix4 &viewMatrix,
+ const Matrix4 &projectionMatrix)
+{
+ DrawArrow(modelMatrix, viewMatrix, projectionMatrix, Color(1.0f, 0.6f, 0.6f), Point3::Origin(), Vector3::UnitX(), 0.02f);
+ DrawArrow(modelMatrix, viewMatrix, projectionMatrix, Color(0.6f, 1.0f, 0.6f), Point3::Origin(), Vector3::UnitY(), 0.02f);
+ DrawArrow(modelMatrix, viewMatrix, projectionMatrix, Color(0.6f, 0.6f, 1.0f), Point3::Origin(), Vector3::UnitZ(), 0.02f);
+
+}
+
+
+void QuickShapes::initFull() {
+ GLfloat vertices[] = {
+ -1, -1, 0, 1, -1, 0, 1, 1, 0,
+ -1, -1, 0, 1, 1, 0, -1, 1, 0
+ };
+
+ GLfloat normals[] = {
+ 0, 0, 1, 0, 0, 1, 0, 0, 1,
+ 0, 0, 1, 0, 0, 1, 0, 0, 1
+ };
+
+ GLfloat texcoords[] = {
+ 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
+ 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f
+ };
+
+ fullMesh_.SetVertices(vertices, 6);
+ fullMesh_.SetNormals(normals, 6);
+ fullMesh_.SetTexCoords(0, texcoords, 6);
+ fullMesh_.UpdateGPUMemory();
+}
+
+
+void QuickShapes::DrawFullscreenTexture(const Color &color, const Texture2D &tex) {
+ if (fullMesh_.num_vertices() == 0) {
+ initFull();
+ }
+ DrawWithFullscreen(color, &fullMesh_, tex);
+}
+
+
+
+
+
+void QuickShapes::DrawWithFullscreen(const Color &color, Mesh *mesh, const Texture2D &tex) {
+ if (!fullscreenShader_.initialized()) {
+ fullscreenShader_.AddVertexShaderFromFile(Platform::FindMinGfxShaderFile("fullscreen.vert"));
+ fullscreenShader_.AddFragmentShaderFromFile(Platform::FindMinGfxShaderFile("fullscreen.frag"));
+ fullscreenShader_.LinkProgram();
+ }
+
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+
+ // Activate the shader program
+ fullscreenShader_.UseProgram();
+
+ // Pass uniforms and textures from C++ to the GPU Shader Program
+ fullscreenShader_.SetUniform("TintColor", color);
+ fullscreenShader_.BindTexture("SurfaceTexture", tex);
+
+ // Draw the mesh using the shader program
+ mesh->Draw();
+
+ // Deactivate the shader program
+ fullscreenShader_.StopProgram();
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+}
+
+
+DefaultShader* QuickShapes::default_shader() {
+ return &defaultShader_;
+}
+
+
+DefaultShader::MaterialProperties* QuickShapes::material() {
+ return &defaultMaterial_;
+}
+
+
+} // end namespace
|