diff --git a/data/uvs.jpg b/data/uvs.jpg new file mode 100644 index 0000000..7b1aef7 Binary files /dev/null and b/data/uvs.jpg differ diff --git a/engine/app.cpp b/engine/app.cpp index 6b6edf3..2e4df3a 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -6,7 +6,7 @@ App App::I; // singleton void App::create() { width = 800; - height = 600; + height = 800; } void App::init() @@ -27,7 +27,7 @@ void App::init() "in vec2 uv;" "out vec4 frag;" "void main(){" - " frag = texture(tex, uv, 0.0);" + " frag = texture(tex, uv);" "}"; static const char* shader_uv_f = "#version 150\n" @@ -55,12 +55,11 @@ void App::init() shader_color.create(shader_color_v, shader_color_f); shader_uv.create(shader_v, shader_uv_f); plane.create<5>(50, 50); - longPlane.create<1>(50, 25); - circle.create<6>(25, 12); - circle1.create<4>(25, 12); + circle.create<6>(25); circle2.create<15>(25, 12); - rounded.create<5>(50, 50, 10); - if (!tex.load("data/image.png")) + rounded.create<3>(50, 50, 10); + slice.create(50, 50, 10); + if (!tex.load("data/uvs.jpg")) printf("error loading image\n"); glViewport(0, 0, width, height); @@ -97,49 +96,46 @@ void App::update(float dt) glm::mat4 proj = glm::ortho(0, width, height, 0, -1, 1); - Shape* shapes[] = { &circle, &circle1, &circle2, &plane, &longPlane }; + Shape* shapes[] = { &circle, &circle2, &plane, &rounded, &slice }; //glClearColor(red, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); auto s = glm::scale(glm::vec3(2)); -// for (int i = 0; i < 5; i++) -// { -// shader.use(); -// -// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -// glActiveTexture(GL_TEXTURE0); -// tex.bind(); -// shader.u_int("tex", 0); -// shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 1, 75 + 120 * i, 0.f}) * s); -// shapes[i]->draw_fill(); -// tex.unbind(); -// -// shader_color.use(); -// shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 2, 75 + 120 * i, 0.f}) * s); -// shader_color.u_vec4("col", {1, 1, 1, 1}); -// shapes[i]->draw_stroke(); -// -// shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 0, 75 + 120 * i, 0.f}) * s); -// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -// shapes[i]->draw_fill(); -// -// shader_uv.use(); -// shader_uv.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 3, 75 + 120 * i, 0.f}) * s); -// shader_uv.u_int("tex", 0); -// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); -// shapes[i]->draw_fill(); -// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -// shader_uv.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 4, 75 + 120 * i, 0.f}) * s); -// shapes[i]->draw_fill(); -// tex.unbind(); -// } - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - shader_uv.use(); - shader_uv.u_mat4("mvp", proj * glm::translate(glm::vec3{width/2, height/2, 0.f}) * glm::scale(glm::vec3(10))); - shader_uv.u_int("tex", 0); - glActiveTexture(GL_TEXTURE0); - tex.bind(); - rounded.draw_fill(); - tex.unbind(); + for (int i = 0; i < 5; i++) + { + shader.use(); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glActiveTexture(GL_TEXTURE0); + tex.bind(); + shader.u_int("tex", 0); + shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 1, 75 + 120 * i, 0.f}) * s); + shapes[i]->draw_fill(); + tex.unbind(); + + shader_color.use(); + shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 2, 75 + 120 * i, 0.f}) * s); + shader_color.u_vec4("col", {1, 1, 1, 1}); + shapes[i]->draw_stroke(); + + shader.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 0, 75 + 120 * i, 0.f}) * s); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + shapes[i]->draw_fill(); + + shader_uv.use(); + shader_uv.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 3, 75 + 120 * i, 0.f}) * s); + shader_uv.u_int("tex", 0); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + shapes[i]->draw_fill(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + shader_uv.u_mat4("mvp", proj * glm::translate(glm::vec3{75 + 120 * 4, 75 + 120 * i, 0.f}) * s); + shapes[i]->draw_fill(); + tex.unbind(); + } + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +// shader_color.use(); +// shader_color.u_mat4("mvp", proj * glm::translate(glm::vec3{width/2, height/2, 0.f}) * glm::scale(glm::vec3(8))); +// shader_color.u_vec4("col", {1, 1, 1, 1}); +// slice.draw_fill(); } diff --git a/engine/app.hpp b/engine/app.hpp index 940bf26..8bbad96 100644 --- a/engine/app.hpp +++ b/engine/app.hpp @@ -10,9 +10,9 @@ class App Shader shader_color; Shader shader_uv; Plane plane; - Plane longPlane; - Circle circle, circle1, circle2; + Circle circle, circle2; Rounded rounded; + Slice9 slice; Texture2D tex; public: static App I; diff --git a/engine/image.cpp b/engine/image.cpp index 9cf3234..6189db1 100644 --- a/engine/image.cpp +++ b/engine/image.cpp @@ -7,7 +7,8 @@ bool Image::load(std::string filename) { stbi_set_flip_vertically_on_load(true); - uint8_t* buffer = stbi_load(filename.c_str(), &width, &height, &comp, 0); + uint8_t* buffer = stbi_load(filename.c_str(), &width, &height, nullptr, 4); + comp = 4; m_data = std::unique_ptr(buffer); return true; } diff --git a/engine/main.cpp b/engine/main.cpp index f3dfb6a..cf99d6e 100644 --- a/engine/main.cpp +++ b/engine/main.cpp @@ -22,7 +22,7 @@ NSOpenGLPFADoubleBuffer, NSOpenGLPFADepthSize, 24, // Must specify the 3.2 Core Profile to use OpenGL 3.2 - NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core, + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, // Multisample NSOpenGLPFAMultisample, NSOpenGLPFASamples, 2, @@ -159,7 +159,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask backing:NSBackingStoreBuffered defer:NO]; - [window setTitle:@"hello engine"]; + [window setTitle:@"hello engine - ui shapes"]; [window center]; [window makeKeyAndOrderFront:controller]; [window setContentView:view]; diff --git a/engine/shape.cpp b/engine/shape.cpp index 7a0dec6..07f97f3 100644 --- a/engine/shape.cpp +++ b/engine/shape.cpp @@ -47,8 +47,8 @@ void Plane::create_impl(float w, float h, int div, GLushort *idx, Shape::vertex_ { count[0] = div * div * 6; count[1] = 8; - ioff[0] = (GLvoid*)(count[1] * sizeof(GLushort)); - ioff[1] = (GLvoid*)0; + ioff[0] = (GLvoid*)0; + ioff[1] = (GLvoid*)(count[0] * sizeof(GLushort)); const float dx = w / div; const float dy = h / div; @@ -69,14 +69,6 @@ void Plane::create_impl(float w, float h, int div, GLushort *idx, Shape::vertex_ } // generate indices - *idx++ = 0; // A - *idx++ = (div+1)*(div); // B - *idx++ = (div+1)*(div); // B - *idx++ = (div+1)*(div+1)-1; // C - *idx++ = (div+1)*(div+1)-1; // C - *idx++ = div; // D - *idx++ = div; // D - *idx++ = 0; // A for (int y = 0; y < div; y++) { int i = y * (div+1); @@ -91,6 +83,15 @@ void Plane::create_impl(float w, float h, int div, GLushort *idx, Shape::vertex_ i++; } } + // outline indices + *idx++ = 0; // A + *idx++ = (div+1)*(div); // B + *idx++ = (div+1)*(div); // B + *idx++ = (div+1)*(div+1)-1; // C + *idx++ = (div+1)*(div+1)-1; // C + *idx++ = div; // D + *idx++ = div; // D + *idx++ = 0; // A } void Circle::create_impl(float radius, int div, GLushort* idx, Shape::vertex_t* vertices) @@ -101,7 +102,7 @@ void Circle::create_impl(float radius, int div, GLushort* idx, Shape::vertex_t* ioff[1] = (GLvoid*)(count[0] * sizeof(GLushort)); auto pidx = idx; - auto pidx2 = idx + div * 3; + auto pidx2 = idx + count[0]; for (int i = 0; i < div; i++) { vertex_t v; @@ -130,7 +131,7 @@ void Circle::create_impl(float radius_out, float radius_in, int div, GLushort* i ioff[1] = (GLvoid*)(count[0] * sizeof(GLushort)); auto pidx = idx; - auto pidx2 = idx + div * 6; + auto pidx2 = idx + count[0]; for (int i = 0; i < div; i++) { float theta = (float)i / div * M_PI * 2.f; @@ -163,6 +164,8 @@ void Rounded::create_impl(float w, float h, float r, int div, GLushort* idx, GLu ioff[0] = (GLvoid*)0; ioff[1] = (GLvoid*)(count[0] * sizeof(GLushort)); + auto idx2 = idx + count[0]; + float X[] = { -w/2, -w/2+r, w/2-r, w/2 }; float Y[] = { -h/2, -h/2+r, h/2-r, h/2 }; @@ -200,27 +203,79 @@ void Rounded::create_impl(float w, float h, float r, int div, GLushort* idx, GLu Q(7,10,11, 8); auto corner = [&](int c, int a, int b, int n) { + auto v = vertices-12; idx_tmp[0] = a; idx_tmp[div] = b; - auto v = vertices-12; for (int i = 1; i < div; i++) { float t = (float)(i) / div; - auto p = glm::normalize(glm::mix(v[a].pos.xyz(), v[b].pos.xyz(), t)); + auto p = glm::normalize(glm::mix(v[a].pos.xyz()-v[c].pos.xyz(), v[b].pos.xyz()-v[c].pos.xyz(), t)); v[n].pos = glm::vec4(p * r + v[c].pos.xyz(), 1); - v[n].uvs = glm::normalize(glm::mix(v[a].uvs, v[b].uvs, t)) * glm::vec2(r/w, r/h) + v[c].uvs; + v[n].uvs = glm::normalize(glm::mix(v[a].uvs-v[c].uvs, v[b].uvs-v[c].uvs, t)) * glm::vec2(r/w, r/h) + v[c].uvs; idx_tmp[i] = n; n++; } for (int i = 0; i < div; i++) { *idx++ = c; - *idx++ = idx_tmp[i]; - *idx++ = idx_tmp[i+1]; + *idx++ = *idx2++ = idx_tmp[i]; + *idx++ = *idx2++ = idx_tmp[i+1]; } }; corner(3, 0, 2, 12 + (div-1)*0); corner(7, 6,10, 12 + (div-1)*1); corner(8,11, 9, 12 + (div-1)*2); corner(4, 5, 1, 12 + (div-1)*3); + + *idx2++ = 0; + *idx2++ = 1; + *idx2++ = 5; + *idx2++ = 9; + *idx2++ = 11; + *idx2++ = 10; + *idx2++ = 6; + *idx2++ = 2; +} + +void Slice9::create_impl(float w, float h, float r, GLushort *idx, Shape::vertex_t *vertices) +{ + count[0] = 3 * 3 * 6; + count[1] = 4 * 2; + ioff[0] = (GLvoid*)0; + ioff[1] = (GLvoid*)(count[0] * sizeof(GLushort)); + + float X[] = { -w/2, -w/2+r, w/2-r, w/2 }; + float Y[] = { -h/2, -h/2+r, h/2-r, h/2 }; + + auto V = [&](int x, int y) -> Shape::vertex_t { + return { glm::vec4(X[x], Y[y], 0, 1), glm::vec2(X[x]/w, Y[y]/h) + 0.5f }; + }; + + for (int y = 0; y < 4; y++) + for (int x = 0; x < 4; x++) + *vertices++ = V(x,y); + + for (int y = 0; y < 3; y++) + { + int i = y * (3+1); + for (int x = 0; x < 3; x++) + { + *idx++ = i; + *idx++ = i + 3 + 1; + *idx++ = i + 3 + 2; + *idx++ = i; + *idx++ = i + 3 + 2; + *idx++ = i + 1; + i++; + } + } + // outline indices + *idx++ = 0; // A + *idx++ = 3; // B + *idx++ = 3; // B + *idx++ = 15; // C + *idx++ = 15; // C + *idx++ = 12; // D + *idx++ = 12; // D + *idx++ = 0; // A } diff --git a/engine/shape.hpp b/engine/shape.hpp index 45a8281..baf3c8d 100644 --- a/engine/shape.hpp +++ b/engine/shape.hpp @@ -58,10 +58,23 @@ public: template bool create(float w, float h, float r) { - static GLushort idx[(10 + div * 4) * 3]; + static GLushort idx[(10 + div * 4) * 3 + (4 + div * 4) * 2]; static GLushort idx_tmp[div+1]; static vertex_t vertices[12 + (div-1) * 4]; create_impl(w, h, r, div, idx, idx_tmp, vertices); return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); } }; + +class Slice9 : public Shape +{ + void create_impl(float w, float h, float r, GLushort* idx, vertex_t* vertices); +public: + bool create(float w, float h, float r) + { + static GLushort idx[3 * 3 * 6 + 4 * 2]; + static vertex_t vertices[4 * 4]; + create_impl(w, h, r, idx, vertices); + return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); + } +};