display slice and wireframe simultaneously

This commit is contained in:
2020-01-30 18:40:15 -05:00
parent 109ac9da10
commit e953f0e13d
12 changed files with 203 additions and 105 deletions

View File

@@ -0,0 +1,38 @@
#version 430
#define SUBS 20
layout(lines) in;
layout(line_strip, max_vertices = SUBS) out;
layout(std430, binding=1) buffer Positions {
vec4 verts[];
};
layout(std140, binding=1) uniform Matrices {
mat4 proj;
mat4 view;
};
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
};
in vec4 gpos[];
out vec4 vpos;
vec4 stereo(vec4 v) {
return vec4(v.xyz, 1);
}
void main() {
for (int i = 0; i < SUBS; i++) {
vpos = mix(gpos[0], gpos[1], i * 1.0f / (SUBS - 1));
vpos = normalize(vpos);
gl_Position = proj * stereo(vpos);
EmitVertex();
}
EndPrimitive();
}

View File

@@ -5,9 +5,22 @@
layout(lines) in; layout(lines) in;
layout(line_strip, max_vertices = SUBS) out; layout(line_strip, max_vertices = SUBS) out;
layout(location=0) uniform mat4 proj; layout(std430, binding=1) buffer Positions {
vec4 verts[];
};
layout(std140, binding=1) uniform Matrices {
mat4 proj;
mat4 view;
};
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
};
in vec4 gpos[]; in vec4 gpos[];
out vec4 vpos; out vec4 vpos;
vec4 stereo(vec4 v) { vec4 stereo(vec4 v) {

View File

@@ -0,0 +1,24 @@
#version 430
layout(std430, binding=1) buffer Positions {
vec4 verts[];
};
layout(std140, binding=1) uniform Matrices {
mat4 proj;
mat4 view;
};
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
};
out vec4 vpos;
void main() {
vec4 pos = verts[gl_VertexID];
vpos = view * pos;
gl_Position = proj * vec4(vpos.xyz / (1), 1);
gl_PointSize = 5;
}

View File

@@ -0,0 +1,24 @@
#version 430
layout(std430, binding=1) buffer Positions {
vec4 verts[];
};
layout(std140, binding=1) uniform Matrices {
mat4 proj;
mat4 view;
};
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
};
out vec4 vpos;
void main() {
vec4 pos = verts[gl_VertexID];
vpos = view * pos;
gl_Position = proj * vec4(vpos.xyz / (1 - vpos.w), 1);
gl_PointSize = 5;
}

View File

@@ -1,17 +0,0 @@
#version 430
out gl_PerVertex {
vec4 gl_Position;
};
layout(location=0) uniform mat4 proj;
layout(location=1) uniform mat4 view;
layout(location=0) in vec4 pos;
out vec4 vpos;
void main() {
vpos = view * pos;
gl_Position = proj * vec4(vpos.xyz / (1), 1);
}

View File

@@ -1,14 +0,0 @@
#version 430
layout(location=0) uniform mat4 proj;
layout(location=1) uniform mat4 view;
layout(location=0) in vec4 pos;
out vec4 vpos;
void main() {
vpos = view * pos;
gl_Position = proj * vec4(vpos.xyz / (1), 1);
gl_PointSize = 5;
}

View File

@@ -1,15 +0,0 @@
#version 430
layout(location=0) uniform mat4 proj;
layout(location=1) uniform mat4 view;
layout(location=0) in vec4 pos;
out vec4 vpos;
void main() {
int i = gl_VertexID;
vpos = view * pos;
gl_Position = proj * vec4(vpos.xyz / (1 - vpos.w), 1);
gl_PointSize = 5 * smoothstep(-2, 2, gl_Position.z);
}

View File

@@ -1,11 +0,0 @@
#version 430
in vec4 vpos;
out vec4 color;
void main() {
float d = smoothstep(-2, 2, vpos.z);
vec3 off = 1.04 * vec3(0, 2, 4) + 2 * vec3(vpos.w);
color = vec4(d * cos(off), 1);
}

View File

@@ -20,8 +20,41 @@ __attribute__((unused)) __declspec(dllexport) int NvOptimusEnablement = 0x000000
struct Matrices { struct Matrices {
glm::mat4 proj; glm::mat4 proj;
glm::mat4 view; glm::mat4 view;
Matrices(const glm::mat4 &proj, const glm::mat4 &view)
: proj(proj), view(view) {
}
}; };
template<unsigned N>
struct MeshRef {
GLuint vao;
GLuint ibo;
unsigned primitive_count;
unsigned index_count;
explicit MeshRef(const Mesh<N> &mesh) {
vao = utilCreateVertexArray();
ibo = utilCreateBuffer();
primitive_count = mesh.size();
index_count = primitive_count * N;
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, ibo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Primitive<N>) * primitive_count, &mesh.prims[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(0, N, GL_INT, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
};
float factor(unsigned index, unsigned size) {
auto num = (float) index;
auto den = size > 1 ? (float) size - 1 : 1;
return num / den;
}
Matrices build(GLFWwindow *window, float st) { Matrices build(GLFWwindow *window, float st) {
int width, height; int width, height;
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
@@ -39,7 +72,7 @@ Matrices build(GLFWwindow *window, float st) {
view *= utilRotate(1, 3, st * .25f); view *= utilRotate(1, 3, st * .25f);
view *= utilRotate(2, 3, st * 1.42f); view *= utilRotate(2, 3, st * 1.42f);
return {proj, view}; return Matrices(proj, view);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@@ -76,19 +109,36 @@ int main(int argc, char *argv[]) {
glCullFace(GL_BACK); glCullFace(GL_BACK);
//region shaders //region shaders
GLuint pipe; GLuint slice_pipe;
glCreateProgramPipelines(1, &pipe); glCreateProgramPipelines(1, &slice_pipe);
GLuint vs, gm, fs; GLuint proj_pipe;
glCreateProgramPipelines(1, &proj_pipe);
// GLuint defer, direct_ortho, direct_stereo, slice, curve_stereo, solid;
GLuint defer, direct_ortho, direct_stereo;
GLuint slice, curve_ortho, curve_stereo;
GLuint solid;
try { try {
vs = utilCreateShaderProgramFile(GL_VERTEX_SHADER, {"shaders/4d/4d.vs.glsl"}); defer = utilCreateShaderProgramFile(GL_VERTEX_SHADER, {"shaders/slice/deferred.vs.glsl"});
gm = utilCreateShaderProgramFile(GL_GEOMETRY_SHADER, {"shaders/4d/4d.gm.glsl"}); direct_ortho = utilCreateShaderProgramFile(GL_VERTEX_SHADER, {"shaders/direct-ortho.vs.glsl"});
fs = utilCreateShaderProgramFile(GL_FRAGMENT_SHADER, {"shaders/one-color.fs.glsl"}); direct_stereo = utilCreateShaderProgramFile(GL_VERTEX_SHADER, {"shaders/direct-stereo.vs.glsl"});
slice = utilCreateShaderProgramFile(GL_GEOMETRY_SHADER, {"shaders/slice/slice.gm.glsl"});
curve_stereo = utilCreateShaderProgramFile(GL_GEOMETRY_SHADER, {"shaders/curve-stereo.gm.glsl"});
curve_ortho = utilCreateShaderProgramFile(GL_GEOMETRY_SHADER, {"shaders/curve-ortho.gm.glsl"});
solid = utilCreateShaderProgramFile(GL_FRAGMENT_SHADER, {"shaders/solid.fs.glsl"});
glUseProgramStages(slice_pipe, GL_VERTEX_SHADER_BIT, defer);
glUseProgramStages(slice_pipe, GL_GEOMETRY_SHADER_BIT, slice);
glUseProgramStages(slice_pipe, GL_FRAGMENT_SHADER_BIT, solid);
glUseProgramStages(proj_pipe, GL_VERTEX_SHADER_BIT, direct_stereo);
// glUseProgramStages(proj_pipe, GL_GEOMETRY_SHADER_BIT, curve_stereo);
glUseProgramStages(proj_pipe, GL_FRAGMENT_SHADER_BIT, solid);
glUseProgramStages(pipe, GL_VERTEX_SHADER_BIT, vs);
glUseProgramStages(pipe, GL_GEOMETRY_SHADER_BIT, gm);
glUseProgramStages(pipe, GL_FRAGMENT_SHADER_BIT, fs);
} catch (const gl_error &e) { } catch (const gl_error &e) {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
glfwTerminate(); glfwTerminate();
@@ -109,36 +159,26 @@ int main(int argc, char *argv[]) {
auto g_gens = gens(group); auto g_gens = gens(group);
std::vector<GLuint> vaos; const unsigned WIRES_N = 2;
std::vector<GLuint> ibos; const GLenum WIRE_MODE = GL_LINES;
std::vector<unsigned> counts; std::vector<MeshRef<WIRES_N>> wires;
auto combos = Combos(g_gens, 3); for (const auto &sg_gens : Combos(g_gens, WIRES_N - 1)) {
// std::vector<std::vector<int>> chosen = { const auto s = triangulate<WIRES_N>(group, sg_gens).tile(group, g_gens, sg_gens);
// {1, 2, 3},
// {0, 2, 3},
// };
auto chosen = combos;
for (const auto &sg_gens : chosen) { wires.emplace_back(s);
const auto s = triangulate<4>(group, sg_gens)
.tile(group, g_gens, sg_gens);
GLuint vao = utilCreateVertexArray();
GLuint ibo = utilCreateBuffer();
unsigned count = s.size();
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, ibo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Primitive<4>) * s.size(), &s.prims[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(0, 4, GL_INT, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
vaos.push_back(vao);
ibos.push_back(ibo);
counts.push_back(count);
} }
const unsigned SLICES_N = 4;
const GLenum SLICES_MODE = GL_POINTS;
std::vector<MeshRef<SLICES_N>> slices;
for (const auto &sg_gens : Combos(g_gens, SLICES_N - 1)) {
const auto s = triangulate<SLICES_N>(group, sg_gens).tile(group, g_gens, sg_gens);
slices.emplace_back(s);
}
//endregion //endregion
GLuint vbo; GLuint vbo;
@@ -168,17 +208,33 @@ int main(int argc, char *argv[]) {
glBufferData(GL_UNIFORM_BUFFER, sizeof(mats), &mats, GL_STATIC_DRAW); glBufferData(GL_UNIFORM_BUFFER, sizeof(mats), &mats, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBuffer(GL_UNIFORM_BUFFER, 0);
for (int i = 0; i < vaos.size(); ++i) { const auto wires_dark = glm::vec3(.3, .3,.3);
auto c = glm::mix( const auto wires_light = wires_dark;
glm::vec3(.3, .2, .5), glBindProgramPipeline(proj_pipe);
glm::vec3(.9, .9, .95), for (int i = 0; i < wires.size(); i++) {
(float) (i) / (vaos.size() - 1.f) const auto &ref = wires[i];
);
glBindProgramPipeline(pipe); const float f = factor(i, slices.size());
glBindVertexArray(vaos[i]); glm::vec3 c = glm::mix(wires_dark, wires_light, f);
glProgramUniform3f(fs, 2, c.r, c.g, c.b); glProgramUniform3f(solid, 2, c.r, c.g, c.b);
glDrawArrays(GL_POINTS, 0, counts[i]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ref.ibo);
glDrawElements(WIRE_MODE, ref.index_count, GL_UNSIGNED_INT, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
const auto slice_dark = glm::vec3(.5, .3, .7);
const auto slice_light = glm::vec3(.9, .9, .95);
glBindProgramPipeline(slice_pipe);
for (int i = 0; i < slices.size(); i++) {
const auto &ref = slices[i];
const float f = factor(i, slices.size());
glm::vec3 c = glm::mix(slice_dark, slice_light, f);
glProgramUniform3f(solid, 2, c.r, c.g, c.b);
glBindVertexArray(ref.vao);
glDrawArrays(SLICES_MODE, 0, ref.primitive_count);
} }
glBindProgramPipeline(0); glBindProgramPipeline(0);