Commit dda3ba31 by Philipp Adolf

Merge branch 'append-vertices' into patchRender

Fixes #8
parents b8573a72 72c43a22
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
<file>subdivide.tcs</file> <file>subdivide.tcs</file>
<file>subdivide.tes</file> <file>subdivide.tes</file>
<file>subdivide.vert</file> <file>subdivide.vert</file>
<file>subdivision-copy.compute</file>
<file>subdivision-edge.compute</file> <file>subdivision-edge.compute</file>
<file>subdivision-vertex.compute</file> <file>subdivision-vertex.compute</file>
<file>subdivideRegular.tcs</file> <file>subdivideRegular.tcs</file>
......
#version 430 core
layout (local_size_x = 1) in;
struct Vertex {
vec3 pos;
vec3 norm;
vec2 uv;
};
layout(std430, binding=0) readonly buffer Input {
Vertex vertices_in[];
};
layout(std430, binding=1) writeonly buffer Output {
Vertex vertices_out[];
};
void main(){
vertices_out[gl_GlobalInvocationID.x] = vertices_in[gl_GlobalInvocationID.x];
}
...@@ -10,6 +10,7 @@ Subdivision::Subdivision(QOpenGLFunctions_4_3_Core *f) ...@@ -10,6 +10,7 @@ Subdivision::Subdivision(QOpenGLFunctions_4_3_Core *f)
Subdivision::~Subdivision() Subdivision::~Subdivision()
{ {
delete copyShader;
delete edgeShader; delete edgeShader;
delete vertexShader; delete vertexShader;
} }
...@@ -21,7 +22,10 @@ QString Subdivision::formatTimeMeasurement(int time){ ...@@ -21,7 +22,10 @@ QString Subdivision::formatTimeMeasurement(int time){
} }
void Subdivision::init() { void Subdivision::init() {
QString source = QLatin1String(":/subdivision-edge.compute"); QString source = QLatin1String(":/subdivision-copy.compute");
copyShader = initComputeShaderProgram(source);
source = QLatin1String(":/subdivision-edge.compute");
edgeShader = initComputeShaderProgram(source); edgeShader = initComputeShaderProgram(source);
source = QLatin1String(":/subdivision-vertex.compute"); source = QLatin1String(":/subdivision-vertex.compute");
...@@ -172,11 +176,15 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) { ...@@ -172,11 +176,15 @@ Subdivision::Tables Subdivision::precomputeTables(Input input) {
precomputeEdgeTable(tables, triangles, triangles_regular, (unsigned int) vb.length()); precomputeEdgeTable(tables, triangles, triangles_regular, (unsigned int) vb.length());
qCDebug(log_timing) << "precomputeEdgeTable:" << formatTimeMeasurement(subTimer.elapsed()); qCDebug(log_timing) << "precomputeEdgeTable:" << formatTimeMeasurement(subTimer.elapsed());
QMap<unsigned int, unsigned int> modified_vertices;
subTimer.restart(); subTimer.restart();
precomputeVertexTable(tables, input); precomputeVertexTable(tables, input, modified_vertices);
qCDebug(log_timing) << "precomputeVertexTable:" << formatTimeMeasurement(subTimer.elapsed()); qCDebug(log_timing) << "precomputeVertexTable:" << formatTimeMeasurement(subTimer.elapsed());
//tables.patch_index_regular = getPatchIndexBuffer(ib, QVector<unsigned int>());//TODO pass regular and irregular index buffer? subTimer.restart();
updateIndexBuffer(tables.index_buffer, modified_vertices);
qCDebug(log_timing) << "updateIndexBuffer:" << formatTimeMeasurement(subTimer.elapsed());
qCDebug(log_subdiv) << "Precompute Tables Done"; qCDebug(log_subdiv) << "Precompute Tables Done";
return tables; return tables;
} }
...@@ -303,18 +311,20 @@ void Subdivision::precomputeEdgeTable(Subdivision::Tables &tables, QVector<Trian ...@@ -303,18 +311,20 @@ void Subdivision::precomputeEdgeTable(Subdivision::Tables &tables, QVector<Trian
} }
} }
void Subdivision::precomputeVertexTable(Subdivision::Tables &tables, Input &input) { void Subdivision::precomputeVertexTable(Subdivision::Tables &tables, Input &input, QMap<unsigned int, unsigned int> &modified_vertices) {
//compute vertex table //compute vertex table
//Format: First entry: original vertex. Other entries: adjacent vertices. //Format: First entry: original vertex. Other entries: adjacent vertices.
QVector<QVector<unsigned int> > duplicates;//for debugging QVector<QVector<unsigned int> > duplicates;//for debugging
QVector<unsigned int> ib_combined = input.index_irregular_buffer + input.index_regular_buffer; QVector<unsigned int> ib_combined = input.index_irregular_buffer + input.index_regular_buffer;
unsigned int offset = 0; unsigned int offset = 0;
unsigned int output_offset = input.vertex_buffer.size() + tables.edge_indices.size() / 4;
for (int i = 0; i < input.vertex_buffer.length(); i++){ for (int i = 0; i < input.vertex_buffer.length(); i++){
//hat evtl viel redundanz //hat evtl viel redundanz
QVector<Vertex> adj_v;//helfer QVector<Vertex> adj_v;//helfer
tables.vertex_offsets.push_back(offset); tables.vertex_offsets.push_back(offset);
tables.vertex_indices.push_back(i); tables.vertex_indices.push_back(i);
modified_vertices.insert(i, output_offset + i);
offset++; offset++;
Vertex originalVertex = input.vertex_buffer[i]; Vertex originalVertex = input.vertex_buffer[i];
...@@ -378,6 +388,13 @@ void Subdivision::precomputeVertexTable(Subdivision::Tables &tables, Input &inpu ...@@ -378,6 +388,13 @@ void Subdivision::precomputeVertexTable(Subdivision::Tables &tables, Input &inpu
} }
} }
void Subdivision::updateIndexBuffer(QVector<unsigned int> &index_buffer, QMap<unsigned int, unsigned int> map) {
for (int i = 0; i < index_buffer.length(); i++) {
unsigned int old = index_buffer[i];
index_buffer[i] = map.value(old, old);
}
}
void Subdivision::splitRegular(Mesh *mesh) { void Subdivision::splitRegular(Mesh *mesh) {
QTime totalTimer; QTime totalTimer;
totalTimer.start(); totalTimer.start();
...@@ -711,38 +728,36 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) { ...@@ -711,38 +728,36 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) {
f->glBufferData(GL_SHADER_STORAGE_BUFFER, tables.edge_indices.size() * sizeof(GLuint), tables.edge_indices.data(), GL_DYNAMIC_DRAW); f->glBufferData(GL_SHADER_STORAGE_BUFFER, tables.edge_indices.size() * sizeof(GLuint), tables.edge_indices.data(), GL_DYNAMIC_DRAW);
// Create an output buffer // Create an output buffer
// the new vertex buffer contains the old vertices + the new edge vertices + the modified non-edge vertices
unsigned int output_size = input.vertex_buffer.size() + tables.edge_indices.size() / 4 + (tables.vertex_offsets.size() - 1);
GLuint output_handle; GLuint output_handle;
f->glGenBuffers(1, &output_handle); f->glGenBuffers(1, &output_handle);
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, output_handle); f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, output_handle);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, (input.vertex_buffer.size() + tables.edge_indices.size() / 4) * sizeof(Vertex), NULL, GL_DYNAMIC_DRAW); f->glBufferData(GL_SHADER_STORAGE_BUFFER, output_size * sizeof(Vertex), NULL, GL_DYNAMIC_DRAW);
result.vb_handle = output_handle; result.vb_handle = output_handle;
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
QTime timer; QTime timer;
timer.start(); timer.start();
runVertexShader(input.vertex_buffer.size(), input.vb_handle, vertex_indices_handle, vertex_offsets_handle, output_handle); runCopyShader(input.vertex_buffer.size(), input.vb_handle, output_handle);
int vertexTime = timer.elapsed(); int copyTime = timer.elapsed();
timer.restart(); timer.restart();
int edgeOffset = input.vertex_buffer.size(); int edge_offset = input.vertex_buffer.size();
runEdgeShader(tables.edge_indices.size() / 4, input.vb_handle, edge_indices_handle, output_handle, edgeOffset); runEdgeShader(tables.edge_indices.size() / 4, input.vb_handle, edge_indices_handle, output_handle, edge_offset);
int edgeTime = timer.elapsed(); int edgeTime = timer.elapsed();
timer.restart(); timer.restart();
int vertex_offset = edge_offset + tables.edge_indices.size() / 4;
runVertexShader(input.vertex_buffer.size(), input.vb_handle, vertex_indices_handle, vertex_offsets_handle, output_handle, vertex_offset);
int vertexTime = timer.elapsed();
timer.restart();
// Map the output buffer so we can read the results // Map the output buffer so we can read the results
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, output_handle); f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, output_handle);
Vertex *ptr; Vertex *ptr;
ptr = (Vertex *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); ptr = (Vertex *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
for (unsigned int i = 0; i < output_size; i++) {
qCDebug(log_subdiv_trace) << "New vertices:";
for (int i = 0; i < input.vertex_buffer.size(); i++) {
qCDebug(log_subdiv_trace) << ptr[i].pos;
result.vertex_buffer.push_back(ptr[i]); result.vertex_buffer.push_back(ptr[i]);
} }
qCDebug(log_subdiv_trace) << "New edge points:";
for (int i = 0; i < tables.edge_indices.size() / 4; i++) {
qCDebug(log_subdiv_trace) << ptr[edgeOffset + i].pos;
result.vertex_buffer.push_back(ptr[edgeOffset + i]);
}
int bufferbildTime = timer.elapsed(); int bufferbildTime = timer.elapsed();
f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
...@@ -752,17 +767,36 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) { ...@@ -752,17 +767,36 @@ Subdivision::Result Subdivision::runShader(Input input, Tables &tables) {
f->glDeleteBuffers(1, &vertex_offsets_handle); f->glDeleteBuffers(1, &vertex_offsets_handle);
f->glDeleteBuffers(1, &edge_indices_handle); f->glDeleteBuffers(1, &edge_indices_handle);
qCDebug(log_timing)<<"Compute Shader done. Vertexshader"<<vertexTime<<"ms; EdgeShader"<<edgeTime<<" BufferToCPU"<<bufferbildTime<<"ms"; qCDebug(log_timing)<<"Compute Shader done. Copyshader"<<copyTime<<"ms; Vertexshader"<<vertexTime<<"ms; EdgeShader"<<edgeTime<<" BufferToCPU"<<bufferbildTime<<"ms";
return result; return result;
} }
void Subdivision::runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle) { void Subdivision::runCopyShader(GLuint size, GLuint vb_in, GLuint vb_out) {
copyShader->bind();
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vb_in);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, vb_out);
// Run the shader
f->glDispatchCompute(size, 1, 1);
// Wait for the shader to complete and the data to be written back to the global memory
f->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
// Unbind the buffers from the shader
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
copyShader->release();
}
void Subdivision::runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle, GLuint offset) {
vertexShader->bind(); vertexShader->bind();
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vb_handle); 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, 1, vertex_indices_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, vertex_offsets_handle); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, vertex_offsets_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, output_handle); f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 3, output_handle, offset * sizeof(Vertex), size * sizeof(Vertex));
// Run the shader // Run the shader
f->glDispatchCompute(size, 1, 1); f->glDispatchCompute(size, 1, 1);
......
...@@ -51,16 +51,19 @@ private: ...@@ -51,16 +51,19 @@ private:
QString formatTimeMeasurement(int time); QString formatTimeMeasurement(int time);
QOpenGLFunctions_4_3_Core *f; QOpenGLFunctions_4_3_Core *f;
QOpenGLShaderProgram *copyShader;
QOpenGLShaderProgram *edgeShader; QOpenGLShaderProgram *edgeShader;
QOpenGLShaderProgram *vertexShader; QOpenGLShaderProgram *vertexShader;
QOpenGLShaderProgram *initComputeShaderProgram(QString &source); QOpenGLShaderProgram *initComputeShaderProgram(QString &source);
Tables precomputeTables(Input input); Tables precomputeTables(Input input);
void precomputeEdgeTable(Subdivision::Tables &tables, QVector<Triangle> &triangles, QVector<Triangle> &triangles_regular, unsigned int offset); void precomputeEdgeTable(Subdivision::Tables &tables, QVector<Triangle> &triangles, QVector<Triangle> &triangles_regular, unsigned int offset);
void precomputeVertexTable(Subdivision::Tables &tables, Input &input); void precomputeVertexTable(Subdivision::Tables &tables, Input &input, QMap<unsigned int, unsigned int> &modified_vertices);
void updateIndexBuffer(QVector<unsigned int> &index_buffer, QMap<unsigned int, unsigned int> map);
void findRegular(QVector<unsigned int> index_buffer, QVector<Vertex> vertex_buffer, QVector<unsigned int> &regular, QVector<unsigned int> &irregular); void findRegular(QVector<unsigned int> index_buffer, QVector<Vertex> vertex_buffer, QVector<unsigned int> &regular, QVector<unsigned int> &irregular);
Result runShader(Input input, Tables &tables); Result runShader(Input input, Tables &tables);
void runVertexShader(GLuint size, GLuint vb_handle, GLuint vertex_indices_handle, GLuint vertex_offsets_handle, GLuint output_handle); 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);
void runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle, GLuint offset); void runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle, GLuint offset);
QVector<unsigned int> patchIBToTriangleIB(QVector<unsigned int> ib); QVector<unsigned int> patchIBToTriangleIB(QVector<unsigned int> ib);
......
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