From 6d104faf5309aadffe5cda462368fe79f011caf8 Mon Sep 17 00:00:00 2001 From: wuyize Date: Fri, 27 Jan 2023 17:36:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=BA=BF=E7=9A=84=E5=8D=95?= =?UTF-8?q?=E4=BE=A7=E6=8F=8F=E8=BE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ArchitectureColoredPainting.vcxproj | 2 +- .../Shaders/painting.comp | 468 ++++++++++-------- .../src/Renderer/Model.cpp | 56 ++- .../src/Renderer/RendererGLWidget.cpp | 111 +++-- ArchitectureColoredPainting/src/SvgParser.cpp | 15 + README.md | 6 +- 6 files changed, 358 insertions(+), 300 deletions(-) diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index 014d110..79ab108 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -67,7 +67,7 @@ - stdcpp17 + stdcpp20 $(SolutionDir)ArchitectureColoredPainting\src\Editor\RightBar;$(SolutionDir)ArchitectureColoredPainting\src\Editor\;$(SolutionDir)QGoodWindow;$(SolutionDir)FramelessHelper\include;$(SolutionDir)FramelessHelper\qmake\inc\core;$(SolutionDir)FramelessHelper\include\FramelessHelper\Core;%(AdditionalIncludeDirectories) FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions) diff --git a/ArchitectureColoredPainting/Shaders/painting.comp b/ArchitectureColoredPainting/Shaders/painting.comp index 7f27e23..96fbdbd 100644 --- a/ArchitectureColoredPainting/Shaders/painting.comp +++ b/ArchitectureColoredPainting/Shaders/painting.comp @@ -252,65 +252,51 @@ int cubic_bezier_int_test(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3) return n_ints; } +bvec3 segment_sign_test(vec2 uv, vec2 p0, vec2 p1) +{ + p0 -= uv; + p1 -= uv; + bvec3 ret; + 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.) + { + if (p0.y * p1.y < 0.) + ret.y = false; + else + ret.y = false; + ret.xz = bvec2(false); + } + else + { + if (p0.y * p1.y < 0.) + ret.y = true; + else + ret.y = false; + ret.xz = bvec2(true); + } + return ret; +} + bvec3 cubic_bezier_sign_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; +// if(abs(p3.y-p0.y)< 1e-4) +// { +// return segment_sign_test(uv, p0,p3); +// } - // vec3 roots = vec3(1e38); - // int n_roots; - - // int n_ints = 0; - // bvec3 result = bvec3(false); - - // 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; - // result[1] = !result[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) - // { - // if(roots[i] >= 0. && roots[i] <= 1.){ - // result[1] = !result[1]; - // } - // else if(roots[i] < 0.) - // { - // result[0]=!result[0]; - // } - // else - // result[2]=!result[2]; - // //n_ints++; - // } - // } - // } - // } - // return result; 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); @@ -506,18 +492,18 @@ int solve_quartic(vec4 coeffs, inout vec4 s){ float c = coeffs[1]; float d = coeffs[0]; - /* substitute x = y - A/4 to eliminate cubic term: + /* substitute x = y - A/4 to eliminate cubic term: x^4 + px^2 + qx + r = 0 */ - float sq_a = a * a; - float p = - 3./8. * sq_a + b; - float q = 1./8. * sq_a * a - 1./2. * a * b + c; - float r = - 3./256.*sq_a*sq_a + 1./16.*sq_a*b - 1./4.*a*c + d; + float sq_a = a * a; + float p = - 3./8. * sq_a + b; + float q = 1./8. * sq_a * a - 1./2. * a * b + c; + float r = - 3./256.*sq_a*sq_a + 1./16.*sq_a*b - 1./4.*a*c + d; int num; /* doesn't seem to happen for me */ - //if(abs(r) 0.){ a[0]=lb; @@ -689,34 +675,34 @@ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEn } if(sign(eval_poly5(b0,b1,b2,b3,b4,roots_drv[1])) != sign(eval_poly5(b0,b1,b2,b3,b4,roots_drv[2]))){ - if(num_roots == 0){ + if(num_roots == 0){ a[0]=roots_drv[1]; b[0]=roots_drv[2]; - num_roots=1; - } - else{ - a[1]=roots_drv[1]; + num_roots=1; + } + else{ + a[1]=roots_drv[1]; b[1]=roots_drv[2]; - num_roots=2; - } + num_roots=2; + } } if(eval_poly5(b0,b1,b2,b3,b4,roots_drv[3]) < 0.){ - if(num_roots == 0){ - a[0]=roots_drv[3]; - b[0]=ub; - num_roots=1; - } - else if(num_roots == 1){ - a[1]=roots_drv[3]; - b[1]=ub; - num_roots=2; - } - else{ - a[2]=roots_drv[3]; - b[2]=ub; - num_roots=3; - } + if(num_roots == 0){ + a[0]=roots_drv[3]; + b[0]=ub; + num_roots=1; + } + else if(num_roots == 1){ + a[1]=roots_drv[3]; + b[1]=ub; + num_roots=2; + } + else{ + a[2]=roots_drv[3]; + b[2]=ub; + num_roots=3; + } } } else{ @@ -753,8 +739,8 @@ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEn a[0]=lb; b[0]=ub; } - - //further subdivide intervals to guarantee convergence of halley's method + + //further subdivide intervals to guarantee convergence of halley's method //by using roots of further derivatives vec3 roots_snd_drv=vec3(1e38); int num_roots_snd_drv=solve_cubic(c2,roots_snd_drv); @@ -799,18 +785,18 @@ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEn float d0 = 1e38; - //compute roots with halley's method - + //compute roots with halley's method + for(int i=0;i<3;i++){ if(i < num_roots){ roots[i] = .5 * (a[i] + b[i]); - for(int j=0;j1.) d0=min(d0,1e38); - else + else { vec2 to_curve = uv - parametric_cub_bezier(roots[i],p0,p1,p2,p3); d0 = min(d0,dot(to_curve,to_curve)); @@ -833,6 +819,81 @@ float cubic_bezier_dis(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool roundEn return sqrt(d0); } + +int cubic_bezier_int_test2(vec2 uv, vec2 p0, vec2 p1, vec2 p2, vec2 p3, bool reverse) +{ + 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 (reverse? uv.x > max(max(p0.x, p1.x), max(p2.x, p3.x)): 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 (reverse? x_pos < uv.x: x_pos > uv.x) n_ints++; + } + } + } + return n_ints; +} + +int ray_int_test(vec2 uv, vec2 p0, vec2 direction, bool reverse) +{ + p0 -= uv; + if (-p0.y * direction.y > 0.) + { + vec2 nor = -direction; + nor = vec2(nor.y, -nor.x); + float sgn = p0.y > direction.y? 1.: -1.; + if(reverse) sgn = -sgn; + return dot(nor, p0) * sgn < 0.? 0: 1; + } + else return 0; +} + +vec2 bezierTangent(float t, vec2 p0, vec2 p1, vec2 p2, vec2 p3) +{ + float u = 1 - t; + float uu = u * u; + float tu = t * u; + float tt = t * t; + + vec2 P = p0 * 3 * uu * (-1.0); + P += p1 * 3 * (uu - 2 * tu); + P += p2 * 3 * (2 * tu - tt); + P += p3 * 3 * tt; + + //返回单位向量 + return normalize(P); +} + +//判断两向量夹角(向量A逆时针到向量B)是否大于180°,大于180°返回真,否则返回假 +bool angleLargeThanPi(vec2 a, vec2 b) +{ + return a.x * b.y - b.x * a.y < 0; +} + void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness) { elementColor = vec4(1); @@ -880,6 +941,7 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metal { bool hitElement = false; vec4 elementColor = vec4(-1); + metallicRoughness = vec2(0, 0.8); uvec4 currentOffset = elementOffset[elementIndex]; uint elementBvhRoot = currentOffset[0]; @@ -926,14 +988,6 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metal uint pLocation = linesOffset + 4 * lineIndex; uvec4 pxIndex = uvec4(pointsOffset)+2*uvec4(elementIndexs[pLocation], elementIndexs[pLocation+1], elementIndexs[pLocation+2], elementIndexs[pLocation+3]); uvec4 pyIndex = uvec4(1)+pxIndex; -// vec2 p0 = vec2(elementData[pxIndex[0]], -// elementData[pyIndex[0]]); -// vec2 p1 = vec2(elementData[pxIndex[1]], -// elementData[pyIndex[1]]); -// vec2 p2 = vec2(elementData[pxIndex[2]], -// elementData[pyIndex[2]]); -// vec2 p3 = vec2(elementData[pxIndex[3]], -// elementData[pyIndex[3]]); mat4x2 p = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]], elementData[pxIndex[2]],elementData[pyIndex[2]], @@ -974,23 +1028,18 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metal { float strokeWidth = elementData[styleIndex+1]; uint contourIndex = linesOffset + leftChild - 0x80000000; - float d = 1e38; - bool signTmp=false; - uint lineCountTmp=0; - uint lastPIndex = -1; - bool lastSign = false; + float minDistance = 1e38; uint lineCount = elementIndexs[contourIndex]; - uint reverseFlag = 0; - for ( uint contourIterator = contourIndex + 1;contourIterator < contourIndex + 1 + lineCount; contourIterator++) + float lineType = elementData[styleIndex+4]; + vec2 p3Last = vec2(1e38); + vec2 p2Last = vec2(1e38); + int debugBegin = 0; + for ( uint contourIterator_ = contourIndex + 1;contourIterator_ <= contourIndex + 1 + lineCount; contourIterator_++) { - uint lineIndex = elementIndexs[contourIterator]; - bool reverse = false; - if(lineIndex>=0x80000000) - { - reverse = true; - lineIndex -= 0x80000000; - } - + uint contourIterator = contourIterator_; + 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]); uvec4 pyIndex = uvec4(1)+pxIndex; @@ -999,98 +1048,77 @@ bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metal elementData[pxIndex[1]], elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]); - - bvec3 signTestResult = cubic_bezier_sign_test(localUV, p[0], p[1], p[2], p[3]); - - if(lastPIndex!=pxIndex[0]) + + if(p[0]==p[1]&&p[2]==p[3]) { - if(lastSign) - signTmp = !signTmp; - float lineType = elementData[styleIndex+4]; - /*if(d<=0.001) - { - hitElement = true; - elementColor = vec4(0,0,0,1); - } - else*/ if(d<=strokeWidth && (lineType==2 || signTmp==(lineType==1-reverseFlag))) - { - d/=strokeWidth; - hitElement = true; - drawLine(d, styleIndex, elementColor, metallicRoughness); - } - if(reverse) - reverseFlag = 1; - d = 1e38; - signTmp=signTestResult[0]; - lineCountTmp = 0; - + p[1] = (p[0]+p[3])/2; + p[2] = p[1]; } - lastPIndex = pxIndex[3]; - lastSign = signTestResult[2]; - lineCountTmp++; - float lineType = elementData[styleIndex+4]; - d = min(d, cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], elementData[styleIndex+2]==0)); - if(signTestResult[1]) - signTmp = !signTmp; + if(distance(localUV,p[0])<=0.001) + { + if(p3Last==p[0]) debugBegin = 2; + else debugBegin = 1; + } + + float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true); + if(d<=strokeWidth) + { + bool onBegin = distance(localUV,p[0])<=strokeWidth&&p3Last==p[0]; + bool fill = true; + if(onBegin) + { + vec2 normalLast = normalize(mat2(0,1,-1,0)*(p3Last-p2Last)); + vec2 normalNow = normalize(mat2(0,1,-1,0)*(p[1]-p[0])); + vec2 normal = normalLast+normalNow; + fill = angleLargeThanPi(normal, localUV-p[0]); + } + if(onBegin?fill:d> 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.01, + 0.02, //strokeEndType 0, //圆角 //strokeFillType 0, //单色 //线类型 - 2, //双侧 + 0, //双侧 //线外描边宽度 0, //线外描边方式 @@ -378,7 +393,7 @@ GLuint Renderer::Model::loadPainting(std::string path) }; vector> element = { std::make_shared(Element{ contour[0], style[1]}), - std::make_shared(Element{ contour[1], style[2]}), + std::make_shared(Element{ contour[1], style[0]}), std::make_shared(Element{ contour[2], style[0]}), }; Painting painting; @@ -420,27 +435,22 @@ GLuint Renderer::Model::loadPainting(std::string path) //elememt1 QVector4D(-1,-1,1,1) }; - std::vector elementOffset0 = { + + /** + * @[0] elementBvhRoot + * @[1] styleOffset + * @[2] pointsOffset + * @[3] linesOffset + */ + std::vector elementOffset0 = { //element0 - 7, //elementBvhRoot - 14, //styleOffset - 0, //pointsOffset - 0, //linesOffset + glm::uvec4(7, 14, 0, 0), //element1 - 10, //elementBvhRoot - 39, //styleOffset - 21, //pointsOffset - 28, //linesOffset + glm::uvec4(10, 39, 21, 28), //element2 - 10, //elementBvhRoot - 51, //styleOffset - 21, //pointsOffset - 28, //linesOffset + glm::uvec4(10, 51, 21, 28), //element3 - 10, //elementBvhRoot - 63, //styleOffset - 21, //pointsOffset - 28, //linesOffset + glm::uvec4(10, 63, 21, 28), }; std::vector elementIndex0 = { @@ -457,10 +467,10 @@ GLuint Renderer::Model::loadPainting(std::string path) //element1 //lines 0,7,8,1, - 1,2,3,4, + 1,1,4,4, 5,5,6,6, //contours - 2, 0 ,1 + 3, 0,1,2 }; std::vector elementData0 = { @@ -534,7 +544,7 @@ GLuint Renderer::Model::loadPainting(std::string path) //m_mesh->paintingIndex = paintingHelper->addPainting(bounds.size(), std::vector(children.begin()+2, children.end()), bounds, // elementOffset, elementIndex, elementData); - /*m_mesh->paintingIndex = paintingHelper->addPainting(bvhChildren0, bvhBounds0, + /*GLuint index = paintingHelper->addPainting(bvhChildren0, bvhBounds0, elementOffset0, elementIndex0, elementData0);*/ GLuint index = paintingHelper->addPainting(painting); paintingLoaded.insert({ path, index }); diff --git a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp index 2270fe8..e40e7ee 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererGLWidget.cpp @@ -22,7 +22,7 @@ RendererGLWidget::RendererGLWidget(QWidget* parent) setFocusPolicy(Qt::StrongFocus); QSurfaceFormat format; format.setSwapInterval(0); - setFormat(format); + //setFormat(format); } RendererGLWidget::~RendererGLWidget() @@ -63,11 +63,18 @@ void RendererGLWidget::stopTimer() timerId = -1; } -bool loadingModel = false; - void RendererGLWidget::setModel() { - loadingModel = true; + makeCurrent(); + model->loadModel("Models/Sponza/Sponza.gltf"); + //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(); + doneCurrent(); } void RendererGLWidget::setMainLightPitch(float pitch) @@ -221,7 +228,7 @@ void RendererGLWidget::initializeGL() paintingHelper = new PaintingHelper(QOpenGLContext::currentContext()->versionFunctions()); model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper); - + quadVAO.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO); @@ -252,18 +259,6 @@ void RendererGLWidget::initializeGL() void RendererGLWidget::paintGL() { - if (loadingModel) - { - model->loadModel("Models/Sponza/Sponza.gltf"); - //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(); - loadingModel = false; - } light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw))); light.lightDirection.setY(sin(qDegreesToRadians(sunPitch))); @@ -312,6 +307,10 @@ void RendererGLWidget::paintGL() fboPtr->release(); } + GLuint paintingCompQuery; + glGenQueries(1, &paintingCompQuery); + glBeginQuery(GL_TIME_ELAPSED, paintingCompQuery); + paintingCompProgramPtr->bind(); glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); glBindImageTexture(1, gbuffers[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); @@ -321,6 +320,9 @@ void RendererGLWidget::paintGL() glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); paintingCompProgramPtr->release(); + glEndQuery(GL_TIME_ELAPSED); + + depthInitProgramPtr->bind(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gbuffers[6]); @@ -411,6 +413,44 @@ void RendererGLWidget::paintGL() //glBindTexture(GL_TEXTURE_2D, gbuffers[8]); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); finalProgramPtr->release(); + + GLuint paintingCompDuration; + glGetQueryObjectuiv(paintingCompQuery, GL_QUERY_RESULT, &paintingCompDuration); + + clock_t currentFrame = std::clock(); + deltaTime = (float)(currentFrame - lastFrame) / CLOCKS_PER_SEC; + lastFrame = currentFrame; + + static float accTime = 0, frameCnt = 0; + accTime += deltaTime; + frameCnt++; + 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"; + accTime = 0; + frameCnt = 0; + } + + if (pressedKeys.contains(Qt::Key_W)) { + camera.ProcessKeyboard(FORWARD, deltaTime); + } + if (pressedKeys.contains(Qt::Key_S)) { + camera.ProcessKeyboard(BACKWARD, deltaTime); + } + if (pressedKeys.contains(Qt::Key_A)) { + camera.ProcessKeyboard(LEFT, deltaTime); + } + if (pressedKeys.contains(Qt::Key_D)) { + camera.ProcessKeyboard(RIGHT, deltaTime); + } + if (pressedKeys.contains(Qt::Key_Shift)) { + camera.ProcessKeyboard(DOWN, deltaTime); + } + if (pressedKeys.contains(Qt::Key_Space)) { + camera.ProcessKeyboard(UP, deltaTime); + } } void RendererGLWidget::resizeGL(int width, int height) @@ -555,23 +595,6 @@ void RendererGLWidget::resizeGL(int width, int height) void RendererGLWidget::timerEvent(QTimerEvent* event) { - clock_t currentFrame = std::clock(); - deltaTime = (float)(currentFrame - lastFrame) / CLOCKS_PER_SEC; - lastFrame = currentFrame; - - - static float accTime = 0, frameCnt = 0; - accTime += deltaTime; - frameCnt++; - if (accTime > 1.) - { - std::cout << " \r"; - std::cout << "FPS: " << frameCnt / accTime << " " << camera.Position.x() << " " << camera.Position.y() << " " << camera.Position.z() << "\r"; - accTime = 0; - frameCnt = 0; - } - - if (hasFocus()) { QPoint center = mapToGlobal(geometry().center()); @@ -582,26 +605,6 @@ void RendererGLWidget::timerEvent(QTimerEvent* event) //qDebug() << center; } - if (pressedKeys.contains(Qt::Key_W)) { - camera.ProcessKeyboard(FORWARD, deltaTime); - } - if (pressedKeys.contains(Qt::Key_S)) { - camera.ProcessKeyboard(BACKWARD, deltaTime); - } - if (pressedKeys.contains(Qt::Key_A)) { - camera.ProcessKeyboard(LEFT, deltaTime); - } - if (pressedKeys.contains(Qt::Key_D)) { - camera.ProcessKeyboard(RIGHT, deltaTime); - } - if (pressedKeys.contains(Qt::Key_Shift)) { - camera.ProcessKeyboard(DOWN, deltaTime); - } - if (pressedKeys.contains(Qt::Key_Space)) { - camera.ProcessKeyboard(UP, deltaTime); - } - - /*sunPitch += sunSpeed * deltaTime; if (sunPitch > 120 || sunPitch < 65) { diff --git a/ArchitectureColoredPainting/src/SvgParser.cpp b/ArchitectureColoredPainting/src/SvgParser.cpp index 6890f3d..e9f866e 100644 --- a/ArchitectureColoredPainting/src/SvgParser.cpp +++ b/ArchitectureColoredPainting/src/SvgParser.cpp @@ -681,6 +681,21 @@ vector> SvgParser::parse() break; } } + + for (auto iter = lines.begin(); iter < lines.end();) + { + if (iter->size() == 2 && (*iter)[0] == (*iter)[1]) + iter = lines.erase(iter); + else if (iter->size() == 4 && (*iter)[0] == (*iter)[3]) + iter = lines.erase(iter); + else + { + for (auto& p : *iter) + p = p * 0.9; + iter++; + } + } + return lines; } void SvgParser::ellipticalArcConverter(Point beginPoint, double radiusX, double radiusY, double phi, bool flagA, diff --git a/README.md b/README.md index 0a8cc6e..946bee7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## 鏋勫缓 -浣跨敤 Visual Studio 2022 鎵撳紑椤圭洰缂栬瘧杩愯銆 +浣跨敤 Visual Studio 2022 鎵撳紑椤圭洰缂栬瘧杩愯銆傞渶瀹夎Qt Visual Studio Tools鎵╁睍骞堕厤缃甉t鐗堟湰锛**椤圭洰璺緞涓嶈兘鍚湁涓枃**銆 ## 杩涘害 @@ -27,5 +27,7 @@ 宸插疄鐜扮敱鍥惧厓鏁版嵁寤虹珛瀹屾暣褰╃粯缂栫爜 -寰呭畬鍠勭嚎鐨勫崟渚ф弿杈 +宸插疄鐜扮嚎鐨勫崟渚ф弿杈 + +寰呭畬鍠勫浘鍏冩牱寮忕殑缂栬В鐮