diff --git a/OpenGLEngine/MeshFactory.h b/OpenGLEngine/MeshFactory.h index 9932de5..44adf9f 100644 --- a/OpenGLEngine/MeshFactory.h +++ b/OpenGLEngine/MeshFactory.h @@ -360,7 +360,6 @@ namespace charcoal } } - protected: static MeshType* create_mesh(unsigned int vertex_count, unsigned int index_count) { MeshType* mesh = new MeshType(); diff --git a/OpenGLEngine/MeshGenerator.h b/OpenGLEngine/MeshGenerator.h new file mode 100644 index 0000000..98fc4eb --- /dev/null +++ b/OpenGLEngine/MeshGenerator.h @@ -0,0 +1,177 @@ +#pragma once + +#include + +#include "MeshFactory.h" + +#include "Mesh.h" + +#include "MeshTypes.h" + +namespace charcoal +{ + namespace builtin + { + // Uses MeshFactory to generate meshes for the builtin vertex types. + class MeshGenerator + { + private: + MeshGenerator() {} + + public: + // Creates a cube centered at the origin with specified width, height, and depth + template + Mesh* MeshGenerator::gen_cube(const DrawMode& draw_mode, float width, float height, float depth) + { + static_assert(std::is_base_of::value); + static_assert(std::is_base_of::value); + + Mesh* mesh; + + float x = width / 2.0f; + float y = height / 2.0f; + float z = depth / 2.0f; + + Position pos0(-x, y, -z); // Front Left Top + Position pos1(-x, -y, -z); // Front Left Bottom + Position pos2(x, y, -z); // Front Right Top + Position pos3(x, -y, -z); // Front Right Bottom + Position pos4(-x, y, z); // Back Left Top + Position pos5(-x, -y, z); // Back Left Bottom + Position pos6(x, y, z); // Back Right Top + Position pos7(x, -y, z); // Back Right Bottom + + Normal front(0.0f, 0.0f, -1.0f); + Normal right(1.0f, 0.0f, 0.0f); + Normal back(0.0f, 0.0f, 1.0f); + Normal left(-1.0f, 0.0f, 0.0f); + Normal top(0.0f, 1.0f, 0.0f); + Normal bottom(0.0f, -1.0f, 0.0f); + switch (draw_mode) + { + case DrawMode::DRAW_TRIANGLES: + mesh = MeshFactory::create_mesh(24, 36); + mesh->vertices[0].set_normal(front); + mesh->vertices[1].set_normal(front); + mesh->vertices[2].set_normal(front); + mesh->vertices[3].set_normal(front); + + mesh->vertices[4].set_normal(right); + mesh->vertices[5].set_normal(right); + mesh->vertices[6].set_normal(right); + mesh->vertices[7].set_normal(right); + + mesh->vertices[8].set_normal(back); + mesh->vertices[9].set_normal(back); + mesh->vertices[10].set_normal(back); + mesh->vertices[11].set_normal(back); + + mesh->vertices[12].set_normal(left); + mesh->vertices[13].set_normal(left); + mesh->vertices[14].set_normal(left); + mesh->vertices[15].set_normal(left); + + mesh->vertices[16].set_normal(top); + mesh->vertices[17].set_normal(top); + mesh->vertices[18].set_normal(top); + mesh->vertices[19].set_normal(top); + + mesh->vertices[20].set_normal(bottom); + mesh->vertices[21].set_normal(bottom); + mesh->vertices[22].set_normal(bottom); + mesh->vertices[23].set_normal(bottom); + + mesh->vertices[0].set_position(pos0); + mesh->vertices[1].set_position(pos1); + mesh->vertices[2].set_position(pos2); + mesh->vertices[3].set_position(pos3); + + mesh->vertices[4].set_position(pos2); + mesh->vertices[5].set_position(pos3); + mesh->vertices[6].set_position(pos6); + mesh->vertices[7].set_position(pos7); + + mesh->vertices[8].set_position(pos6); + mesh->vertices[9].set_position(pos7); + mesh->vertices[10].set_position(pos4); + mesh->vertices[11].set_position(pos5); + + mesh->vertices[12].set_position(pos4); + mesh->vertices[13].set_position(pos5); + mesh->vertices[14].set_position(pos0); + mesh->vertices[15].set_position(pos1); + + mesh->vertices[16].set_position(pos4); + mesh->vertices[17].set_position(pos0); + mesh->vertices[18].set_position(pos6); + mesh->vertices[19].set_position(pos2); + + mesh->vertices[20].set_position(pos1); + mesh->vertices[21].set_position(pos5); + mesh->vertices[22].set_position(pos3); + mesh->vertices[23].set_position(pos7); + + // Counter Clockwise + // Front + mesh->indices[0] = 1; + mesh->indices[1] = 3; + mesh->indices[2] = 0; + mesh->indices[3] = 0; + mesh->indices[4] = 3; + mesh->indices[5] = 2; + // Right + mesh->indices[6] = 5; + mesh->indices[7] = 7; + mesh->indices[8] = 4; + mesh->indices[9] = 4; + mesh->indices[10] = 7; + mesh->indices[11] = 6; + // Back + mesh->indices[12] = 9; + mesh->indices[13] = 11; + mesh->indices[14] = 8; + mesh->indices[15] = 8; + mesh->indices[16] = 11; + mesh->indices[17] = 10; + // Left + mesh->indices[18] = 13; + mesh->indices[19] = 15; + mesh->indices[20] = 12; + mesh->indices[21] = 12; + mesh->indices[22] = 15; + mesh->indices[23] = 14; + // Top + mesh->indices[24] = 17; + mesh->indices[25] = 19; + mesh->indices[26] = 16; + mesh->indices[27] = 16; + mesh->indices[28] = 19; + mesh->indices[29] = 18; + // Bottom + mesh->indices[30] = 21; + mesh->indices[31] = 23; + mesh->indices[32] = 20; + mesh->indices[33] = 20; + mesh->indices[34] = 23; + mesh->indices[35] = 22; + return mesh; + case DrawMode::DRAW_POINTS: + case DrawMode::DRAW_LINES: + case DrawMode::DRAW_LINE_STRIP: + case DrawMode::DRAW_LINE_LOOP: + case DrawMode::DRAW_TRIANGLE_STRIP: + case DrawMode::DRAW_TRIANGLE_FAN: + case DrawMode::DRAW_LINE_STRIP_ADJACENCY: + case DrawMode::DRAW_LINES_ADJACENCY: + case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: + case DrawMode::DRAW_TRIANGLES_ADJACENCY: + case DrawMode::DRAW_PATCHES: + default: + throw EXCEPTION("Unable to gen_cube for current draw mode: " + std::to_string(draw_mode)); + } + } + + // TODO: Mesh* gen_cube(const DrawMode& draw_mode, float width, float height, float depth); + }; + } +} diff --git a/OpenGLEngine/MeshTypes.h b/OpenGLEngine/MeshTypes.h new file mode 100644 index 0000000..9a0e4ac --- /dev/null +++ b/OpenGLEngine/MeshTypes.h @@ -0,0 +1,60 @@ +#pragma once + +#include + +namespace charcoal +{ + namespace builtin + { + using namespace glm; + + typedef vec3 Position; + typedef vec3 Normal; + typedef vec4 Color; + typedef vec2 UV; + + typedef unsigned int Index; + + class Positioned + { + virtual void set_position(const Position& position) = 0; + }; + + class Normaled + { + virtual void set_normal(const Normal& normal) = 0; + }; + + class Colored + { + virtual void set_color(const Color& color) = 0; + }; + + class Textured + { + virtual void set_uv(const UV& uv) = 0; + }; + + // Simple types that implement the interfaces + + struct PNVertex : public Positioned, public Normaled + { + void set_position(const Position& position) override { this->position = position; } + void set_normal(const Normal& normal) override { this->normal = normal; } + + Position position; + Normal normal; + }; + + struct PNTVertex : public Positioned, public Normaled, public Textured + { + void set_position(const Position& position) override { this->position = position; } + void set_normal(const Normal& normal) override { this->normal = normal; } + void set_uv(const UV& uv) override { this->uv = uv; } + + Position position; + Normal normal; + UV uv; + }; + } +} \ No newline at end of file diff --git a/OpenGLEngine/OpenGLEngine.vcxproj b/OpenGLEngine/OpenGLEngine.vcxproj index 6430b64..12bf742 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj +++ b/OpenGLEngine/OpenGLEngine.vcxproj @@ -189,6 +189,7 @@ + @@ -204,6 +205,7 @@ + diff --git a/OpenGLEngine/OpenGLEngine.vcxproj.filters b/OpenGLEngine/OpenGLEngine.vcxproj.filters index 127f1ae..915d100 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj.filters +++ b/OpenGLEngine/OpenGLEngine.vcxproj.filters @@ -52,6 +52,12 @@ {0c68fb1a-eaef-450c-ab9e-56bcfd75fdff} + + {65489d6f-e0f8-4530-8e9b-769234deea85} + + + {233b4bce-fc64-4ad1-994e-c986befa7ff2} + @@ -200,6 +206,12 @@ Header Files\Engine + + Header Files\Engine\builtin + + + Header Files\Engine\builtin +