X-Git-Url: https://git.lukelau.me/?p=opengl.git;a=blobdiff_plain;f=shapes.hpp;h=876ce3c550ebf97c3951850d4483f1ddaf6fe1ae;hp=92cc8adb0882ecd6c3d3c54955bad6eb0a25d286;hb=b91a0d30ae6484b6c4d981aeafa8d4996c98effe;hpb=9886c33eb8cd31f28234585718410cd51aef2a4c diff --git a/shapes.hpp b/shapes.hpp index 92cc8ad..876ce3c 100644 --- a/shapes.hpp +++ b/shapes.hpp @@ -1,4 +1,6 @@ #include +#include +#include #define GLM_FORCE_PURE #include @@ -24,7 +26,70 @@ constexpr array plane() { }); } -constexpr array cube() { +inline vector cube() { + int i = 0; + vector vertices(36); + + const array front = { + glm::vec3(1, -1, -1), + glm::vec3(-1, -1, -1), + glm::vec3(-1, 1, -1), + glm::vec3(1, 1, -1) + }; + + for (auto v: quadToTriangles(front)) + vertices[i++] = v; + + const array back = { + glm::vec3(1, 1, 1), + glm::vec3(-1, 1, 1), + glm::vec3(-1, -1, 1), + glm::vec3(1, -1, 1) + }; + for (auto v: quadToTriangles(back)) + vertices[i++] = v; + + + const array top = { + glm::vec3(1, 1, -1), + glm::vec3(-1, 1, -1), + glm::vec3(-1, 1, 1), + glm::vec3(1, 1, 1) + }; + for (auto v: quadToTriangles(top)) + vertices[i++] = v; + + const array bottom = { + glm::vec3(1, -1, 1), + glm::vec3(-1, -1, 1), + glm::vec3(-1, -1, -1), + glm::vec3(1, -1, -1) + }; + for (auto v: quadToTriangles(bottom)) + vertices[i++] = v; + + const array left = { + glm::vec3(-1, 1, 1), + glm::vec3(-1, 1, -1), + glm::vec3(-1, -1, -1), + glm::vec3(-1, -1, 1) + }; + for (auto v: quadToTriangles(left)) + vertices[i++] = v; + + const array right = { + glm::vec3(1, 1, -1), + glm::vec3(1, 1, 1), + glm::vec3(1, -1, 1), + glm::vec3(1, -1, -1) + }; + for (auto v: quadToTriangles(right)) + vertices[i++] = v; + + return vertices; +} + +constexpr array cubeArray() { int i = 0; array vertices; @@ -112,7 +177,72 @@ constexpr glm::vec3 pyramid[18] = { glm::vec3(1, -1, 1) }; -// TODO: Add a sphere -/* constexpr std::vector sphere() { */ +// taken from http://www.songho.ca/opengl/gl_sphere.html +#define SECTOR_COUNT 16 +#define STACK_COUNT 16 +inline std::vector sphere(float radius = 1) { + float sectorStep = 2 * M_PI / SECTOR_COUNT; + float stackStep = M_PI / STACK_COUNT; + + std::vector vertices; + + for(int i = 0; i <= STACK_COUNT; i++) { + float stackAngle = M_PI / 2 - i * stackStep; // starting from pi/2 to -pi/2 + float xy = radius * cosf(stackAngle); // r * cos(u) + float z = radius * sinf(stackAngle); // r * sin(u) + + // add (sectorCount+1) vertices per stack + // the first and last vertices have same position and normal, but different tex coords + for(int j = 0; j <= SECTOR_COUNT; j++) + { + float sectorAngle = j * sectorStep; // starting from 0 to 2pi + + // vertex position (x, y, z) + float x = xy * cosf(sectorAngle); // r * cos(u) * cos(v) + float y = xy * sinf(sectorAngle); // r * cos(u) * sin(v) + vertices.push_back({x, y, z}); + + // normalized vertex normal (nx, ny, nz) + /* nx = x * lengthInv; */ + /* ny = y * lengthInv; */ + /* nz = z * lengthInv; */ + /* normals.push_back(nx); */ + /* normals.push_back(ny); */ + /* normals.push_back(nz); */ + + } + } + return vertices; +} + +inline std::vector sphereIndices() { + // generate CCW index list of sphere triangles + vector indices; + int k1, k2; + for(int i = 0; i < STACK_COUNT; ++i) + { + k1 = i * (SECTOR_COUNT + 1); // beginning of current stack + k2 = k1 + SECTOR_COUNT + 1; // beginning of next stack + + for(int j = 0; j < SECTOR_COUNT; ++j, ++k1, ++k2) + { + // 2 triangles per sector excluding first and last stacks + // k1 => k2 => k1+1 + if(i != 0) + { + indices.push_back(k1); + indices.push_back(k2); + indices.push_back(k1 + 1); + } -/* } */ + // k1+1 => k2 => k2+1 + if(i != (STACK_COUNT-1)) + { + indices.push_back(k1 + 1); + indices.push_back(k2); + indices.push_back(k2 + 1); + } + } + } + return indices; +}