diff --git a/engine.xcodeproj/project.pbxproj b/engine.xcodeproj/project.pbxproj index a344240..b3acb5f 100644 --- a/engine.xcodeproj/project.pbxproj +++ b/engine.xcodeproj/project.pbxproj @@ -97,9 +97,9 @@ AD58E0641E2A76FD006ACC15 /* shader.hpp */, AD58E0521E107411006ACC15 /* main.cpp */, AD58E06D1E2A80BC006ACC15 /* shape.cpp */, + AD58E06E1E2A80BC006ACC15 /* shape.hpp */, AD58E0701E2A90EF006ACC15 /* app.cpp */, AD58E0711E2A90EF006ACC15 /* app.hpp */, - AD58E06E1E2A80BC006ACC15 /* shape.hpp */, AD58E0661E2A7741006ACC15 /* image.cpp */, AD58E0671E2A7741006ACC15 /* image.hpp */, AD58E0691E2A774F006ACC15 /* texture.cpp */, diff --git a/engine/app.cpp b/engine/app.cpp index a39d7df..c9fbd65 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -47,7 +47,7 @@ void App::init() shader_color.create(shader_color_v, shader_color_f); plane.create<15>(.5f, .5f); longPlane.create<1>(.3, .05f); - circle.create<6>(.5f); + circle.create<6>(.5f, .25f); if (!tex.load("data/image.png")) printf("error loading image\n"); @@ -84,7 +84,7 @@ void App::update(float dt) glm::mat4 view = glm::lookAt(glm::vec3(sinf(theta), 0, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); auto mvp = proj * view * model; - glClearColor(red, 0, 0, 1); + //glClearColor(red, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); shader.use(); shader.u_mat4("mvp", glm::mat4()); @@ -92,7 +92,7 @@ void App::update(float dt) glActiveTexture(GL_TEXTURE0); tex.bind(); - //circle.draw_fill(); + circle.draw_fill(); tex.unbind(); shader_color.use(); diff --git a/engine/shape.cpp b/engine/shape.cpp index 199c2d4..37f9a61 100644 --- a/engine/shape.cpp +++ b/engine/shape.cpp @@ -1,9 +1,12 @@ #include "pch.h" #include "shape.hpp" -void Shape::create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize) +bool Shape::create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize) { glGenBuffers(2, buffers); + if (!(buffers[0] && buffers[1])) + return false; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, isize, idx, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); @@ -12,6 +15,8 @@ void Shape::create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize) glBindBuffer(GL_ARRAY_BUFFER, 0); glGenVertexArrays(2, arrays); + if (!(arrays[0] && arrays[1])) + return false; for (int i = 0; i < 2; i++) { @@ -25,6 +30,7 @@ void Shape::create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize) } glBindVertexArray(0); + return true; } void Shape::draw_fill() const { @@ -36,3 +42,115 @@ void Shape::draw_stroke() const glBindVertexArray(arrays[1]); glDrawElements(GL_LINES, count[1], GL_UNSIGNED_SHORT, ioff[1]); } + +void Plane::create_impl(float w, float h, int div, GLushort *idx, Shape::vertex_t *vertices) +{ + count[0] = div * div * 6; + count[1] = 4; + ioff[0] = (GLvoid*)4; + ioff[1] = (GLvoid*)0; + + const float dx = w / div; + const float dy = h / div; + const float ox = -w * 0.5f; + const float oy = -h * 0.5f; + int v_index = 0; + for (int y = 0; y <= div; y++) + { + for (int x = 0; x <= div; x++) + { + vertex_t v; + v.pos.x = ox + dx * (float)x; + v.pos.y = oy + dy * (float)y; + v.pos.z = 0; + v.pos.w = 1; + v.uvs = glm::vec2(x, y) / (float)div; + vertices[v_index++] = v; + } + } + + // generate indices + auto pidx = idx; + *pidx++ = 0; + *pidx++ = div; + *pidx++ = (div+1)*(div); + *pidx++ = (div+1)*(div+1)-1; + for (int y = 0; y < div; y++) + { + int i = y * (div+1); + for (int x = 0; x < div; x++) + { + *pidx++ = i; + *pidx++ = i + div + 1; + *pidx++ = i + div + 2; + *pidx++ = i; + *pidx++ = i + div + 2; + *pidx++ = i + 1; + i++; + } + } +} + +void Circle::create_impl(float radius, int div, GLushort* idx, Shape::vertex_t* vertices) +{ + count[0] = div * 3; + count[1] = div * 2; + ioff[0] = (GLvoid*)0; + ioff[1] = (GLvoid*)(div * 3 * sizeof(GLushort)); + + auto pidx = idx; + auto pidx2 = idx + div * 3; + for (int i = 0; i < div; i++) + { + vertex_t v; + float theta = (float)i / div * M_PI * 2.f; + v.pos.x = sinf(theta) * radius; + v.pos.y = cosf(theta) * radius; + v.pos.z = 0; + v.pos.w = 1; + v.uvs = v.pos.xy() * 0.5f + 0.5f; + vertices[i+1] = v; + + *pidx++ = 0; + *pidx++ = i+1; + *pidx++ = ((i+1) % div) + 1; + + *pidx2++ = 1 + i; + *pidx2++ = 1 + ((i+1) % div); + } + vertices[0].pos = { 0, 0, 0, 1 }; + vertices[0].uvs = { 0.5f, 0.5f }; +} + +void Circle::create_impl(float radius_out, float radius_in, int div, GLushort* idx, Shape::vertex_t* vertices) +{ + count[0] = div * 6; + count[1] = div * 4; + ioff[0] = (GLvoid*)0; + ioff[1] = (GLvoid*)(div * 6 * sizeof(GLushort)); + + auto pidx = idx; + auto pidx2 = idx + div * 6; + for (int i = 0; i < div; i++) + { + float theta = (float)i / div * M_PI * 2.f; + vertices[i*2].pos = { sinf(theta) * radius_in, cosf(theta) * radius_in, 0, 1 }; + vertices[i*2].uvs = vertices[i*2].pos.xy() * 0.5f + 0.5f; + vertices[i*2+1].pos = { sinf(theta) * radius_out, cosf(theta) * radius_out, 0, 1 }; + vertices[i*2+1].uvs = vertices[i*2+1].pos.xy() * 0.5f + 0.5f; + + *pidx++ = i*2; // A + *pidx++ = i*2+1; // B + *pidx++ = ((i+1)*2+1) % (div*2); // C + + *pidx++ = i*2; // A + *pidx++ = ((i+1)*2+1) % (div*2); // C + *pidx++ = ((i+1)*2) % (div*2); // D + + *pidx2++ = i*2; // A + *pidx2++ = ((i+1)*2) % (div*2); // D + + *pidx2++ = i*2+1; // B + *pidx2++ = ((i+1)*2+1) % (div*2);// C + } +} diff --git a/engine/shape.hpp b/engine/shape.hpp index 4e79e0f..c3a3afc 100644 --- a/engine/shape.hpp +++ b/engine/shape.hpp @@ -9,146 +9,44 @@ protected: GLvoid* ioff[2]; struct vertex_t { glm::vec4 pos; glm::vec2 uvs; }; public: - void create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize); + bool create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize); void draw_fill() const; void draw_stroke() const; }; class Plane : public Shape { + void create_impl(float w, float h, int div, GLushort* idx, vertex_t* vertices); public: template bool create(float w, float h) { - - static GLshort idx[div * div * 6 + 4]; + static GLushort idx[div * div * 6 + 4]; static vertex_t vertices[(div+1)*(div+1)]; - - count[0] = div * div * 6; - count[1] = 4; - ioff[0] = (GLvoid*)4; - ioff[1] = (GLvoid*)0; - - const float dx = w / div; - const float dy = h / div; - const float ox = -w * 0.5f; - const float oy = -h * 0.5f; - int v_index = 0; - for (int y = 0; y <= div; y++) - { - for (int x = 0; x <= div; x++) - { - vertex_t v; - v.pos.x = ox + dx * (float)x; - v.pos.y = oy + dy * (float)y; - v.pos.z = 0; - v.pos.w = 1; - v.uvs = glm::vec2(x, y) / (float)div; - vertices[v_index++] = v; - } - } - - // generate indices - auto pidx = idx; - *pidx++ = 0; - *pidx++ = div; - *pidx++ = (div+1)*(div); - *pidx++ = (div+1)*(div+1)-1; - for (int y = 0; y < div; y++) - { - int i = y * (div+1); - for (int x = 0; x < div; x++) - { - *pidx++ = i; - *pidx++ = i + div + 1; - *pidx++ = i + div + 2; - *pidx++ = i; - *pidx++ = i + div + 2; - *pidx++ = i + 1; - i++; - } - } - - create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); - - return true; + create_impl(w, h, div, idx, vertices); + return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } }; class Circle : public Shape { + void create_impl(float radius, int div, GLushort* idx, vertex_t* vertices); + void create_impl(float radius_out, float radius_in, int div, GLushort* idx, vertex_t* vertices); public: template bool create(float radius) { static GLushort idx[div * 3 + div * 2]; static vertex_t vertices[div + 1]; - - count[0] = div * 3; - count[1] = div * 2; - ioff[0] = (GLvoid*)0; - ioff[1] = (GLvoid*)(div * 3 * sizeof(idx[0])); - - auto pidx = idx; - auto pidx2 = idx + div * 3; - for (int i = 0; i < div; i++) - { - vertex_t v; - float theta = (float)i / div * M_PI * 2.f; - v.pos.x = sinf(theta) * radius; - v.pos.y = cosf(theta) * radius; - v.pos.z = 0; - v.pos.w = 1; - v.uvs = v.pos.xy() * 0.5f + 0.5f; - vertices[i+1] = v; - - *pidx++ = 0; - *pidx++ = i+1; - *pidx++ = ((i+1) % div) + 1; - - *pidx2++ = 1 + i; - *pidx2++ = 1 + ((i+1) % div); - } - vertices[0].pos = { 0, 0, 0, 1 }; - vertices[0].uvs = { 0.5f, 0.5f }; - - create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); - - return true; + create_impl(radius, div, idx, vertices); + return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } template bool create(float radius_out, float radius_in) { - static GLubyte idx[div*6 + div*2]; + static GLushort idx[div*6 + div*4]; static vertex_t vertices[div * 2]; - - count[0] = div * 6; - count[1] = div * 2; - - auto pidx = idx; - auto pidx2 = idx + div * 6; - for (int i = 0; i < div; i++) - { - float theta = (float)i / div * M_PI * 2.f; - vertices[i*2].pos = { sinf(theta) * radius_in, cosf(theta) * radius_in, 0, 1 }; - vertices[i*2].uvs = vertices[i*2].pos.xy() * 0.5f + 0.5f; - vertices[i*2+1].pos = { sinf(theta) * radius_out, cosf(theta) * radius_out, 0, 1 }; - vertices[i*2+1].uvs = vertices[i*2+1].pos.xy() * 0.5f + 0.5f; - - *pidx++ = i*2; // A - *pidx++ = i*2+1; // B - *pidx++ = ((i+1)*2+1) % (div*2); // C - - *pidx++ = i*2; // A - *pidx++ = ((i+1)*2+1) % (div*2); // C - *pidx++ = ((i+1)*2) % (div*2); // D - - *pidx2++ = 1 + i; - *pidx2++ = 1 + ((i+1) % div); - } - - create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); - - return true; + create_impl(radius_out, radius_in, div, idx, vertices); + return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } };