Commit 61f40d18 by Kai Westerkamp

rebuild tesselation stages

parent 2e7a899f
......@@ -106,7 +106,17 @@ void MainWidget::initializeGL(){
glDisable(GL_CULL_FACE);
// Shader
subdevisionShader = initShaderProgram();
QString vertSource = QLatin1String(":/subdivide.vert");
QString tesselationControlSource = QLatin1String(":/subdivide.tcs");
QString tesselationEvaluationSource = QLatin1String(":/subdivide.tes");
QString tesselationControlSource2 = QLatin1String(":/subdivideRegular.tcs");
QString tesselationEvaluationSource2 = QLatin1String(":/subdivideRegular.tes");
QString geometrySource = QLatin1String(":/subdivide.geo");
QString fragSource = QLatin1String(":/subdivide.frag");
subdevisionShader = initShaderProgram(vertSource,tesselationControlSource,tesselationEvaluationSource,geometrySource,fragSource);
regularShader = initShaderProgram(vertSource,tesselationControlSource2,tesselationEvaluationSource2,geometrySource,fragSource);
subdivision->init();
//loadNewMesh( "../Models/demon_head.3ds");
......@@ -134,8 +144,9 @@ void MainWidget::loadNewMesh(QString path){
}
void MainWidget::subdivide(int level){
subdivision->subdivide(mesh);
subdivision->subdivide(mesh, level);
subdivLevel = level;
}
void MainWidget::setdebugOutput(bool output){
......@@ -154,13 +165,7 @@ void MainWidget::setWireframe(bool active){
this->wireframe = active;
}
QOpenGLShaderProgram* MainWidget::initShaderProgram(){
QString vertSource = QLatin1String(":/subdivide.vert");
QString tesselationControlSource = QLatin1String(":/subdivide.tcs");
QString tesselationEvaluationSource = QLatin1String(":/subdivide.tes");
QString geometrySource = QLatin1String(":/subdivide.geo");
QString fragSource = QLatin1String(":/subdivide.frag");
QOpenGLShaderProgram* MainWidget::initShaderProgram(QString vertSource, QString tesselationControlSource, QString tesselationEvaluationSource, QString geometrySource, QString fragSource ){
QOpenGLShader *vert = initGLShader(vertSource,QOpenGLShader::Vertex);
QOpenGLShader *tesselationControl = initGLShader(tesselationControlSource,QOpenGLShader::TessellationControl);
......@@ -213,7 +218,10 @@ void MainWidget::paintGL(){
subdevisionShader->setUniformValue("colorTexture",0);
subdevisionShader->setUniformValue("LightPos",QVector3D(0,100,100));
mesh->render(subdevisionShader,cam->getMatrix()*rot, m_projection,subdivLevel);
mesh->render(subdevisionShader,cam->getMatrix()*rot, m_projection,subdivLevel,false);
//glEnable (GL_BLEND);
//glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
subdevisionShader->release();
update();
......
......@@ -54,6 +54,7 @@ private:
Camera *cam;
QOpenGLShaderProgram* subdevisionShader;
QOpenGLShaderProgram* regularShader;
QMatrix4x4 m_projection;
QTime startTime;
QTime rotTime;
......@@ -67,7 +68,7 @@ private:
Subdivision *subdivision;
Mesh *mesh;
QOpenGLShaderProgram* initShaderProgram();
QOpenGLShaderProgram* initShaderProgram(QString vertSource, QString tesselationControlSource, QString tesselationEvaluationSource, QString geometrySource, QString fragSource );
QOpenGLShader* initGLShader(QString scource, QOpenGLShader::ShaderType type);
};
......
......@@ -42,8 +42,9 @@ MainWindow::MainWindow(QWidget *parent) :
subdivSlider = new QSlider(Qt::Horizontal);
subdivSlider->setMinimum(0);
subdivSlider->setMaximum(10);
subdivSlider->setMaximum(5);
subdivSlider->setSliderPosition(0);
subdivSlider->setSingleStep(1);
connect(subdivSlider, SIGNAL(valueChanged(int)),
m_centralWidget, SLOT(subdivide(int)));
......
......@@ -6,58 +6,87 @@ QDebug operator<< (QDebug d, const Vertex &v) {
return d;
}
Mesh::MeshEntry::MeshEntry()
Mesh::SubdivEntry::SubdivEntry()
{
materialIndex = 0xFFFFFFFF;
numIndex = 0;
VB_handle = 0xFFFFFFFF;
IB_handle = 0xFFFFFFFF;
double amax = std::numeric_limits<float>::max();
min = QVector3D(amax,amax,amax);
max = QVector3D(-amax,-amax,-amax);
IB_Regular = 0xFFFFFFFF;
}
void Mesh::MeshEntry::init(QOpenGLFunctions_4_3_Core *f,QVector<Vertex>& Vertices,
QVector<unsigned int>& Indices){
this->f = f;
f->glGenBuffers(1, &VB_handle);
f->glBindBuffer(GL_ARRAY_BUFFER, VB_handle);
f->glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * Vertices.size(), &Vertices[0], GL_STATIC_DRAW);
Mesh::SubdivEntry::~SubdivEntry()
{
f->glDeleteBuffers(1, &VB_handle);
f->glDeleteBuffers(1, &IB_handle);
f->glDeleteBuffers(1, &IB_Regular);
//for(int i = 0; i < Vertices.length(); i++){
// qDebug()<<"V:"<<i<<Vertices[i];
//}
}
QVector<unsigned int> Indices2;
void Mesh::SubdivEntry::addRegular(QVector<unsigned int>& Indices){
//TODO fixme
for(int i = 0; i < Indices.length(); i+=3){
// qDebug()<<"T:"<<Indices[i]<<Indices[i+1]<<Indices[i+2];
Indices2.push_back(0);//0
Indices2.push_back(0);//1
Indices2.push_back(0);//2
Indices2.push_back(Indices[i]);//3
Indices2.push_back(0);//4
Indices2.push_back(0);//5
Indices2.push_back(Indices[i+1]);//6
Indices2.push_back(Indices[i+2]);//7
Indices2.push_back(0);//8
Indices2.push_back(0);//9
Indices2.push_back(0);//10
Indices2.push_back(0);//11
indicesRegular.push_back(0);//0
indicesRegular.push_back(0);//1
indicesRegular.push_back(0);//2
indicesRegular.push_back(Indices[i]);//3
indicesRegular.push_back(0);//4
indicesRegular.push_back(0);//5
indicesRegular.push_back(Indices[i+1]);//6
indicesRegular.push_back(Indices[i+2]);//7
indicesRegular.push_back(0);//8
indicesRegular.push_back(0);//9
indicesRegular.push_back(0);//10
indicesRegular.push_back(0);//11
}
numIndex = Indices2.size();
f->glGenBuffers(1, &IB_handle);
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IB_handle);
f->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * numIndex, &Indices2[0], GL_STATIC_DRAW);
f->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indicesRegular.size(), &indicesRegular[0], GL_STATIC_DRAW);
}
void Mesh::SubdivEntry::init(QOpenGLFunctions_4_3_Core *f,QVector<Vertex>& Vertices,
QVector<unsigned int>& Indices){
f->glGenBuffers(1, &VB_handle);
f->glBindBuffer(GL_ARRAY_BUFFER, VB_handle);
f->glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * Vertices.size(), &Vertices[0], GL_STATIC_DRAW);
this->init(f,VB_handle,Vertices,Indices);
}
void Mesh::SubdivEntry::init(QOpenGLFunctions_4_3_Core *f,GLuint VB_handle, QVector<Vertex>& Vertices,
QVector<unsigned int>& Indices){
this->f = f;
this->VB_handle = VB_handle;
indices = Indices;
vertices = Vertices;
indices = Indices;
f->glGenBuffers(1, &IB_handle);
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IB_handle);
f->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * Indices.size(), &Indices[0], GL_STATIC_DRAW);
}
Mesh::MeshEntry::MeshEntry()
{
materialIndex = 0xFFFFFFFF;
double amax = std::numeric_limits<float>::max();
min = QVector3D(amax,amax,amax);
max = QVector3D(-amax,-amax,-amax);
}
void Mesh::MeshEntry::init(QOpenGLFunctions_4_3_Core *f,QVector<Vertex>& Vertices,
QVector<unsigned int>& Indices){
this->f = f;
buffers.resize(1);
buffers[0].init(f,Vertices,Indices);
//calc AABB
for (int i = 0; i < Vertices.size(); ++i) {
......@@ -73,24 +102,13 @@ void Mesh::MeshEntry::init(QOpenGLFunctions_4_3_Core *f,QVector<Vertex>& Vertice
}
void Mesh::MeshEntry::update(GLuint VB, QVector<Vertex>& Vertices, QVector<unsigned int>& Indices){
numIndex = Indices.size();
indices = Indices;
vertices = Vertices;
f->glDeleteBuffers(1, &IB_handle);
f->glGenBuffers(1, &IB_handle);
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IB_handle);
f->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * numIndex, &Indices[0], GL_STATIC_DRAW);
f->glDeleteBuffers(1, &VB_handle);
VB_handle = VB;
buffers.resize(buffers.size()+1);
buffers[buffers.size()-1].init(f,VB,Vertices,Indices);
}
Mesh::MeshEntry::~MeshEntry()
{
f->glDeleteBuffers(1, &VB_handle);
f->glDeleteBuffers(1, &IB_handle);
//moved to subdiventry
}
Mesh::MaterialInfo::MaterialInfo()
......@@ -276,13 +294,6 @@ Mesh::MeshEntry *Mesh::getMeshEntry(int index){
return &entries[index];
}
QVector<unsigned int> Mesh::MeshEntry::getIndexBuffer(){
return indices;
}
QVector<Vertex> Mesh::MeshEntry::getVertexBuffer(){
return vertices;
}
void Mesh::initNode(const aiScene *scene, aiNode *node, Node &newNode,QString debugoffset){
newNode.name = node->mName.length != 0 ? node->mName.C_Str() : "";
......@@ -392,7 +403,7 @@ void Mesh::initMeshEntry(int index, aiMesh * entry){
}
void Mesh::render(QOpenGLShaderProgram *shader, QMatrix4x4 V,QMatrix4x4 P, int subdivision){
void Mesh::render(QOpenGLShaderProgram *shader, QMatrix4x4 V,QMatrix4x4 P, int subdivision, bool regular){
if(!loaded)
return;
if(f == NULL){
......@@ -404,7 +415,7 @@ void Mesh::render(QOpenGLShaderProgram *shader, QMatrix4x4 V,QMatrix4x4 P, int s
f->glEnableVertexAttribArray(normalIndex);
f->glEnableVertexAttribArray(uvIndex);
renderNode(shader,rootNode,V*screenTransform,P,QMatrix4x4(),subdivision);
renderNode(shader,rootNode,V*screenTransform,P,QMatrix4x4(),subdivision, regular);
f->glDisableVertexAttribArray(positionIndex);
f->glDisableVertexAttribArray(normalIndex);
......@@ -414,7 +425,7 @@ void Mesh::render(QOpenGLShaderProgram *shader, QMatrix4x4 V,QMatrix4x4 P, int s
}
void Mesh::renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMatrix4x4 P,QMatrix4x4 M, int subdivision){
void Mesh::renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMatrix4x4 P,QMatrix4x4 M, int subdivision, bool regular){
M *= node.transformation;
QMatrix4x4 MV = V*M;
......@@ -426,15 +437,15 @@ void Mesh::renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMa
for (int i = 0 ; i < node.meshes.size() ; i++) {
int index = node.meshes[i];
//load Material
renderMesh(shader, index,subdivision);
renderMesh(shader, index,subdivision, regular);
}
for (int i = 0 ; i < node.children.size() ; i++) {
renderNode(shader,node.children[i],V,P,M, subdivision);
renderNode(shader,node.children[i],V,P,M, subdivision,regular);
}
}
void Mesh::renderMesh(QOpenGLShaderProgram *shader, int index, int subdivision)
void Mesh::renderMesh(QOpenGLShaderProgram *shader, int index, int subdivision, bool regular)
{
int MaterialIndex = entries[index].materialIndex;
if (MaterialIndex < materials.size()) {
......@@ -449,15 +460,33 @@ void Mesh::renderMesh(QOpenGLShaderProgram *shader, int index, int subdivision)
materials[MaterialIndex].texture.bind(f,GL_TEXTURE0);
}
if(entries[index].buffers.size()<= subdivision){
subdivision = entries[index].buffers.size()-1;
}
SubdivEntry *entry = &entries[index].buffers[subdivision];
// Draw Vertex Array
f->glBindBuffer(GL_ARRAY_BUFFER, entries[index].VB_handle);
f->glBindBuffer(GL_ARRAY_BUFFER, entry->VB_handle);
f->glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entries[index].IB_handle);
// qDebug()<<"Render"<<subdivision<<entry->indices;
if(regular){
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entry->IB_Regular);
f->glPatchParameteri(GL_PATCH_VERTICES, 12);
f->glDrawElements(GL_PATCHES, entry->indicesRegular.size(), GL_UNSIGNED_INT, 0);
} else{
f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, entry->IB_handle);
f->glPatchParameteri(GL_PATCH_VERTICES, 3);
f->glDrawElements(GL_PATCHES, entry->indices.size(), GL_UNSIGNED_INT, 0);
}
f->glPatchParameteri(GL_PATCH_VERTICES, 12);
f->glDrawElements(GL_PATCHES, entries[index].numIndex, GL_UNSIGNED_INT, 0);
}
void Mesh::findObjectDimension(Node node, QMatrix4x4 transform, QVector3D &min, QVector3D &max){
......
......@@ -51,16 +51,36 @@ public:
Mesh(QOpenGLFunctions_4_3_Core *f, Mesh *mesh, QVector<Vertex> &vertex_buffer, QVector<GLuint> &index_buffer);
~Mesh();
void render(QOpenGLShaderProgram *shader, QMatrix4x4 V,QMatrix4x4 P, int subdivision);
void render(QOpenGLShaderProgram *shader, QMatrix4x4 V,QMatrix4x4 P, int subdivision, bool regular);
const aiScene *scene;
bool debug = true;
struct SubdivEntry{
SubdivEntry();
~SubdivEntry();
GLuint VB_handle;
GLuint IB_handle;
GLuint IB_Regular;
QVector<Vertex> vertices;
QVector<unsigned int> indices;
QVector<unsigned int> indicesRegular;
QOpenGLFunctions_4_3_Core *f;
void init(QOpenGLFunctions_4_3_Core *f,QVector<Vertex>& Vertices,
QVector<unsigned int>& Indices);
void init(QOpenGLFunctions_4_3_Core *f,GLuint VB_handle,QVector<Vertex>& Vertices,
QVector<unsigned int>& Indices);
void addRegular(QVector<unsigned int>& Indices);
};
struct MeshEntry{
MeshEntry();
~MeshEntry();
QVector<unsigned int> getIndexBuffer();
QVector<Vertex> getVertexBuffer();
void init(QOpenGLFunctions_4_3_Core *f,QVector<Vertex>& Vertices,
QVector<unsigned int>& Indices);
......@@ -68,13 +88,10 @@ public:
void update(GLuint VB_handle,QVector<Vertex>& Vertices, QVector<unsigned int>& Indices);
QString name;
GLuint VB_handle;
GLuint IB_handle;
QVector<unsigned int> indices;
QVector<Vertex> vertices;
QVector<SubdivEntry> buffers;
int numIndex;
int materialIndex;
QOpenGLFunctions_4_3_Core *f;
......@@ -127,8 +144,8 @@ private:
void initNode(const aiScene *scene, aiNode *node, Node &newNode, QString debugoffset);
void renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMatrix4x4 P,QMatrix4x4 M, int subdivision);
void renderMesh(QOpenGLShaderProgram *shader, int index, int subdivision);
void renderNode(QOpenGLShaderProgram *shader, Node &node, QMatrix4x4 V,QMatrix4x4 P,QMatrix4x4 M, int subdivision, bool regular);
void renderMesh(QOpenGLShaderProgram *shader, int index, int subdivision, bool regular);
void findObjectDimension(Node node, QMatrix4x4 transform, QVector3D &min, QVector3D &max);
......
......@@ -7,5 +7,7 @@
<file>subdivide.vert</file>
<file>subdivision-edge.compute</file>
<file>subdivision-vertex.compute</file>
<file>subdivideRegular.tcs</file>
<file>subdivideRegular.tes</file>
</qresource>
</RCC>
#version 430
layout(vertices = 12) out;
layout(vertices = 3) out;
in vec3 vPosition[];
out vec3 tcPosition[];
......
......@@ -4,8 +4,6 @@ layout(triangles, equal_spacing, cw) in;
in vec3 tcPosition[];
out vec3 teCamPosition;
out vec3 tePatchDistance;
uniform mat4x4 MV;
......@@ -15,26 +13,19 @@ uniform mat4x4 MVP;
void main()
{
vec3 p0 = tcPosition[0];
vec3 p1 = tcPosition[1];
vec3 p2 = tcPosition[2];
vec3 p3 = tcPosition[3];
vec3 p4 = tcPosition[4];
vec3 p5 = tcPosition[5];
vec3 p6 = tcPosition[6];
vec3 p7 = tcPosition[7];
vec3 p8 = tcPosition[8];
vec3 p9 = tcPosition[9];
vec3 p10 = tcPosition[10];
vec3 p11 = tcPosition[11];
tePatchDistance = gl_TessCoord.xyz;
vec3 d0 = gl_TessCoord.x * p3;
vec3 d1 = gl_TessCoord.y * p6;
vec3 d2 = gl_TessCoord.z * p7;
vec3 d0 = gl_TessCoord.x * p0;
vec3 d1 = gl_TessCoord.y * p1;
vec3 d2 = gl_TessCoord.z * p2;
vec4 pos = vec4((d0 + d1 + d2),1);
tePatchDistance = gl_TessCoord.xyz;
teCamPosition = vec4(MV*pos).xyz;
gl_Position = MVP * pos;
......
#version 430
layout(vertices = 12) out;
in vec3 vPosition[];
out vec3 tcPosition[];
void main()
{
tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
float tesselation = 1.0;
gl_TessLevelOuter[0] = tesselation;
gl_TessLevelOuter[1] = tesselation;
gl_TessLevelOuter[2] = tesselation;
gl_TessLevelInner[0] = tesselation;
}
#version 430
layout(triangles, equal_spacing, cw) in;
in vec3 tcPosition[];
out vec3 teCamPosition;
out vec3 tePatchDistance;
uniform mat4x4 MV;
uniform mat4x4 MVP;
void main()
{
vec3 p0 = tcPosition[0];
vec3 p1 = tcPosition[1];
vec3 p2 = tcPosition[2];
vec3 p3 = tcPosition[3];
vec3 p4 = tcPosition[4];
vec3 p5 = tcPosition[5];
vec3 p6 = tcPosition[6];
vec3 p7 = tcPosition[7];
vec3 p8 = tcPosition[8];
vec3 p9 = tcPosition[9];
vec3 p10 = tcPosition[10];
vec3 p11 = tcPosition[11];
vec3 d0 = gl_TessCoord.x * p3;
vec3 d1 = gl_TessCoord.y * p6;
vec3 d2 = gl_TessCoord.z * p7;
vec4 pos = vec4((d0 + d1 + d2),1);
tePatchDistance = gl_TessCoord.xyz;
teCamPosition = vec4(MV*pos).xyz;
gl_Position = MVP * pos;
}
......@@ -44,21 +44,30 @@ QOpenGLShaderProgram *Subdivision::initComputeShaderProgram(QString &source){
return shader;
}
Mesh *Subdivision::subdivide(Mesh *mesh) {
void Subdivision::subdivide(Mesh *mesh, int level) {
// For now we only look at the first mesh entry
Mesh::Node root = mesh->getRootNode();
int first_mesh_index = -1;
if (!root.getFirstMeshIndex(first_mesh_index)) {
qCritical()<<"No mesh found, aborting subdivision";
return NULL;
return;
}
Mesh::MeshEntry *current_mesh = mesh->getMeshEntry(first_mesh_index);
Input input;
input.vb_handle = current_mesh->VB_handle;
input.vertex_buffer = current_mesh->getVertexBuffer();
input.index_buffer = current_mesh->getIndexBuffer();
int currentMax = current_mesh->buffers.size()-1;
qDebug()<<"Subdiv Level"<<level<<"Requested. Current Max:"<<currentMax;
if(level <= currentMax)
return;
Mesh::SubdivEntry* entry = &current_mesh->buffers[currentMax];
input.vb_handle = entry->VB_handle;
input.vertex_buffer = entry->vertices;
input.index_buffer = entry->indices;
Tables tables = precomputeTables(input);
Result result = runShader(input, tables);
......
......@@ -13,7 +13,7 @@ public:
~Subdivision();
void init();
Mesh *subdivide(Mesh *mesh);
void subdivide(Mesh *mesh, int level);
void setDebugOutbut(bool debug);
private:
......
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