Commit 2e3de66d by Philipp Adolf

Merge refactor into master (using imerge)

parents bb3551a1 1221b6c9
...@@ -11,21 +11,11 @@ Subdivision::~Subdivision() ...@@ -11,21 +11,11 @@ Subdivision::~Subdivision()
} }
void Subdivision::init() { void Subdivision::init() {
edgeShader = initEdgeComputeShaderProgram();
}
QVector<unsigned int> Subdivision::fillVector(unsigned int a, unsigned int b, unsigned int c,unsigned int d){
QVector<unsigned int> x;
x.push_back(a);
x.push_back(b);
x.push_back(c);
x.push_back(d);
return x;
}
QOpenGLShaderProgram *Subdivision::initEdgeComputeShaderProgram(){
QString source = QLatin1String(":/subdivision-edge.compute"); QString source = QLatin1String(":/subdivision-edge.compute");
edgeShader = initComputeShaderProgram(source);
}
QOpenGLShaderProgram *Subdivision::initComputeShaderProgram(QString &source){
qDebug()<<"Compiling compute shader ..."; qDebug()<<"Compiling compute shader ...";
QOpenGLShader *computeShader = new QOpenGLShader(QOpenGLShader::Compute); QOpenGLShader *computeShader = new QOpenGLShader(QOpenGLShader::Compute);
if(!computeShader->compileSourceFile(source)){ if(!computeShader->compileSourceFile(source)){
...@@ -47,18 +37,23 @@ QOpenGLShaderProgram *Subdivision::initEdgeComputeShaderProgram(){ ...@@ -47,18 +37,23 @@ QOpenGLShaderProgram *Subdivision::initEdgeComputeShaderProgram(){
} }
Mesh *Subdivision::subdivide(Mesh *mesh) { Mesh *Subdivision::subdivide(Mesh *mesh) {
QVector<QVector<unsigned int> > edgeIndices; // For now we only look at the first mesh entry
QVector<unsigned int> vertexIndices; Mesh::Node root = mesh->getRootNode();
QVector<unsigned int> vertexIndicesOffsets;
/* int first_mesh_index = -1;
* Die Indices im neuen Indexbuffer gehen davon aus, if (!root.getFirstMeshIndex(first_mesh_index)) {
* dass im neuen Vertex-buffer erst die Vertex-points kommen, qCritical()<<"No mesh found, aborting subdivision";
* die direkt aus den Vertices aus dem Vertexbuffer erstellt werden, return NULL;
* und dann die Edgepoints in der Reihenfolge von edgeIndices. }
* */
QVector<unsigned int> newIndexBuffer; Mesh::MeshEntry *current_mesh = mesh->getMeshEntry(first_mesh_index);
precomputeTables(mesh, edgeIndices, vertexIndices, vertexIndicesOffsets, newIndexBuffer); Input input;
runShader(mesh, edgeIndices); input.vb_handle = current_mesh->VB_handle;
input.vertex_buffer = current_mesh->getVertexBuffer();
input.index_buffer = current_mesh->getIndexBuffer();
Tables tables = precomputeTables(input);
runShader(input, tables);
return NULL; return NULL;
} }
...@@ -73,25 +68,13 @@ Mesh *Subdivision::subdivide(Mesh *mesh) { ...@@ -73,25 +68,13 @@ Mesh *Subdivision::subdivide(Mesh *mesh) {
* *
* Einträge in neuem Vertex-buffer: Verschobene Knoten aus altem Vertex-Buffer :: edge-vertices erstellt aus edgeIndices_base. * Einträge in neuem Vertex-buffer: Verschobene Knoten aus altem Vertex-Buffer :: edge-vertices erstellt aus edgeIndices_base.
*/ */
void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &edgeIndices_base, Subdivision::Tables Subdivision::precomputeTables(Input input) {
QVector<unsigned int> &vertexIndices, QVector<unsigned int> &vertexIndicesOffsets, Tables tables;
QVector<unsigned int> &newIndexBuffer) {
Mesh::Node root = mesh->getRootNode();
int firstMeshEntryIndex = -1;
bool meshExists = root.getFirstMeshIndex(firstMeshEntryIndex);
if (!meshExists){
qDebug()<<"No Mesh found. Abort subdiv table precomputation.";
return;
}
qDebug()<<"Mesh found. Index:"<<firstMeshEntryIndex;
//die drei zeilen machen das bild schwarz. wenn man davor returnt tuts. QVector<unsigned int> ib = input.index_buffer;
Mesh::MeshEntry *firstMeshEntry = mesh->getMeshEntry(firstMeshEntryIndex);
QVector<unsigned int> ib = firstMeshEntry->getIndexBuffer();
qDebug()<<"Index Buffer: "<<ib; qDebug()<<"Index Buffer: "<<ib;
QVector<Vertex> vb = firstMeshEntry->getVertexBuffer(); QVector<Vertex> vb = input.vertex_buffer;
//qDebug()<<"Vertex Buffer: "<<vb; //qDebug()<<"Vertex Buffer: "<<vb;
//compute edge table //compute edge table
...@@ -113,7 +96,7 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > & ...@@ -113,7 +96,7 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &
/* /*
* Find edge xy in all other triangles, add to edgeIndices_base * Find edge xy in all other triangles, add to edge_indices
* Find edge yz * Find edge yz
* Find edge zx * Find edge zx
* - We assume that we have a closed surface, i.e. each triangle has exactly one adjacent triangle at each edge * - We assume that we have a closed surface, i.e. each triangle has exactly one adjacent triangle at each edge
...@@ -140,13 +123,22 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > & ...@@ -140,13 +123,22 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &
//zx = ba, cb, ac //zx = ba, cb, ac
//TODO if oder else if? //TODO if oder else if?
if (x.samePos(a) && y.samePos(c)){ if (x.samePos(a) && y.samePos(c)){
edgeIndices_base.push_back(fillVector(x_i,y_i,z_i,b_i)); tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(b_i);
} }
if (x.samePos(b) && y.samePos(a)){ if (x.samePos(b) && y.samePos(a)){
edgeIndices_base.push_back(fillVector(x_i,y_i,z_i,c_i)); tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(c_i);
} }
if (x.samePos(c) && y.samePos(b)){ if (x.samePos(c) && y.samePos(b)){
edgeIndices_base.push_back(fillVector(x_i,y_i,z_i,a_i)); tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(a_i);
} }
} }
} }
...@@ -167,13 +159,22 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > & ...@@ -167,13 +159,22 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &
//yz = ba, cb, ac //yz = ba, cb, ac
if (y.samePos(a) && z.samePos(c)){ if (y.samePos(a) && z.samePos(c)){
edgeIndices_base.push_back(fillVector(y_i,z_i,x_i,b_i)); tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(b_i);
} }
if (y.samePos(b) && z.samePos(a)){ if (y.samePos(b) && z.samePos(a)){
edgeIndices_base.push_back(fillVector(y_i,z_i,x_i,c_i)); tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(c_i);
} }
if (y.samePos(c) && z.samePos(b)){ if (y.samePos(c) && z.samePos(b)){
edgeIndices_base.push_back(fillVector(y_i,z_i,x_i,a_i)); tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(a_i);
} }
} }
} }
...@@ -194,41 +195,50 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > & ...@@ -194,41 +195,50 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &
if (x.samePos(a) && z.samePos(b)){ if (x.samePos(a) && z.samePos(b)){
edgeIndices_base.push_back(fillVector(x_i,z_i,y_i,c_i)); tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(c_i);
} }
if (x.samePos(b) && z.samePos(c)){ if (x.samePos(b) && z.samePos(c)){
edgeIndices_base.push_back(fillVector(x_i,z_i,y_i,a_i)); tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(a_i);
} }
if (x.samePos(c) && z.samePos(a)){ if (x.samePos(c) && z.samePos(a)){
edgeIndices_base.push_back(fillVector(x_i,z_i,y_i,b_i)); tables.edge_indices.push_back(x_i);
tables.edge_indices.push_back(z_i);
tables.edge_indices.push_back(y_i);
tables.edge_indices.push_back(b_i);
} }
} }
}//quadratische Laufzeit ftw }//quadratische Laufzeit ftw
//add indices to new index buffer //add indices to new index buffer
newIndexBuffer.push_back(ib[i]); tables.index_buffer.push_back(ib[i]);
newIndexBuffer.push_back(nib_offset + 3*i); tables.index_buffer.push_back(nib_offset + 3*i);
newIndexBuffer.push_back(nib_offset + 3*i + 2); tables.index_buffer.push_back(nib_offset + 3*i + 2);
newIndexBuffer.push_back(ib[i+1]); tables.index_buffer.push_back(ib[i+1]);
newIndexBuffer.push_back(nib_offset + 3*i + 1); tables.index_buffer.push_back(nib_offset + 3*i + 1);
newIndexBuffer.push_back(nib_offset + 3*i); tables.index_buffer.push_back(nib_offset + 3*i);
newIndexBuffer.push_back(ib[i+2]); tables.index_buffer.push_back(ib[i+2]);
newIndexBuffer.push_back(nib_offset + 3*i + 2); tables.index_buffer.push_back(nib_offset + 3*i + 2);
newIndexBuffer.push_back(nib_offset + 3*i + 1); tables.index_buffer.push_back(nib_offset + 3*i + 1);
newIndexBuffer.push_back(nib_offset + 3*i); tables.index_buffer.push_back(nib_offset + 3*i);
newIndexBuffer.push_back(nib_offset + 3*i + 1); tables.index_buffer.push_back(nib_offset + 3*i + 1);
newIndexBuffer.push_back(nib_offset + 3*i + 2); tables.index_buffer.push_back(nib_offset + 3*i + 2);
//Wichtig: Wir gehen davon aus, dass wir geschlossene Oberflächen haben, dh für jede Kante von einem Dreieck wird eine passende Kante bei einem anderen Dreieck gefunden. //Wichtig: Wir gehen davon aus, dass wir geschlossene Oberflächen haben, dh für jede Kante von einem Dreieck wird eine passende Kante bei einem anderen Dreieck gefunden.
}//for each index in indexbuffer }//for each index in indexbuffer
qDebug()<<"Done with edge table. "<<edgeIndices_base.length()<<" edges found. Table: "<<edgeIndices_base; qDebug()<<"Done with edge table. "<<tables.edge_indices.length()<<" edges found. Table: "<<tables.edge_indices;
if (true){ if (true){
qDebug()<<"Table (long version):"; qDebug()<<"Table (long version):";
for (int i = 0; i < edgeIndices_base.length(); i++){ for (int i = 0; i < tables.edge_indices.length(); i++){
qDebug()<<"blub:"<<edgeIndices_base[i]; qDebug()<<"blub:"<<tables.edge_indices[i];
} }
} }
...@@ -240,8 +250,8 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > & ...@@ -240,8 +250,8 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &
//hat evtl viel redundanz //hat evtl viel redundanz
QVector<Vertex> adj_v;//helfer QVector<Vertex> adj_v;//helfer
vertexIndicesOffsets.push_back(offset); tables.vertex_offsets.push_back(offset);
vertexIndices.push_back(i); tables.vertex_indices.push_back(i);
offset++; offset++;
Vertex originalVertex = vb[i]; Vertex originalVertex = vb[i];
...@@ -278,12 +288,12 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > & ...@@ -278,12 +288,12 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &
} }
if (!found1){ if (!found1){
adj_v.push_back(v1); adj_v.push_back(v1);
vertexIndices.push_back(i1); tables.vertex_indices.push_back(i1);
offset++; offset++;
} }
if (!found2){ if (!found2){
adj_v.push_back(v2); adj_v.push_back(v2);
vertexIndices.push_back(i2); tables.vertex_indices.push_back(i2);
offset++; offset++;
} }
//if one adjacent vertex is referenced by multiple different indices, only its first index will appear in the adjacent_indices list.1 //if one adjacent vertex is referenced by multiple different indices, only its first index will appear in the adjacent_indices list.1
...@@ -294,57 +304,58 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > & ...@@ -294,57 +304,58 @@ void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &
qDebug()<<"Done with vertex index table. "; qDebug()<<"Done with vertex index table. ";
vertexIndicesOffsets.push_back(offset); tables.vertex_offsets.push_back(offset);
qDebug()<<"Duplicates: "; qDebug()<<"Duplicates: ";
for (int i = 0; i < duplicates.length(); i++){ for (int i = 0; i < duplicates.length(); i++){
qDebug()<<duplicates[i]; qDebug()<<duplicates[i];
} }
return tables;
} }
void Subdivision::runShader(Mesh *mesh, QVector<QVector<unsigned int> > &edgeIndices) { void Subdivision::runShader(Input input, Tables &tables) {
qDebug()<<"Running compute shader"; qDebug()<<"Running compute shader";
Mesh::Node root = mesh->getRootNode(); // Create an input buffer and set it to the value of offset
GLuint edge_indices_handle;
f->glGenBuffers(1, &edge_indices_handle);
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, edge_indices_handle);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, tables.edge_indices.size() * sizeof(GLuint), tables.edge_indices.data(), GL_DYNAMIC_DRAW);
int firstMeshEntryIndex = -1; // Create an output buffer
bool meshExists = root.getFirstMeshIndex(firstMeshEntryIndex); GLuint output_handle;
if (!meshExists){ f->glGenBuffers(1, &output_handle);
qDebug()<<"No Mesh found. Abort shader execution."; f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, output_handle);
return; f->glBufferData(GL_SHADER_STORAGE_BUFFER, tables.edge_indices.size() * sizeof(Vertex) / 4, NULL, GL_DYNAMIC_DRAW);
}
qDebug()<<"Mesh found. Index:"<<firstMeshEntryIndex;
Mesh::MeshEntry *firstMeshEntry = mesh->getMeshEntry(firstMeshEntryIndex); f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLuint vb_handle = firstMeshEntry->VB_handle;
QVector<Vertex> vb = firstMeshEntry->getVertexBuffer();
edgeShader->bind(); runEdgeShader(tables.edge_indices.size() / 4, input.vb_handle, edge_indices_handle, output_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vb_handle);
GLuint *edgeIDs = new GLuint[edgeIndices.size() * 4]; // Map the output buffer so we can read the results
for (uint i = 0; i < edgeIndices.size(); i++) { f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, output_handle);
for (uint j = 0; j < 4; j++) { Vertex *ptr;
edgeIDs[4 * i + j] = edgeIndices[i][j]; ptr = (Vertex *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
} for (int i = 0; i < tables.edge_indices.size() / 4; i++) {
qDebug() << ptr[i].pos;
} }
f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
// Create an input buffer and set it to the value of offset // Delete the buffers the free the resources
GLuint indicesID; f->glDeleteBuffers(1, &edge_indices_handle);
f->glGenBuffers(1, &indicesID); f->glDeleteBuffers(1, &output_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, indicesID); }
f->glBufferData(GL_SHADER_STORAGE_BUFFER, edgeIndices.size() * sizeof(GLuint) * 4, &edgeIDs[0], GL_DYNAMIC_DRAW);
delete edgeIDs;
// Create an output buffer void Subdivision::runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle) {
GLuint bufferID; edgeShader->bind();
f->glGenBuffers(1, &bufferID);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bufferID); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vb_handle);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, edgeIndices.size() * sizeof(Vertex), NULL, GL_DYNAMIC_DRAW); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, edge_indices_handle);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, output_handle);
// Run the shader // Run the shader
f->glDispatchCompute(edgeIndices.size(), 1, 1); f->glDispatchCompute(size, 1, 1);
// Wait for the shader to complete and the data to be written back to the global memory // Wait for the shader to complete and the data to be written back to the global memory
f->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); f->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
...@@ -354,18 +365,5 @@ void Subdivision::runShader(Mesh *mesh, QVector<QVector<unsigned int> > &edgeInd ...@@ -354,18 +365,5 @@ void Subdivision::runShader(Mesh *mesh, QVector<QVector<unsigned int> > &edgeInd
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
// Map the output buffer so we can read the results
f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferID);
Vertex *ptr;
ptr = (Vertex *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
for (int i = 0; i < edgeIndices.size(); i++) {
qDebug() << ptr[i].pos;
}
f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
// Delete the buffers the free the resources
f->glDeleteBuffers(1, &indicesID);
f->glDeleteBuffers(1, &bufferID);
edgeShader->release(); edgeShader->release();
} }
...@@ -16,16 +16,28 @@ public: ...@@ -16,16 +16,28 @@ public:
Mesh *subdivide(Mesh *mesh); Mesh *subdivide(Mesh *mesh);
private: private:
struct Input
{
GLuint vb_handle;
QVector<unsigned int> index_buffer;
QVector<Vertex> vertex_buffer;
};
struct Tables
{
QVector<GLuint> edge_indices;
QVector<GLuint> vertex_indices;
QVector<GLuint> vertex_offsets;
QVector<GLuint> index_buffer;
};
QOpenGLFunctions_4_3_Core *f; QOpenGLFunctions_4_3_Core *f;
QOpenGLShaderProgram *edgeShader; QOpenGLShaderProgram *edgeShader;
QOpenGLShaderProgram *initEdgeComputeShaderProgram(); QOpenGLShaderProgram *initComputeShaderProgram(QString &source);
void precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &edgeIndices_base, Tables precomputeTables(Input input);
QVector<unsigned int> &vertexIndices, QVector<unsigned int> &vertexIndicesOffsets, void runShader(Input input, Tables &tables);
QVector<unsigned int> &newIndexBuffer); void runEdgeShader(GLuint size, GLuint vb_handle, GLuint edge_indices_handle, GLuint output_handle);
void runShader(Mesh *mesh, QVector<QVector<unsigned int> > &edgeIndices);
QVector<unsigned int> fillVector(unsigned int a, unsigned int b, unsigned int c,unsigned int d);
}; };
#endif #endif
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