From 5fd42b6636fdb56c59893eeac9cfc36ad0d9bf30 Mon Sep 17 00:00:00 2001 From: wuyize Date: Sun, 31 Jul 2022 22:02:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E7=A1=AE=E5=AE=9ABVH?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArchitectureColoredPainting/Model.cpp | 35 ++- ArchitectureColoredPainting/Model.h | 1 + ArchitectureColoredPainting/PaintingMesh.cpp | 6 + ArchitectureColoredPainting/PaintingMesh.h | 46 ++-- .../Shaders/painting.frag | 199 +++++++++--------- ArchitectureColoredPainting/main.cpp | 4 + 6 files changed, 173 insertions(+), 118 deletions(-) diff --git a/ArchitectureColoredPainting/Model.cpp b/ArchitectureColoredPainting/Model.cpp index 4e74aa9..e333fbb 100644 --- a/ArchitectureColoredPainting/Model.cpp +++ b/ArchitectureColoredPainting/Model.cpp @@ -5,9 +5,11 @@ #include #include #include "PaintingMesh.h" +#include Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram) : context(context) + , glFunc(context->versionFunctions()) , shaderProgram(shaderProgram) , directory(path) { @@ -28,6 +30,7 @@ Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shader Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram) : context(context) + , glFunc(context->versionFunctions()) , shaderProgram(shaderProgram) , paintingProgram(paintingProgram) , directory(path) @@ -100,11 +103,11 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod aiString str; material->GetTexture(aiTextureType_BASE_COLOR, 0, &str); - if (paintingProgram != nullptr && std::strcmp(str.C_Str(), "17876391417123941155.jpg")==0) + if (paintingProgram != nullptr && std::strcmp(str.C_Str(), "17876391417123941155.jpg") == 0) { qDebug() << str.C_Str(); // 初始化网格 - PaintingMesh* m_mesh = new PaintingMesh(QOpenGLContext::currentContext()->versionFunctions(), paintingProgram, model); + PaintingMesh* m_mesh = new PaintingMesh(glFunc, paintingProgram, model); // 遍历网格的每个顶点 for (unsigned int i = 0; i < mesh->mNumVertices; i++) { @@ -136,13 +139,39 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod } } + + GLuint bvhChildren[] = {7/*数组长度*/,0/*与显存对齐*/, + 1,2, + 3,4, 5,6, + 7,0, 7,45./360* 4294967296 , 7,0, 7,0}; + QVector4D bvhBound[] = { QVector4D(-1,-1,1,1) , + QVector4D(0.1,0.1,0.4,0.9), QVector4D(0.6,0.1,0.9,0.9), + QVector4D(0.2,0.2,0.3,0.4), QVector4D(0.2,0.5,0.3,0.8), QVector4D(0.7,0.2,0.8,0.4), QVector4D(0.7,0.3,0.8,0.8) }; + glFunc->glGenBuffers(1, &m_mesh->bvhSSBO); + glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->bvhSSBO); + glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER,sizeof(bvhChildren), bvhChildren, GL_DYNAMIC_DRAW); + glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + glFunc->glGenBuffers(1, &m_mesh->bvhBoundSSBO); + glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->bvhBoundSSBO); + glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(bvhBound), bvhBound, GL_DYNAMIC_DRAW); + glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + + GLfloat elementData[] = { 1,2,3,4,5 }; + glFunc->glGenBuffers(1, &m_mesh->elementSSBO); + glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_mesh->elementSSBO); + glFunc->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(elementData), elementData, GL_DYNAMIC_DRAW); + glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + m_mesh->setupMesh(); return m_mesh; } else { // 初始化网格 - Mesh* m_mesh = new Mesh(QOpenGLContext::currentContext()->versionFunctions(), shaderProgram, model); + Mesh* m_mesh = new Mesh(glFunc, shaderProgram, model); // 遍历网格的每个顶点 for (unsigned int i = 0; i < mesh->mNumVertices; i++) { diff --git a/ArchitectureColoredPainting/Model.h b/ArchitectureColoredPainting/Model.h index c414a06..6914019 100644 --- a/ArchitectureColoredPainting/Model.h +++ b/ArchitectureColoredPainting/Model.h @@ -16,6 +16,7 @@ private: ~Model(); QOpenGLContext* context; //opengl函数入口 + QOpenGLFunctions_4_5_Compatibility* glFunc; QOpenGLShaderProgram* shaderProgram = nullptr; QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序 /* 模型数据 */ diff --git a/ArchitectureColoredPainting/PaintingMesh.cpp b/ArchitectureColoredPainting/PaintingMesh.cpp index 763c928..7ab1d7d 100644 --- a/ArchitectureColoredPainting/PaintingMesh.cpp +++ b/ArchitectureColoredPainting/PaintingMesh.cpp @@ -14,7 +14,13 @@ void PaintingMesh::draw() shaderProgram->bind(); QOpenGLVertexArrayObject::Binder bind(&VAO); shaderProgram->setUniformValue("model", model); + + glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, bvhSSBO); + glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, bvhBoundSSBO); + glFunc->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, elementSSBO); + glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); + glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); shaderProgram->release(); } void PaintingMesh::setupMesh() diff --git a/ArchitectureColoredPainting/PaintingMesh.h b/ArchitectureColoredPainting/PaintingMesh.h index c2a44cd..8d6fd40 100644 --- a/ArchitectureColoredPainting/PaintingMesh.h +++ b/ArchitectureColoredPainting/PaintingMesh.h @@ -17,31 +17,41 @@ struct PaintingVertex { - QVector3D Position; - QVector3D Normal; - QVector2D TexCoords; - QVector3D Tangent; - QVector3D Bitangent; + QVector3D Position; + QVector3D Normal; + QVector2D TexCoords; + QVector3D Tangent; + QVector3D Bitangent; +}; + +struct BvhNode { + GLuint leftChild; + GLuint rightChild; + GLuint padding[2];//与显存对齐 + QVector4D bound; + BvhNode(GLuint leftChild, GLuint rightChild, QVector4D bound) :leftChild(leftChild), rightChild(rightChild), bound(bound) {} }; class PaintingMesh : public Drawable { public: - /* 网格数据 */ - QVector vertices; //顶点数据 - QVector indices; //索引数组 - QMatrix4x4 model; //模型矩阵 - QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口 - QOpenGLShaderProgram* shaderProgram; //着色器程序 + /* 网格数据 */ + QVector vertices; //顶点数据 + QVector indices; //索引数组 + QMatrix4x4 model; //模型矩阵 + QOpenGLFunctions_4_5_Compatibility* glFunc; //opengl函数入口 + QOpenGLShaderProgram* shaderProgram; //着色器程序 - /* 函数 */ - PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model); - void draw() override; - void setupMesh(); + GLuint bvhSSBO, bvhBoundSSBO, elementSSBO; + + /* 函数 */ + PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, aiMatrix4x4 model); + void draw() override; + void setupMesh(); private: - /* 渲染数据 */ - QOpenGLVertexArrayObject VAO; - QOpenGLBuffer VBO, EBO; + /* 渲染数据 */ + QOpenGLVertexArrayObject VAO; + QOpenGLBuffer VBO, EBO; }; diff --git a/ArchitectureColoredPainting/Shaders/painting.frag b/ArchitectureColoredPainting/Shaders/painting.frag index ff6fbce..81285ae 100644 --- a/ArchitectureColoredPainting/Shaders/painting.frag +++ b/ArchitectureColoredPainting/Shaders/painting.frag @@ -9,7 +9,26 @@ in vec2 TexCoords; in vec3 WorldPos; in vec3 Normal; +layout(std430, binding = 1) buffer bvhBuffer +{ + uint bvhLength; + uvec2 bvhChildren[]; +}; +layout(std430, binding = 2) buffer bvhBoundBuffer +{ + vec4 bvhBound[]; +}; +layout(std430, binding = 3) buffer elementIndexBuffer +{ + int elementCount; + int elementIndex[]; +}; +layout(std430, binding = 4) buffer elementBuffer +{ + float elementData[]; +}; +const float PI = 3.14159265359; //////////////////////////////////////////////////////////////////////////// @@ -139,6 +158,9 @@ float bezier_sd(vec2 uv, vec2 p0, vec2 p1, vec2 p2){ } + + + float render_serif(vec2 uv){ uv.y-=.5; @@ -153,100 +175,7 @@ float render_serif(vec2 uv){ float d1 = 1e38; vec2 p0,p1,p2; - /* - if(all(lessThan(abs(uv-vec2(-1.29705090246,0.49556210191)),vec2(0.203622751405,0.194877434267)+vec2(border)))){ - d1=1e38; - d1=abs_min(d1,line_dist(uv,vec2(-1.50067365386,0.690439536177),vec2(-1.50067365386,0.662506649919))); - d1=abs_min(d1,line_dist(uv,vec2(-1.34847869375,0.690439536177),vec2(-1.50067365386,0.690439536177))); - d1=abs_min(d1,line_dist(uv,vec2(-1.34847869375,0.662506649919),vec2(-1.34847869375,0.690439536177))); - d1=abs_min(d1,line_dist(uv,vec2(-1.50067365386,0.662506649919),vec2(-1.34847869375,0.662506649919))); - - if(d1<=0.){ - return d1; - } - else{ - poly_d=min(d1,poly_d); - } - - d1=1e38; - d1=abs_min(d1,line_dist(uv,vec2(-1.50067365386,0.328356479174),vec2(-1.50067365386,0.300684667642))); - d1=abs_min(d1,line_dist(uv,vec2(-1.50067365386,0.300684667642),vec2(-1.34847869375,0.300684667642))); - d1=abs_min(d1,line_dist(uv,vec2(-1.34847869375,0.300684667642),vec2(-1.34847869375,0.328356479174))); - d1=abs_min(d1,line_dist(uv,vec2(-1.34847869375,0.328356479174),vec2(-1.50067365386,0.328356479174))); - - if(d1<=0.){ - return d1; - } - else{ - poly_d=min(d1,poly_d); - } - - d1=1e38; - d1=abs_min(d1,line_dist(uv,vec2(-1.24562309793,0.328356479174),vec2(-1.24562309793,0.300684667642))); - d1=abs_min(d1,line_dist(uv,vec2(-1.09342815105,0.328356479174),vec2(-1.24562309793,0.328356479174))); - d1=abs_min(d1,line_dist(uv,vec2(-1.09342815105,0.300684667642),vec2(-1.09342815105,0.328356479174))); - d1=abs_min(d1,line_dist(uv,vec2(-1.24562309793,0.300684667642),vec2(-1.09342815105,0.300684667642))); - - if(d1<=0.){ - return d1; - } - else{ - poly_d=min(d1,poly_d); - } - - d1=1e38; - d1=abs_min(d1,line_dist(uv,vec2(-1.24562309793,0.690439536177),vec2(-1.24562309793,0.662506649919))); - d1=abs_min(d1,line_dist(uv,vec2(-1.09342815105,0.690439536177),vec2(-1.24562309793,0.690439536177))); - d1=abs_min(d1,line_dist(uv,vec2(-1.09342815105,0.662506649919),vec2(-1.09342815105,0.690439536177))); - d1=abs_min(d1,line_dist(uv,vec2(-1.24562309793,0.662506649919),vec2(-1.09342815105,0.662506649919))); - - if(d1<=0.){ - return d1; - } - else{ - poly_d=min(d1,poly_d); - } - - d1=1e38; - d1=abs_min(d1,line_dist(uv,vec2(-1.45107323965,0.300684667642),vec2(-1.39807911127,0.300684667642))); - d1=abs_min(d1,line_dist(uv,vec2(-1.39807911127,0.300684667642),vec2(-1.39807911127,0.690439536177))); - d1=abs_min(d1,line_dist(uv,vec2(-1.39807911127,0.690439536177),vec2(-1.45107323965,0.690439536177))); - d1=abs_min(d1,line_dist(uv,vec2(-1.45107323965,0.690439536177),vec2(-1.45107323965,0.300684667642))); - - if(d1<=0.){ - return d1; - } - else{ - poly_d=min(d1,poly_d); - } - - d1=1e38; - d1=abs_min(d1,line_dist(uv,vec2(-1.45107323965,0.527802348895),vec2(-1.45107323965,0.495953672637))); - d1=abs_min(d1,line_dist(uv,vec2(-1.45107323965,0.495953672637),vec2(-1.14302855203,0.495953672637))); - d1=abs_min(d1,line_dist(uv,vec2(-1.14302855203,0.495953672637),vec2(-1.14302855203,0.527802348895))); - d1=abs_min(d1,line_dist(uv,vec2(-1.14302855203,0.527802348895),vec2(-1.45107323965,0.527802348895))); - - if(d1<=0.){ - return d1; - } - else{ - poly_d=min(d1,poly_d); - } - - d1=1e38; - d1=abs_min(d1,line_dist(uv,vec2(-1.19602268041,0.300684667642),vec2(-1.14302855203,0.300684667642))); - d1=abs_min(d1,line_dist(uv,vec2(-1.14302855203,0.300684667642),vec2(-1.14302855203,0.690439536177))); - d1=abs_min(d1,line_dist(uv,vec2(-1.14302855203,0.690439536177),vec2(-1.19602268041,0.690439536177))); - d1=abs_min(d1,line_dist(uv,vec2(-1.19602268041,0.690439536177),vec2(-1.19602268041,0.300684667642))); - - if(d1<=0.){ - return d1; - } - else{ - poly_d=min(d1,poly_d); - } - } - */ + if(all(lessThan(abs(uv-vec2(-0.905207605282,0.43943531671)),vec2(0.131571631799,0.146321237064)+vec2(border)))){ p0=vec2(-0.980652472562,0.432256320122);p1=vec2(-0.980652472562,0.376129514241);p2=vec2(-0.959444621888,0.347459653556); if(tri_test(uv, p0, p1, p2, true)){ @@ -466,7 +395,7 @@ float render_serif(vec2 uv){ void mainImage( out vec4 fragColor, in vec2 fragCoord ){ - border = 0.0; + border = 0.01; vec2 uv = fragCoord.xy; @@ -478,14 +407,90 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord ){ d=min(d,render_serif(uv)); - fragColor=vec4(smoothstep(0., 0.0, d)); + //fragColor=vec4(smoothstep(0., border, d)); + fragColor=vec4(vec3(d*10),1); } +const uint STACK_SIZE = 10; +struct Stack { + uint top; + uint data[STACK_SIZE]; + + bool empty() { + return top==0; + } + bool full() { + return top==STACK_SIZE; + } + bool getTop(out uint x) { + if(empty()) + return false; + x = data[top-1]; + return true; + } + bool pop() { + if(empty()) + return false; + top--; + return true; + } + bool push(in uint x) { + if(full()) + return false; + data[top]=x; + top++; + return true; + } +} stack; + + + + void main() { //gBaseColor = vec4(TexCoords,1,1); //gBaseColor = vec4(240./255, 220./255,157./255,1); - mainImage(gBaseColor, vec2(1.,1.)-TexCoords); + //gBaseColor = vec4(bvh[0].bound==vec4(0,0,1,1)); + + vec2 uv = vec2(1.,1.)-TexCoords*2; + vec3 debugBVH=vec3(0); + stack.top=0; + uint index=0; + while(index=bvhLength) + { + float angle = float(bvhChildren[index].y)/4294967296.*2*PI; + mat2 rotation = {{cos(angle),-sin(angle)},{sin(angle),cos(angle)}}; + vec2 localUV = uv-(bound.xy+bound.zw)/2; + localUV=rotation*localUV; + localUV/=(bound.zw-bound.xy)/2; + if(all(lessThan(vec2(-1), localUV))&&all(lessThan( localUV, vec2(1)))) + debugBVH.bg+=0.5*(localUV+vec2(1)); + index=bvhLength; + } + else if(all(lessThan(bound.xy, uv))&&all(lessThan( uv, bound.zw))) + { + debugBVH.r+=0.2; + stack.push(index); + index = leftChild; + } + else + index=bvhLength; + } + if (!stack.empty()) { + stack.getTop(index); + stack.pop(); + index = bvhChildren[index].y; + } + } + + gBaseColor = vec4( debugBVH,1 ); + //mainImage(gBaseColor, vec2(1.,1.)-TexCoords); gPosition = WorldPos; gNormal = normalize(Normal); //gMetallicRoughness = vec2(1, 46./255); diff --git a/ArchitectureColoredPainting/main.cpp b/ArchitectureColoredPainting/main.cpp index 2336890..2186f50 100644 --- a/ArchitectureColoredPainting/main.cpp +++ b/ArchitectureColoredPainting/main.cpp @@ -1,6 +1,10 @@ #include "MainWindow.h" #include +extern "C" { + _declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; +} + int main(int argc, char *argv[]) { QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);