From 57b537b66b03163420e1b240df62d537a9cc4dda Mon Sep 17 00:00:00 2001 From: wuyize Date: Tue, 21 Feb 2023 20:13:07 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=94=B9=E7=94=A8?= =?UTF-8?q?=E8=99=9A=E6=8B=9F=E7=BA=B9=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/Shaders/model.frag | 16 +- .../res/Shaders/painting.comp | 14 +- .../res/Shaders/painting.frag | 638 +----------------- .../src/Renderer/IblUtils.cpp | 9 +- .../src/Renderer/Mesh.h | 6 +- .../src/Renderer/Model.cpp | 90 ++- .../src/Renderer/Model.h | 31 +- .../src/Renderer/Painting/BaseStyle.h | 3 +- .../src/Renderer/Painting/Element.h | 2 +- .../src/Renderer/Painting/ElementStyle.h | 1 - .../Renderer/Painting/MaterialStyleStroke.h | 1 + .../src/Renderer/Painting/Painting.h | 1 - .../src/Renderer/PaintingMesh.cpp | 7 + .../src/Renderer/Preview/ElementRenderer.cpp | 16 +- .../src/Renderer/RendererGLWidget.cpp | 6 +- .../src/Renderer/RendererGLWidget.h | 3 + .../src/Renderer/VirtualTextureManager.cpp | 95 ++- .../src/Renderer/VirtualTextureManager.h | 15 +- ArchitectureColoredPainting/src/main.cpp | 59 +- 19 files changed, 276 insertions(+), 737 deletions(-) diff --git a/ArchitectureColoredPainting/res/Shaders/model.frag b/ArchitectureColoredPainting/res/Shaders/model.frag index e2cd1ec..62b7b3b 100644 --- a/ArchitectureColoredPainting/res/Shaders/model.frag +++ b/ArchitectureColoredPainting/res/Shaders/model.frag @@ -36,12 +36,22 @@ vec3 getNormalFromMap() void main() { - gBaseColor = texture(texture_basecolor, TexCoords); + if(textureSize(texture_basecolor,0)!=vec2(0)) + gBaseColor = texture(texture_basecolor, TexCoords); + else + gBaseColor = vec4(1); if(gBaseColor.a<0.4) discard; gPosition = WorldPos; - gNormal = getNormalFromMap(); - gMetallicRoughness = texture(texture_metallic_roughness, TexCoords).bg; + if(textureSize(texture_normal,0)!=vec2(0)) + gNormal = getNormalFromMap(); + else + gNormal = Normal; + if(textureSize(texture_metallic_roughness,0)!=vec2(0)) + gMetallicRoughness = texture(texture_metallic_roughness, TexCoords).bg; + else + gMetallicRoughness = vec2(0,1); + gPaintingIndex = 0; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index ce54b95..91d39d0 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -2,10 +2,10 @@ layout (local_size_x = 8, local_size_y = 8) in; +uniform ivec2 pixelOffset; + layout(rgba8, binding = 0) uniform image2D gBaseColor; layout(rg8, binding = 1) uniform image2D gMetallicRoughness; -layout(r16ui, binding = 2) uniform uimage2D gPaintingIndex; -layout(rg32f, binding = 3) uniform image2D gPaintingTexCoord; layout(std430, binding = 1) buffer paintingOffsetBuffer { @@ -1184,11 +1184,13 @@ void main() { //ivec2 pixelLocation = ivec2(((gl_LocalInvocationID.xy)*imageSize(gPaintingIndex)/gl_WorkGroupSize.xy + gl_WorkGroupID.xy).xy); ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy); - uint paintingIndex = imageLoad(gPaintingIndex, pixelLocation).r; - if(paintingIndex==0) - return; - vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg; + vec2 uv = (pixelOffset + pixelLocation + vec2(0.5)) / imageSize(gBaseColor); + imageStore(gBaseColor, ivec2( pixelOffset + pixelLocation), vec4(uv,1,1)); + imageStore(gMetallicRoughness, ivec2( pixelOffset + pixelLocation), vec4(uv,1,1)); + return; + uv= uv*2-vec2(1); + //vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg; vec3 debugBVH = vec3(0); //bool debugHit = false; diff --git a/ArchitectureColoredPainting/res/Shaders/painting.frag b/ArchitectureColoredPainting/res/Shaders/painting.frag index 0c2f200..677deb2 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.frag +++ b/ArchitectureColoredPainting/res/Shaders/painting.frag @@ -1,5 +1,8 @@ #version 450 core +uniform sampler2D texture_basecolor; +uniform sampler2D texture_metallic_roughness; + layout(location = 0) out vec4 gBaseColor; layout(location = 1) out vec3 gNormal; layout(location = 2) out vec3 gPosition; @@ -13,635 +16,18 @@ in vec3 Normal; void main() { - - gBaseColor = vec4( vec3(1),1 ); + gBaseColor = texture(texture_basecolor, TexCoords); + if(gBaseColor.a<0.4) + discard; + //gBaseColor = vec4( vec3(1),1 ); // mainImage(gBaseColor, vec2(1.,1.)-TexCoords); gPosition = WorldPos; gNormal = normalize(Normal); - // gMetallicRoughness = vec2(1, 46./255); - gMetallicRoughness = vec2(0); - gPaintingIndex = 1; + //gMetallicRoughness = vec2(0,1); + gMetallicRoughness = texture(texture_metallic_roughness, TexCoords).rg; + //gPaintingIndex = 1; + gPaintingIndex = 0; gPaintingTexCoord = vec2(1., 1.) - TexCoords * 2; return; -} - - -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; - -//////////////////////////////////////////////////////////////////////////// - -float border = 0; - -mat2 inv(mat2 m) -{ - return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) / (m[0][0] * m[1][1] - m[1][0] * m[0][1]); -} - -float abs_min(float a, float b) -{ - if (abs(a) < abs(b)) - { - return a; - } - else - { - return b; - } -} - -int i_mod(int a, int m) -{ - return int(mod(float(a), float(m))); -} - -float line_dist(vec2 uv, const vec2 p0, vec2 p1) -{ - vec2 tang = p1 - p0; - vec2 nor = normalize(vec2(tang.y, -tang.x)); - - if (dot(tang, uv) < dot(tang, p0)) - { - return distance(p0, uv); - } - else if (dot(tang, uv) > dot(tang, p1)) - { - return distance(p1, uv); - } - else - { - return dot(nor, uv) - dot(nor, p0); - } -} - -bool int_test(vec2 uv, vec2 last_point, vec2 p0, vec2 p1) -{ - last_point -= uv; - p0 -= uv; - p1 -= uv; - - bool ret; - if (p0.y == 0.) - { - ret = (p0.x >= 0. && p1.y * last_point.y < 0.); - } - else if (p1.y == 0.) - { - ret = false; - } - else if (p0.y * p1.y < 0.) - { - if (p0.x >= 0. && p1.x >= 0.) - { - ret = true; - } - else if (p0.x < 0. && p1.x < 0.) - { - ret = false; - } - else - { - vec2 nor; - if (p0.y > p1.y) - { - nor = p0 - p1; - } - else - { - nor = p1 - p0; - } - - nor = vec2(nor.y, -nor.x); - if (dot(nor, p0) < 0.) - { - ret = false; - } - else - { - ret = true; - } - } - } - else - { - ret = false; - } - - return ret; -} - -bool tri_test(vec2 uv, vec2 p0, vec2 p1, vec2 p2, bool inside) -{ - vec2 nor1 = normalize(p0 - p1); - nor1 = vec2(nor1.y, -nor1.x); - vec2 nor2 = normalize(p1 - p2); - nor2 = vec2(nor2.y, -nor2.x); - vec2 tan3 = normalize(p2 - p0); - vec2 nor3 = vec2(tan3.y, -tan3.x); - - if (inside) - { - if (dot(tan3, p0) >= dot(tan3, uv) || dot(tan3, p2) <= dot(tan3, uv)) - { - return false; - } - - float brd = max(dot(nor3, nor1), dot(nor3, nor2)) * border; - return (dot(uv, nor1) >= dot(p0, nor1) && dot(uv, nor2) >= dot(p1, nor2) && - dot(uv, nor3) >= dot(p2, nor3) + brd) || - (dot(uv, nor1) <= dot(p0, nor1) && dot(uv, nor2) <= dot(p1, nor2) && - dot(uv, nor3) <= dot(p2, nor3) - brd); - } - else - { - float brd1 = dot(nor1, tan3) * border; - float brd2 = dot(nor2, tan3) * border; - - if (dot(tan3, p0) >= dot(tan3, uv) - brd1 || dot(tan3, p2) <= dot(tan3, uv) - brd2) - { - return false; - } - return (dot(uv, nor1) >= dot(p0, nor1) - border && dot(uv, nor2) >= dot(p1, nor2) - border && - dot(uv, nor3) >= dot(p2, nor3)) || - (dot(uv, nor1) <= dot(p0, nor1) + border && dot(uv, nor2) <= dot(p1, nor2) + border && - dot(uv, nor3) <= dot(p2, nor3)); - } -} - -float bezier_sd(vec2 uv, vec2 p0, vec2 p1, vec2 p2) -{ - - const mat2 trf1 = mat2(-1, 2, 1, 2); - mat2 trf2 = inv(mat2(p0 - p1, p2 - p1)); - mat2 trf = trf1 * trf2; - - uv -= p1; - vec2 xy = trf * uv; - xy.y -= 1.; - - vec2 gradient; - gradient.x = 2. * trf[0][0] * (trf[0][0] * uv.x + trf[1][0] * uv.y) - trf[0][1]; - gradient.y = 2. * trf[1][0] * (trf[0][0] * uv.x + trf[1][0] * uv.y) - trf[1][1]; - - return (xy.x * xy.x - xy.y) / length(gradient); -} - -//////////////////////////////// - -// Modified from http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c -// Credits to Doublefresh for hinting there -int solve_quadric(vec2 coeffs, inout vec2 roots) -{ - - // normal form: x^2 + px + q = 0 - float p = coeffs[1] / 2.; - float q = coeffs[0]; - - float D = p * p - q; - - if (D < 0.) - { - return 0; - } - else - { - roots[0] = -sqrt(D) - p; - roots[1] = sqrt(D) - p; - - return 2; - } -} - -// From Trisomie21 -// But instead of his cancellation fix i'm using a newton iteration -int solve_cubic(vec3 coeffs, inout vec3 r) -{ - - float a = coeffs[2]; - float b = coeffs[1]; - float c = coeffs[0]; - - float p = b - a * a / 3.0; - float q = a * (2.0 * a * a - 9.0 * b) / 27.0 + c; - float p3 = p * p * p; - float d = q * q + 4.0 * p3 / 27.0; - float offset = -a / 3.0; - if (d >= 0.0) - { // Single solution - float z = sqrt(d); - float u = (-q + z) / 2.0; - float v = (-q - z) / 2.0; - u = sign(u) * pow(abs(u), 1.0 / 3.0); - v = sign(v) * pow(abs(v), 1.0 / 3.0); - r[0] = offset + u + v; - - // Single newton iteration to account for cancellation - float f = ((r[0] + a) * r[0] + b) * r[0] + c; - float f1 = (3. * r[0] + 2. * a) * r[0] + b; - - r[0] -= f / f1; - - return 1; - } - float u = sqrt(-p / 3.0); - float v = acos(-sqrt(-27.0 / p3) * q / 2.0) / 3.0; - float m = cos(v), n = sin(v) * 1.732050808; - - // Single newton iteration to account for cancellation - //(once for every root) - r[0] = offset + u * (m + m); - r[1] = offset - u * (n + m); - r[2] = offset + u * (n - m); - - vec3 f = ((r + a) * r + b) * r + c; - vec3 f1 = (3. * r + 2. * a) * r + b; - - r -= f / f1; - - return 3; -} - -float cubic_bezier_normal_iteration(float t, vec2 a0, vec2 a1, vec2 a2, vec2 a3) -{ - // horner's method - vec2 a_2 = a2 + t * a3; - vec2 a_1 = a1 + t * a_2; - vec2 b_2 = a_2 + t * a3; - - vec2 uv_to_p = a0 + t * a_1; - vec2 tang = a_1 + t * b_2; - - float l_tang = dot(tang, tang); - return t - dot(tang, uv_to_p) / l_tang; -} - -float cubic_bezier_dis_approx_sq(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3) -{ - vec2 a3 = (-p0 + 3. * p1 - 3. * p2 + p3); - vec2 a2 = (3. * p0 - 6. * p1 + 3. * p2); - vec2 a1 = (-3. * p0 + 3. * p1); - vec2 a0 = p0 - uv; - - float d0 = 1e38; - - float t; - vec3 params = vec3(0, .5, 1); - - for (int i = 0; i < 3; i++) - { - t = params[i]; - for (int j = 0; j < 3; j++) - { - t = cubic_bezier_normal_iteration(t, a0, a1, a2, a3); - } - t = clamp(t, 0., 1.); - vec2 uv_to_p = ((a3 * t + a2) * t + a1) * t + a0; - d0 = min(d0, dot(uv_to_p, uv_to_p)); - } - - return d0; -} - -// segment_dis_sq by iq -float length2(vec2 v) -{ - return dot(v, v); -} - -float segment_dis_sq(vec2 p, vec2 a, vec2 b) -{ - vec2 pa = p - a, ba = b - a; - float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); - return length2(pa - ba * h); -} - -int segment_int_test(vec2 uv, vec2 p0, vec2 p1) -{ - p0 -= uv; - p1 -= uv; - - int ret; - - if (p0.y * p1.y < 0.) - { - vec2 nor = p0 - p1; - nor = vec2(nor.y, -nor.x); - - float sgn; - - if (p0.y > p1.y) - { - sgn = 1.; - } - else - { - sgn = -1.; - } - - if (dot(nor, p0) * sgn < 0.) - { - ret = 0; - } - else - { - ret = 1; - } - } - else - { - ret = 0; - } - - return ret; -} - -int cubic_bezier_int_test(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3) -{ - - float cu = (-p0.y + 3. * p1.y - 3. * p2.y + p3.y); - float qu = (3. * p0.y - 6. * p1.y + 3. * p2.y); - float li = (-3. * p0.y + 3. * p1.y); - float co = p0.y - uv.y; - - vec3 roots = vec3(1e38); - int n_roots; - - int n_ints = 0; - - if (uv.x < min(min(p0.x, p1.x), min(p2.x, p3.x))) - { - if (uv.y >= min(p0.y, p3.y) && uv.y <= max(p0.y, p3.y)) - { - n_ints = 1; - } - } - else - { - - if (abs(cu) < .0001) - { - n_roots = solve_quadric(vec2(co / qu, li / qu), roots.xy); - } - else - { - n_roots = solve_cubic(vec3(co / cu, li / cu, qu / cu), roots); - } - - for (int i = 0; i < n_roots; i++) - { - if (roots[i] >= 0. && roots[i] <= 1.) - { - float x_pos = -p0.x + 3. * p1.x - 3. * p2.x + p3.x; - x_pos = x_pos * roots[i] + 3. * p0.x - 6. * p1.x + 3. * p2.x; - x_pos = x_pos * roots[i] + -3. * p0.x + 3. * p1.x; - x_pos = x_pos * roots[i] + p0.x; - - if (x_pos > uv.x) - { - n_ints++; - } - } - } - } - - return n_ints; -} - -float path2_dis_sq(vec2 uv) -{ - float dis_sq = 1e38; - - int num_its = 0; - - vec2[45] p = vec2[](vec2(-0.124919, 0.0496896), vec2(-0.127105, 0.0391554), vec2(-0.127105, 0.0405467), - vec2(-0.127105, 0.0463107), vec2(-0.131876, 0.0506833), vec2(-0.143205, 0.0506833), - vec2(-0.177789, 0.0506833), vec2(-0.194286, 0.00795032), vec2(-0.194286, -0.018882), - vec2(-0.194286, -0.0425342), vec2(-0.181366, -0.0508821), vec2(-0.167851, -0.0508821), - vec2(-0.153739, -0.0508821), vec2(-0.144397, -0.0417392), vec2(-0.138236, -0.0325963), - vec2(-0.137043, -0.0445217), vec2(-0.129888, -0.0508821), vec2(-0.118758, -0.0508821), - vec2(-0.108025, -0.0508821), vec2(-0.0901364, -0.0465093), vec2(-0.0788071, -0.0141118), - vec2(-0.087155, -0.0141118), vec2(-0.0901364, -0.0240497), vec2(-0.0955028, -0.0327951), - vec2(-0.103254, -0.0327951), vec2(-0.10882, -0.0327951), vec2(-0.111403, -0.0298137), - vec2(-0.111403, -0.0242485), vec2(-0.111403, -0.0224597), vec2(-0.111205, -0.0204721), - vec2(-0.110609, -0.0178882), vec2(-0.0962985, 0.0496896), vec2(-0.137043, 0.0383603), - vec2(-0.130683, 0.0383603), vec2(-0.128894, 0.0331926), vec2(-0.128894, 0.0308075), - vec2(-0.138435, -0.0141118), vec2(-0.14082, -0.0256398), vec2(-0.149168, -0.0316026), - vec2(-0.154931, -0.0316026), vec2(-0.158509, -0.0316026), vec2(-0.164869, -0.0314042), - vec2(-0.164869, -0.0160994), vec2(-0.164869, 0.00258385), vec2(-0.153938, 0.0383603)); - - ivec2[6] seg = ivec2[](ivec2(0, 1), ivec2(1, 2), ivec2(20, 21), ivec2(30, 31), ivec2(31, 0), ivec2(35, 36)); - - ivec4[13] c_bez = - ivec4[](ivec4(2, 3, 4, 5), ivec4(5, 6, 7, 8), ivec4(8, 9, 10, 11), ivec4(11, 12, 13, 14), ivec4(14, 15, 16, 17), - ivec4(17, 18, 19, 20), ivec4(21, 22, 23, 24), ivec4(24, 25, 26, 27), ivec4(27, 28, 29, 30), - ivec4(32, 33, 34, 35), ivec4(36, 37, 38, 39), ivec4(39, 40, 41, 42), ivec4(42, 43, 44, 32)); - - if (all(lessThan(uv, vec2(-0.0788071, 0.0506833) + border)) && - all(greaterThan(uv, vec2(-0.194286, -0.0508821) - border))) - { - for (int i = 0; i < 6; i++) - { - dis_sq = min(dis_sq, segment_dis_sq(uv, p[seg[i][0]], p[seg[i][1]])); - num_its += segment_int_test(uv, p[seg[i][0]], p[seg[i][1]]); - } - for (int i = 0; i < 13; i++) - { - dis_sq = min( - dis_sq, cubic_bezier_dis_approx_sq(uv, p[c_bez[i][0]], p[c_bez[i][1]], p[c_bez[i][2]], p[c_bez[i][3]])); - num_its += cubic_bezier_int_test(uv, p[c_bez[i][0]], p[c_bez[i][1]], p[c_bez[i][2]], p[c_bez[i][3]]); - } - } - - float sgn = 1.; - - if (num_its % 2 == 1) - { - sgn = -1.; - } - - return sgn * dis_sq; -} - -void mainImage(out vec3 fragColor, in vec2 fragCoord) -{ - border = 0.01; - vec2 uv = fragCoord; - uv -= .5; - - float dis_sq = 1e38; - - if (all(lessThan(uv, vec2(0.4, 0.0993791) + border)) && all(greaterThan(uv, vec2(-0.4, -0.0993791) - border))) - { - dis_sq = min(dis_sq, path2_dis_sq(uv)); - } - - float dis = sign(dis_sq) * sqrt(abs(dis_sq)); - - fragColor = vec3(smoothstep(0., border, dis)); - if (dis > 0 && dis <= border) - fragColor = vec3(1, 1, 0); -} -/////////////////////////////// - -const uint STACK_SIZE = 40; - -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; - -vec3 drawElement(uint elementIndex, vec2 localUV, inout vec3 debugBVH = vec3(0)) -{ - vec4 elementColor = vec4(0); - - uvec4 currentOffset = elementOffset[elementIndex]; - uint elementBvhRoot = currentOffset.x; - uint elementBvhLength = currentOffset.y; - uint pointsOffset = currentOffset.z; - uint linesOffset = currentOffset.w; - - elementStack.top = 0; - uint elementBvhIndex = 0; - while (elementBvhIndex < elementBvhLength || !elementStack.empty()) - { - - while (elementBvhIndex < elementBvhLength) - { - vec4 bound = bvhBound[elementBvhRoot + elementBvhIndex]; - uint leftChild = bvhChildren[elementBvhRoot + elementBvhIndex].x; - - if (all(lessThan(bound.xy, localUV)) && all(lessThan(localUV, bound.zw))) - { - if (leftChild >= elementBvhLength) - { - debugBVH.g += 0.5; - - uint styleIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y - elementBvhLength; - // for(int i = 0; i<200;i++) - if (elementData[styleIndex] == 0.) //面 - { - - uint lineCount = elementIndexs[leftChild - elementBvhLength]; - uint num_its = 0; - - for (uint contourIterator = leftChild - elementBvhLength + 1; - contourIterator <= leftChild - elementBvhLength + lineCount; contourIterator++) - { - uint lineIndex = elementIndexs[contourIterator]; - uint p0Index = elementIndexs[linesOffset + 4 * lineIndex]; - uint p1Index = elementIndexs[linesOffset + 4 * lineIndex + 1]; - uint p2Index = elementIndexs[linesOffset + 4 * lineIndex + 2]; - uint p3Index = elementIndexs[linesOffset + 4 * lineIndex + 3]; - - vec2 p0 = vec2(elementData[pointsOffset + 2 * p0Index], - elementData[pointsOffset + 2 * p0Index + 1]); - vec2 p1 = vec2(elementData[pointsOffset + 2 * p1Index], - elementData[pointsOffset + 2 * p1Index + 1]); - vec2 p2 = vec2(elementData[pointsOffset + 2 * p2Index], - elementData[pointsOffset + 2 * p2Index + 1]); - vec2 p3 = vec2(elementData[pointsOffset + 2 * p3Index], - elementData[pointsOffset + 2 * p3Index + 1]); - - if (p0 == p1 && p2 == p3) - { - num_its += segment_int_test(localUV, p0, p3); - } - - else - num_its += cubic_bezier_int_test(localUV, p0, p1, p2, p3); - } - - if (num_its % 2 == 1) - { - elementColor = vec4(1); - //debugHit = true; - } - } - else if (elementData[styleIndex] == 1) //线 - { - } - - elementBvhIndex = elementBvhLength; - } - else - { - // debugBVH.b += 0.2; - elementStack.push(elementBvhIndex); - elementBvhIndex = leftChild; - } - } - else - elementBvhIndex = elementBvhLength; - } - if (!elementStack.empty()) - { - elementStack.getTop(elementBvhIndex); - elementStack.pop(); - elementBvhIndex = bvhChildren[elementBvhRoot + elementBvhIndex].y; - } - } - return elementColor.xyz; -} - - - +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/IblUtils.cpp b/ArchitectureColoredPainting/src/Renderer/IblUtils.cpp index f464c20..dd17d64 100644 --- a/ArchitectureColoredPainting/src/Renderer/IblUtils.cpp +++ b/ArchitectureColoredPainting/src/Renderer/IblUtils.cpp @@ -3,8 +3,11 @@ #include #include #include +#ifndef STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION #include +#endif + void Renderer::IblUtils::renderCube(QOpenGLFunctions_4_5_Core* glFunc) { @@ -262,7 +265,7 @@ GLuint Renderer::IblUtils::generateCubemap(QOpenGLFunctions_4_5_Core* glFunc, GL glFunc->glViewport(0, 0, cubemapSize, cubemapSize); glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); - + for (unsigned int i = 0; i < 6; ++i) { shader.setUniformValue("view", captureViews[i]); @@ -337,7 +340,7 @@ GLuint Renderer::IblUtils::generatePrefilterMap(QOpenGLFunctions_4_5_Core* glFun constexpr int prefilterMapSize = 128; // pbr: create a pre-filter cubemap, and re-scale capture FBO to pre-filter scale. - // -------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------- unsigned int prefilterMap; glFunc->glGenTextures(1, &prefilterMap); glFunc->glBindTexture(GL_TEXTURE_CUBE_MAP, prefilterMap); @@ -399,7 +402,7 @@ GLuint Renderer::IblUtils::gererateBrdfLut(QOpenGLFunctions_4_5_Core* glFunc) constexpr int lutSize = 512; // pbr: generate a 2D LUT from the BRDF equations used. - // ---------------------------------------------------- + // ---------------------------------------------------- unsigned int brdfLUTTexture; glFunc->glGenTextures(1, &brdfLUTTexture); diff --git a/ArchitectureColoredPainting/src/Renderer/Mesh.h b/ArchitectureColoredPainting/src/Renderer/Mesh.h index 8033441..fa98a33 100644 --- a/ArchitectureColoredPainting/src/Renderer/Mesh.h +++ b/ArchitectureColoredPainting/src/Renderer/Mesh.h @@ -41,9 +41,9 @@ namespace Renderer QVector vertices; QVector indices; //QVector textures; - GLuint textureBasecolor; - GLuint textureMetallicRoughness; - GLuint textureNormal; + GLuint textureBasecolor = 0; + GLuint textureMetallicRoughness = 0; + GLuint textureNormal = 0; QMatrix4x4 model; QOpenGLFunctions_4_5_Compatibility* glFunc; diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index 5b833b4..06dcb7b 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -14,56 +14,34 @@ using namespace Renderer; using std::vector; -Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram) - : context(context) - , glFunc(context->versionFunctions()) - , shaderProgram(shaderProgram) - , directory(path) -{ - Assimp::Importer importer; - const aiScene* scene = importer.ReadFile(directory.absolutePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs); - if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) - { - qDebug() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl; - return; - } - qDebug() << directory.absolutePath() << "Loaded Successfully"; - qDebug() << "NumMeshes: " << scene->mNumMeshes; - qDebug() << "NumMaterials: " << scene->mNumMaterials; - qDebug() << "NumTextures: " << scene->mNumTextures; - directory.cdUp(); - processNode(scene->mRootNode, scene); -} - -Model::Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, PaintingHelper* paintingHelper) +Model::Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, + QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, + PaintingHelper* paintingHelper, VirtualTextureManager* vtManager) : context(context) , glFunc(context->versionFunctions()) , shaderProgram(shaderProgram) , paintingProgram(paintingProgram) , shadowProgram(shadowProgram) , paintingHelper(paintingHelper) + , vtManager(vtManager) { - } Model::~Model() //销毁对象 { - for (auto& it : meshes) { - delete it; - } } void Model::draw() { //shaderProgram->bind(); - for (Drawable* mesh : meshes) { + for (auto& mesh : meshes) { mesh->draw(); } } void Model::drawShadow() { //shaderProgram->bind(); - for (Drawable* mesh : meshes) { + for (auto& mesh : meshes) { mesh->drawShadow(); } } @@ -74,11 +52,6 @@ void Model::destroy() delete this; } -Model* Model::createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram) -{ - return new Model(path, context, shaderProgram); -} - void Renderer::Model::loadModel(QString path) { directory = path; @@ -94,6 +67,12 @@ void Renderer::Model::loadModel(QString path) qDebug() << "NumMaterials: " << scene->mNumMaterials; qDebug() << "NumTextures: " << scene->mNumTextures; directory.cdUp(); + minX = std::numeric_limits::max(); + maxX = std::numeric_limits::min(); + minY = std::numeric_limits::max(); + maxY = std::numeric_limits::min(); + minZ = std::numeric_limits::max(); + maxZ = std::numeric_limits::min(); processNode(scene->mRootNode, scene); AABB.push_back(QVector3D(minX, minY, minZ)); AABB.push_back(QVector3D(minX, minY, maxZ)); @@ -111,8 +90,8 @@ void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4) // 处理节点所有的网格(如果有的话) for (unsigned int i = 0; i < node->mNumMeshes; i++) { - aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; - meshes.push_back(processMesh(mesh, scene, mat4)); + if (auto mesh = processMesh(scene->mMeshes[node->mMeshes[i]], scene, mat4)) + meshes.emplace_back(std::move(mesh)); } // 接下来对它的子节点重复这一过程 @@ -131,7 +110,7 @@ GLuint encodeZIndexAngle(GLuint zIndex, float angle) return GLuint(angle / 360 * 65536 + zIndex * 65536); } -Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model) +std::unique_ptr Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model) { aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; QMatrix4x4 modelQ((float*)&model); @@ -143,7 +122,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod { qDebug() << str.C_Str() << "Replaced"; // 初始化网格 - PaintingMesh* m_mesh = new PaintingMesh(glFunc, paintingProgram, shadowProgram, modelQ); + auto m_mesh = std::make_unique(glFunc, paintingProgram, shadowProgram, modelQ); // 遍历网格的每个顶点 for (unsigned int i = 0; i < mesh->mNumVertices; i++) { @@ -169,14 +148,15 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod } } - m_mesh->paintingIndex = loadPainting(std::string(str.C_Str())); + //m_mesh->paintingIndex = loadPainting(std::string(str.C_Str())); + std::tie(m_mesh->textureBasecolor, m_mesh->textureMetallicRoughness) = loadPainting(std::string(str.C_Str())); m_mesh->setupMesh(); return m_mesh; } else { // 初始化网格 - Mesh* m_mesh = new Mesh(glFunc, shaderProgram, shadowProgram, modelQ); + auto m_mesh = std::make_unique(glFunc, shaderProgram, shadowProgram, modelQ); // 遍历网格的每个顶点 for (unsigned int i = 0; i < mesh->mNumVertices; i++) { @@ -199,12 +179,21 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod m_mesh->indices.push_back(*indice); // 处理材质 - m_mesh->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR); - m_mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS); - m_mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS); + if (!(m_mesh->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR))) + qWarning() << "Basecolor Texture Loading Failed!"; + if (!(m_mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS))) + qWarning() << "MetallicRoughness Texture Loading Failed!"; + if (!(m_mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS))) + qWarning() << "Normal Texture Loading Failed!"; + + if (m_mesh->textureBasecolor && m_mesh->textureMetallicRoughness && m_mesh->textureNormal) + { + m_mesh->setupMesh(); + return m_mesh; + } + else + return nullptr; - m_mesh->setupMesh(); - return m_mesh; } } @@ -226,7 +215,7 @@ GLuint Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type) return 0; //qDebug() << "Loading" << path.c_str(); - auto [it, _] = texturesLoaded.emplace(std::piecewise_construct, std::make_tuple(path), std::make_tuple(QOpenGLTexture::Target2D)); + auto [it, _] = texturesLoaded.emplace(path, QOpenGLTexture::Target2D); auto& texture = it->second; texture.create(); texture.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat); @@ -236,7 +225,7 @@ GLuint Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type) return texture.textureId(); } -GLuint Renderer::Model::loadPainting(std::string path) +std::tuple Renderer::Model::loadPainting(std::string path) { auto iter = paintingLoaded.find(path); if (iter != paintingLoaded.end()) @@ -474,7 +463,10 @@ GLuint Renderer::Model::loadPainting(std::string path) // elementOffset, elementIndex, elementData); /*GLuint index = paintingHelper->addPainting(bvhChildren0, bvhBounds0, elementOffset0, elementIndex0, elementData0);*/ - GLuint index = paintingHelper->addPainting(painting); - paintingLoaded.insert({ path, index }); - return index; + //GLuint index = paintingHelper->addPainting(painting); + //paintingLoaded.insert({ path, index }); + + auto ids = vtManager->createVirtualTexture(painting); + paintingLoaded.emplace(path, ids); + return ids; } diff --git a/ArchitectureColoredPainting/src/Renderer/Model.h b/ArchitectureColoredPainting/src/Renderer/Model.h index ffff1f4..2993026 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.h +++ b/ArchitectureColoredPainting/src/Renderer/Model.h @@ -2,6 +2,7 @@ #include "Mesh.h" #include "Drawable.h" #include "Painting/PaintingHelper.h" +#include "VirtualTextureManager.h" #include #include @@ -15,43 +16,37 @@ namespace Renderer void draw(); void drawShadow(); void destroy(); - static Model* createModel(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram); void loadModel(QString path); - Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, PaintingHelper* paintingHelper); + Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, PaintingHelper* paintingHelper, VirtualTextureManager* vtManager); private: - Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram); - ~Model(); - QOpenGLContext* context; //opengl函数入口 - QOpenGLFunctions_4_5_Compatibility* glFunc; + QOpenGLContext* context; + QOpenGLFunctions_4_5_Compatibility* glFunc = nullptr; QOpenGLShaderProgram* shaderProgram = nullptr; QOpenGLShaderProgram* paintingProgram = nullptr; //彩绘着色器程序 QOpenGLShaderProgram* shadowProgram = nullptr; PaintingHelper* paintingHelper = nullptr; + VirtualTextureManager* vtManager = nullptr; /* 模型数据 */ - std::unordered_map paintingLoaded; + std::unordered_map> paintingLoaded; std::unordered_map texturesLoaded; - //std::vector textures_loaded; //纹理 - QVector meshes; //网格 - QDir directory; //模型所在路径 + std::vector> meshes; - float minX = std::numeric_limits::max(); - float maxX = std::numeric_limits::min(); - float minY = std::numeric_limits::max(); - float maxY = std::numeric_limits::min(); - float minZ = std::numeric_limits::max(); - float maxZ = std::numeric_limits::min(); + /// 模型所在路径 + QDir directory; + + float minX, maxX, minY, maxY, minZ, maxZ; //递归遍历结点 void processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4 = aiMatrix4x4()); //加载网格 - Drawable* processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model); + std::unique_ptr processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model); //加载材质纹理 GLuint loadMaterialTextures(aiMaterial* mat, aiTextureType type); - GLuint loadPainting(std::string path); + std::tuple loadPainting(std::string path); }; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/BaseStyle.h b/ArchitectureColoredPainting/src/Renderer/Painting/BaseStyle.h index e478faf..d32f4dc 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/BaseStyle.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/BaseStyle.h @@ -1,6 +1,7 @@ #pragma once -#include +#include #include +#include #include #include diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Element.h b/ArchitectureColoredPainting/src/Renderer/Painting/Element.h index bb869ff..58a3b25 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Element.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Element.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include "Line.h" #include "ElementStyle.h" diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/ElementStyle.h b/ArchitectureColoredPainting/src/Renderer/Painting/ElementStyle.h index 8b81e85..8b1e3e1 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/ElementStyle.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/ElementStyle.h @@ -1,6 +1,5 @@ #pragma once #include -#include #include "BaseStyle.h" namespace Renderer diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.h b/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.h index 120fa3d..e7008c5 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.h @@ -1,5 +1,6 @@ #pragma once #include "BaseStyle.h" +#include namespace Renderer { diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h index 496d879..a4ccedd 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h @@ -1,7 +1,6 @@ #pragma once #include #include -#include #include #include "Line.h" #include "BvhTree.h" diff --git a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp index 2bb7f4d..64cbd09 100644 --- a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp +++ b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp @@ -13,6 +13,13 @@ void PaintingMesh::draw() { if (shaderProgram->bind()) { + glFunc->glActiveTexture(GL_TEXTURE0); + glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor); + glFunc->glActiveTexture(GL_TEXTURE1); + glFunc->glBindTexture(GL_TEXTURE_2D, textureMetallicRoughness); + shaderProgram->setUniformValue("texture_basecolor", 0); + shaderProgram->setUniformValue("texture_metallic_roughness", 1); + QOpenGLVertexArrayObject::Binder bind(&VAO); shaderProgram->setUniformValue("model", model); EBO.bind(); diff --git a/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp b/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp index 4405bd7..d8a7a92 100644 --- a/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp @@ -37,15 +37,15 @@ std::vector generatePathBuffer(const QPainterPath& path) switch (element.type) { case QPainterPath::MoveToElement: - qDebug() << "MoveToElement"; - qDebug() << element; + //qDebug() << "MoveToElement"; + //qDebug() << element; pathBuffer.push_back(glm::vec2(std::numeric_limits::infinity())); pathBuffer.push_back(glm::vec2(element.x, element.y)); break; case QPainterPath::LineToElement: { - qDebug() << "LineToElement"; - qDebug() << element; + //qDebug() << "LineToElement"; + //qDebug() << element; glm::vec2 end = glm::vec2(element.x, element.y); glm::vec2 mid = (pathBuffer.back() + end) / 2.f; pathBuffer.push_back(mid); @@ -55,14 +55,14 @@ std::vector generatePathBuffer(const QPainterPath& path) } case QPainterPath::CurveToElement: { - qDebug() << "CurveToElement"; - qDebug() << element; + //qDebug() << "CurveToElement"; + //qDebug() << element; glm::vec2 p1 = glm::vec2(element.x, element.y); element = path.elementAt(++i); - qDebug() << element; + //qDebug() << element; glm::vec2 p2 = glm::vec2(element.x, element.y); element = path.elementAt(++i); - qDebug() << element; + //qDebug() << element; glm::vec2 p3 = glm::vec2(element.x, element.y); if (p3 != pathBuffer.back()) { diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index bc4c71b..8f68578 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -9,6 +9,7 @@ #include #include #include "IblUtils.h" +#include "VirtualTextureManager.h" using namespace Renderer; @@ -231,8 +232,9 @@ void RendererGLWidget::initializeGL() finalProgramPtr->setUniformValue("gBaseColor", 0); finalProgramPtr->release(); + vtManager = std::make_unique(gl.get()); paintingHelper = new PaintingHelper(glFunc); - model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper); + model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper, vtManager.get()); skyBoxProgramPtr->bind(); skyBoxProgramPtr->setUniformValue("environmentMap", 0); @@ -353,7 +355,7 @@ void RendererGLWidget::paintGL() gl->BindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI); gl->BindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F); - gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); + //gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); paintingCompProgramPtr->release(); gl->EndQuery(GL_TIME_ELAPSED); diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h index 66ec814..a068dff 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h @@ -15,6 +15,8 @@ struct GladGLContext; namespace Renderer { + class VirtualTextureManager; + class RendererGLWidget : public QOpenGLWidget { Q_OBJECT @@ -77,5 +79,6 @@ namespace Renderer QOpenGLVertexArrayObject quadVAO; Model* model = nullptr; PaintingHelper* paintingHelper; + std::unique_ptr vtManager; }; } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp index 4a1580d..4d6d2ef 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp @@ -1,7 +1,100 @@ -#include "VirtualTextureManager.h" #include +#include "VirtualTextureManager.h" +#include +#include +#include +#include +#define GLM_ENABLE_EXPERIMENTAL +#include + Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl) :gl(gl) { + GLint numPageSizes; + + // Figure out how many page sizes are available for a 2D texture + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes); + std::vector pageSizesX(numPageSizes); + std::vector pageSizesY(numPageSizes); + std::vector pageSizesZ(numPageSizes); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesX.data()); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesY.data()); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesZ.data()); + qDebug() << "RGBA8" << numPageSizes; + for (int i = 0; i < numPageSizes; i++) + qDebug() << pageSizesX[i] << pageSizesY[i] << pageSizesZ[i]; + + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes); + std::vector pageSizesRG8X(numPageSizes); + std::vector pageSizesRG8Y(numPageSizes); + std::vector pageSizesRG8Z(numPageSizes); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesRG8X.data()); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Y.data()); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Z.data()); + qDebug() << "RG8" << numPageSizes; + for (int i = 0; i < numPageSizes; i++) + qDebug() << pageSizesRG8X[i] << pageSizesRG8Y[i] << pageSizesRG8Z[i]; + + pageSize = std::max(pageSizesRG8X[0], pageSizesRG8Y[0]); + qDebug() << "pageSize:" << pageSize; + + + if (!program.addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp")) + qDebug() << "ERROR:" << program.log(); + if (!program.link()) + qDebug() << "ERROR:" << program.log(); + +} + +std::tuple Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) +{ + const GLsizei levels = static_cast(glm::log2(textureSize) + static_cast(1)); + + GLuint textures[2]; + gl->CreateTextures(GL_TEXTURE_2D, 2, textures); + GLuint& baseColor = textures[0]; + GLuint& metallicRoughness = textures[1]; + + gl->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE); + gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT); + gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT); + gl->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize)); + + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize)); + + for (std::size_t level = 0; level < 1; ++level) + { + GLsizei levelSize = (textureSize >> level); + for (GLsizei j = 0; j < levelSize / pageSize; ++j) + for (GLsizei i = 0; i < levelSize / pageSize; ++i) + { + gl->TexturePageCommitmentEXT(baseColor, static_cast(level), + static_cast(pageSize) * i, static_cast(pageSize) * j, 0, + static_cast(pageSize), static_cast(pageSize), 1, + GL_TRUE); + gl->TexturePageCommitmentEXT(metallicRoughness, static_cast(level), + static_cast(pageSize) * i, static_cast(pageSize) * j, 0, + static_cast(pageSize), static_cast(pageSize), 1, + GL_TRUE); + + program.bind(); + gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * i, static_cast(pageSize) * j); + gl->BindImageTexture(0, baseColor, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); + gl->BindImageTexture(1, metallicRoughness, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); + + gl->DispatchCompute(pageSize / 8, pageSize / 8, 1); + program.release(); + + } + } + + return { baseColor, metallicRoughness }; } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h index 81d4b31..947e4ac 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h @@ -1,17 +1,30 @@ #pragma once - +#include "Painting/Painting.h" +#include struct GladGLContext; namespace Renderer { + + class VirtualTextureManager { public: + static constexpr GLsizei textureSize = 16384; VirtualTextureManager(GladGLContext* gl); + /** + * @brief + * @param painting + * @return 0 baseColor + * @return 1 metallicRoughness + */ + std::tuple createVirtualTexture(Painting painting); private: GladGLContext* gl; + GLint pageSize; + QOpenGLShaderProgram program; }; } diff --git a/ArchitectureColoredPainting/src/main.cpp b/ArchitectureColoredPainting/src/main.cpp index ec0d673..0d8791b 100644 --- a/ArchitectureColoredPainting/src/main.cpp +++ b/ArchitectureColoredPainting/src/main.cpp @@ -2,26 +2,59 @@ #include #include #include +#include +#include +#include "consoleapi2.h" extern "C" { - _declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; + _declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; } FRAMELESSHELPER_USE_NAMESPACE +void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) +{ + switch (type) + { + case QtInfoMsg: + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY); + break; + case QtDebugMsg: + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + break; + case QtWarningMsg: + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); + break; + case QtCriticalMsg: + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE); + break; + case QtFatalMsg: + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED); + break; + + } + std::cout << std::format("{}({},{}) {}\n", + QString(context.file).splitRef("\\").back().toLocal8Bit().data(), + context.line, + QString(context.function).splitRef("(").first().split(" ").back().split(":").back().toLocal8Bit().data(), + msg.toStdString()); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); +} + int main(int argc, char* argv[]) { - //FramelessHelper::Widgets::initialize(); - FramelessHelper::Core::initialize(); - //QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); - QApplication a(argc, argv); - //FramelessHelper::Core::setApplicationOSThemeAware(); - FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur); - FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); - FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow); - MainWindow w; - w.show(); - return a.exec(); + qInstallMessageHandler(messageHandler); + //FramelessHelper::Widgets::initialize(); + FramelessHelper::Core::initialize(); + //QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); + QApplication a(argc, argv); + //FramelessHelper::Core::setApplicationOSThemeAware(); + FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur); + FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); + FramelessConfig::instance()->set(Global::Option::CenterWindowBeforeShow); + MainWindow w; + w.show(); + return a.exec(); } From 063be364c2ed2c8a1302dffcba5334bed8d18a22 Mon Sep 17 00:00:00 2001 From: wuyize Date: Wed, 22 Feb 2023 12:49:46 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E9=87=87=E6=A0=B7=E6=9C=80=E6=8E=A5?= =?UTF-8?q?=E8=BF=91=E7=9A=84=E5=8F=AF=E7=94=A8mipmap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/Shaders/painting.comp | 33 +++++++------------ .../res/Shaders/painting.frag | 12 +++++-- .../src/Renderer/Model.cpp | 16 +++++---- .../src/Renderer/Model.h | 4 +-- .../src/Renderer/Painting/Painting.cpp | 16 +++++++-- .../src/Renderer/Painting/Painting.h | 5 ++- .../src/Renderer/RendererGLWidget.cpp | 8 ++--- .../src/Renderer/VirtualTextureManager.cpp | 28 ++++++++++------ .../src/Renderer/VirtualTextureManager.h | 19 +++++++---- 9 files changed, 85 insertions(+), 56 deletions(-) diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index 91d39d0..b00edc5 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -7,24 +7,15 @@ uniform ivec2 pixelOffset; layout(rgba8, binding = 0) uniform image2D gBaseColor; layout(rg8, binding = 1) uniform image2D gMetallicRoughness; -layout(std430, binding = 1) buffer paintingOffsetBuffer -{ - /********************** - ** @x paintingBvhRoot - ** @y paintingBvhLength - **********************/ - uvec2 paintingOffsets[]; -}; - -layout(std430, binding = 2) buffer bvhBuffer +layout(std430, binding = 0) buffer bvhBuffer { uvec2 bvhChildren[]; }; -layout(std430, binding = 3) buffer bvhBoundBuffer +layout(std430, binding = 1) buffer bvhBoundBuffer { vec4 bvhBound[]; }; -layout(std430, binding = 4) buffer elementOffsetBuffer +layout(std430, binding = 2) buffer elementOffsetBuffer { /********************** ** @[0] elementBvhRoot @@ -34,11 +25,11 @@ layout(std430, binding = 4) buffer elementOffsetBuffer **********************/ uvec4 elementOffset[]; }; -layout(std430, binding = 5) buffer elementIndexBuffer +layout(std430, binding = 3) buffer elementIndexBuffer { uint elementIndexs[]; //线和面 }; -layout(std430, binding = 6) buffer elementDataBuffer +layout(std430, binding = 4) buffer elementDataBuffer { float elementData[]; //点和Style }; @@ -1182,14 +1173,12 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metal void main() { - //ivec2 pixelLocation = ivec2(((gl_LocalInvocationID.xy)*imageSize(gPaintingIndex)/gl_WorkGroupSize.xy + gl_WorkGroupID.xy).xy); - ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy); - - vec2 uv = (pixelOffset + pixelLocation + vec2(0.5)) / imageSize(gBaseColor); - imageStore(gBaseColor, ivec2( pixelOffset + pixelLocation), vec4(uv,1,1)); - imageStore(gMetallicRoughness, ivec2( pixelOffset + pixelLocation), vec4(uv,1,1)); - return; - uv= uv*2-vec2(1); + ivec2 pixelLocation = ivec2(pixelOffset + gl_GlobalInvocationID.xy); + vec2 uv = (pixelLocation + vec2(0.5)) / imageSize(gBaseColor); + //imageStore(gBaseColor, pixelLocation, vec4(uv,1,1)); + //imageStore(gMetallicRoughness, pixelLocation, vec4(uv,1,1)); + //return; + uv = vec2(1)-uv*2; //vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg; vec3 debugBVH = vec3(0); diff --git a/ArchitectureColoredPainting/res/Shaders/painting.frag b/ArchitectureColoredPainting/res/Shaders/painting.frag index 677deb2..f027120 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.frag +++ b/ArchitectureColoredPainting/res/Shaders/painting.frag @@ -1,4 +1,5 @@ #version 450 core +#extension GL_ARB_sparse_texture2 : enable uniform sampler2D texture_basecolor; uniform sampler2D texture_metallic_roughness; @@ -16,7 +17,10 @@ in vec3 Normal; void main() { - gBaseColor = texture(texture_basecolor, TexCoords); + float lod = textureQueryLod(texture_basecolor, TexCoords).x; + while(!sparseTexelsResidentARB(sparseTextureLodARB(texture_basecolor, TexCoords, lod, gBaseColor))&&lod Model::processMesh(aiMesh* mesh, const aiScene* scene, } } - //m_mesh->paintingIndex = loadPainting(std::string(str.C_Str())); - std::tie(m_mesh->textureBasecolor, m_mesh->textureMetallicRoughness) = loadPainting(std::string(str.C_Str())); + m_mesh->paintingIndex = loadPainting(std::string(str.C_Str())); + auto& handle = vtManager->paintings[m_mesh->paintingIndex]; + m_mesh->textureBasecolor = handle.baseColor; + m_mesh->textureMetallicRoughness = handle.metallicRoughness; m_mesh->setupMesh(); return m_mesh; } @@ -225,7 +227,7 @@ GLuint Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type) return texture.textureId(); } -std::tuple Renderer::Model::loadPainting(std::string path) +GLuint Renderer::Model::loadPainting(std::string path) { auto iter = paintingLoaded.find(path); if (iter != paintingLoaded.end()) @@ -327,7 +329,7 @@ std::tuple Renderer::Model::loadPainting(std::string path) //painting.addElement(element[1], QVector4D(-0.7, 0.2, -0.2, 0.7), 0, 0); //painting.addElement(element[2], QVector4D(0.2, -0.8, 0.8, -0.1), 0, 0); - painting.generateBuffers(); + painting.generateBuffers(glFunc); ///////////////////////////////////////////////////////////////////////////////////////////////// std::vector bvhChildren0 = { //root @@ -466,7 +468,7 @@ std::tuple Renderer::Model::loadPainting(std::string path) //GLuint index = paintingHelper->addPainting(painting); //paintingLoaded.insert({ path, index }); - auto ids = vtManager->createVirtualTexture(painting); - paintingLoaded.emplace(path, ids); - return ids; + auto index = vtManager->createVirtualTexture(painting); + paintingLoaded.emplace(path, index); + return index; } diff --git a/ArchitectureColoredPainting/src/Renderer/Model.h b/ArchitectureColoredPainting/src/Renderer/Model.h index 2993026..3883a08 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.h +++ b/ArchitectureColoredPainting/src/Renderer/Model.h @@ -29,7 +29,7 @@ namespace Renderer VirtualTextureManager* vtManager = nullptr; /* 模型数据 */ - std::unordered_map> paintingLoaded; + std::unordered_map paintingLoaded; std::unordered_map texturesLoaded; std::vector> meshes; @@ -47,6 +47,6 @@ namespace Renderer //加载材质纹理 GLuint loadMaterialTextures(aiMaterial* mat, aiTextureType type); - std::tuple loadPainting(std::string path); + GLuint loadPainting(std::string path); }; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp index e78a81a..18fc638 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp @@ -105,13 +105,12 @@ BvhTreeData Painting::encodeElementLeaf(ElementWithTransform e) return BvhTreeData(bound, elementPool[e.element], rightSon); } -void Painting::generateBuffers() +void Painting::generateBuffers(QOpenGLFunctions_4_5_Compatibility* glFunc) { qDebug() << "Element Count: " << elementPool.size(); qDebug() << "Coutour Count: " << contourPool.size(); qDebug() << " Style Count: " << stylePool.size(); - bvhChildren.clear(); bvhBounds.clear(); elementOffset.clear(); @@ -161,6 +160,19 @@ void Painting::generateBuffers() elementOffset.push_back({ contourBuffer->bvhOffset, stylePool[i.first.style], contourBuffer->pointsOffset, contourBuffer->linesOffset }); //std::cout << std::format("{} {} {} {}\n", contourBuffer->bvhOffset, stylePool[i.first->style], contourBuffer->pointsOffset, contourBuffer->linesOffset); } + + glFunc->glCreateBuffers(5, buffers.data()); + GLuint& bvhSSBO = buffers[0]; + GLuint& bvhBoundSSBO = buffers[1]; + GLuint& elementOffsetSSBO = buffers[2]; + GLuint& elementIndexSSBO = buffers[3]; + GLuint& elementDataSSBO = buffers[4]; + + glFunc->glNamedBufferData(bvhSSBO, bvhChildren.size() * sizeof(GLuint), bvhChildren.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(bvhBoundSSBO, bvhBounds.size() * sizeof(QVector4D), bvhBounds.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(elementOffsetSSBO, elementOffset.size() * sizeof(glm::uvec4), elementOffset.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(elementIndexSSBO, elementIndex.size() * sizeof(GLuint), elementIndex.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(elementDataSSBO, elementData.size() * sizeof(GLfloat), elementData.data(), GL_STATIC_READ); } GLuint Renderer::Painting::getElementCount() diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h index a4ccedd..fe29c1d 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h @@ -1,11 +1,13 @@ #pragma once #include +#include #include #include #include "Line.h" #include "BvhTree.h" #include "ElementStyle.h" #include "Element.h" +#include namespace Renderer { @@ -64,12 +66,13 @@ namespace Renderer std::vector elementIndex; std::vector elementData; int paintingId = 0; + std::array buffers; Painting(); void addElement(ElementWithTransform element); void addElement(const Element& element, const ElementTransform& transform); void addElement(std::shared_ptr element, QVector4D bound, float rotation, int zIndex); - void generateBuffers(); + void generateBuffers(QOpenGLFunctions_4_5_Compatibility* glFunc); GLuint getElementCount(); private: std::unordered_map, std::pair/*面*/, std::shared_ptr/*线*/>> contourPool; diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index 8f68578..5bebcab 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -75,10 +75,10 @@ void RendererGLWidget::setModel() //model = new Model("E:\\3D Objects\\gallery_gltf\\gallery_gltf.gltf", context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper); light.model = model; qDebug() << model->AABB; - paintingHelper->allocateBuffers(); - paintingCompProgramPtr->bind(); - paintingHelper->bindPaintingBuffers(); - paintingCompProgramPtr->release(); + //paintingHelper->allocateBuffers(); + //paintingCompProgramPtr->bind(); + //paintingHelper->bindPaintingBuffers(); + //paintingCompProgramPtr->release(); doneCurrent(); } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp index 4d6d2ef..375db34 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp @@ -44,12 +44,13 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl) qDebug() << "ERROR:" << program.log(); if (!program.link()) qDebug() << "ERROR:" << program.log(); - + } -std::tuple Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) +GLuint Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) { - const GLsizei levels = static_cast(glm::log2(textureSize) + static_cast(1)); + const GLsizei levels = glm::log2(textureSize / pageSize) + 1; + qDebug() << "levels:" << levels; GLuint textures[2]; gl->CreateTextures(GL_TEXTURE_2D, 2, textures); @@ -57,20 +58,27 @@ std::tuple Renderer::VirtualTextureManager::createVirtualTexture GLuint& metallicRoughness = textures[1]; gl->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE); + gl->TextureParameteri(baseColor, GL_TEXTURE_BASE_LEVEL, 0); + gl->TextureParameteri(baseColor, GL_TEXTURE_MAX_LEVEL, levels - 1); gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT); gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT); - gl->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); gl->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize)); gl->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_BASE_LEVEL, 0); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAX_LEVEL, levels - 1); gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT); gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize)); - for (std::size_t level = 0; level < 1; ++level) + for (int i = 0; i < 5; i++) + gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); + + for (auto level = levels - 1; level < levels; ++level) { GLsizei levelSize = (textureSize >> level); for (GLsizei j = 0; j < levelSize / pageSize; ++j) @@ -87,14 +95,14 @@ std::tuple Renderer::VirtualTextureManager::createVirtualTexture program.bind(); gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * i, static_cast(pageSize) * j); - gl->BindImageTexture(0, baseColor, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); - gl->BindImageTexture(1, metallicRoughness, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); - + gl->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); + gl->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); gl->DispatchCompute(pageSize / 8, pageSize / 8, 1); program.release(); } } + paintings.emplace_back(baseColor, metallicRoughness, painting.buffers); - return { baseColor, metallicRoughness }; + return paintings.size() - 1; } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h index 947e4ac..de06da3 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h @@ -6,25 +6,32 @@ struct GladGLContext; namespace Renderer { - + struct PaintingHandle + { + GLuint baseColor; + GLuint metallicRoughness; + std::array buffers; + }; class VirtualTextureManager { public: static constexpr GLsizei textureSize = 16384; + std::vector paintings; + VirtualTextureManager(GladGLContext* gl); /** - * @brief - * @param painting - * @return 0 baseColor - * @return 1 metallicRoughness + * @brief + * @param painting + * @return 在paintings中索引 */ - std::tuple createVirtualTexture(Painting painting); + GLuint createVirtualTexture(Painting painting); private: GladGLContext* gl; GLint pageSize; QOpenGLShaderProgram program; + }; } From b23d55e87678ff3b4e6a9ac22eb9c3aeb0841675 Mon Sep 17 00:00:00 2001 From: wuyize Date: Thu, 23 Feb 2023 22:18:52 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90page?= =?UTF-8?q?=E7=9A=84=E6=8C=89=E9=9C=80=E5=8A=A0=E8=BD=BD=E5=8D=B8=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ArchitectureColoredPainting.vcxproj | 2 + ...rchitectureColoredPainting.vcxproj.filters | 3 + .../res/MainWindow.qrc | 1 + .../res/Shaders/model.frag | 4 +- .../res/Shaders/model_shadow.frag | 8 +- .../res/Shaders/pageId_downsample.comp | 14 ++ .../res/Shaders/painting.frag | 32 ++- .../src/Renderer/Mesh.cpp | 12 +- .../src/Renderer/Model.cpp | 4 +- .../src/Renderer/PaintingMesh.cpp | 9 +- .../src/Renderer/PaintingMesh.h | 2 +- .../src/Renderer/RendererGLWidget.cpp | 201 +++++++++--------- .../src/Renderer/RendererGLWidget.h | 2 +- .../src/Renderer/VirtualTextureManager.cpp | 66 +++++- .../src/Renderer/VirtualTextureManager.h | 26 ++- ArchitectureColoredPainting/src/main.cpp | 7 +- 16 files changed, 256 insertions(+), 137 deletions(-) create mode 100644 ArchitectureColoredPainting/res/Shaders/pageId_downsample.comp diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index 6fa540b..fd1624c 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -70,6 +70,7 @@ stdcpp20 $(ProjectDir)include;$(SolutionDir)ArchitectureColoredPainting\src\Editor\RightBar;$(SolutionDir)ArchitectureColoredPainting\src\Editor\;$(SolutionDir)FramelessHelper\include;$(SolutionDir)FramelessHelper\qmake\inc\core;$(SolutionDir)FramelessHelper\include\FramelessHelper\Core;%(AdditionalIncludeDirectories) FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions) + Level1 opengl32.lib;%(AdditionalDependencies) @@ -171,6 +172,7 @@ + diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters index aa91db3..6a72e52 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters @@ -326,6 +326,9 @@ Resource Files\Shaders + + Resource Files\Shaders + diff --git a/ArchitectureColoredPainting/res/MainWindow.qrc b/ArchitectureColoredPainting/res/MainWindow.qrc index 5fb0bed..05dcdbb 100644 --- a/ArchitectureColoredPainting/res/MainWindow.qrc +++ b/ArchitectureColoredPainting/res/MainWindow.qrc @@ -31,6 +31,7 @@ Shaders/irradiance_convolution.frag Shaders/cubemap_prefilter.frag Shaders/brdf_lut.comp + Shaders/pageId_downsample.comp qt.conf diff --git a/ArchitectureColoredPainting/res/Shaders/model.frag b/ArchitectureColoredPainting/res/Shaders/model.frag index 62b7b3b..97e724a 100644 --- a/ArchitectureColoredPainting/res/Shaders/model.frag +++ b/ArchitectureColoredPainting/res/Shaders/model.frag @@ -9,7 +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 uint gPaintingIndex; +layout (location = 4) out uvec2 gPaintingIndex; in vec2 TexCoords; in vec3 WorldPos; @@ -52,6 +52,6 @@ void main() else gMetallicRoughness = vec2(0,1); - gPaintingIndex = 0; + gPaintingIndex = uvec2(0); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/res/Shaders/model_shadow.frag b/ArchitectureColoredPainting/res/Shaders/model_shadow.frag index 391e444..308e92b 100644 --- a/ArchitectureColoredPainting/res/Shaders/model_shadow.frag +++ b/ArchitectureColoredPainting/res/Shaders/model_shadow.frag @@ -1,4 +1,5 @@ #version 450 core +#extension GL_ARB_sparse_texture2 : enable uniform sampler2D texture_basecolor; @@ -6,8 +7,11 @@ in vec2 TexCoords; void main() { - //gBaseColor = vec4(1,0,0,1); - vec4 baseColor = texture(texture_basecolor, TexCoords); + vec4 baseColor;// = texture(texture_basecolor, TexCoords); + float lod = textureQueryLod(texture_basecolor, TexCoords).x; + while(!sparseTexelsResidentARB(sparseTextureLodARB(texture_basecolor, TexCoords, lod, baseColor))&&lodbind()) { - glFunc->glActiveTexture(GL_TEXTURE0); - glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor); - glFunc->glActiveTexture(GL_TEXTURE1); - glFunc->glBindTexture(GL_TEXTURE_2D, textureMetallicRoughness); - glFunc->glActiveTexture(GL_TEXTURE2); - glFunc->glBindTexture(GL_TEXTURE_2D, textureNormal); + glFunc->glBindTextureUnit(0, textureBasecolor); + glFunc->glBindTextureUnit(1, textureMetallicRoughness); + glFunc->glBindTextureUnit(2, textureNormal); shaderProgram->setUniformValue("texture_basecolor", 0); shaderProgram->setUniformValue("texture_metallic_roughness", 1); shaderProgram->setUniformValue("texture_normal", 2); @@ -44,8 +41,7 @@ void Mesh::drawShadow() { if (shadowProgram->bind()) { - glFunc->glActiveTexture(GL_TEXTURE0); - glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor); + glFunc->glBindTextureUnit(0, textureBasecolor); shadowProgram->setUniformValue("texture_basecolor", 0); QOpenGLVertexArrayObject::Binder bind(&VAO); diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index 9f1edad..773d4cf 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -148,8 +148,8 @@ std::unique_ptr Model::processMesh(aiMesh* mesh, const aiScene* scene, } } - m_mesh->paintingIndex = loadPainting(std::string(str.C_Str())); - auto& handle = vtManager->paintings[m_mesh->paintingIndex]; + m_mesh->paintingId = loadPainting(std::string(str.C_Str())); + auto& handle = vtManager->getPaintingHandle(m_mesh->paintingId); m_mesh->textureBasecolor = handle.baseColor; m_mesh->textureMetallicRoughness = handle.metallicRoughness; m_mesh->setupMesh(); diff --git a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp index 64cbd09..4449a96 100644 --- a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp +++ b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.cpp @@ -13,15 +13,14 @@ void PaintingMesh::draw() { if (shaderProgram->bind()) { - glFunc->glActiveTexture(GL_TEXTURE0); - glFunc->glBindTexture(GL_TEXTURE_2D, textureBasecolor); - glFunc->glActiveTexture(GL_TEXTURE1); - glFunc->glBindTexture(GL_TEXTURE_2D, textureMetallicRoughness); + glFunc->glBindTextureUnit(0, textureBasecolor); + glFunc->glBindTextureUnit(1, textureMetallicRoughness); shaderProgram->setUniformValue("texture_basecolor", 0); shaderProgram->setUniformValue("texture_metallic_roughness", 1); QOpenGLVertexArrayObject::Binder bind(&VAO); shaderProgram->setUniformValue("model", model); + glFunc->glUniform1ui(glFunc->glGetUniformLocation(shaderProgram->programId(), "paintingId"), paintingId); EBO.bind(); glFunc->glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); shaderProgram->release(); @@ -31,6 +30,8 @@ void PaintingMesh::drawShadow() { if (shadowProgram->bind()) { + glFunc->glBindTextureUnit(0, textureBasecolor); + shadowProgram->setUniformValue("texture_basecolor", 0); QOpenGLVertexArrayObject::Binder bind(&VAO); shadowProgram->setUniformValue("model", model); EBO.bind(); diff --git a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.h b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.h index 3d55d0a..8c22c21 100644 --- a/ArchitectureColoredPainting/src/Renderer/PaintingMesh.h +++ b/ArchitectureColoredPainting/src/Renderer/PaintingMesh.h @@ -25,7 +25,7 @@ namespace Renderer QMatrix4x4 model; QOpenGLFunctions_4_5_Compatibility* glFunc; QOpenGLShaderProgram* shaderProgram, * shadowProgram; - GLuint paintingIndex; + GLuint paintingId; PaintingMesh(QOpenGLFunctions_4_5_Compatibility* glFunc, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* shadowProgram, const QMatrix4x4& model); void draw() override; diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index 5bebcab..2944193 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -10,6 +10,7 @@ #include #include "IblUtils.h" #include "VirtualTextureManager.h" +#include using namespace Renderer; @@ -101,16 +102,34 @@ void Renderer::RendererGLWidget::setExposure(float exposure) QOpenGLTexture randomMap(QOpenGLTexture::Target2D); +void GLAPIENTRY MessageCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) +{ + //fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n", + // (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), + // type, severity, message); + if (type == GL_DEBUG_TYPE_ERROR) + qCritical() << QString::fromStdString(std::format("GL_ERROR: type = {:#x}, severity = {:#x}, message = {}", + type, severity, message)); +} void RendererGLWidget::initializeGL() { gl = std::make_unique(); if (!gladLoadGLContext(gl.get(), [](const char* name) { return (GLADapiproc)QOpenGLContext::currentContext()->getProcAddress(name); })) - qDebug() << "Failed to initialize GLAD"; - + qCritical() << "Failed to initialize GLAD"; + QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions(); qDebug() << "GL_VERSION" << (char*)gl->GetString(GL_VERSION); + gl->Enable(GL_DEBUG_OUTPUT); + gl->DebugMessageCallback(MessageCallback, 0); + gl->Enable(GL_DEPTH_TEST); gl->DepthFunc(GL_LEQUAL); gl->Enable(GL_TEXTURE_CUBE_MAP_SEAMLESS); @@ -118,83 +137,83 @@ void RendererGLWidget::initializeGL() shadowProgramPtr = new QOpenGLShaderProgram; if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model_shadow.vert")) - qDebug() << "ERROR:" << shadowProgramPtr->log(); + qCritical() << "ERROR:" << shadowProgramPtr->log(); if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Geometry, ":/Shaders/model_shadow.geom")) - qDebug() << "ERROR:" << shadowProgramPtr->log(); + qCritical() << "ERROR:" << shadowProgramPtr->log(); if (!shadowProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/model_shadow.frag")) - qDebug() << "ERROR:" << shadowProgramPtr->log(); + qCritical() << "ERROR:" << shadowProgramPtr->log(); if (!shadowProgramPtr->link()) - qDebug() << "ERROR:" << shadowProgramPtr->log(); + qCritical() << "ERROR:" << shadowProgramPtr->log(); plainProgramPtr = new QOpenGLShaderProgram; if (!plainProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/shader.vert")) - qDebug() << "ERROR:" << plainProgramPtr->log(); + qCritical() << "ERROR:" << plainProgramPtr->log(); if (!plainProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/shader.frag")) - qDebug() << "ERROR:" << plainProgramPtr->log(); + qCritical() << "ERROR:" << plainProgramPtr->log(); if (!plainProgramPtr->link()) - qDebug() << "ERROR:" << plainProgramPtr->log(); + qCritical() << "ERROR:" << plainProgramPtr->log(); modelProgramPtr = new QOpenGLShaderProgram; if (!modelProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/model.vert")) - qDebug() << "ERROR:" << modelProgramPtr->log(); + qCritical() << "ERROR:" << modelProgramPtr->log(); if (!modelProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/model.frag")) - qDebug() << "ERROR:" << modelProgramPtr->log(); + qCritical() << "ERROR:" << modelProgramPtr->log(); if (!modelProgramPtr->link()) - qDebug() << "ERROR:" << modelProgramPtr->log(); + qCritical() << "ERROR:" << modelProgramPtr->log(); paintingProgramPtr = new QOpenGLShaderProgram; if (!paintingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/painting.vert")) - qDebug() << "ERROR:" << paintingProgramPtr->log(); + qCritical() << "ERROR:" << paintingProgramPtr->log(); if (!paintingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/painting.frag")) - qDebug() << "ERROR:" << paintingProgramPtr->log(); + qCritical() << "ERROR:" << paintingProgramPtr->log(); if (!paintingProgramPtr->link()) - qDebug() << "ERROR:" << paintingProgramPtr->log(); + qCritical() << "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(); + pageIdDownsampleProgramPtr = new QOpenGLShaderProgram; + if (!pageIdDownsampleProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/pageId_downsample.comp")) + qCritical() << "ERROR:" << pageIdDownsampleProgramPtr->log(); + if (!pageIdDownsampleProgramPtr->link()) + qCritical() << "ERROR:" << pageIdDownsampleProgramPtr->log(); depthInitProgramPtr = new QOpenGLShaderProgram; if (!depthInitProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/depth_init.comp")) - qDebug() << "ERROR:" << depthInitProgramPtr->log(); + qCritical() << "ERROR:" << depthInitProgramPtr->log(); if (!depthInitProgramPtr->link()) - qDebug() << "ERROR:" << depthInitProgramPtr->log(); + qCritical() << "ERROR:" << depthInitProgramPtr->log(); depthMipmapProgramPtr = new QOpenGLShaderProgram; if (!depthMipmapProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/depth_mipmap.comp")) - qDebug() << "ERROR:" << depthMipmapProgramPtr->log(); + qCritical() << "ERROR:" << depthMipmapProgramPtr->log(); if (!depthMipmapProgramPtr->link()) - qDebug() << "ERROR:" << depthMipmapProgramPtr->log(); + qCritical() << "ERROR:" << depthMipmapProgramPtr->log(); shadowMappingProgramPtr = new QOpenGLShaderProgram; if (!shadowMappingProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/shadow_mapping.comp")) - qDebug() << "ERROR:" << shadowMappingProgramPtr->log(); + qCritical() << "ERROR:" << shadowMappingProgramPtr->log(); if (!shadowMappingProgramPtr->link()) - qDebug() << "ERROR:" << shadowMappingProgramPtr->log(); + qCritical() << "ERROR:" << shadowMappingProgramPtr->log(); ssgiProgramPtr = new QOpenGLShaderProgram; if (!ssgiProgramPtr->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/ssgi.comp")) - qDebug() << "ERROR:" << ssgiProgramPtr->log(); + qCritical() << "ERROR:" << ssgiProgramPtr->log(); if (!ssgiProgramPtr->link()) - qDebug() << "ERROR:" << ssgiProgramPtr->log(); + qCritical() << "ERROR:" << ssgiProgramPtr->log(); finalProgramPtr = new QOpenGLShaderProgram; if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/final.vert")) - qDebug() << "ERROR:" << finalProgramPtr->log(); + qCritical() << "ERROR:" << finalProgramPtr->log(); if (!finalProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/final.frag")) - qDebug() << "ERROR:" << finalProgramPtr->log(); + qCritical() << "ERROR:" << finalProgramPtr->log(); if (!finalProgramPtr->link()) - qDebug() << "ERROR:" << finalProgramPtr->log(); + qCritical() << "ERROR:" << finalProgramPtr->log(); skyBoxProgramPtr = new QOpenGLShaderProgram; if (!skyBoxProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/skybox.vert")) - qDebug() << "ERROR:" << skyBoxProgramPtr->log(); + qCritical() << "ERROR:" << skyBoxProgramPtr->log(); if (!skyBoxProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/skybox.frag")) - qDebug() << "ERROR:" << skyBoxProgramPtr->log(); + qCritical() << "ERROR:" << skyBoxProgramPtr->log(); if (!skyBoxProgramPtr->link()) - qDebug() << "ERROR:" << skyBoxProgramPtr->log(); + qCritical() << "ERROR:" << skyBoxProgramPtr->log(); shadowProgramPtr->bind(); gl->GenBuffers(1, &lightSpaceMatricesUBO); @@ -271,6 +290,11 @@ void RendererGLWidget::initializeGL() void RendererGLWidget::paintGL() { QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions(); + GLuint timeQuery; + gl->GenQueries(1, &timeQuery); + gl->BeginQuery(GL_TIME_ELAPSED, timeQuery); + + gl->Enable(GL_CULL_FACE); @@ -316,7 +340,7 @@ void RendererGLWidget::paintGL() paintingProgramPtr->release(); if (model != nullptr) model->draw(); - + plainProgramPtr->bind(); plainProgramPtr->setUniformValue("projection", projection); plainProgramPtr->setUniformValue("view", view); @@ -330,11 +354,11 @@ void RendererGLWidget::paintGL() for (int col = 0; col < nrColumns; ++col) { plainProgramPtr->setUniformValue("roughness", glm::clamp((float)col / (float)nrColumns, 0.05f, 1.0f)); - + model.setToIdentity(); model.scale(10); model.translate(QVector3D((float)(col - (nrColumns / 2)) * spacing, - (float)(row - (nrRows / 2)) * spacing+20, + (float)(row - (nrRows / 2)) * spacing + 20, -2.0f)); plainProgramPtr->setUniformValue("model", model); IblUtils::renderSphere(glFunc); @@ -342,40 +366,35 @@ void RendererGLWidget::paintGL() } plainProgramPtr->release(); + pageIdDownsampleProgramPtr->bind(); + gl->BindImageTexture(3, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16UI); + gl->DispatchCompute(ceil(frameWidth / 8. / 8.), ceil(frameWidth / 8. / 8.), 1); + pageIdDownsampleProgramPtr->release(); + + std::vector pixels; + pixels.resize(ceil(frameWidth / 8.) * ceil(frameHeight / 8.)); + gl->ReadBuffer(GL_COLOR_ATTACHMENT4); + gl->ReadnPixels(0, 0, ceil(frameWidth / 8.), ceil(frameHeight / 8.), GL_RG_INTEGER, GL_UNSIGNED_SHORT, pixels.size() * sizeof(glm::u16vec2), pixels.data()); + vtManager->updatePages(pixels); + fboPtr->release(); } - GLuint paintingCompQuery; - gl->GenQueries(1, &paintingCompQuery); - gl->BeginQuery(GL_TIME_ELAPSED, paintingCompQuery); + //depthInitProgramPtr->bind(); + //gl->ActiveTexture(GL_TEXTURE0); + //gl->BindTexture(GL_TEXTURE_2D, gbuffers[6]); + //gl->BindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); + //gl->DispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1); + //depthInitProgramPtr->release(); - paintingCompProgramPtr->bind(); - gl->BindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); - gl->BindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); - gl->BindImageTexture(2, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16UI); - gl->BindImageTexture(3, gbuffers[5], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F); - - //gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); - paintingCompProgramPtr->release(); - - gl->EndQuery(GL_TIME_ELAPSED); - - - depthInitProgramPtr->bind(); - gl->ActiveTexture(GL_TEXTURE0); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[6]); - gl->BindImageTexture(0, gbuffers[7], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); - gl->DispatchCompute(ceil(depthWidth / 8.), ceil(depthHeight / 8.), 1); - depthInitProgramPtr->release(); - - depthMipmapProgramPtr->bind(); - for (int i = 0; i <= 3; i++) - gl->BindImageTexture(i, gbuffers[7], i, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); - gl->DispatchCompute(ceil(depthWidth / 2. / 8.), ceil(depthHeight / 2. / 8.), 1); - for (int i = 0; i <= 3; i++) - gl->BindImageTexture(i, gbuffers[7], i + 3, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); - gl->DispatchCompute(ceil(depthWidth / 2. / 8. / 8.), ceil(depthHeight / 2. / 8. / 8.), 1); - depthMipmapProgramPtr->release(); + //depthMipmapProgramPtr->bind(); + //for (int i = 0; i <= 3; i++) + // gl->BindImageTexture(i, gbuffers[7], i, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); + //gl->DispatchCompute(ceil(depthWidth / 2. / 8.), ceil(depthHeight / 2. / 8.), 1); + //for (int i = 0; i <= 3; i++) + // gl->BindImageTexture(i, gbuffers[7], i + 3, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); + //gl->DispatchCompute(ceil(depthWidth / 2. / 8. / 8.), ceil(depthHeight / 2. / 8. / 8.), 1); + //depthMipmapProgramPtr->release(); shadowMappingProgramPtr->bind(); shadowMappingProgramPtr->setUniformValue("view", view); @@ -388,22 +407,15 @@ void RendererGLWidget::paintGL() shadowMappingProgramPtr->setUniformValue("camPos", camera.Position); shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection); shadowMappingProgramPtr->setUniformValue("mainLightRadiance", mainLightRadiance); - /*gl->ActiveTexture(GL_TEXTURE0); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]);*/ - gl->ActiveTexture(GL_TEXTURE1); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[1]); - gl->ActiveTexture(GL_TEXTURE2); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[2]); - gl->ActiveTexture(GL_TEXTURE3); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[3]); - gl->ActiveTexture(GL_TEXTURE4); - gl->BindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer); - gl->ActiveTexture(GL_TEXTURE5); - gl->BindTexture(GL_TEXTURE_CUBE_MAP, irradianceMap); - gl->ActiveTexture(GL_TEXTURE6); - gl->BindTexture(GL_TEXTURE_CUBE_MAP, prefilterMap); - gl->ActiveTexture(GL_TEXTURE7); - gl->BindTexture(GL_TEXTURE_2D, brdfLUTTexture); + + gl->BindTextureUnit(1, gbuffers[1]); + gl->BindTextureUnit(2, gbuffers[2]); + gl->BindTextureUnit(3, gbuffers[3]); + gl->BindTextureUnit(4, shadowGbuffer); + gl->BindTextureUnit(5, irradianceMap); + gl->BindTextureUnit(6, prefilterMap); + gl->BindTextureUnit(7, brdfLUTTexture); + gl->BindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); gl->BindImageTexture(1, gbuffers[8], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F); gl->DispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); @@ -435,11 +447,9 @@ void RendererGLWidget::paintGL() gl->Viewport(0, 0, frameWidth, frameHeight); gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO); finalProgramPtr->bind(); finalProgramPtr->setUniformValue("exposure", exposure); - gl->ActiveTexture(GL_TEXTURE0); - gl->BindTexture(GL_TEXTURE_2D, gbuffers[0]); + gl->BindTextureUnit(0, gbuffers[0]); quadVAO.bind(); gl->DrawArrays(GL_TRIANGLE_STRIP, 0, 4); quadVAO.release(); @@ -448,30 +458,31 @@ void RendererGLWidget::paintGL() skyBoxProgramPtr->bind(); gl->Disable(GL_CULL_FACE); skyBoxProgramPtr->setUniformValue("view", view); - skyBoxProgramPtr->setUniformValue("projection", projection); + skyBoxProgramPtr->setUniformValue("projection", projection); skyBoxProgramPtr->setUniformValue("exposure", exposure); - gl->ActiveTexture(GL_TEXTURE0); - gl->BindTexture(GL_TEXTURE_CUBE_MAP, skyCubemap); + gl->BindTextureUnit(0, skyCubemap); IblUtils::renderCube(glFunc); skyBoxProgramPtr->release(); - GLuint paintingCompDuration; - gl->GetQueryObjectuiv(paintingCompQuery, GL_QUERY_RESULT, &paintingCompDuration); + gl->EndQuery(GL_TIME_ELAPSED); + GLuint frameDuration; + gl->GetQueryObjectuiv(timeQuery, GL_QUERY_RESULT, &frameDuration); clock_t currentFrame = std::clock(); deltaTime = (float)(currentFrame - lastFrame) / CLOCKS_PER_SEC; lastFrame = currentFrame; - static float accTime = 0, frameCnt = 0; + static float accTime = 0, frameCnt = 0, averageDuration = 0; accTime += deltaTime; frameCnt++; + averageDuration += frameDuration; if (accTime > 1.) { std::cout << std::format("{:20}\r", ""); - std::cout << std::format("FPS: {:.2f} Painting: {}ms Pos: {},{},{}\r", frameCnt / accTime, paintingCompDuration / 1e6, camera.Position.x(), camera.Position.y(), camera.Position.z()); - //std::cout << "FPS: " << frameCnt / accTime << " " << camera.Position.x() << " " << camera.Position.y() << " " << camera.Position.z() << "\r"; + std::cout << std::format("FPS: {:.2f}({:.2f}ms) Pos: {:.2f},{:.2f},{:.2f}\r", frameCnt / accTime, averageDuration / 1e6 / frameCnt, camera.Position.x(), camera.Position.y(), camera.Position.z()); accTime = 0; frameCnt = 0; + averageDuration = 0; } if (pressedKeys.contains(Qt::Key_W)) { @@ -536,7 +547,7 @@ void RendererGLWidget::resizeGL(int width, int height) gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gbuffers[3], 0); //gPaintingIndex gl->BindTexture(GL_TEXTURE_2D, gbuffers[4]); - gl->TexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, frameWidth, frameHeight, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); + gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RG16UI, frameWidth, frameHeight, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, NULL); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gbuffers[4], 0); diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h index a068dff..dc62637 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h @@ -59,7 +59,7 @@ namespace Renderer QOpenGLShaderProgram* plainProgramPtr = nullptr; QOpenGLShaderProgram* modelProgramPtr = nullptr; QOpenGLShaderProgram* paintingProgramPtr = nullptr; - QOpenGLShaderProgram* paintingCompProgramPtr = nullptr; + QOpenGLShaderProgram* pageIdDownsampleProgramPtr = nullptr; QOpenGLShaderProgram* depthInitProgramPtr = nullptr; QOpenGLShaderProgram* depthMipmapProgramPtr = nullptr; QOpenGLShaderProgram* shadowMappingProgramPtr = nullptr; diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp index 375db34..f1f0371 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp @@ -47,7 +47,7 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl) } -GLuint Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) +std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) { const GLsizei levels = glm::log2(textureSize / pageSize) + 1; qDebug() << "levels:" << levels; @@ -103,6 +103,66 @@ GLuint Renderer::VirtualTextureManager::createVirtualTexture(Painting painting) } } paintings.emplace_back(baseColor, metallicRoughness, painting.buffers); - - return paintings.size() - 1; + return paintings.size(); +} + +Renderer::PaintingHandle& Renderer::VirtualTextureManager::getPaintingHandle(std::uint16_t id) +{ + return paintings[id - 1]; +} + +void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit) +{ + auto& painting = getPaintingHandle(pageId.x >> 4); + GLint level = pageId.x & 0b1111; + glm::ivec2 page(pageId.y & 0b11111111, pageId.y >> 8); + qDebug() << commit << level << page.x << page.y; + gl->TexturePageCommitmentEXT(painting.baseColor, level, + static_cast(pageSize) * page.x, static_cast(pageSize) * page.y, 0, + static_cast(pageSize), static_cast(pageSize), 1, + commit); + gl->TexturePageCommitmentEXT(painting.metallicRoughness, level, + static_cast(pageSize) * page.x, static_cast(pageSize) * page.y, 0, + static_cast(pageSize), static_cast(pageSize), 1, + commit); + + if (commit) + { + program.bind(); + gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * page.x, static_cast(pageSize) * page.y); + gl->BindImageTexture(0, painting.baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); + gl->BindImageTexture(1, painting.metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); + gl->DispatchCompute(pageSize / 8, pageSize / 8, 1); + program.release(); + } +} + +void Renderer::VirtualTextureManager::updatePages(const std::vector& pageIds) +{ + for (auto iter = loadedPages.begin(); iter != loadedPages.end();) + { + iter->second--; + if (iter->second == 0) + { + pageCommitmentById(iter->first, GL_FALSE); + iter = loadedPages.erase(iter); + } + else + iter++; + } + for (auto& pageId : pageIds) + { + if (pageId.x) + { + auto [iter, success] = loadedPages.emplace(pageId, lifeTime); + if (success) + { + pageCommitmentById(pageId, GL_TRUE); + + } + else + iter->second = lifeTime; + } + } + } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h index de06da3..61e9ca9 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h @@ -1,6 +1,7 @@ #pragma once #include "Painting/Painting.h" #include +#include struct GladGLContext; @@ -16,22 +17,35 @@ namespace Renderer class VirtualTextureManager { public: - static constexpr GLsizei textureSize = 16384; - std::vector paintings; - VirtualTextureManager(GladGLContext* gl); /** * @brief * @param painting - * @return 在paintings中索引 + * @return 虚拟纹理id */ - GLuint createVirtualTexture(Painting painting); + std::uint16_t createVirtualTexture(Painting painting); + PaintingHandle& getPaintingHandle(std::uint16_t id); + void updatePages(const std::vector& pageIds); private: GladGLContext* gl; + static constexpr GLsizei textureSize = 16384; + static constexpr int lifeTime = 64; GLint pageSize; QOpenGLShaderProgram program; - + std::vector paintings; + + struct u16vec2Hash + { + std::size_t operator()(glm::u16vec2 const& v) const + { + return ((std::size_t)v.y << 16) + v.x; + } + }; + + std::unordered_map loadedPages; + + void pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit); }; } diff --git a/ArchitectureColoredPainting/src/main.cpp b/ArchitectureColoredPainting/src/main.cpp index 0d8791b..6cd3b6b 100644 --- a/ArchitectureColoredPainting/src/main.cpp +++ b/ArchitectureColoredPainting/src/main.cpp @@ -27,12 +27,11 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); break; case QtCriticalMsg: - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE); - break; - case QtFatalMsg: SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED); break; - + case QtFatalMsg: + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_RED); + break; } std::cout << std::format("{}({},{}) {}\n", QString(context.file).splitRef("\\").back().toLocal8Bit().data(), From 8920dc39ad64abafafd2f6195df0e55825a4eb39 Mon Sep 17 00:00:00 2001 From: wuyize Date: Sat, 25 Feb 2023 13:34:24 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E7=BA=B9=E7=90=86=E7=9A=84=E5=BC=82=E6=AD=A5=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ArchitectureColoredPainting.vcxproj | 3 +- .../src/Renderer/IblUtils.cpp | 10 +- .../src/Renderer/IblUtils.h | 2 + .../src/Renderer/Model.cpp | 26 +-- .../src/Renderer/RendererGLWidget.cpp | 57 +++--- .../src/Renderer/RendererGLWidget.h | 2 + .../src/Renderer/VirtualTextureManager.cpp | 175 ++++++++++++------ .../src/Renderer/VirtualTextureManager.h | 22 ++- UnitTest/ElementRendererTest.cpp | 8 + 9 files changed, 201 insertions(+), 104 deletions(-) diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index fd1624c..a1bbcba 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -71,6 +71,7 @@ $(ProjectDir)include;$(SolutionDir)ArchitectureColoredPainting\src\Editor\RightBar;$(SolutionDir)ArchitectureColoredPainting\src\Editor\;$(SolutionDir)FramelessHelper\include;$(SolutionDir)FramelessHelper\qmake\inc\core;$(SolutionDir)FramelessHelper\include\FramelessHelper\Core;%(AdditionalIncludeDirectories) FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions) Level1 + Speed opengl32.lib;%(AdditionalDependencies) @@ -81,7 +82,7 @@ true true ProgramDatabase - Disabled + MaxSpeed MultiThreadedDebugDLL diff --git a/ArchitectureColoredPainting/src/Renderer/IblUtils.cpp b/ArchitectureColoredPainting/src/Renderer/IblUtils.cpp index dd17d64..ab3c879 100644 --- a/ArchitectureColoredPainting/src/Renderer/IblUtils.cpp +++ b/ArchitectureColoredPainting/src/Renderer/IblUtils.cpp @@ -182,8 +182,8 @@ std::tuple Renderer::IblUtils::precomputeCubemap // ---------------------- unsigned int captureFBO; unsigned int captureRBO; - glFunc->glGenFramebuffers(1, &captureFBO); - glFunc->glGenRenderbuffers(1, &captureRBO); + glFunc->glCreateFramebuffers(1, &captureFBO); + glFunc->glCreateRenderbuffers(1, &captureRBO); glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); glFunc->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO); @@ -262,6 +262,8 @@ GLuint Renderer::IblUtils::generateCubemap(QOpenGLFunctions_4_5_Core* glFunc, GL glFunc->glActiveTexture(GL_TEXTURE0); glFunc->glBindTexture(GL_TEXTURE_2D, hdrTexture); + glFunc->glBindRenderbuffer(GL_RENDERBUFFER, captureRBO); + glFunc->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, cubemapSize, cubemapSize); glFunc->glViewport(0, 0, cubemapSize, cubemapSize); glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO); @@ -285,8 +287,6 @@ GLuint Renderer::IblUtils::generateCubemap(QOpenGLFunctions_4_5_Core* glFunc, GL GLuint Renderer::IblUtils::generateIrradianceMap(QOpenGLFunctions_4_5_Core* glFunc, GLuint captureFBO, GLuint captureRBO, const QMatrix4x4& captureProjection, const std::array& captureViews, GLuint envCubemap) { - constexpr int irradianceMapSize = 32; - // pbr: create an irradiance cubemap, and re-scale capture FBO to irradiance scale. // -------------------------------------------------------------------------------- unsigned int irradianceMap; @@ -337,8 +337,6 @@ GLuint Renderer::IblUtils::generateIrradianceMap(QOpenGLFunctions_4_5_Core* glFu GLuint Renderer::IblUtils::generatePrefilterMap(QOpenGLFunctions_4_5_Core* glFunc, GLuint captureFBO, GLuint captureRBO, const QMatrix4x4& captureProjection, const std::array& captureViews, GLuint envCubemap) { - constexpr int prefilterMapSize = 128; - // pbr: create a pre-filter cubemap, and re-scale capture FBO to pre-filter scale. // -------------------------------------------------------------------------------- unsigned int prefilterMap; diff --git a/ArchitectureColoredPainting/src/Renderer/IblUtils.h b/ArchitectureColoredPainting/src/Renderer/IblUtils.h index 2305976..1f292fc 100644 --- a/ArchitectureColoredPainting/src/Renderer/IblUtils.h +++ b/ArchitectureColoredPainting/src/Renderer/IblUtils.h @@ -7,6 +7,8 @@ namespace Renderer { public: static constexpr int cubemapSize = 1024; + static constexpr int irradianceMapSize = 32; + static constexpr int prefilterMapSize = 128; static void renderCube(QOpenGLFunctions_4_5_Core* glFunc); static void renderSphere(QOpenGLFunctions_4_5_Core* glFunc); /** diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index 773d4cf..c146104 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -311,18 +311,20 @@ GLuint Renderer::Model::loadPainting(std::string path) std::make_shared(Element{ contour[2], style[0]}), }; Painting painting; - //for (int i = 0; i < 3; i++) - //{ - // float x = (float)rand() / RAND_MAX * 2 - 1; - // float y = (float)rand() / RAND_MAX * 2 - 1; - // float z = 0.05 + x;//(float)rand() / RAND_MAX * (0.1) + x; - // float w = 0.05 + y;//(float)rand() / RAND_MAX * (0.1) + y; - // //rootBvhTreeData.push_back(BvhTreeData(QVector4D(x, y, z, w), 0, encodeZIndexAngle(1, (float)rand() / RAND_MAX * 360))); - // painting.addElement(element[i%3], QVector4D(x, y, z, w), (float)rand() / RAND_MAX * 360, 1); - //} - painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.5,-0.45), glm::vec2(0.6,0.7), 45, glm::bvec2(true, false), 0 }); - painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.5,0.5), 0, glm::bvec2(false), 0 }); - painting.addElement(*element[2], ElementTransform{ glm::vec2(0.5,-0.45), glm::vec2(0.6,0.7), 0, glm::bvec2(false), 0 }); + for (int i = 0; i < 1000; i++) + { + float x = (float)rand() / RAND_MAX * 2 - 1; + float y = (float)rand() / RAND_MAX * 2 - 1; + float z = 0.05 + x;//(float)rand() / RAND_MAX * (0.1) + x; + float w = 0.05 + y;//(float)rand() / RAND_MAX * (0.1) + y; + //rootBvhTreeData.push_back(BvhTreeData(QVector4D(x, y, z, w), 0, encodeZIndexAngle(1, (float)rand() / RAND_MAX * 360))); + //painting.addElement(element[i%3], QVector4D(x, y, z, w), (float)rand() / RAND_MAX * 360, 1); + painting.addElement(*element[i%3], ElementTransform{ glm::vec2(x,y), glm::vec2(0.05), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 }); + + } + //painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.5,-0.45), glm::vec2(0.6,0.7), 45, glm::bvec2(true, false), 0 }); + //painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.5,0.5), 0, glm::bvec2(false), 0 }); + //painting.addElement(*element[2], ElementTransform{ glm::vec2(0.5,-0.45), glm::vec2(0.6,0.7), 0, glm::bvec2(false), 0 }); //painting.addElement(element[0], QVector4D(-0.8, -0.8, -0.2, -0.1), 0, 0); diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index 2944193..90f675e 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -26,8 +26,9 @@ RendererGLWidget::RendererGLWidget(QWidget* parent) //startTimer(); lastFrame = std::clock(); setFocusPolicy(Qt::StrongFocus); - QSurfaceFormat format; - format.setSwapInterval(0); + //QSurfaceFormat format; + //format.setProfile(QSurfaceFormat::CoreProfile); + ////format.setSwapInterval(0); //setFormat(format); } @@ -60,7 +61,10 @@ void RendererGLWidget::startTimer() { //startTimer(1000 / QGuiApplication::primaryScreen()->refreshRate()); if (timerId == -1) + { timerId = QObject::startTimer(1); + + } } void RendererGLWidget::stopTimer() @@ -102,7 +106,7 @@ void Renderer::RendererGLWidget::setExposure(float exposure) QOpenGLTexture randomMap(QOpenGLTexture::Target2D); -void GLAPIENTRY MessageCallback(GLenum source, +void GLAPIENTRY messageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, @@ -128,7 +132,8 @@ void RendererGLWidget::initializeGL() qDebug() << "GL_VERSION" << (char*)gl->GetString(GL_VERSION); gl->Enable(GL_DEBUG_OUTPUT); - gl->DebugMessageCallback(MessageCallback, 0); + //gl->Enable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + gl->DebugMessageCallback(messageCallback, 0); gl->Enable(GL_DEPTH_TEST); gl->DepthFunc(GL_LEQUAL); @@ -252,6 +257,7 @@ void RendererGLWidget::initializeGL() finalProgramPtr->release(); vtManager = std::make_unique(gl.get()); + paintingHelper = new PaintingHelper(glFunc); model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper, vtManager.get()); @@ -283,17 +289,28 @@ void RendererGLWidget::initializeGL() reinterpret_cast(3 * sizeof(GLfloat))); quadVBO.release(); - - + gl->GenQueries(1, &timeQuery); } void RendererGLWidget::paintGL() { QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions(); - GLuint timeQuery; - gl->GenQueries(1, &timeQuery); - gl->BeginQuery(GL_TIME_ELAPSED, timeQuery); + pageIdDownsampleProgramPtr->bind(); + gl->BindImageTexture(3, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16UI); + gl->DispatchCompute(ceil(frameWidth / 8. / 8.), ceil(frameWidth / 8. / 8.), 1); + pageIdDownsampleProgramPtr->release(); + std::vector pixels; + pixels.resize(ceil(frameWidth / 8.) * ceil(frameHeight / 8.)); + fboPtr->bind(); + gl->ReadBuffer(GL_COLOR_ATTACHMENT4); + gl->ReadnPixels(0, 0, ceil(frameWidth / 8.), ceil(frameHeight / 8.), GL_RG_INTEGER, GL_UNSIGNED_SHORT, pixels.size() * sizeof(glm::u16vec2), pixels.data()); + //gl->GetTextureSubImage(gbuffers[4], 0, 0, 0, 0, ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1, GL_RG_INTEGER, GL_UNSIGNED_SHORT, pixels.size() * sizeof(glm::u16vec2), pixels.data()); + fboPtr->release(); + vtManager->tryUpdatePages(pixels); + + + gl->BeginQuery(GL_TIME_ELAPSED, timeQuery); gl->Enable(GL_CULL_FACE); @@ -311,6 +328,7 @@ void RendererGLWidget::paintGL() } gl->BindBuffer(GL_UNIFORM_BUFFER, 0); + vtManager->commitMutex.lock(); { gl->BindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle); gl->Viewport(0, 0, shadowMapResolution, shadowMapResolution); @@ -365,20 +383,10 @@ void RendererGLWidget::paintGL() } } plainProgramPtr->release(); - - pageIdDownsampleProgramPtr->bind(); - gl->BindImageTexture(3, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16UI); - gl->DispatchCompute(ceil(frameWidth / 8. / 8.), ceil(frameWidth / 8. / 8.), 1); - pageIdDownsampleProgramPtr->release(); - - std::vector pixels; - pixels.resize(ceil(frameWidth / 8.) * ceil(frameHeight / 8.)); - gl->ReadBuffer(GL_COLOR_ATTACHMENT4); - gl->ReadnPixels(0, 0, ceil(frameWidth / 8.), ceil(frameHeight / 8.), GL_RG_INTEGER, GL_UNSIGNED_SHORT, pixels.size() * sizeof(glm::u16vec2), pixels.data()); - vtManager->updatePages(pixels); - fboPtr->release(); } + gl->Finish(); + vtManager->commitMutex.unlock(); //depthInitProgramPtr->bind(); //gl->ActiveTexture(GL_TEXTURE0); @@ -479,7 +487,8 @@ void RendererGLWidget::paintGL() if (accTime > 1.) { std::cout << std::format("{:20}\r", ""); - std::cout << std::format("FPS: {:.2f}({:.2f}ms) Pos: {:.2f},{:.2f},{:.2f}\r", frameCnt / accTime, averageDuration / 1e6 / frameCnt, camera.Position.x(), camera.Position.y(), camera.Position.z()); + std::cout << std::format("FPS: {:.2f}({:.2f}ms) Page: {:}ms Pos: {:.2f},{:.2f},{:.2f}\r", frameCnt / accTime, averageDuration / 1e6 / frameCnt, vtManager->pageLoadDuration / 1e6, camera.Position.x(), camera.Position.y(), camera.Position.z()); + vtManager->pageLoadDuration = 0; accTime = 0; frameCnt = 0; averageDuration = 0; @@ -583,8 +592,8 @@ void RendererGLWidget::resizeGL(int width, int height) gl->TexImage2D(GL_TEXTURE_2D, i, GL_R32F, depthWidth / pow(2, i), depthHeight / pow(2, i), 0, GL_RED, GL_FLOAT, NULL); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); gl->TexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, std::begin({ 1.0f, 1.0f, 1.0f, 1.0f })); diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h index dc62637..f6e9195 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.h @@ -80,5 +80,7 @@ namespace Renderer Model* model = nullptr; PaintingHelper* paintingHelper; std::unique_ptr vtManager; + + GLuint timeQuery; }; } diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp index f1f0371..0dc53c4 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp @@ -1,49 +1,97 @@ #include #include "VirtualTextureManager.h" +#include #include #include -#include #include #define GLM_ENABLE_EXPERIMENTAL #include +std::mutex pageIdBufferMutex; -Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* gl) - :gl(gl) +Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain) + :glMain(glMain) { - GLint numPageSizes; + auto mainContext = QOpenGLContext::currentContext(); + auto mainSurface = mainContext->surface(); + surface.setFormat(mainContext->format()); + surface.create(); + mainContext->doneCurrent(); - // Figure out how many page sizes are available for a 2D texture - gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes); - std::vector pageSizesX(numPageSizes); - std::vector pageSizesY(numPageSizes); - std::vector pageSizesZ(numPageSizes); - gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesX.data()); - gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesY.data()); - gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesZ.data()); - qDebug() << "RGBA8" << numPageSizes; - for (int i = 0; i < numPageSizes; i++) - qDebug() << pageSizesX[i] << pageSizesY[i] << pageSizesZ[i]; + thread = std::jthread([&] { + QOpenGLContext context; + context.setFormat(mainContext->format()); + context.setShareContext(mainContext); + context.create(); + context.makeCurrent(&surface); - gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes); - std::vector pageSizesRG8X(numPageSizes); - std::vector pageSizesRG8Y(numPageSizes); - std::vector pageSizesRG8Z(numPageSizes); - gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesRG8X.data()); - gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Y.data()); - gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Z.data()); - qDebug() << "RG8" << numPageSizes; - for (int i = 0; i < numPageSizes; i++) - qDebug() << pageSizesRG8X[i] << pageSizesRG8Y[i] << pageSizesRG8Z[i]; + gl = std::make_unique(); + if (!gladLoadGLContext(gl.get(), [](const char* name) { return (GLADapiproc)QOpenGLContext::currentContext()->getProcAddress(name); })) + qCritical() << "Failed to initialize GLAD"; - pageSize = std::max(pageSizesRG8X[0], pageSizesRG8Y[0]); - qDebug() << "pageSize:" << pageSize; + GLint numPageSizes; + // Figure out how many page sizes are available for a 2D texture + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes); + std::vector pageSizesX(numPageSizes); + std::vector pageSizesY(numPageSizes); + std::vector pageSizesZ(numPageSizes); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesX.data()); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesY.data()); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesZ.data()); + qDebug() << "RGBA8" << numPageSizes; + for (int i = 0; i < numPageSizes; i++) + qDebug() << pageSizesX[i] << pageSizesY[i] << pageSizesZ[i]; - if (!program.addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp")) - qDebug() << "ERROR:" << program.log(); - if (!program.link()) - qDebug() << "ERROR:" << program.log(); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof(GLint), &numPageSizes); + std::vector pageSizesRG8X(numPageSizes); + std::vector pageSizesRG8Y(numPageSizes); + std::vector pageSizesRG8Z(numPageSizes); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_X_ARB, numPageSizes * sizeof(GLint), pageSizesRG8X.data()); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Y_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Y.data()); + gl->GetInternalformativ(GL_TEXTURE_2D, GL_RG8, GL_VIRTUAL_PAGE_SIZE_Z_ARB, numPageSizes * sizeof(GLint), pageSizesRG8Z.data()); + qDebug() << "RG8" << numPageSizes; + for (int i = 0; i < numPageSizes; i++) + qDebug() << pageSizesRG8X[i] << pageSizesRG8Y[i] << pageSizesRG8Z[i]; + + pageSize = std::max(pageSizesRG8X[0], pageSizesRG8Y[0]); + qDebug() << "pageSize:" << pageSize; + + if (!program.addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/painting.comp")) + qDebug() << "ERROR:" << program.log(); + if (!program.link()) + qDebug() << "ERROR:" << program.log(); + + initialized = true; + + GLuint pageLoadTimeQuery; + gl->GenQueries(1, &pageLoadTimeQuery); + + while (true) + { + if (needUpdate) + { + needUpdate = false; + auto& pageIds = pageIdsBuffer[currentBuffer]; + pageIdBufferMutex.lock(); + currentBuffer = 1 - currentBuffer; + pageIdBufferMutex.unlock(); + + gl->BeginQuery(GL_TIME_ELAPSED, pageLoadTimeQuery); + updatePages(pageIds); + gl->EndQuery(GL_TIME_ELAPSED); + GLuint duration; + gl->GetQueryObjectuiv(pageLoadTimeQuery, GL_QUERY_RESULT, &duration); + //qDebug() << duration; + pageLoadDuration += duration; + } + } + }); + + while (!initialized) + std::this_thread::yield(); + + mainContext->makeCurrent(mainSurface); } @@ -53,30 +101,30 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai qDebug() << "levels:" << levels; GLuint textures[2]; - gl->CreateTextures(GL_TEXTURE_2D, 2, textures); + glMain->CreateTextures(GL_TEXTURE_2D, 2, textures); GLuint& baseColor = textures[0]; GLuint& metallicRoughness = textures[1]; - gl->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE); - gl->TextureParameteri(baseColor, GL_TEXTURE_BASE_LEVEL, 0); - gl->TextureParameteri(baseColor, GL_TEXTURE_MAX_LEVEL, levels - 1); - gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT); - gl->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT); - gl->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - gl->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize)); + glMain->TextureParameteri(baseColor, GL_TEXTURE_SPARSE_ARB, GL_TRUE); + glMain->TextureParameteri(baseColor, GL_TEXTURE_BASE_LEVEL, 0); + glMain->TextureParameteri(baseColor, GL_TEXTURE_MAX_LEVEL, levels - 1); + glMain->TextureParameteri(baseColor, GL_TEXTURE_WRAP_S, GL_REPEAT); + glMain->TextureParameteri(baseColor, GL_TEXTURE_WRAP_T, GL_REPEAT); + glMain->TextureParameteri(baseColor, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glMain->TextureParameteri(baseColor, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glMain->TextureStorage2D(baseColor, levels, GL_RGBA8, GLsizei(textureSize), GLsizei(textureSize)); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_BASE_LEVEL, 0); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAX_LEVEL, levels - 1); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - gl->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize)); + glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_SPARSE_ARB, GL_TRUE); + glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_BASE_LEVEL, 0); + glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MAX_LEVEL, levels - 1); + glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_S, GL_REPEAT); + glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_WRAP_T, GL_REPEAT); + glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glMain->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize)); for (int i = 0; i < 5; i++) - gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); + glMain->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); for (auto level = levels - 1; level < levels; ++level) { @@ -84,20 +132,20 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai for (GLsizei j = 0; j < levelSize / pageSize; ++j) for (GLsizei i = 0; i < levelSize / pageSize; ++i) { - gl->TexturePageCommitmentEXT(baseColor, static_cast(level), + glMain->TexturePageCommitmentEXT(baseColor, static_cast(level), static_cast(pageSize) * i, static_cast(pageSize) * j, 0, static_cast(pageSize), static_cast(pageSize), 1, GL_TRUE); - gl->TexturePageCommitmentEXT(metallicRoughness, static_cast(level), + glMain->TexturePageCommitmentEXT(metallicRoughness, static_cast(level), static_cast(pageSize) * i, static_cast(pageSize) * j, 0, static_cast(pageSize), static_cast(pageSize), 1, GL_TRUE); program.bind(); - gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * i, static_cast(pageSize) * j); - gl->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); - gl->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); - gl->DispatchCompute(pageSize / 8, pageSize / 8, 1); + glMain->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * i, static_cast(pageSize) * j); + glMain->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); + glMain->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); + glMain->DispatchCompute(pageSize / 8, pageSize / 8, 1); program.release(); } @@ -111,12 +159,22 @@ Renderer::PaintingHandle& Renderer::VirtualTextureManager::getPaintingHandle(std return paintings[id - 1]; } +void Renderer::VirtualTextureManager::tryUpdatePages(const std::vector& pageIds) +{ + pageIdBufferMutex.lock(); + pageIdsBuffer[currentBuffer] = pageIds; + pageIdBufferMutex.unlock(); + needUpdate = true; +} + void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit) { auto& painting = getPaintingHandle(pageId.x >> 4); GLint level = pageId.x & 0b1111; glm::ivec2 page(pageId.y & 0b11111111, pageId.y >> 8); - qDebug() << commit << level << page.x << page.y; + //qDebug() << commit << level << page.x << page.y; + commitMutex.lock(); + gl->TexturePageCommitmentEXT(painting.baseColor, level, static_cast(pageSize) * page.x, static_cast(pageSize) * page.y, 0, static_cast(pageSize), static_cast(pageSize), 1, @@ -129,12 +187,16 @@ void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pag if (commit) { program.bind(); + for (int i = 0; i < 5; i++) + gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * page.x, static_cast(pageSize) * page.y); gl->BindImageTexture(0, painting.baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); gl->BindImageTexture(1, painting.metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); gl->DispatchCompute(pageSize / 8, pageSize / 8, 1); program.release(); } + gl->Finish(); + commitMutex.unlock(); } void Renderer::VirtualTextureManager::updatePages(const std::vector& pageIds) @@ -158,7 +220,6 @@ void Renderer::VirtualTextureManager::updatePages(const std::vectorsecond = lifeTime; diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h index 61e9ca9..e1d3a03 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h @@ -2,6 +2,10 @@ #include "Painting/Painting.h" #include #include +#include +#include +#include +#include struct GladGLContext; @@ -17,7 +21,7 @@ namespace Renderer class VirtualTextureManager { public: - VirtualTextureManager(GladGLContext* gl); + VirtualTextureManager(GladGLContext* glMain); /** * @brief @@ -26,9 +30,17 @@ namespace Renderer */ std::uint16_t createVirtualTexture(Painting painting); PaintingHandle& getPaintingHandle(std::uint16_t id); - void updatePages(const std::vector& pageIds); + void tryUpdatePages(const std::vector& pageIds); + + std::atomic initialized = false; + std::atomic needUpdate = false; + std::atomic pageLoadDuration = 0; + std::mutex commitMutex; private: - GladGLContext* gl; + std::jthread thread; + QOffscreenSurface surface; + std::unique_ptr gl; + GladGLContext* glMain; static constexpr GLsizei textureSize = 16384; static constexpr int lifeTime = 64; GLint pageSize; @@ -42,9 +54,11 @@ namespace Renderer return ((std::size_t)v.y << 16) + v.x; } }; - std::unordered_map loadedPages; + std::vector pageIdsBuffer[2]; + int currentBuffer = 0; + void updatePages(const std::vector& pageIds); void pageCommitmentById(const glm::u16vec2& pageId, GLboolean commit); }; } diff --git a/UnitTest/ElementRendererTest.cpp b/UnitTest/ElementRendererTest.cpp index f9c9538..d852077 100644 --- a/UnitTest/ElementRendererTest.cpp +++ b/UnitTest/ElementRendererTest.cpp @@ -3,6 +3,8 @@ #include #include "ElementRendererTest.h" #include "Renderer/Painting/ElementStyle.h" +#include + using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace Renderer; @@ -12,6 +14,12 @@ namespace UnitTest TEST_CLASS(ElementRendererStokeTypeTest) { public: + TEST_METHOD(TestFile) + { + QFile file("D:\\BigC2022\\temp\\ArchitectureColoredPainting\\README.md"); + Logger::WriteMessage(file.open(QIODevice::ReadOnly)? "True":"False"); + } + TEST_METHOD(TestBothSidesRound) { QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); From a4a1b2984ec5c9ddaf4561757f9d1128cd870fc4 Mon Sep 17 00:00:00 2001 From: wuyize Date: Sat, 25 Feb 2023 17:00:38 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E6=94=B9painitng.comp=E4=BB=A5?= =?UTF-8?q?=E9=80=82=E5=BA=94=E7=BC=96=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArchitectureColoredPainting/res/Shaders/painting.comp | 8 ++++---- ArchitectureColoredPainting/src/Renderer/Model.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index b00edc5..30339ab 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -1010,8 +1010,8 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metal for ( uint contourIterator = contourIndex + 1;contourIterator < contourIndex + 1 + lineCount; contourIterator++) { uint lineIndex = elementIndexs[contourIterator]; - uint pLocation = linesOffset + 4 * lineIndex; - uvec4 pxIndex = uvec4(pointsOffset)+2*uvec4(elementIndexs[pLocation], elementIndexs[pLocation+1], elementIndexs[pLocation+2], elementIndexs[pLocation+3]); + uint pLocation = linesOffset + 2 * lineIndex; + uvec4 pxIndex = uvec4(pointsOffset)+2*uvec4(elementIndexs[pLocation]>>16, elementIndexs[pLocation]&0xFFFF, elementIndexs[pLocation+1]>>16, elementIndexs[pLocation+1]&0xFFFF); uvec4 pyIndex = uvec4(1)+pxIndex; mat4x2 p = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]], @@ -1069,8 +1069,8 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metal if(contourIterator_==contourIndex + 1 + lineCount) contourIterator = contourIndex + 1; uint lineIndex = elementIndexs[contourIterator]; - uint pLocation = linesOffset + 4 * lineIndex; - uvec4 pxIndex = uvec4(pointsOffset)+2*uvec4(elementIndexs[pLocation], elementIndexs[pLocation+1], elementIndexs[pLocation+2], elementIndexs[pLocation+3]); + uint pLocation = linesOffset + 3 * lineIndex; + uvec4 pxIndex = uvec4(pointsOffset)+2*uvec4(elementIndexs[pLocation]>>16, elementIndexs[pLocation]&0xFFFF, elementIndexs[pLocation+1]>>16, elementIndexs[pLocation+1]&0xFFFF); uvec4 pyIndex = uvec4(1)+pxIndex; mat4x2 p = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index c146104..ee419f2 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -319,12 +319,12 @@ GLuint Renderer::Model::loadPainting(std::string path) float w = 0.05 + y;//(float)rand() / RAND_MAX * (0.1) + y; //rootBvhTreeData.push_back(BvhTreeData(QVector4D(x, y, z, w), 0, encodeZIndexAngle(1, (float)rand() / RAND_MAX * 360))); //painting.addElement(element[i%3], QVector4D(x, y, z, w), (float)rand() / RAND_MAX * 360, 1); - painting.addElement(*element[i%3], ElementTransform{ glm::vec2(x,y), glm::vec2(0.05), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 }); + //painting.addElement(*element[i%3], ElementTransform{ glm::vec2(x,y), glm::vec2(0.05), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 }); } - //painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.5,-0.45), glm::vec2(0.6,0.7), 45, glm::bvec2(true, false), 0 }); - //painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.5,0.5), 0, glm::bvec2(false), 0 }); - //painting.addElement(*element[2], ElementTransform{ glm::vec2(0.5,-0.45), glm::vec2(0.6,0.7), 0, glm::bvec2(false), 0 }); + painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.5,-0.45), glm::vec2(0.6,0.7), 45, glm::bvec2(true, false), 0 }); + painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.5,0.5), 0, glm::bvec2(false), 0 }); + painting.addElement(*element[2], ElementTransform{ glm::vec2(0.5,-0.45), glm::vec2(0.6,0.7), 0, glm::bvec2(false), 0 }); //painting.addElement(element[0], QVector4D(-0.8, -0.8, -0.2, -0.1), 0, 0);