Commit 8a65f39d by Philipp Adolf

Handle sharp edges in vertex buffer

parent d9b12745
......@@ -22,30 +22,61 @@ layout(std430, binding=2) readonly buffer VertexOffsets {
unsigned int offsets[];
};
layout(std430, binding=3) writeonly buffer Output {
layout(std430, binding=3) readonly buffer VertexSharpness {
unsigned int sharpness[];
};
layout(std430, binding=4) writeonly buffer Output {
Vertex new_vertices[];
};
layout(std430, binding=4) readonly buffer OutputOffset {
layout(std430, binding=5) readonly buffer OutputOffset {
unsigned int output_offset;
};
void main(){
unsigned int size = offsets[gl_GlobalInvocationID.x + 1] - offsets[gl_GlobalInvocationID.x];
unsigned int offset = offsets[gl_GlobalInvocationID.x];
unsigned int size = offsets[gl_GlobalInvocationID.x + 1] - offset;
new_vertices[output_offset + gl_GlobalInvocationID.x].uv = vec2(0.0f, 0.0f);
new_vertices[output_offset + gl_GlobalInvocationID.x].norm = vec3(0.0f, 0.0f, 0.0f);
// FIXME: size or size - 1?
float t = 3.0f/8.0f + 2.0f/8.0f * cos(2.0f * M_PI / (float(size) - 1.0f));
float alpha = 5.0f/8.0f - t * t;
unsigned int sharp = 0;
unsigned int sharp_a = 0;
unsigned int sharp_b = 0;
for (unsigned int i = 1; i < size; i++) {
if (sharpness[offset + i] > 0) {
sharp++;
if (sharp == 1) {
sharp_a = i;
} else if (sharp == 2) {
sharp_b = i;
}
}
}
vec3 pos = vec3(0.0f, 0.0f, 0.0f);
vec3 norm = vec3(0.0f, 0.0f, 0.0f);
switch (sharp) {
case 0:
case 1:
for (unsigned int i = 1; i < size; i++) {
pos += vertices[indices[offsets[gl_GlobalInvocationID.x] + i]].pos;
norm += vertices[indices[offsets[gl_GlobalInvocationID.x] + i]].norm;
pos += vertices[indices[offset + i]].pos;
}
pos = (1.0f - alpha) * vertices[indices[offset]].pos + alpha / (float(size) - 1.0f) * pos;
break;
case 2:
pos = (6.0f * vertices[indices[offset]].pos + vertices[indices[offset + sharp_a]].pos + vertices[indices[offset + sharp_b]].pos) / 8.0f;
break;
default:
pos = vertices[indices[offset]].pos;
}
new_vertices[output_offset + gl_GlobalInvocationID.x].pos = (1.0f - alpha) * vertices[indices[offsets[gl_GlobalInvocationID.x]]].pos + alpha / (float(size) - 1.0f) * pos;
new_vertices[output_offset + gl_GlobalInvocationID.x].norm = normalize((1.0f - alpha) * vertices[indices[offsets[gl_GlobalInvocationID.x]]].norm + alpha / (float(size) - 1.0f) * norm);
new_vertices[output_offset + gl_GlobalInvocationID.x].pos = pos;
}
......@@ -182,6 +182,10 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) {
qCDebug(log_timing) << "precomputeVertexTable:" << formatTimeMeasurement(subTimer.elapsed());
subTimer.restart();
precomputeSharpnessEdges(input, tables);
qCDebug(log_timing) << "precomputeSharpnessEdges:" << formatTimeMeasurement(subTimer.elapsed());
subTimer.restart();
updateIndexBuffer(tables.index_buffer, modified_vertices);
updateIndexBuffer(tables.extra_triangles, modified_vertices);
qCDebug(log_timing) << "updateIndexBuffer:" << formatTimeMeasurement(subTimer.elapsed());
......@@ -738,6 +742,27 @@ void Subdivision::updateSharpEdges(const QMap<Edge,unsigned int> &sharp_edges_ol
}
}
void Subdivision::precomputeSharpnessEdges(const Input &input, Tables &tables) {
for (int i = 0; i < tables.vertex_offsets.length() - 1; i++) {
int size = tables.vertex_offsets[i+1] - tables.vertex_offsets[i];
GLuint center = tables.vertex_indices[tables.vertex_offsets[i]];
tables.vertex_sharpness.push_back(0); // vertex to itself isn't used
for (int j = 1; j < size; j++) {
GLuint neighbor = tables.vertex_indices[tables.vertex_offsets[i] + j];
bool sharp = false;
Edge e = { center, neighbor };
if (input.sharp_edges.value(e, 0) > 0) {
sharp = true;
}
e = { neighbor, center };
if (input.sharp_edges.value(e, 0) > 0) {
sharp = true;
}
tables.vertex_sharpness.push_back((GLuint) (sharp ? 1 : 0));
}
}
}
void Subdivision::splitRegular(Mesh *mesh) {
QTime totalTimer;
totalTimer.start();
......@@ -965,6 +990,12 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) {
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, vertex_offsets_handle);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, tables.vertex_offsets.size() * sizeof(GLuint), tables.vertex_offsets.data(), GL_DYNAMIC_DRAW);
// Create an input buffer for the vertex sharpnesses
GLuint vertex_sharpness_handle;
f->glGenBuffers(1, &vertex_sharpness_handle);
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, vertex_sharpness_handle);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, tables.vertex_sharpness.size() * sizeof(GLuint), tables.vertex_sharpness.data(), GL_DYNAMIC_DRAW);
// Create an input buffer for the edge indices
GLuint edge_indices_handle;
f->glGenBuffers(1, &edge_indices_handle);
......@@ -1030,7 +1061,7 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) {
offset_buffer = (GLuint *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
*offset_buffer = input.vertex_buffer.size() + tables.edge_indices.size() / 4;
f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
runVertexShader(tables.vertex_offsets.size() - 1, input.vb_handle, vertex_indices_handle, vertex_offsets_handle, output_handle, offset_handle);
runVertexShader(tables.vertex_offsets.size() - 1, input.vb_handle, vertex_indices_handle, vertex_offsets_handle, vertex_sharpness_handle, output_handle, offset_handle);
int vertexTime = timer.elapsed();
timer.restart();
......@@ -1074,14 +1105,15 @@ void Subdivision::runCopyShader(GLuint size, GLuint vb_in, GLuint vb_out) {
copyShader->release();
}
void Subdivision::runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle, GLuint offset_handle) {
void Subdivision::runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint vertex_sharpness_handle, GLuint output_handle, GLuint offset_handle) {
vertexShader->bind();
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vb_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, vertex_indices_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, vertex_offsets_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, output_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, offset_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, vertex_sharpness_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, output_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, offset_handle);
// Run the shader
f->glDispatchCompute(size, 1, 1);
......@@ -1095,6 +1127,7 @@ void Subdivision::runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_i
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, 0);
vertexShader->release();
}
......
......@@ -34,6 +34,7 @@ private:
QMap<Edge,unsigned int> sharp_edges;
QVector<GLuint> vertex_indices;
QVector<GLuint> vertex_offsets;
QVector<GLuint> vertex_sharpness;
QVector<GLuint> index_buffer;
QVector<GLuint> patch_index_regular;
QVector<GLuint> extra_triangles;
......@@ -79,10 +80,11 @@ private:
QMap<Edge,unsigned int> &sharp_edges_new,
const QMap<unsigned int, unsigned int>& old_vertex_to_new_vertex,
const QMap<Edge,unsigned int> &old_edge_to_new_vertex);
void precomputeSharpnessEdges(const Input &input, Tables &tables);
void findRegular(QVector<Triangle> triangles, QMap<Triangle, Triangle::Neighbors> neighbors, QVector<Triangle> &regular, QVector<Triangle> &irregular);
Result runShader(Input input, Tables &tables);
void runCopyShader(GLuint size, GLuint vb_in, GLuint vb_out);
void runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle, GLuint offset_handle);
void runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint vertex_sharpness_handle, GLuint output_handle, GLuint offset_handle);
void runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint edge_sharpness_handle, GLuint output_handle, GLuint offset_handle);
void updateIrregularForDraw(const QVector<Triangle> &triangles, QMap<Triangle, Triangle::Neighbors> &neighbors, Result &result);
bool containsVertex(QVector<Vertex> &vertices, Vertex vertex);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment