From 1ee97c51548ac48481d4aa7a5668a1552f110d4b Mon Sep 17 00:00:00 2001 From: allem Date: Thu, 20 Dec 2018 11:26:18 -0500 Subject: [PATCH] working intersection - rotating simplex --- framework/include/util.h | 4 ++ simplex/shaders/main.frag | 6 ++- simplex/shaders/main.vert | 15 ++---- simplex/shaders/sect.geom | 56 +++++++++++++++++++++ simplex/shaders/wire.geom | 37 ++++++++++++++ simplex/src/main.cpp | 100 +++++++++++++++++++++----------------- 6 files changed, 161 insertions(+), 57 deletions(-) create mode 100644 simplex/shaders/sect.geom create mode 100644 simplex/shaders/wire.geom diff --git a/framework/include/util.h b/framework/include/util.h index e74457d..6b3b90d 100644 --- a/framework/include/util.h +++ b/framework/include/util.h @@ -73,6 +73,8 @@ namespace util { return buildShader(kind, "VERTEX", paths); case GL_FRAGMENT_SHADER: return buildShader(kind, "FRAGMENT", paths); + case GL_GEOMETRY_SHADER: + return buildShader(kind, "GEOMETRY", paths); default: return buildShader(kind, "?", paths); } @@ -88,6 +90,8 @@ namespace util { return buildShader(GL_VERTEX_SHADER, paths); } else if (ext == ".frag") { return buildShader(GL_FRAGMENT_SHADER, paths); + } else if (ext == ".geom") { + return buildShader(GL_GEOMETRY_SHADER, paths); } else { fprintf(stderr, "Cannot parse path %s\n", path.c_str()); return 0; diff --git a/simplex/shaders/main.frag b/simplex/shaders/main.frag index 0a05d8b..a3f72e7 100644 --- a/simplex/shaders/main.frag +++ b/simplex/shaders/main.frag @@ -11,7 +11,9 @@ vec3 hsv2rgb(vec3 c) { } void main() { - vec3 hsv = vec3(pos.w/3 + .6, 1, 1); + float h = pos.w / 3 + .6; + float s = 1; + float v = smoothstep(1, -1, pos.z); - fcolor = vec4(hsv2rgb(hsv), 1); + fcolor = vec4(hsv2rgb(vec3(h, s, v)), 1); } \ No newline at end of file diff --git a/simplex/shaders/main.vert b/simplex/shaders/main.vert index 3d10154..73c062b 100644 --- a/simplex/shaders/main.vert +++ b/simplex/shaders/main.vert @@ -1,16 +1,11 @@ #version 440 core -layout(location=0) in vec4 pos4; +layout(location=0) in ivec4 vInds; -layout(std140, binding=1) uniform Matrices { - mat4 model; - mat4 view; - mat4 proj; -}; - -out vec4 pos; +out ivec4 inds; void main() { - pos = model * pos4; - gl_Position = proj * view * vec4(pos.xyz, -pos.w + 2); + inds = vInds; + + gl_Position = vec4(0, 0, 0, 1); } diff --git a/simplex/shaders/sect.geom b/simplex/shaders/sect.geom new file mode 100644 index 0000000..1ae0eb5 --- /dev/null +++ b/simplex/shaders/sect.geom @@ -0,0 +1,56 @@ +#version 440 core + +layout(points) in; +layout(triangle_strip, max_vertices=48) out; + +layout(std430, binding=1) buffer Positions { + vec4 verts[]; +}; + +layout(std140, binding=1) uniform Matrices { + mat4 model; + mat4 view; + mat4 proj; +}; + +in ivec4 inds[]; + +out vec4 pos; + +void emit(vec4 v) { + pos = v; + gl_Position = proj * view * vec4(v.xyz, -v.w + 2); + EmitVertex(); +} + +void main() { + vec4 pos4[4]; + for(int i = 0; i < 4; ++i) pos4[i] = model * verts[inds[0][i]]; + + int lo[4], L = 0; + int hi[4], H = 0; + + for(int i = 0; i < 4; ++i) { + if (pos4[i].w < 0) { + lo[L++] = i; + } else { + hi[H++] = i; + } + } + + vec4 sect[4]; int S = 0; + for (int l = 0; l < L; ++l) { + for (int h = 0; h < H; ++h) { + vec4 a = pos4[lo[l]]; + vec4 b = pos4[hi[h]]; + + sect[S++] = (0 - a.w) / (b.w - a.w) * (b-a) + a; + } + } + + for(int s = 0; s < S; ++s) { + emit(sect[s]); + } + + EndPrimitive(); +} diff --git a/simplex/shaders/wire.geom b/simplex/shaders/wire.geom new file mode 100644 index 0000000..9c2d3c8 --- /dev/null +++ b/simplex/shaders/wire.geom @@ -0,0 +1,37 @@ +#version 440 core + +layout(points) in; +layout(line_strip, max_vertices=48) out; + +layout(std430, binding=1) buffer Positions { + vec4 verts[]; +}; + +layout(std140, binding=1) uniform Matrices { + mat4 model; + mat4 view; + mat4 proj; +}; + +in ivec4 inds[]; + +out vec4 pos; + +void emit(vec4 v) { + pos = v; + gl_Position = proj * view * vec4(v.xyz, -v.w + 2); + EmitVertex(); +} + +void main() { + vec4 pos4[4]; + for(int i = 0; i < 4; ++i) pos4[i] = model * verts[inds[0][i]]; + + for(int i = 0; i < 4; ++i) { + for(int j = i + 1; j < 4; ++j) { + emit(pos4[i]); + emit(pos4[j]); + EndPrimitive(); + } + } +} diff --git a/simplex/src/main.cpp b/simplex/src/main.cpp index 8cfba21..34eac17 100644 --- a/simplex/src/main.cpp +++ b/simplex/src/main.cpp @@ -28,37 +28,34 @@ class GLApp : public App { Matrices matrices{}; GLuint cell_array{}; - GLuint cell_vert_buf{}, cell_elem_arr_buf{}; - GLuint wire_prog{}; - GLuint matrix_buffer{}; + GLuint cell_vert_buf{}, cell_elem_arr_buf{}, matrix_buffer{}; + GLuint matrix_binding_point = 1; + GLuint verts_binding_point = 1; + + GLuint wire_prog{}, sect_prog{}; void init() override { cell_verts = { - glm::vec4(-0.5, -0.5, -0.5, -0.5), - glm::vec4(-0.5, -0.5, -0.5, +0.5), - glm::vec4(-0.5, -0.5, +0.5, -0.5), - glm::vec4(-0.5, -0.5, +0.5, +0.5), - glm::vec4(-0.5, +0.5, -0.5, -0.5), - glm::vec4(-0.5, +0.5, -0.5, +0.5), - glm::vec4(-0.5, +0.5, +0.5, -0.5), - glm::vec4(-0.5, +0.5, +0.5, +0.5), - glm::vec4(+0.5, -0.5, -0.5, -0.5), - glm::vec4(+0.5, -0.5, -0.5, +0.5), - glm::vec4(+0.5, -0.5, +0.5, -0.5), - glm::vec4(+0.5, -0.5, +0.5, +0.5), - glm::vec4(+0.5, +0.5, -0.5, -0.5), - glm::vec4(+0.5, +0.5, -0.5, +0.5), - glm::vec4(+0.5, +0.5, +0.5, -0.5), - glm::vec4(+0.5, +0.5, +0.5, +0.5), + glm::vec4(+1, +1, +1, -.447) / 2.f, + glm::vec4(+1, -1, -1, -.447) / 2.f, + glm::vec4(-1, +1, -1, -.447) / 2.f, + glm::vec4(-1, -1, +1, -.447) / 2.f, + glm::vec4(+0, +0, +0, 1.788) / 2.f, }; cell_elems = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15, - 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, - 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15, +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, +// 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15, +// 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, +// 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15, + + 0, 1, 2, 3, + 0, 1, 2, 4, + 0, 1, 3, 4, + 0, 2, 3, 4, + 1, 2, 3, 4, }; matrices = { @@ -68,23 +65,29 @@ class GLApp : public App { }; //region Shaders - GLuint vs = util::buildShader(GL_VERTEX_SHADER, {"shaders/main.vert"}); - GLuint fs = util::buildShader(GL_FRAGMENT_SHADER, {"shaders/main.frag"}); - wire_prog = util::buildProgram(false, {vs, fs}); - glDeleteShader(vs); - glDeleteShader(fs); + GLuint main_vs = util::buildShader(GL_VERTEX_SHADER, {"shaders/main.vert"}); + GLuint main_fs = util::buildShader(GL_FRAGMENT_SHADER, {"shaders/main.frag"}); + GLuint sect_gs = util::buildShader(GL_GEOMETRY_SHADER, {"shaders/sect.geom"}); + GLuint wire_gs = util::buildShader(GL_GEOMETRY_SHADER, {"shaders/wire.geom"}); + wire_prog = util::buildProgram(false, {main_vs, main_fs, wire_gs}); + sect_prog = util::buildProgram(false, {main_vs, main_fs, sect_gs}); + glDeleteShader(main_vs); + glDeleteShader(main_fs); + glDeleteShader(sect_gs); + glDeleteShader(wire_gs); //endregion //region Buffers glGenBuffers(1, &cell_vert_buf); - glBindBuffer(GL_ARRAY_BUFFER, cell_vert_buf); - util::bufferData(GL_ARRAY_BUFFER, cell_verts, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, verts_binding_point, cell_vert_buf); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, cell_vert_buf); + util::bufferData(GL_SHADER_STORAGE_BUFFER, cell_verts, GL_STATIC_DRAW); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glGenBuffers(1, &cell_elem_arr_buf); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cell_elem_arr_buf); - util::bufferData(GL_ELEMENT_ARRAY_BUFFER, cell_elems, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, cell_elem_arr_buf); + util::bufferData(GL_ARRAY_BUFFER, cell_elems, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &matrix_buffer); glBindBufferBase(GL_UNIFORM_BUFFER, matrix_binding_point, matrix_buffer); @@ -97,13 +100,19 @@ class GLApp : public App { glGenVertexArrays(1, &cell_array); glBindVertexArray(cell_array); - glBindBuffer(GL_ARRAY_BUFFER, cell_vert_buf); - auto pos4_loc = (GLuint) glGetAttribLocation(wire_prog, "pos4"); - glEnableVertexAttribArray(pos4_loc); - glVertexAttribPointer(pos4_loc, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (void *) nullptr); + glBindBuffer(GL_ARRAY_BUFFER, cell_elem_arr_buf); + auto ind_loc = (GLuint) glGetAttribLocation(wire_prog, "vInds"); + glEnableVertexAttribArray(ind_loc); + glVertexAttribIPointer(ind_loc, 4, GL_UNSIGNED_INT, sizeof(int) * 4, (void *) nullptr); glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cell_elem_arr_buf); +// glBindBuffer(GL_ARRAY_BUFFER, cell_vert_buf); +// auto pos4_loc = (GLuint) glGetAttribLocation(wire_prog, "pos4"); +// glEnableVertexAttribArray(pos4_loc); +// glVertexAttribPointer(pos4_loc, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (void *) nullptr); +// glBindBuffer(GL_ARRAY_BUFFER, 0); + +// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cell_elem_arr_buf); glBindVertexArray(0); //endregion }; @@ -114,8 +123,8 @@ class GLApp : public App { float ratio = (float) width / height; matrices.model = - rotor(glm::vec4(1,0,0,0), glm::vec4(0,0,1,0), getTime() / 4) * - rotor(glm::vec4(0,1,0,0), glm::vec4(0,0,0,1), getTime() / 4); + rotor(glm::vec4(1, 0, 0, 0), glm::vec4(0, 0, 1, 0), getTime() / 4) * + rotor(glm::vec4(0, 1, 0, 0), glm::vec4(0, 0, 0, 1), getTime() / 4); matrices.view = glm::lookAt(glm::vec3(0, 0, -2), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); matrices.proj = glm::perspective(1.f, ratio, 0.1f, 10.0f); @@ -135,11 +144,12 @@ class GLApp : public App { glPointSize(10); glLineWidth(2); - glEnable(GL_DEPTH_BUFFER_BIT); - glUseProgram(wire_prog); + glEnable(GL_DEPTH_TEST); glBindVertexArray(cell_array); - glDrawElements(GL_LINES, (GLsizei) cell_elems.size(), GL_UNSIGNED_INT, nullptr); -// glDrawArrays(GL_POINTS, 0, (GLsizei) cell_verts.size()); + glUseProgram(sect_prog); + glDrawArrays(GL_POINTS, 0, (GLsizei) cell_elems.size() / 4); + glUseProgram(wire_prog); + glDrawArrays(GL_POINTS, 0, (GLsizei) cell_elems.size() / 4); glBindVertexArray(0); glFinish();