Commit 1360526f by Philipp Adolf

Add edge computation shader

parents 188a8f55 09a808ae
...@@ -370,8 +370,8 @@ void Mesh::renderMesh(QOpenGLShaderProgram *shader, int index) ...@@ -370,8 +370,8 @@ void Mesh::renderMesh(QOpenGLShaderProgram *shader, int index)
// Draw Vertex Array // Draw Vertex Array
f->glBindBuffer(GL_ARRAY_BUFFER, entries[index].VB_handle); f->glBindBuffer(GL_ARRAY_BUFFER, entries[index].VB_handle);
f->glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); f->glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
f->glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12); //12 f->glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)16); //3*4+4
f->glVertexAttribPointer(uvIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)24); // 12+12 f->glVertexAttribPointer(uvIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)32); // 12+4+12+4
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entries[index].IB_handle); f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entries[index].IB_handle);
......
...@@ -17,8 +17,14 @@ ...@@ -17,8 +17,14 @@
struct Vertex struct Vertex
{ {
QVector3D pos; QVector3D pos;
float padding0;
QVector3D normal; QVector3D normal;
float padding1;
QVector2D tex; QVector2D tex;
QVector2D padding2;
Vertex(){} Vertex(){}
......
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
<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.compute</file> <file>subdivision-edge.compute</file>
</qresource> </qresource>
</RCC> </RCC>
#version 430 core
layout (local_size_x = 1) in;
struct Vertex {
vec3 pos;
vec3 norm;
vec2 uv;
};
layout(std430, binding=0) readonly buffer Vertices {
Vertex vertices[];
};
layout(std430, binding=1) readonly buffer EdgeIndices {
unsigned int indices[][4];
};
layout(std430, binding=2) writeonly buffer Output {
Vertex edges[];
};
void main(){
edges[gl_GlobalInvocationID.x].norm = vec3(0.0, 0.0, 0.0);
edges[gl_GlobalInvocationID.x].uv = vec2(0.0, 0.0);
edges[gl_GlobalInvocationID.x].pos = 3.0/8.0 * (vertices[indices[gl_GlobalInvocationID.x][0]].pos + vertices[indices[gl_GlobalInvocationID.x][1]].pos) + 1.0/8.0 * (vertices[indices[gl_GlobalInvocationID.x][2]].pos + vertices[indices[gl_GlobalInvocationID.y][3]].pos);
}
#version 430 core
layout (local_size_x = 2) in;
layout(std430, binding=0) readonly buffer Input {
float offset;
};
layout(std430, binding=1) writeonly buffer Output {
float data[];
};
void main(){
data[gl_GlobalInvocationID.x] = 100 * gl_GlobalInvocationID.x + gl_LocalInvocationID.x + offset;
}
...@@ -7,11 +7,11 @@ Subdivision::Subdivision(QOpenGLFunctions_4_3_Core *f) ...@@ -7,11 +7,11 @@ Subdivision::Subdivision(QOpenGLFunctions_4_3_Core *f)
Subdivision::~Subdivision() Subdivision::~Subdivision()
{ {
delete shader; delete edgeShader;
} }
void Subdivision::init() { void Subdivision::init() {
shader = initComputeShaderProgram(); edgeShader = initEdgeComputeShaderProgram();
} }
QVector<unsigned int> Subdivision::fillVector(unsigned int a, unsigned int b, unsigned int c,unsigned int d){ QVector<unsigned int> Subdivision::fillVector(unsigned int a, unsigned int b, unsigned int c,unsigned int d){
...@@ -23,8 +23,8 @@ QVector<unsigned int> Subdivision::fillVector(unsigned int a, unsigned int b, un ...@@ -23,8 +23,8 @@ QVector<unsigned int> Subdivision::fillVector(unsigned int a, unsigned int b, un
return x; return x;
} }
QOpenGLShaderProgram *Subdivision::initComputeShaderProgram(){ QOpenGLShaderProgram *Subdivision::initEdgeComputeShaderProgram(){
QString source = QLatin1String(":/subdivision.compute"); QString source = QLatin1String(":/subdivision-edge.compute");
qDebug()<<"Compiling compute shader ..."; qDebug()<<"Compiling compute shader ...";
QOpenGLShader *computeShader = new QOpenGLShader(QOpenGLShader::Compute); QOpenGLShader *computeShader = new QOpenGLShader(QOpenGLShader::Compute);
...@@ -47,12 +47,13 @@ QOpenGLShaderProgram *Subdivision::initComputeShaderProgram(){ ...@@ -47,12 +47,13 @@ QOpenGLShaderProgram *Subdivision::initComputeShaderProgram(){
} }
Mesh *Subdivision::subdivide(Mesh *mesh) { Mesh *Subdivision::subdivide(Mesh *mesh) {
precomputeTables(mesh); QVector<QVector<unsigned int> > edgeIndices;
runShader(mesh); precomputeTables(mesh, edgeIndices);
runShader(mesh, edgeIndices);
return NULL; return NULL;
} }
void Subdivision::precomputeTables(Mesh *mesh) { void Subdivision::precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &edgeIndices_base) {
Mesh::Node root = mesh->getRootNode(); Mesh::Node root = mesh->getRootNode();
int firstMeshEntryIndex = -1; int firstMeshEntryIndex = -1;
...@@ -73,7 +74,6 @@ void Subdivision::precomputeTables(Mesh *mesh) { ...@@ -73,7 +74,6 @@ void Subdivision::precomputeTables(Mesh *mesh) {
//compute edge table //compute edge table
//Format: first two entries: edge vertices. last two entries: distant vertices. //Format: first two entries: edge vertices. last two entries: distant vertices.
QVector<QVector<unsigned int> > edgeIndices_base;
for (int i = 0; i < ib.length(); i+=3){ for (int i = 0; i < ib.length(); i+=3){
//schaue alle dreiecke an //schaue alle dreiecke an
...@@ -265,33 +265,48 @@ void Subdivision::precomputeTables(Mesh *mesh) { ...@@ -265,33 +265,48 @@ void Subdivision::precomputeTables(Mesh *mesh) {
} }
void Subdivision::runShader(Mesh *mesh) { void Subdivision::runShader(Mesh *mesh, QVector<QVector<unsigned int> > &edgeIndices) {
/*
* This shader will set the output buffer to its global ID times hundred + the local id + offset.
*
* So, for offset = 0 we will get 0, 101, 200, 301 and so on as there's two threads in a local group.
*/
qDebug()<<"Running compute shader"; qDebug()<<"Running compute shader";
int num = 6 * 2; // must be a multiple of two as we do not handle the other case
GLfloat offset = 3.0f;
shader->bind(); Mesh::Node root = mesh->getRootNode();
int firstMeshEntryIndex = -1;
bool meshExists = root.getFirstMeshIndex(firstMeshEntryIndex);
if (!meshExists){
qDebug()<<"No Mesh found. Abort shader execution.";
return;
}
qDebug()<<"Mesh found. Index:"<<firstMeshEntryIndex;
Mesh::MeshEntry *firstMeshEntry = mesh->getMeshEntry(firstMeshEntryIndex);
GLuint vb_handle = firstMeshEntry->VB_handle;
QVector<Vertex> vb = firstMeshEntry->getVertexBuffer();
edgeShader->bind();
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, vb_handle);
GLuint *edgeIDs = new GLuint[edgeIndices.size() * 4];
for (uint i = 0; i < edgeIndices.size(); i++) {
for (uint j = 0; j < 4; j++) {
edgeIDs[4 * i + j] = edgeIndices[i][j];
}
}
// Create an input buffer and set it to the value of offset // Create an input buffer and set it to the value of offset
GLuint offsetBufferID; GLuint indicesID;
f->glGenBuffers(1, &offsetBufferID); f->glGenBuffers(1, &indicesID);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, offsetBufferID); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, indicesID);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat), &offset, GL_DYNAMIC_DRAW); f->glBufferData(GL_SHADER_STORAGE_BUFFER, edgeIndices.size() * sizeof(GLuint) * 4, &edgeIDs[0], GL_DYNAMIC_DRAW);
delete edgeIDs;
// Create an output buffer // Create an output buffer
GLuint bufferID; GLuint bufferID;
f->glGenBuffers(1, &bufferID); f->glGenBuffers(1, &bufferID);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bufferID); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bufferID);
f->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat) * num, NULL, GL_DYNAMIC_DRAW); f->glBufferData(GL_SHADER_STORAGE_BUFFER, edgeIndices.size() * sizeof(Vertex), NULL, GL_DYNAMIC_DRAW);
// Run the shader // Run the shader
f->glDispatchCompute(num/2, 1, 1); f->glDispatchCompute(edgeIndices.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);
...@@ -299,19 +314,20 @@ void Subdivision::runShader(Mesh *mesh) { ...@@ -299,19 +314,20 @@ void Subdivision::runShader(Mesh *mesh) {
// Unbind the buffers from the shader // Unbind the buffers from the shader
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0); f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
// 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, bufferID); f->glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferID);
GLfloat *ptr; Vertex *ptr;
ptr = (GLfloat *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); ptr = (Vertex *) f->glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
for (int i = 0; i < num; i++) { for (int i = 0; i < edgeIndices.size(); i++) {
qDebug()<<i<<ptr[i]; qDebug() << ptr[i].pos;
} }
f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); f->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
// Delete the buffers the free the resources // Delete the buffers the free the resources
f->glDeleteBuffers(1, &offsetBufferID); f->glDeleteBuffers(1, &indicesID);
f->glDeleteBuffers(1, &bufferID); f->glDeleteBuffers(1, &bufferID);
shader->release(); edgeShader->release();
} }
...@@ -17,11 +17,11 @@ public: ...@@ -17,11 +17,11 @@ public:
private: private:
QOpenGLFunctions_4_3_Core *f; QOpenGLFunctions_4_3_Core *f;
QOpenGLShaderProgram *shader; QOpenGLShaderProgram *edgeShader;
QOpenGLShaderProgram *initComputeShaderProgram(); QOpenGLShaderProgram *initEdgeComputeShaderProgram();
void precomputeTables(Mesh *mesh); void precomputeTables(Mesh *mesh, QVector<QVector<unsigned int> > &edgeIndices_base);
void runShader(Mesh *mesh); 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); QVector<unsigned int> fillVector(unsigned int a, unsigned int b, unsigned int c,unsigned int d);
}; };
......
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