From 57b537b66b03163420e1b240df62d537a9cc4dda Mon Sep 17 00:00:00 2001 From: wuyize Date: Tue, 21 Feb 2023 20:13:07 +0800 Subject: [PATCH 1/9] =?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/9] =?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/9] =?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 ab391ed0ec8235255df2ff6e221b8b24b3fc4947 Mon Sep 17 00:00:00 2001 From: "yang.yongquan" <3395816735@qq.com> Date: Sat, 25 Feb 2023 10:47:27 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=86=E5=89=B2?= =?UTF-8?q?=E7=82=B9=E5=9C=A8=E5=8E=9F=E7=BA=BF=E7=9A=84=E6=AF=94=E4=BE=8B?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E4=B8=8ESvg=E5=A4=84=E7=90=86=E5=8F=98?= =?UTF-8?q?=E6=8D=A2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Editor/util/SvgFileLoader.cpp | 148 +++++++++++++++--- .../src/Editor/util/SvgFileLoader.h | 7 +- .../src/Renderer/Painting/CubicBezier.cpp | 28 +++- .../src/Renderer/Painting/CubicBezier.h | 2 + .../src/Renderer/Painting/Line.cpp | 39 +++++ .../src/Renderer/Painting/Line.h | 9 +- .../src/Renderer/Painting/LineTree.cpp | 35 +++-- .../src/Renderer/Painting/StraightLine.cpp | 4 + .../src/Renderer/Painting/StraightLine.h | 1 + UnitTest/ElementRendererTest.cpp | 2 + UnitTest/UnitTest.cpp | 64 ++++++++ svg/test.svg | 6 + 12 files changed, 303 insertions(+), 42 deletions(-) create mode 100644 svg/test.svg diff --git a/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp b/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp index 30f0ae6..d4c7d03 100644 --- a/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp @@ -2,9 +2,12 @@ #include #include "../ThirdPartyLib/qquick/qquicksvgparser_p.h" #include +#include using std::map; +using std::vector; +using std::reverse; bool SvgFileLoader::loadSvgFile(const QString& filePath, QPainterPath& painterPath) { QFile file(filePath); @@ -46,12 +49,12 @@ bool SvgFileLoader::loadSvgFile(const QString& filePath, QPainterPath& painterPa } } } - + qDebug() << painterPath; file.close(); return true; } -QMap SvgFileLoader::transformStyle(QString style) { +QMap SvgFileLoader::handleAttrStyle(QString style) { QMap resStyleMap; for (auto& attr : style.split(';')) { if (attr.isEmpty() || attr.trimmed() == "") continue; @@ -62,7 +65,7 @@ QMap SvgFileLoader::transformStyle(QString style) { return resStyleMap; } -QPolygonF SvgFileLoader::transformPoints(QString points) { +QPolygonF SvgFileLoader::handleAttrPoints(QString points) { QPolygonF resPointVector; QPointF point(0, 0); bool isX = true; @@ -80,10 +83,58 @@ QPolygonF SvgFileLoader::transformPoints(QString points) { return resPointVector; } +void SvgFileLoader::handleAttrTransform(QString transformStyle, QPainterPath& painterPath) { + QTransform trans; + QStringList ops = transformStyle.split(')'); + reverse(ops.begin(), ops.end()); + vector numbers; + for (auto op : ops) { + op = op.simplified(); + if (op.isEmpty()) continue; + QString type = (*op.split('(').begin()).trimmed(); + QString numStr = (*op.split('(').rbegin()).trimmed() + ','; + QString tmpNum = ""; + for (auto c : numStr) { + if (isdigit(c.toLatin1())) { + tmpNum += c; + } + else { + if (c == ',' && tmpNum.size() == 0) { + numbers.push_back(0); + } + else if (tmpNum.size() > 0) { + numbers.push_back(tmpNum.toDouble()); + } + tmpNum.clear(); + } + } + qDebug() << type << "///:" << numbers; + if (type == "translate") { + trans.translate(numbers[0], numbers[1]); + } + if (type == "scale") { + trans.scale(numbers[0], numbers[1]); + } + if (type == "rotate") { + trans.translate(numbers[1], numbers[2]); + trans.rotate(numbers[0]); + trans.translate(-numbers[1], -numbers[2]); + } + if (type == "skewX") { + trans.shear(numbers[0], 0); + } + if (type == "skewY") { + trans.shear(0, numbers[1]); + } + } + painterPath = trans.map(painterPath); + qDebug() << painterPath; +} + void SvgFileLoader::handleLabelG(QPainterPath& painterPath) { for (auto& attr : xmlReader->attributes()) { if (attr.name().toString() == QLatin1String("style")) { - styleMap = transformStyle(attr.value().toLatin1()); + styleMap = handleAttrStyle(attr.value().toLatin1()); } else { styleMap.insert(attr.name().toLatin1(), attr.value().toLatin1()); @@ -94,22 +145,33 @@ void SvgFileLoader::handleLabelG(QPainterPath& painterPath) { } void SvgFileLoader::handleLabelPath(QPainterPath& painterPath) { + QPainterPath elementPainterPath; + QString transformStyle = ""; QMap labelStyle; for (auto& attr : xmlReader->attributes()) { if (attr.name().toString() == QLatin1String("d")) { - QQuickSvgParser::parsePathDataFast(attr.value().toLatin1(), painterPath); + QQuickSvgParser::parsePathDataFast(attr.value().toLatin1(), elementPainterPath); } else if (attr.name().toString() == QLatin1String("style")) { - labelStyle = transformStyle(attr.value().toLatin1()); + labelStyle = handleAttrStyle(attr.value().toLatin1()); } + else if (attr.name().toString() == QLatin1String("transform")) { + transformStyle = attr.value().toLatin1(); + } else { labelStyle.insert(attr.name().toLatin1(), attr.value().toLatin1()); } } + if (!transformStyle.isEmpty()) { + handleAttrTransform(transformStyle, elementPainterPath); + } + painterPath.addPath(elementPainterPath); } void SvgFileLoader::handleLabelRect(QPainterPath& painterPath) { QMap labelStyle; + QPainterPath elementPainterPath; + QString transformStyle = ""; double xBegin = 0, yBegin = 0, width = 0, height = 0;; for (auto& attr : xmlReader->attributes()) { if (attr.name().toString() == QLatin1String("x")) { @@ -122,17 +184,26 @@ void SvgFileLoader::handleLabelRect(QPainterPath& painterPath) { height = attr.value().toDouble(); } else if (attr.name().toString() == QLatin1String("style")) { - labelStyle = transformStyle(attr.value().toLatin1()); + labelStyle = handleAttrStyle(attr.value().toLatin1()); + } + else if (attr.name().toString() == QLatin1String("transform")) { + transformStyle = attr.value().toLatin1(); } else { labelStyle.insert(attr.name().toLatin1(), attr.value().toLatin1()); } } qDebug() << labelStyle; - painterPath.addRect(xBegin, yBegin, xBegin + width, yBegin + height); + elementPainterPath.addRect(xBegin, yBegin, xBegin + width, yBegin + height); + if (!transformStyle.isEmpty()) { + handleAttrTransform(transformStyle, elementPainterPath); + } + painterPath.addPath(elementPainterPath); } void SvgFileLoader::handleLabelCircle(QPainterPath& painterPath) { + QPainterPath elementPainterPath; + QString transformStyle = ""; QMap labelStyle; double cx = 0, cy = 0, r = 0; for (auto& attr : xmlReader->attributes()) { @@ -144,18 +215,28 @@ void SvgFileLoader::handleLabelCircle(QPainterPath& painterPath) { r = attr.value().toDouble(); } else if (attr.name().toString() == QLatin1String("style")) { - labelStyle = transformStyle(attr.value().toLatin1()); + labelStyle = handleAttrStyle(attr.value().toLatin1()); + } + else if (attr.name().toString() == QLatin1String("transform")) { + transformStyle = attr.value().toLatin1(); } else { labelStyle.insert(attr.name().toLatin1(), attr.value().toLatin1()); } } qDebug() << labelStyle; + elementPainterPath.addEllipse(cx, cy, r, r); + if (!transformStyle.isEmpty()) { + handleAttrTransform(transformStyle, elementPainterPath); + } + painterPath.addPath(elementPainterPath); //addEllipse(cx, cy, r, r, painterPath); - painterPath.addEllipse(cx, cy, r, r); + } void SvgFileLoader::handleLabelEllipse(QPainterPath& painterPath) { + QPainterPath elementPainterPath; + QString transformStyle = ""; QMap labelStyle; double cx = 0, cy = 0, rx = 0, ry = 0; for (auto& attr : xmlReader->attributes()) { @@ -168,7 +249,10 @@ void SvgFileLoader::handleLabelEllipse(QPainterPath& painterPath) { } else if (attr.name().toString() == QLatin1String("ry")) { rx = attr.value().toDouble(); } else if (attr.name().toString() == QLatin1String("style")) { - labelStyle = transformStyle(attr.value().toLatin1()); + labelStyle = handleAttrStyle(attr.value().toLatin1()); + } + else if (attr.name().toString() == QLatin1String("transform")) { + transformStyle = attr.value().toLatin1(); } else { labelStyle.insert(attr.name().toLatin1(), attr.value().toLatin1()); @@ -176,49 +260,73 @@ void SvgFileLoader::handleLabelEllipse(QPainterPath& painterPath) { } qDebug() << labelStyle; //addEllipse(cx, cy, rx, ry, painterPath); - painterPath.addEllipse(cx, cy, rx, ry); + elementPainterPath.addEllipse(cx, cy, rx, ry); + if (!transformStyle.isEmpty()) { + handleAttrTransform(transformStyle, elementPainterPath); + } + painterPath.addPath(elementPainterPath); } void SvgFileLoader::handleLabelPolyline(QPainterPath& painterPath) { + QPainterPath elementPainterPath; + QString transformStyle = ""; QMap labelStyle; for (auto& attr : xmlReader->attributes()) { if (attr.name().toString() == QLatin1String("points")) { - QPolygonF points = transformPoints(attr.value().toLatin1()); - painterPath.addPolygon(points); + QPolygonF points = handleAttrPoints(attr.value().toLatin1()); + elementPainterPath.addPolygon(points); } else if (attr.name().toString() == QLatin1String("style")) { - labelStyle = transformStyle(attr.value().toLatin1()); + labelStyle = handleAttrStyle(attr.value().toLatin1()); + } + else if (attr.name().toString() == QLatin1String("transform")) { + transformStyle = attr.value().toLatin1(); } else { labelStyle.insert(attr.name().toLatin1(), attr.value().toLatin1()); } } qDebug() << labelStyle; + if (!transformStyle.isEmpty()) { + handleAttrTransform(transformStyle, elementPainterPath); + } + painterPath.addPath(elementPainterPath); } void SvgFileLoader::handleLabelPolygon(QPainterPath & painterPath) { + QPainterPath elementPainterPath; + QString transformStyle = ""; QMap labelStyle; for (auto& attr : xmlReader->attributes()) { if (attr.name().toString() == QLatin1String("points")) { - QPolygonF points = transformPoints(attr.value().toLatin1()); + QPolygonF points = handleAttrPoints(attr.value().toLatin1()); //points.push_back(*points.begin()); - painterPath.addPolygon(points); - painterPath.closeSubpath(); + elementPainterPath.addPolygon(points); + elementPainterPath.closeSubpath(); } else if (attr.name().toString() == QLatin1String("style")) { - labelStyle = transformStyle(attr.value().toLatin1()); + labelStyle = handleAttrStyle(attr.value().toLatin1()); + } + else if (attr.name().toString() == "transform") { + transformStyle = attr.value().toLatin1(); } else { labelStyle.insert(attr.name().toLatin1(), attr.value().toLatin1()); } } qDebug() << labelStyle; + if (!transformStyle.isEmpty()) { + handleAttrTransform(transformStyle, elementPainterPath); + } + painterPath.addPath(elementPainterPath); } +/* void SvgFileLoader::addEllipse(double x, double y, double w, double h, QPainterPath& painterPath) { double k = w / 0.75; painterPath.moveTo(x, y - h); painterPath.cubicTo(QPointF(x + k, y - h), QPointF(x + k, y + h), QPointF(x, y + h)); painterPath.cubicTo(QPointF(x - k, y + h), QPointF(x - k, y - h), QPointF(x, y - h)); painterPath.closeSubpath(); -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.h b/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.h index 352b9b0..3bdcd8a 100644 --- a/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.h +++ b/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.h @@ -13,9 +13,10 @@ private: bool existFatherLabelG; QMap styleMap; std::shared_ptr xmlReader; - QPolygonF transformPoints(QString points); - QMap transformStyle(QString style); - void addEllipse(double cx, double cy, double h, double w, QPainterPath& painterPath); + QPolygonF handleAttrPoints(QString points); + QMap handleAttrStyle(QString style); + void handleAttrTransform(QString transformStyle, QPainterPath& painterPath); + //void addEllipse(double cx, double cy, double h, double w, QPainterPath& painterPath); void handleLabelG(QPainterPath& painterPath); void handleLabelPath(QPainterPath& painterPath); void handleLabelRect(QPainterPath& painterPath); diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.cpp index 5c01eb8..442a6d2 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.cpp @@ -22,6 +22,12 @@ Point CubicBezier::calculateControlPoint(Point a, Point b) { }; } +double CubicBezier::ValueOfFunctionS(double t) { + double dxt = -3 * vX[0] * (1 - t) * (1 - t) + 3 * vX[1] * (1 - t) * (1 - 3 * t) + 3 * vX[2] * t * (2 - 3 * t) + 3 * vX[3] * t * t; + double dyt = -3 * vY[0] * (1 - t) * (1 - t) + 3 * vY[1] * (1 - t) * (1 - 3 * t) + 3 * vY[2] * t * (2 - 3 * t) + 3 * vY[3] * t * t; + return sqrt(dxt * dxt + dyt * dyt); +} + void CubicBezier::findPointsOfDivison(vector &p, vector& res) { double a = (-p[0] + 3 * p[1] - 3 * p[2] + p[3]); if (fabs(a) > eps) { @@ -55,20 +61,26 @@ void CubicBezier::transformToCubic() { } void CubicBezier::splitBezierCubic(double t, vector& res) { - LinePtr Lf(new CubicBezier()); - float pt = 1 - t; Point pointE = { getLineValueByT(t, false), getLineValueByT(t, true) }; Point pointF = getPointByT(getPointByIndex(0), getPointByIndex(1), t); Point pointG = getPointByT(getPointByIndex(1), getPointByIndex(2), t); Point pointH = getPointByT(getPointByIndex(2), getPointByIndex(3), t); - Lf->push_back(getPointByIndex(0)); - Lf->push_back(pointF); - Lf->push_back(getPointByT(pointF, pointG, t)); - Lf->push_back(pointE); - res.push_back(Lf); + vector vP; vP.clear(); + vP.push_back(getPointByIndex(0)); + vP.push_back(pointF); + vP.push_back(getPointByT(pointF, pointG, t)); + vP.push_back(pointE); + LinePtr lf(new CubicBezier(vP)); + double totalLen = getIntegralByT(1), len = getIntegralByT(t); + if (totalLen <= eps) return; + double ratePoint = (1 - len / totalLen) * rate.first + len / totalLen * rate.second; + lf->setRate({ rate.first, ratePoint }); + res.push_back(lf); setPointByIndex(0, pointE); setPointByIndex(1, getPointByT(pointG, pointH, t)); setPointByIndex(2, pointH); + updateLeftType(); + setRate({ ratePoint, rate.second }); } void CubicBezier::monotonization(vector & res) { @@ -120,4 +132,4 @@ int CubicBezier::judgeOneSideIntersection(double xy, double l, double r, bool is double CubicBezier::getMinDistanceFromPoint(Point p) { return CubicBezierSignedDistance::cubic_bezier_dis(p, getBegin(), getPointByIndex(1), getPointByIndex(2), getEnd()); -} \ No newline at end of file +} diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.h b/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.h index 81f9d5d..e479f67 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/CubicBezier.h @@ -11,12 +11,14 @@ namespace Renderer static Point calculateControlPoint(Point a, Point b); static void findPointsOfDivison(std::vector& p, std::vector& res); void splitBezierCubic(double t, std::vector& res); + public: virtual double findTByValue(double value, bool isY); virtual void monotonization(std::vector & res); virtual double getLineValueByT(double t, bool isY); virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY); virtual double getMinDistanceFromPoint(Point p); + virtual double ValueOfFunctionS(double t); void transformToCubic(); }; } diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Line.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/Line.cpp index f26afd7..dbd6c0f 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Line.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Line.cpp @@ -1,4 +1,5 @@ #include "Line.h" +#include using namespace Renderer; using std::vector; using std::pair; @@ -14,14 +15,29 @@ Line::Line(vector Vp) { vX.push_back(now.x); vY.push_back(now.y); } + updateLeftType(); + rate = { 0, 1 }; +} + +bool Line::updateLeftType() { if (*vY.rbegin() < vY[0]) leftType = 0; else leftType = 1; + return true; } int Line::size() { return siz; } +bool Line::setRate(std::pair inRate) { + rate = inRate; + return true; +} + +uint Line::getRate() { + return glm::packUnorm2x16(glm::vec2(rate.first, rate.second)); +} + vector Line::toPointVector() const { vector vL; for (int i = 0; i < siz; i++) { @@ -151,4 +167,27 @@ bool Line::judgeIntersectionWithWidth(QVector4D bound, double width, int type) { || judgeOneSideIntersectionWithWidth(bound.w(), bound.x(), bound.z(), true, width, type) || judgeOneSideIntersectionWithWidth(bound.x(), bound.y(), bound.w(), false, width, type) || judgeOneSideIntersectionWithWidth(bound.z(), bound.y(), bound.w(), false, width, type); +} + +double Line::getIntegralByT(double t) { + double T[12][12], err = 1, S = 0, tmpPow4 = 1; + T[1][1] = t * (ValueOfFunctionS(t) + ValueOfFunctionS(0)) / 2; + int n = 1, k = 0; + while (err > eps) { + ++k; S = 0; + for (int i = 1; i <= n; i++) { + double x = t * (2 * i - 1) / 2; + S = S + ValueOfFunctionS(x); + } + tmpPow4 = 1; + T[k + 1][1] = (T[k][1] + t * S) / 2; + for (int m = 1; m <= k; m++) { + tmpPow4 *= 4; + T[k + 1][m + 1] = (tmpPow4 * T[k + 1][m] - T[k][m]) / (tmpPow4 - 1); + } + err = fabs(T[k + 1][k + 1] - T[k + 1][k]); + n <<= 1; t = t / 2; + if (k >= 8) break; + } + return T[k + 1][k + 1]; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Line.h b/ArchitectureColoredPainting/src/Renderer/Painting/Line.h index e9accc4..2198f8c 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Line.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Line.h @@ -49,21 +49,28 @@ namespace Renderer protected: std::vector vX, vY; int siz, leftType; + std::pair rate; public: typedef std::shared_ptr LinePtr; - Line() :siz(0) {} + Line() : siz(0), leftType(0), rate({0, 1}) {} Line(std::vector Vp); int size(); + bool setRate(std::pair inRate); + uint getRate(); void clear(); Point getBegin(); Point getEnd(); int direction(bool isY); + bool updateLeftType(); virtual double getLineValueByT(double t, bool isY) = 0; + // s = sqrt(x^2+y^2); + virtual double ValueOfFunctionS(double t) = 0; virtual void monotonization(std::vector & res) = 0; virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY) = 0; virtual double getMinDistanceFromPoint(Point p) = 0; bool judgeOneSideIntersectionWithWidth(double xy, double l, double r, bool isY, double width, int type); virtual double findTByValue(double value, bool isY) = 0; + double getIntegralByT(double t); bool judgeIntersectionWithWidth(QVector4D bound, double width, int type); bool judgeIntersection(QVector4D bound); int getPointSideOfLine(Point p); diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp index 736b55e..2b4cd56 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp @@ -108,15 +108,30 @@ void LineTree::monotonization(vector& inLines, vectortoPointVector(); + canPut = false; + index = 0; for (Point& p : pointVector) { int pointIndex = getPointIndex(p); - lineIndexs.push_back(pointIndex); - if (pointVector.size() == 2) - lineIndexs.push_back(pointIndex); + if (pointVector.size() == 2) { + index = (pointIndex << 16) + pointIndex; + lineIndexs.push_back(index); + } + else { + index <<= 16; + index += pointIndex; + if (canPut) { + lineIndexs.push_back(index); + index = 0; + } + canPut = !canPut; + } } + lineIndexs.push_back(nowLine->getRate()); } } @@ -237,15 +252,15 @@ vector LineTree::getPointLineAndBvhTree(vector& resPoints, v for (auto& vectorIter : tmpPoints) { resPoints.push_back(vectorIter.second.x); resPoints.push_back(vectorIter.second.y); - vectorIter.second.show(); - std::cout << '\n'; + //vectorIter.second.show(); + //std::cout << '\n'; } // 线集 for (auto& nowLineIndex : lineIndexs) { resLines.push_back(nowLineIndex); - std::cout << nowLineIndex << ' '; + //std::cout << nowLineIndex << ' '; } - std::cout << '\n'; + //std::cout << '\n'; // 返回构造BvhTree数据 vector resBvhTreeData; for (auto& nowTreeNode : restOfTreeNodes) { @@ -253,13 +268,13 @@ vector LineTree::getPointLineAndBvhTree(vector& resPoints, v oneData.leftSon = resLines.size(); oneData.rightSon = 0; oneData.bound = nowTreeNode.bound; - std::cout << nowTreeNode.lineSet.size() << ' '; + //std::cout << nowTreeNode.lineSet.size() << ' '; resLines.push_back(nowTreeNode.lineSet.size()); for (auto& lineIndex : nowTreeNode.lineSet) { resLines.push_back(lineIndex); - std::cout << lineIndex << ' '; + //std::cout << lineIndex << ' '; } - std::cout << '\n'; + //std::cout << '\n'; resBvhTreeData.push_back(oneData); } return resBvhTreeData; diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.cpp index 5351c22..101b5f8 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.cpp @@ -14,6 +14,10 @@ double StraightLine::getLineValueByT(double t, bool isY) { return t * (valueEnd - valueBegin) + valueBegin; } +double StraightLine::ValueOfFunctionS(double t) { + return sqrt((vX[1] - vX[0]) * (vX[1] - vX[0]) + (vY[1] - vY[0]) * (vY[1] - vY[0])); +} + double StraightLine::findTByValue(double value, bool isY) { Point pointBegin = getPointByIndex(0), pointEnd = getPointByIndex(1); if (!isY) { diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h index f2101d4..73625c0 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/StraightLine.h @@ -11,5 +11,6 @@ namespace Renderer virtual double findTByValue(double value, bool isY); virtual int judgeOneSideIntersection(double xy, double l, double r, bool isY); virtual double getMinDistanceFromPoint(Point p); + virtual double ValueOfFunctionS(double t); }; } \ No newline at end of file diff --git a/UnitTest/ElementRendererTest.cpp b/UnitTest/ElementRendererTest.cpp index f9c9538..859f4a3 100644 --- a/UnitTest/ElementRendererTest.cpp +++ b/UnitTest/ElementRendererTest.cpp @@ -3,6 +3,7 @@ #include #include "ElementRendererTest.h" #include "Renderer/Painting/ElementStyle.h" +#include using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace Renderer; @@ -195,4 +196,5 @@ namespace UnitTest a.exec(); } }; + } diff --git a/UnitTest/UnitTest.cpp b/UnitTest/UnitTest.cpp index a03f793..d24ce02 100644 --- a/UnitTest/UnitTest.cpp +++ b/UnitTest/UnitTest.cpp @@ -3,12 +3,43 @@ #include #include #include +#include +#include "Renderer/Painting/CubicBezier.h" +#include using namespace Microsoft::VisualStudio::CppUnitTestFramework; namespace UnitTest { + 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; + + } + Logger::WriteMessage(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()).c_str()); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + } TEST_CLASS(UnitTest) { public: @@ -31,4 +62,37 @@ namespace UnitTest a.exec(); } }; + + TEST_CLASS(SvgLoaderTest) + { + public: + TEST_METHOD(LoadSvg) + { + qInstallMessageHandler(messageHandler); + QPainterPath painterPath; + SvgFileLoader svgloader; + svgloader.loadSvgFile("D:\\BigC\\Project\\ArchitectureColoredPainting\\svg\\test.svg", painterPath); + } + }; + + TEST_CLASS(CubicBezierTest) + { + public: + TEST_METHOD(CubicIntegral) + { + qInstallMessageHandler(messageHandler); + std::shared_ptr line(new Renderer::CubicBezier()); + line->push_back({ -1, -1 }); + line->push_back({ -1, 1 }); + line->push_back({ 1, 1 }); + line->push_back({ 1, -1 }); + vector> outLines; + line->monotonization(outLines); + for (auto line : outLines) { + qDebug() << line->getRate(); + } + + } + }; + } diff --git a/svg/test.svg b/svg/test.svg new file mode 100644 index 0000000..1424018 --- /dev/null +++ b/svg/test.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file From 8920dc39ad64abafafd2f6195df0e55825a4eb39 Mon Sep 17 00:00:00 2001 From: wuyize Date: Sat, 25 Feb 2023 13:34:24 +0800 Subject: [PATCH 5/9] =?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 6/9] =?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); From 4d9fe01fe9fc2eaae779ad7792c5561c74125212 Mon Sep 17 00:00:00 2001 From: "yang.yongquan" <3395816735@qq.com> Date: Sat, 25 Feb 2023 17:08:45 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86ShortCutTree?= =?UTF-8?q?=E9=83=A8=E5=88=86=E7=9A=84=E7=BA=BF=E9=83=A8=E5=88=86=E7=B4=A2?= =?UTF-8?q?=E5=BC=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Renderer/Painting/ShortCutTree.cpp | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.cpp index 7308c33..df50a92 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/ShortCutTree.cpp @@ -112,10 +112,8 @@ void ShortCutTree::generateShortCutSegment(ShortCutNode& nowTreeNode) { } for (auto& iter : pointSet) { nowTreeNode.lineSet.push_back(numLine); - lineIndexs.push_back(iter.first); - lineIndexs.push_back(iter.first); - lineIndexs.push_back(iter.second); - lineIndexs.push_back(iter.second); + lineIndexs.push_back((iter.first << 16) + iter.first); + lineIndexs.push_back((iter.second << 16) + iter.second); numLine++; } } @@ -149,14 +147,28 @@ bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNod } void ShortCutTree::simplifyLineVector() { + bool canPut = false; + GLuint index = 0; numLine = allLines.size(); for (auto& nowLine : allLines) { PointVector pointVector = nowLine->toPointVector(); + canPut = false; + index = 0; for (Point& p : pointVector) { int pointIndex = getPointIndex(p); - lineIndexs.push_back(pointIndex); - if (pointVector.size() == 2) - lineIndexs.push_back(pointIndex); + if (pointVector.size() == 2) { + index = (pointIndex << 16) + pointIndex; + lineIndexs.push_back(index); + } + else { + index <<= 16; + index += pointIndex; + if (canPut) { + lineIndexs.push_back(index); + index = 0; + } + canPut = !canPut; + } } } for (auto& nowTreeNode : restOfTreeNodes) { From f798ea410d4ae8f3f391ae33fb8a7423e7935e1f Mon Sep 17 00:00:00 2001 From: wuyize Date: Sat, 25 Feb 2023 19:38:35 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BA=86=E5=A4=84?= =?UTF-8?q?=E7=90=86svg=E5=B9=B3=E7=A7=BB=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp | 2 +- ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp b/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp index d4c7d03..81d8966 100644 --- a/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp @@ -95,7 +95,7 @@ void SvgFileLoader::handleAttrTransform(QString transformStyle, QPainterPath& pa QString numStr = (*op.split('(').rbegin()).trimmed() + ','; QString tmpNum = ""; for (auto c : numStr) { - if (isdigit(c.toLatin1())) { + if (isdigit(c.toLatin1()) || c == '-' || c == '.') { tmpNum += c; } else { diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index 90f675e..ed629b0 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -487,7 +487,7 @@ void RendererGLWidget::paintGL() if (accTime > 1.) { std::cout << std::format("{:20}\r", ""); - 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()); + std::cout << std::format("FPS: {:.2f}({:.2f}ms) Page: {:.2f}ms Pos: {:.2f},{:.2f},{:.2f}\r", frameCnt / accTime, averageDuration / 1e6 / frameCnt, vtManager->pageLoadDuration / 1e6 / frameCnt, camera.Position.x(), camera.Position.y(), camera.Position.z()); vtManager->pageLoadDuration = 0; accTime = 0; frameCnt = 0; From 723c0a9760051fedd303a870771142d0b30000ea Mon Sep 17 00:00:00 2001 From: wuyize Date: Sun, 26 Feb 2023 13:57:53 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E7=BA=B9=E7=90=86=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...rchitectureColoredPainting.vcxproj.filters | 6 +- .../res/Shaders/pageId_downsample.comp | 2 +- .../src/Renderer/Model.cpp | 230 ++---------------- .../src/Renderer/Painting/Element.h | 1 + .../src/Renderer/Painting/Painting.h | 3 +- .../src/Renderer/RendererGLWidget.cpp | 30 +-- 6 files changed, 38 insertions(+), 234 deletions(-) diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters index 6a72e52..95af788 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters @@ -201,9 +201,6 @@ Source Files\Renderer\Preview - - Source Files - Source Files @@ -216,6 +213,9 @@ Source Files + + Source Files\Editor + diff --git a/ArchitectureColoredPainting/res/Shaders/pageId_downsample.comp b/ArchitectureColoredPainting/res/Shaders/pageId_downsample.comp index e2783b0..a5156a4 100644 --- a/ArchitectureColoredPainting/res/Shaders/pageId_downsample.comp +++ b/ArchitectureColoredPainting/res/Shaders/pageId_downsample.comp @@ -4,7 +4,7 @@ layout (local_size_x = 8, local_size_y = 8) in; layout(rg16ui, binding = 3) uniform uimage2D gPageId; -uniform uvec2 dither = uvec2(0); +layout(location = 0) uniform uvec2 dither = uvec2(0); void main() { diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index ee419f2..0304eca 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -11,6 +11,7 @@ #include "Painting/ShortCutTree.h" #include "Painting/Painting.h" #include "../SvgParser.h" +#include using namespace Renderer; using std::vector; @@ -118,7 +119,7 @@ std::unique_ptr Model::processMesh(aiMesh* mesh, const aiScene* scene, aiString str; material->GetTexture(aiTextureType_BASE_COLOR, 0, &str); - if (paintingProgram != nullptr && std::strcmp(str.C_Str(), "17876391417123941155.jpg") == 0) + if (paintingProgram != nullptr && ( std::strcmp(str.C_Str(), "17876391417123941155.jpg") == 0 || std::strcmp(str.C_Str(), "11474523244911310074.jpg") == 0)) { qDebug() << str.C_Str() << "Replaced"; // 初始化网格 @@ -233,72 +234,12 @@ GLuint Renderer::Model::loadPainting(std::string path) if (iter != paintingLoaded.end()) return iter->second; - //vector < vector > lineSet = { - // {{-0.5,0.9}, {0.1,0.3}}, - // {{0.1,0.3}, {0.0204656,0.379534}, {-0.2,0.0632573}, {-0.2,0.175736}}, - // {{-0.2,0.175736}, {-0.2,0.288215}, {-0.579534,0.220466}, {-0.5,0.3}}, - // {{-0.5,0.3}, {-0.420466,0.379534}, {-0.736743,0.6}, {-0.624264,0.6}}, - // {{-0.624264,0.6}, {-0.511785,0.6}, {-0.579534,0.979534}, {-0.5,0.9}} - //}; - - //Contour ctr = SvgParser("M308.49,212.25l23,28.38-82,78.31c-14.28,13.64-26.34-20.6-53.44,9.32l-30.24-13.4,63.56-51.59L190.71,215.6l-32.92,26.72L149.5,232.1l32.92-26.72L173.2,194l-32.91,26.72-7.38-9.08L165.83,185l-38.69-47.66L94.22,164,85,152.65l32.91-26.72-9.21-11.35L75.79,141.3l-5.53-6.81,32.92-26.72L94,96.42,61.05,123.14l-12-14.76L37.72,117.6l12,14.75L30.41,148,0,110.55,136.2,0l30.4,37.46L147.31,53.12l-12-14.76L124,47.58l12,14.75L103.05,89.05l9.21,11.35,32.92-26.72,5.52,6.81-32.91,26.72L127,118.56l32.92-26.72,9.21,11.35-32.91,26.72,38.69,47.67,32.91-26.72,7.37,9.08-32.91,26.72L191.49,198l32.92-26.72,8.29,10.22-32.92,26.71,38.7,47.68L302,204.3l6.45,7.95Z", 331.52, 328.26).parse(); - //ctr = Contour(ctr.begin()+1 , ctr.begin() + 4); - //qDebug() << "Contour---------------------"; - //for (auto& line : ctr) - //{ - // for (auto& p : line) - // p.show(); - // std::cout << std::endl; - //} - //qDebug() << "----------------------------"; - vector> contour = { std::make_shared(SvgParser("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", 100, 100).parse()), - //std::make_shared(SvgParser("M292.82,107.78s0,0,0,0,0,3.59,0,7.62c0,3.85,0,5.78.06,6.43a19.94,19.94,0,0,0,2.87,7.58,15.85,15.85,0,0,0,6.61,6.23A14.75,14.75,0,0,0,310,137a11.69,11.69,0,0,0,7.59-2.92,11,11,0,0,0,3.2-6.84c.15-1.27.58-4.84-1.79-7.64a8.54,8.54,0,0,0-3.56-2.44c-1.32-.52-3.32-1.31-5.06-.33a5.41,5.41,0,0,0-2.14,3,3.48,3.48,0,0,0-.16,2.71c.78,1.86,3.36,2.14,3.47,2.15", 29.07, 30.28).parse()), std::make_shared(SvgParser("M308.49,212.25l23,28.38-82,78.31c-14.28,13.64-26.34-20.6-53.44,9.32l-30.24-13.4,63.56-51.59L190.71,215.6l-32.92,26.72L149.5,232.1l32.92-26.72L173.2,194l-32.91,26.72-7.38-9.08L165.83,185l-38.69-47.66L94.22,164,85,152.65l32.91-26.72-9.21-11.35L75.79,141.3l-5.53-6.81,32.92-26.72L94,96.42,61.05,123.14l-12-14.76L37.72,117.6l12,14.75L30.41,148,0,110.55,136.2,0l30.4,37.46L147.31,53.12l-12-14.76L124,47.58l12,14.75L103.05,89.05l9.21,11.35,32.92-26.72,5.52,6.81-32.91,26.72L127,118.56l32.92-26.72,9.21,11.35-32.91,26.72,38.69,47.67,32.91-26.72,7.37,9.08-32.91,26.72L191.49,198l32.92-26.72,8.29,10.22-32.92,26.71,38.7,47.68L302,204.3l6.45,7.95Z", 331.52, 328.26).parse()), std::make_shared(SvgParser("M377,459.61a11.26,11.26,0,0,1,11.27-11.27H696.12a11.27,11.27,0,0,0,11-8.62A359.84,359.84,0,0,0,708,280.56a11.26,11.26,0,0,0-11-8.73H388.27A11.26,11.26,0,0,1,377,260.57h0a11.26,11.26,0,0,1,11.27-11.26H683.71A11.32,11.32,0,0,0,694.28,234C649.8,113.69,542.57,23.85,412.3,4.12a11.22,11.22,0,0,0-12.76,11.17v158.9a11.26,11.26,0,0,0,11.26,11.27H583.12a11.32,11.32,0,0,0,9.26-17.75c-31.67-46.59-78.51-75.2-109.11-90.07a11.25,11.25,0,0,0-16.13,10.17V115.2a11.24,11.24,0,0,0,6.22,10.07l7.51,3.76a11.28,11.28,0,0,1,5,15.12h0a11.27,11.27,0,0,1-15.11,5l-20-10a11.27,11.27,0,0,1-6.22-10.07V54a11.27,11.27,0,0,1,14.62-10.75c5.11,1.59,125.66,40.35,172.24,149A11.27,11.27,0,0,1,621.11,208H388.27A11.26,11.26,0,0,1,377,196.73V11.36A11.32,11.32,0,0,0,365.89.08C363.34,0,360.79,0,358.22,0s-5.11,0-7.66.08a11.32,11.32,0,0,0-11.11,11.28V196.74A11.26,11.26,0,0,1,328.18,208H95.35A11.27,11.27,0,0,1,85,192.3c46.57-108.67,167.12-147.42,172.23-149A11.26,11.26,0,0,1,271.86,54v75.11a11.25,11.25,0,0,1-6.23,10.07l-20,10a11.27,11.27,0,0,1-15.11-5h0a11.26,11.26,0,0,1,5-15.11l7.52-3.76a11.27,11.27,0,0,0,6.22-10.07V87.82a11.25,11.25,0,0,0-16.14-10.16c-30.6,14.87-77.45,43.48-109.1,90.07a11.3,11.3,0,0,0,9.25,17.74H305.66a11.26,11.26,0,0,0,11.27-11.26V15.31A11.22,11.22,0,0,0,304.17,4.14C173.88,23.86,66.66,113.71,22.17,234a11.32,11.32,0,0,0,10.56,15.29H328.18a11.26,11.26,0,0,1,11.27,11.26v0a11.26,11.26,0,0,1-11.27,11.26H19.52a11.26,11.26,0,0,0-11,8.72,359.84,359.84,0,0,0,.83,159.16,11.26,11.26,0,0,0,11,8.61H328.18a11.26,11.26,0,0,1,11.27,11.27h0a11.26,11.26,0,0,1-11.27,11.26h-294a11.32,11.32,0,0,0-10.53,15.4C69,604.65,175.3,692.78,304.16,712.3a11.21,11.21,0,0,0,12.76-11.16V542.22A11.26,11.26,0,0,0,305.66,531h-166c-9.53,0-14.89,11.22-8.69,18.47,34.09,39.77,74.45,65.66,101.77,80.18a11.25,11.25,0,0,0,16.53-10V591a11.26,11.26,0,0,1,11.26-11.26h0A11.26,11.26,0,0,1,271.85,591v63.85A11.27,11.27,0,0,1,256.8,665.5c-4.45-1.59-109.58-40-171-139.9a11.27,11.27,0,0,1,9.59-17.17H328.18a11.26,11.26,0,0,1,11.27,11.26V705.08a11.32,11.32,0,0,0,11.11,11.28q3.82.07,7.66.08c2.57,0,5.12,0,7.67-.08A11.32,11.32,0,0,0,377,705.08V519.69a11.25,11.25,0,0,1,11.27-11.26H621.1a11.26,11.26,0,0,1,9.59,17.16c-61.46,99.87-166.59,138.3-171,139.9a11.27,11.27,0,0,1-15-10.61V591a11.26,11.26,0,0,1,11.26-11.26h0A11.26,11.26,0,0,1,467.14,591v28.6a11.25,11.25,0,0,0,16.53,10c27.33-14.53,67.68-40.42,101.77-80.19,6.2-7.23.85-18.46-8.69-18.46h-166a11.26,11.26,0,0,0-11.26,11.26V701.12a11.21,11.21,0,0,0,12.76,11.17c128.86-19.51,235.14-107.66,280.48-226a11.33,11.33,0,0,0-10.53-15.41h-294A11.25,11.25,0,0,1,377,459.61ZM35.27,399.53V316.9a11.26,11.26,0,0,1,11.27-11.26H669.92a11.25,11.25,0,0,1,11.26,11.26v82.63a11.25,11.25,0,0,1-11.26,11.26H46.54a11.27,11.27,0,0,1-11.27-11.26Z", 716.45, 716.44).parse()) }; - //vector> style = { - // std::make_shared(std::vector{ - // //strokeStyle - // //stroke - // 1, - // //strokeWidth - // 0.02, - // //strokeEndType - // 0, //圆角 - // //strokeFillType - // 0, //单色 - // //线类型 - // 0, //双侧 - // //线外描边宽度 - // 0, - // //线外描边方式 - // 0, //单色 - // //strokeFillColorMetallicRoughness - // 1,0,1, 0,0.8, - // }), - // std::make_shared(std::vector{ - // //fillStyle - // //fill - // 0, - // //fillType - // 0, //单色 - // //fillColorMetallicRoughness - // 240 / 255., 220 / 255., 160 / 255., 0.996, 0.18, - // }), - // std::make_shared(std::vector{ - // //fillStyle - // //fill - // 0, - // //fillType - // 0, //单色 - // //fillColorMetallicRoughness - // 24 / 255., 220 / 255., 16 / 255., 0., 0.18, - // }), - //}; - vector> style = { std::make_shared(), std::make_shared(0.02), @@ -311,164 +252,25 @@ GLuint Renderer::Model::loadPainting(std::string path) std::make_shared(Element{ contour[2], style[0]}), }; Painting painting; - for (int i = 0; i < 1000; i++) + + if (path == "17876391417123941155.jpg") { - 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 }); + } + else + { + for (int i = 0; i < 1000; i++) + { + float x = (float)rand() / RAND_MAX * 2 - 1; + float y = (float)rand() / RAND_MAX * 2 - 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); - //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(glFunc); - ///////////////////////////////////////////////////////////////////////////////////////////////// - std::vector bvhChildren0 = { - //root - 1,2, - 3,4, 5,6, - encodeChild(2),0, encodeChild(1),GLuint(30. / 360 * 65536 + 1 * 65536) /*右儿子用来表示旋转角度和zIndex*/, encodeChild(3),0, encodeChild(0),0, - //elememt0 - 1,2, - encodeChild(20)/*contour索引,由于contour不定长,这里需要给到contour在elementIndex中位置*/,0/*封闭图形*/, encodeChild(24), 0, - //elememt1 - encodeChild(12)/*contour索引*/, 1/*线*/ - - }; - std::vector bvhBounds0 = { - //root - QVector4D(-1,-1,1,1), - QVector4D(-0.9,-0.9,-0.1,0.9), QVector4D(0.1, -0.9,0.9,0.9), - QVector4D(-0.8,-0.8,-0.2,-0.1), QVector4D(-0.7,0.2,-0.2,0.7), QVector4D(0.2,-0.8,0.8,-0.1), QVector4D(0.3,0.2,0.7,0.7), - //elememt0 - QVector4D(-1,-1,1,1), - QVector4D(-1,-1,-0.2,1), QVector4D(-0.2,-1,1,1), - //elememt1 - QVector4D(-1,-1,1,1) - }; - - /** - * @[0] elementBvhRoot - * @[1] styleOffset - * @[2] pointsOffset - * @[3] linesOffset - */ - std::vector elementOffset0 = { - //element0 - glm::uvec4(7, 14, 0, 0), - //element1 - glm::uvec4(10, 39, 21, 28), - //element2 - glm::uvec4(10, 51, 21, 28), - //element3 - glm::uvec4(10, 63, 21, 28), - }; - - std::vector elementIndex0 = { - //element0 - //lines, 全部当作三阶贝塞尔, 每条线四个点索引 - 0,1,1,2, - 0,0,3,3, - 3,4,4,5, - 2,2,5,5, - 5,5,6,6, - //contours, 第一个元素为线数,后面为轮廓线索引 - 3, 1,2,4, - 3, 0,2,3, - //element1 - //lines - 0,7,8,1, - 1,1,4,4, - 5,5,6,6, - //contours - 3, 0,1,2 - }; - - std::vector elementData0 = { - //element0 - //points - -0.2,1, -0.2,-0.2, 1,-0.2, -1,1, -1,-1, 1,-1, 1,1, - //fillStyle - //fill - 0, - //fillType - 0, //单色 - //fillColorMetallicRoughness - 1,1,0, 0,0.8, - - //element1 - //points - 0.5,-0.5, 0.5,0.5, -0.2,0.5, -0.5,0.2, -0.5,-0.5, -0.8,-0.5, -0.8,0.5, 0.5,-0.4, 0.5,0.4, - //strokeStyle - //stroke - 1, - //strokeWidth - 0.1, - //strokeEndType - 0, //圆角 - //strokeFillType - 0, //单色 - //线类型 - 2, //左侧 - //线外描边宽度 - 0, - //线外描边方式 - 0, //单色 - //strokeFillColorMetallicRoughness - 1,0,1, 0,0.8, - //strokeStyle - //stroke - 1, - //strokeWidth - 0.1, - //strokeEndType - 0, //圆角 - //strokeFillType - 2, //单色 - //线类型 - 1, //左侧 - //线外描边宽度 - 0, - //线外描边方式 - 0, //单色 - //strokeFillColorMetallicRoughness - 1,0,1, 0,0.8, - //strokeStyle - //stroke - 1, - //strokeWidth - 0.1, - //strokeEndType - 0, //圆角 - //strokeFillType - 1, //单色 - //线类型 - 0, //左侧 - //线外描边宽度 - 0, - //线外描边方式 - 0, //单色 - //strokeFillColorMetallicRoughness - 1,0,1, 0,0.8, - }; - - - //m_mesh->paintingIndex = paintingHelper->addPainting(bounds.size(), std::vector(children.begin()+2, children.end()), bounds, - // elementOffset, elementIndex, elementData); - /*GLuint index = paintingHelper->addPainting(bvhChildren0, bvhBounds0, - elementOffset0, elementIndex0, elementData0);*/ - //GLuint index = paintingHelper->addPainting(painting); - //paintingLoaded.insert({ path, index }); auto index = vtManager->createVirtualTexture(painting); paintingLoaded.emplace(path, index); diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Element.h b/ArchitectureColoredPainting/src/Renderer/Painting/Element.h index 58a3b25..3ff1d85 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Element.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Element.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "Line.h" #include "ElementStyle.h" diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h index fe29c1d..8821dc6 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h @@ -69,7 +69,6 @@ namespace Renderer 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(QOpenGLFunctions_4_5_Compatibility* glFunc); @@ -81,6 +80,8 @@ namespace Renderer std::unordered_map, GLuint> stylePool; std::map elementPool; std::vector elements; + + void addElement(ElementWithTransform element); void insertContourBuffer(std::shared_ptr buffer); BvhTreeData encodeElementLeaf(ElementWithTransform e); }; diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index ed629b0..b9f4a80 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -296,23 +296,8 @@ void RendererGLWidget::paintGL() { QOpenGLFunctions_4_5_Core* glFunc = QOpenGLContext::currentContext()->versionFunctions(); - 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); light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw))); @@ -383,6 +368,21 @@ void RendererGLWidget::paintGL() } } plainProgramPtr->release(); + + pageIdDownsampleProgramPtr->bind(); + gl->BindImageTexture(3, gbuffers[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG16UI); + gl->Uniform2ui(0, rand() % 8, rand() % 8); + 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); + fboPtr->release(); } gl->Finish();