diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index e12aa09..f506146 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -105,6 +105,7 @@ + diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters index ac95887..a2b13fe 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters @@ -92,6 +92,9 @@ Resource Files\Shaders + + Resource Files\Shaders + diff --git a/ArchitectureColoredPainting/MainWindow.qrc b/ArchitectureColoredPainting/MainWindow.qrc index c7f85b4..fc1c47d 100644 --- a/ArchitectureColoredPainting/MainWindow.qrc +++ b/ArchitectureColoredPainting/MainWindow.qrc @@ -9,5 +9,6 @@ container.jpg Shaders/painting.frag Shaders/painting.vert + Shaders/painting.comp diff --git a/ArchitectureColoredPainting/Model.cpp b/ArchitectureColoredPainting/Model.cpp index 0b920de..c1d2930 100644 --- a/ArchitectureColoredPainting/Model.cpp +++ b/ArchitectureColoredPainting/Model.cpp @@ -6,6 +6,7 @@ #include #include "PaintingMesh.h" #include +#include "BvhTree.h" Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram) : context(context) @@ -139,39 +140,61 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod } - GLuint bvhChildren[] = {7/*rootBVH长度*/,0/*与显存对齐*/, + GLuint bvhChildren[] = { 7/*rootBVH长度*/,0/*与显存对齐*/, //root - 1,2, + 1,2, 3,4, 5,6, - 7,0, 7,30./360* 65536 + 1*65536 /*右儿子用来表示旋转角度和层数*/, 8,0, 7,0, + 7,0, 7,30. / 360 * 65536 + 1 * 65536 /*右儿子用来表示旋转角度和层数*/, 8,0, 7,0, //elememt0 1,2, - 5+28/*contour索引,由于contour不定长,这里需要给到contour在elementIndex中位置*/,5+12/*style索引,在elementData中位置*/, 3,4, - 5+36,5+12, 5+32,5+12, + 5 + 28/*contour索引,由于contour不定长,这里需要给到contour在elementIndex中位置*/,5 + 12/*style索引,在elementData中位置*/, 3,4, + 5 + 36,5 + 12, 5 + 32,5 + 12, //elememt1 - 1+0/*line索引,element中第几条*/,1 + 25 + 1 + 0/*line索引,element中第几条*/,1 + 25 }; - QVector4D bvhBound[] = { + QVector4D bvhBound[] = { //root QVector4D(-1,-1,1,1), - QVector4D(-0.9,-0.9,-0.1,0.9), QVector4D(0.1, -0.9,0.9,0.9), + QVector4D(-0.9,-0.9,-0.1,0.9), QVector4D(0.1, -0.9,0.9,0.9), QVector4D(-0.8,-0.8,-0.2,-0.1), QVector4D(-0.7,0.2,-0.2,0.7), QVector4D(0.2,-0.8,0.8,-0.1), QVector4D(0.2,0.1,0.8,0.8), //elememt0 QVector4D(-1,-1,1,1), QVector4D(-1,-0.5,1,1), QVector4D(-1,-1,1,0.5), QVector4D(-1,-1,1,-0.5), QVector4D(-1,-0.5,1,0.5), - //elememt1 - QVector4D(-1,0,1,1), + //elememt1 + QVector4D(-1,0,1,1), }; + + BvhTree bvhTree; + std::vector initBound; + for (int i = 0; i < 2000; i++) + { + float x = (float)rand() / RAND_MAX * 2 - 1; + float y = (float)rand() / RAND_MAX * 2 - 1; + float z = 0.1+x;//(float)rand() / RAND_MAX * (0.1) + x; + float w = 0.1+y;//(float)rand() / RAND_MAX * (0.1) + y; + initBound.push_back(QVector4D(x,y,z,w)); + } + /* initBound.push_back(QVector4D(-0.8, -0.8, -0.7, -0.7)); + initBound.push_back(QVector4D(-0.8, 0.7, -0.7, 0.8)); + initBound.push_back(QVector4D(0.7, -0.8, 0.8, -0.7)); + initBound.push_back(QVector4D(0.7, 0.7, 0.8, 0.8));*/ + bvhTree.buildBvhTree(initBound.data(), initBound.size()); + std::vector children; + std::vector bounds; + bvhTree.getBvhArray(children, bounds); + qDebug() << children; + qDebug() << bounds; + 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->glBufferData(GL_SHADER_STORAGE_BUFFER, children.size()*sizeof(GLuint), children.data(), 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->glBufferData(GL_SHADER_STORAGE_BUFFER, bounds.size()*sizeof(QVector4D), bounds.data(), GL_DYNAMIC_DRAW); glFunc->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); GLuint elementOffset[] = { @@ -222,7 +245,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod -1,0.5, -1,-0.5, 0,1, 0,-1, 1,0.5, 1,-0.5, //fillStyle //fill - 0, + 0, //fillType 0, //单色 //fillColorMetallicRoughness diff --git a/ArchitectureColoredPainting/RendererWidget.cpp b/ArchitectureColoredPainting/RendererWidget.cpp index 9789cdd..4f0fcc6 100644 --- a/ArchitectureColoredPainting/RendererWidget.cpp +++ b/ArchitectureColoredPainting/RendererWidget.cpp @@ -64,6 +64,12 @@ void RendererWidget::initializeGL() if (!paintingProgramPtr->link()) qDebug() << "ERROR:" << paintingProgramPtr->log(); + paintingCompProgramPtr = new QOpenGLShaderProgram; + if (!paintingCompProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp")) + qDebug() << "ERROR:" << paintingCompProgramPtr->log(); + if (!paintingCompProgramPtr->link()) + qDebug() << "ERROR:" << paintingCompProgramPtr->log(); + finalProgramPtr = new QOpenGLShaderProgram; if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert")) qDebug() << "ERROR:" << finalProgramPtr->log(); @@ -72,11 +78,13 @@ void RendererWidget::initializeGL() if (!finalProgramPtr->link()) qDebug() << "ERROR:" << finalProgramPtr->log(); + finalProgramPtr->bind(); finalProgramPtr->setUniformValue("gBaseColor", 0); finalProgramPtr->setUniformValue("gNormal", 1); finalProgramPtr->setUniformValue("gPosition", 2); finalProgramPtr->setUniformValue("gMetallicRoughness", 3); + finalProgramPtr->setUniformValue("gPainting", 4); finalProgramPtr->release(); model = new Model("Models/Sponza/Sponza.gltf", context(), modelProgramPtr, paintingProgramPtr); @@ -126,11 +134,19 @@ void RendererWidget::paintGL() paintingProgramPtr->setUniformValue("projection", projection); paintingProgramPtr->setUniformValue("view", view); paintingProgramPtr->release(); - + model->draw(); fboPtr->release(); } + paintingCompProgramPtr->bind(); + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, gbuffers[4]); + glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); + glBindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16); + glBindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); + //QOpenGLFramebufferObject::blitFramebuffer(nullptr, QRect(0, 0, 2*width(), 2*height()), fboPtr, QRect(0, 0, 1156, 756)); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -142,7 +158,7 @@ void RendererWidget::paintGL() finalProgramPtr->setUniformValueArray("lightPositions", lightPositions, 4); finalProgramPtr->setUniformValueArray("lightColors", lightColors, 4); - QVector gbuffers = fboPtr->textures(); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gbuffers[0]); glActiveTexture(GL_TEXTURE1); @@ -151,6 +167,8 @@ void RendererWidget::paintGL() glBindTexture(GL_TEXTURE_2D, gbuffers[2]); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, gbuffers[3]); + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, gbuffers[4]); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); finalProgramPtr->release(); } @@ -165,12 +183,18 @@ void RendererWidget::resizeGL(int width, int height) if (fboPtr != nullptr) delete fboPtr; fboPtr = new QOpenGLFramebufferObject(frameWidth, frameHeight, QOpenGLFramebufferObject::Depth, GL_TEXTURE_2D); - fboPtr->bind(); - fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F); - fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F); - fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG); - GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; - glDrawBuffers(4, attachments); + if (fboPtr->bind()) + { + fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F); + fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGB16F); + fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RG16); + fboPtr->addColorAttachment(frameWidth, frameHeight, GL_RGBA32F); + GLenum attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4 }; + glDrawBuffers(5, attachments); + gbuffers = fboPtr->textures(); + + fboPtr->release(); + } std::cout << "\033[?25l"; @@ -183,7 +207,7 @@ void RendererWidget::timerEvent(QTimerEvent* event) lastFrame = currentFrame; - static float accTime = 0,frameCnt = 0; + static float accTime = 0, frameCnt = 0; accTime += deltaTime; frameCnt++; if (accTime > 1.) @@ -193,7 +217,7 @@ void RendererWidget::timerEvent(QTimerEvent* event) accTime = 0; frameCnt = 0; } - + if (hasFocus()) { @@ -241,9 +265,9 @@ void RendererWidget::keyReleaseEvent(QKeyEvent* event) QOpenGLWidget::keyReleaseEvent(event); } -void RendererWidget::wheelEvent(QWheelEvent* event) +void RendererWidget::wheelEvent(QWheelEvent* event) { - camera.ProcessMouseScroll(event->delta()/15.); + camera.ProcessMouseScroll(event->delta() / 15.); } void RendererWidget::focusInEvent(QFocusEvent* event) diff --git a/ArchitectureColoredPainting/RendererWidget.h b/ArchitectureColoredPainting/RendererWidget.h index 68bb2d0..7a07611 100644 --- a/ArchitectureColoredPainting/RendererWidget.h +++ b/ArchitectureColoredPainting/RendererWidget.h @@ -36,8 +36,10 @@ private: float deltaTime; QOpenGLShaderProgram* modelProgramPtr = nullptr; QOpenGLShaderProgram* paintingProgramPtr = nullptr; + QOpenGLShaderProgram* paintingCompProgramPtr = nullptr; QOpenGLShaderProgram* finalProgramPtr = nullptr; QOpenGLFramebufferObject* fboPtr = nullptr; + QVector gbuffers; QOpenGLBuffer quadVBO; QOpenGLVertexArrayObject quadVAO; Model* model; diff --git a/ArchitectureColoredPainting/Shaders/final.frag b/ArchitectureColoredPainting/Shaders/final.frag index 1616f9b..2d28b67 100644 --- a/ArchitectureColoredPainting/Shaders/final.frag +++ b/ArchitectureColoredPainting/Shaders/final.frag @@ -8,7 +8,7 @@ uniform sampler2D gBaseColor; uniform sampler2D gNormal; uniform sampler2D gPosition; uniform sampler2D gMetallicRoughness; - +uniform sampler2D gPainting; // lights uniform vec3 lightPositions[4]; uniform vec3 lightColors[4]; @@ -108,4 +108,6 @@ void main() color = pow(color, vec3(1.0/2.2)); FragColor = vec4(color, 1.0); + //FragColor = vec4(texture(gPainting, TexCoords).rgb, 1.0); + } \ No newline at end of file diff --git a/ArchitectureColoredPainting/Shaders/model.frag b/ArchitectureColoredPainting/Shaders/model.frag index bbd4400..bb6a470 100644 --- a/ArchitectureColoredPainting/Shaders/model.frag +++ b/ArchitectureColoredPainting/Shaders/model.frag @@ -9,6 +9,7 @@ layout (location = 0) out vec4 gBaseColor; layout (location = 1) out vec3 gNormal; layout (location = 2) out vec3 gPosition; layout (location = 3) out vec2 gMetallicRoughness; +layout(location = 4) out vec3 gPainting; in vec2 TexCoords; in vec3 WorldPos; @@ -42,6 +43,6 @@ void main() gPosition = WorldPos; gNormal = getNormalFromMap(); gMetallicRoughness = texture(texture_metallic_roughness, TexCoords).bg; - + gPainting = vec3(0); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/Shaders/painting.comp b/ArchitectureColoredPainting/Shaders/painting.comp new file mode 100644 index 0000000..ac913ac --- /dev/null +++ b/ArchitectureColoredPainting/Shaders/painting.comp @@ -0,0 +1,149 @@ +#version 450 core + +layout (local_size_x = 8, local_size_y = 8) in; + +layout(rgba8, binding = 0) uniform image2D gBaseColor; +layout(rg16, binding = 1) uniform image2D gMetallicRoughness; +layout(rgba32f, binding = 2) uniform image2D gPainting; + + + +layout(std430, binding = 1) buffer bvhBuffer +{ + uint bvhLength; + uvec2 bvhChildren[]; +}; +layout(std430, binding = 2) buffer bvhBoundBuffer +{ + vec4 bvhBound[]; +}; +layout(std430, binding = 3) buffer elementOffsetBuffer +{ + /********************** + ** @x elementBvhRoot + ** @y elementBvhLength + ** @z pointsOffset + ** @w linesOffset + **********************/ + uvec4 elementOffset[]; +}; +layout(std430, binding = 4) buffer elementIndexBuffer +{ + uint elementIndexs[]; //线和面 +}; +layout(std430, binding = 5) buffer elementDataBuffer +{ + float elementData[]; //点和Style +}; + +const float PI = 3.14159265358979; + + +const uint STACK_SIZE = 30; + +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, elementStack; + + + +void main() +{ + ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy); + if(imageLoad(gPainting, pixelLocation).r==0) + return; + + imageStore(gMetallicRoughness, pixelLocation, vec4(0 /*金属度*/, 0.8 /*粗糙度*/, 0, 1)); + + vec2 uv = imageLoad(gPainting, pixelLocation).gb; + + vec3 debugBVH = vec3(0); + bool debugHit = false; + stack.top = 0; + uint index = 0, visitTime = 0; + while (index < bvhLength || !stack.empty()) + { + while (index < bvhLength) + { + visitTime++; + vec4 bound = bvhBound[index]; + uint leftChild = bvhChildren[index].x; + if (leftChild >= bvhLength) + { + uint zIndex = bvhChildren[index].y / 65535; + float angle = (bvhChildren[index].y / 65535. - zIndex) * 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)))) + { + if (zIndex == 1) + debugBVH = vec3(1, 0, 1); + uint elementIndex = leftChild - bvhLength; + debugBVH.bg += 0.5 * (localUV + vec2(1)); + // debugBVH = vec3(0); + + //debugHit = drawElement(leftChild - bvhLength, localUV, debugBVH) == vec3(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; + } + } + + if (debugHit) + imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1)); + else + imageStore(gBaseColor, pixelLocation, vec4(debugBVH,1)); + +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/Shaders/painting.frag b/ArchitectureColoredPainting/Shaders/painting.frag index 08dfe0b..2c66ebf 100644 --- a/ArchitectureColoredPainting/Shaders/painting.frag +++ b/ArchitectureColoredPainting/Shaders/painting.frag @@ -4,6 +4,7 @@ layout(location = 0) out vec4 gBaseColor; layout(location = 1) out vec3 gNormal; layout(location = 2) out vec3 gPosition; layout(location = 3) out vec2 gMetallicRoughness; +layout(location = 4) out vec3 gPainting; in vec2 TexCoords; in vec3 WorldPos; @@ -493,7 +494,7 @@ void mainImage(out vec3 fragColor, in vec2 fragCoord) } /////////////////////////////// -const uint STACK_SIZE = 10; +const uint STACK_SIZE = 40; struct Stack { @@ -629,19 +630,30 @@ vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0)) void main() { + + gBaseColor = vec4( vec3(1,0,0),1 ); + // mainImage(gBaseColor, vec2(1.,1.)-TexCoords); + gPosition = WorldPos; + gNormal = normalize(Normal); + // gMetallicRoughness = vec2(1, 46./255); + gMetallicRoughness = vec2(0 /*金属度*/, 0.8 /*粗糙度*/); + gPainting = vec3(1, vec2(1., 1.) - TexCoords * 2); + return; // gBaseColor = vec4(TexCoords,1,1); // gBaseColor = vec4(240./255, 220./255,157./255,1); // gBaseColor = vec4(bvh[0].bound==vec4(0,0,1,1)); - vec2 uv = vec2(1., 1.) - TexCoords * 2; + //vec2 uv = vec2(1., 1.) - TexCoords * 2; + vec2 uv = vec2(0., -0.7) ; vec3 debugBVH = vec3(0); bool debugHit = false; stack.top = 0; - uint index = 0; + uint index = 0, visitTime = 0; while (index < bvhLength || !stack.empty()) { while (index < bvhLength) { + visitTime++; vec4 bound = bvhBound[index]; uint leftChild = bvhChildren[index].x; if (leftChild >= bvhLength) @@ -658,10 +670,10 @@ void main() if (zIndex == 1) debugBVH = vec3(1, 0, 1); uint elementIndex = leftChild - bvhLength; - // debugBVH.bg += 0.5 * (localUV + vec2(1)); + debugBVH.bg += 0.5 * (localUV + vec2(1)); // debugBVH = vec3(0); - debugHit = drawElement(leftChild - bvhLength, localUV, debugBVH) == vec3(1); + //debugHit = drawElement(leftChild - bvhLength, localUV, debugBVH) == vec3(1); // mainImage(debugBVH,localUV); @@ -710,14 +722,10 @@ void main() index = bvhChildren[index].y; } } + if (debugHit) gBaseColor = vec4(vec3(1, 1, 0), 1); else - gBaseColor = vec4(debugBVH, 1); - // gBaseColor = vec4( vec3(elementData[6]<0.5),1 ); - // mainImage(gBaseColor, vec2(1.,1.)-TexCoords); - gPosition = WorldPos; - gNormal = normalize(Normal); - // gMetallicRoughness = vec2(1, 46./255); - gMetallicRoughness = vec2(0 /*金属度*/, 0.8 /*粗糙度*/); + gBaseColor = vec4(vec3(int(visitTime)-9), 1); + } \ No newline at end of file