From 57b537b66b03163420e1b240df62d537a9cc4dda Mon Sep 17 00:00:00 2001 From: wuyize Date: Tue, 21 Feb 2023 20:13:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=94=B9=E7=94=A8=E8=99=9A?= =?UTF-8?q?=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(); }