Renderer图元变换改用矩阵
parent
84bddf4447
commit
fd1baf42f6
|
@ -20,22 +20,25 @@ layout(std430, binding = 1) buffer bvhBoundBuffer
|
|||
{
|
||||
vec4 bvhBound[];
|
||||
};
|
||||
layout(std430, binding = 2) buffer elementOffsetBuffer
|
||||
layout(std430, binding = 2) buffer elementTranformBuffer
|
||||
{
|
||||
mat3x2 elementTranform[];
|
||||
};
|
||||
layout(std430, binding = 3) buffer elementOffsetBuffer
|
||||
{
|
||||
/**
|
||||
* @[0] elementBvhRoot
|
||||
* @[1] styleOffset
|
||||
* @[2] pointsOffset
|
||||
* @[3] linesOffset
|
||||
|
||||
*/
|
||||
uint elementOffset[][5];
|
||||
uint elementOffset[][4];
|
||||
};
|
||||
layout(std430, binding = 3) buffer elementIndexBuffer
|
||||
layout(std430, binding = 4) buffer elementIndexBuffer
|
||||
{
|
||||
uint elementIndexs[]; // ÏߺÍÃæ
|
||||
};
|
||||
layout(std430, binding = 4) buffer elementDataBuffer
|
||||
layout(std430, binding = 5) buffer elementDataBuffer
|
||||
{
|
||||
float elementData[]; // µãºÍStyle
|
||||
};
|
||||
|
@ -1115,15 +1118,11 @@ bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsO
|
|||
}
|
||||
|
||||
bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex,
|
||||
float widthHeightRatio, inout vec4 elementColor, inout vec2 metallicRoughness)
|
||||
inout vec4 elementColor, inout vec2 metallicRoughness)
|
||||
{
|
||||
bool hitElement = false;
|
||||
float strokeWidth = elementData[styleIndex];
|
||||
|
||||
vec2 size = normalize(vec2(widthHeightRatio, 1)) + vec2(2 * strokeWidth);
|
||||
vec2 ratio = widthHeightRatio < 1 ? vec2(widthHeightRatio, 1) : vec2(1, 1 / widthHeightRatio);
|
||||
localUV *= ratio;
|
||||
|
||||
float minDistance = 1e38;
|
||||
uint lineCount = elementIndexs[contourIndex];
|
||||
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 1]));
|
||||
|
@ -1149,17 +1148,13 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
mat4x2 p =
|
||||
mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]],
|
||||
elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]);
|
||||
p[0] *= ratio;
|
||||
p[1] *= ratio;
|
||||
p[2] *= ratio;
|
||||
p[3] *= ratio;
|
||||
|
||||
vec2 tangentBeginNext = vec2(0);
|
||||
if (contourIterator + 1 < contourIndex + 1 + lineCount)
|
||||
{
|
||||
uint lineIndex = elementIndexs[contourIterator + 1];
|
||||
uint pLocation = linesOffset + 3 * lineIndex;
|
||||
//vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]);
|
||||
// vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]);
|
||||
uvec4 pxIndex = uvec4(pointsOffset) +
|
||||
2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF,
|
||||
elementIndexs[pLocation + 1] >> 16, elementIndexs[pLocation + 1] & 0xFFFF);
|
||||
|
@ -1168,10 +1163,6 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
mat4x2 pNext = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]],
|
||||
elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]],
|
||||
elementData[pxIndex[3]], elementData[pyIndex[3]]);
|
||||
pNext[0] *= ratio;
|
||||
pNext[1] *= ratio;
|
||||
pNext[2] *= ratio;
|
||||
pNext[3] *= ratio;
|
||||
|
||||
if (pNext[0] == pNext[1] && pNext[2] == pNext[3])
|
||||
{
|
||||
|
@ -1179,7 +1170,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
pNext[2] = pNext[1];
|
||||
}
|
||||
|
||||
//if(pNext[0]!=p[3])
|
||||
// if(pNext[0]!=p[3])
|
||||
// break;
|
||||
if (pNext[0] != pNext[1])
|
||||
tangentBeginNext = normalize(pNext[0] - pNext[1]);
|
||||
|
@ -1221,11 +1212,11 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
|
||||
bool hit = d < minDistance;
|
||||
if (onBegin)
|
||||
hit =
|
||||
hit && shouldFillBeginCap(localUV, contourIterator == contourIndex + 1, endType, p[0], tangentBegin, p3Last - p2Last);
|
||||
hit = hit && shouldFillBeginCap(localUV, contourIterator == contourIndex + 1, endType, p[0],
|
||||
tangentBegin, p3Last - p2Last);
|
||||
if (onEnd)
|
||||
hit = hit &&
|
||||
shouldFillEndCap(localUV, tangentBeginNext==vec2(0), endType, p[3], tangentEnd, tangentBeginNext);
|
||||
hit = hit && shouldFillEndCap(localUV, tangentBeginNext == vec2(0), endType, p[3], tangentEnd,
|
||||
tangentBeginNext);
|
||||
if (hit)
|
||||
{
|
||||
|
||||
|
@ -1272,7 +1263,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
|||
return hitElement;
|
||||
}
|
||||
|
||||
bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, out vec2 metallicRoughness,
|
||||
bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metallicRoughness,
|
||||
inout vec3 debugBVH = vec3(0))
|
||||
{
|
||||
bool hitElement = false;
|
||||
|
@ -1284,7 +1275,7 @@ bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, ou
|
|||
uint styleIndex = currentOffset[1];
|
||||
uint pointsOffset = currentOffset[2];
|
||||
uint linesOffset = currentOffset[3];
|
||||
float widthHeightRatio = uintBitsToFloat(currentOffset[4]);
|
||||
// float widthHeightRatio = uintBitsToFloat(currentOffset[4]);
|
||||
|
||||
elementStack.top = 0;
|
||||
uint elementBvhIndex = 0;
|
||||
|
@ -1317,7 +1308,7 @@ bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, ou
|
|||
else // Ïß
|
||||
{
|
||||
hitElement = strokeElement(localUV, contourIndex, linesOffset, pointsOffset, styleIndex,
|
||||
widthHeightRatio, elementColor, metallicRoughness);
|
||||
elementColor, metallicRoughness);
|
||||
}
|
||||
|
||||
elementBvhIndex = elementBvhLength;
|
||||
|
@ -1357,7 +1348,7 @@ void main()
|
|||
|
||||
vec3 debugBVH = vec3(0);
|
||||
// bool debugHit = false;
|
||||
//vec4 color = vec4(0.76, 0.33, 0.15, -1);
|
||||
// vec4 color = vec4(0.76, 0.33, 0.15, -1);
|
||||
vec4 color = vec4(backgroundColor, -1);
|
||||
vec2 metallicRoughness = vec2(0, 0.8);
|
||||
stack.top = 0;
|
||||
|
@ -1371,50 +1362,40 @@ void main()
|
|||
visitTime++;
|
||||
vec4 bound = bvhBound[index];
|
||||
uint leftChild = bvhChildren[index].x;
|
||||
|
||||
if (all(lessThan(bound.xy, uv)) && all(lessThan(uv, bound.zw)))
|
||||
{
|
||||
if (any(greaterThan(bound.xy + vec2(0.005), uv)) || any(greaterThan(uv, bound.zw - vec2(0.005))))
|
||||
debugBVH.g += 0.3;
|
||||
|
||||
if (leftChild >= bvhLength)
|
||||
{
|
||||
uint transformIndex = leftChild - 0x80000000;
|
||||
uint zIndex = bvhChildren[index].y >> 18;
|
||||
bvec2 flip = bvec2(bvhChildren[index].y & (1 << 16), bvhChildren[index].y & (1 << 17));
|
||||
float angle = (float(bvhChildren[index].y & ((1 << 16) - 1)) / 65535.0) * 2 * PI;
|
||||
mat2 rotation = {{cos(angle), -sin(angle)}, {sin(angle), cos(angle)}};
|
||||
vec2 localUV = uv - (bound.xy + bound.zw) / 2;
|
||||
localUV = rotation * localUV;
|
||||
vec2 scale = (bound.zw - bound.xy) / 2;
|
||||
localUV /= scale;
|
||||
if (all(lessThan(vec2(-1), localUV)) && all(lessThan(localUV, vec2(1))) && zIndex > color.w)
|
||||
{
|
||||
// if (any(greaterThan(bound.xy+vec2(0.005), uv)) || any(greaterThan(uv, bound.zw-vec2(0.005))))
|
||||
if (any(greaterThan(vec2(-1) + vec2(0.005), localUV)) ||
|
||||
any(greaterThan(localUV, vec2(1) - vec2(0.005))))
|
||||
debugBVH.g += 0.3;
|
||||
// uint elementIndex = leftChild - bvhLength;
|
||||
// debugBVH.bg += 0.5 * (localUV + vec2(1));
|
||||
uint elementIndex = bvhChildren[index].y - zIndex;
|
||||
mat3x2 transform = elementTranform[transformIndex];
|
||||
vec2 localUV =
|
||||
(mat3(vec3(transform[0], 0), vec3(transform[1], 0), vec3(transform[2], 1)) * vec3(uv, 1)).xy;
|
||||
|
||||
// debugBVH = vec3(0);
|
||||
if (flip.x)
|
||||
localUV.x = -localUV.x;
|
||||
if (flip.y)
|
||||
localUV.y = -localUV.y;
|
||||
vec3 elementColor;
|
||||
vec2 elementMetallicRoughness;
|
||||
if (drawElement(leftChild - 0x80000000, localUV, scale, elementColor, elementMetallicRoughness,
|
||||
if (drawElement(elementIndex, localUV, elementColor, elementMetallicRoughness,
|
||||
debugBVH))
|
||||
{
|
||||
color = vec4(elementColor, zIndex);
|
||||
metallicRoughness = elementMetallicRoughness;
|
||||
}
|
||||
}
|
||||
//if(elementIndex == 1 && transformIndex==1)
|
||||
// color = vec4(1,1,0,1);
|
||||
|
||||
index = bvhLength;
|
||||
}
|
||||
else if (all(lessThan(bound.xy, uv)) && all(lessThan(uv, bound.zw)))
|
||||
else
|
||||
{
|
||||
if (any(greaterThan(bound.xy + vec2(0.005), uv)) || any(greaterThan(uv, bound.zw - vec2(0.005))))
|
||||
debugBVH.g += 0.3;
|
||||
// debugBVH.r += 0.02;
|
||||
stack.push(index);
|
||||
index = leftChild;
|
||||
}
|
||||
}
|
||||
else
|
||||
index = bvhLength;
|
||||
}
|
||||
|
@ -1428,7 +1409,7 @@ void main()
|
|||
|
||||
imageStore(gBaseColor, pixelLocation, vec4(color.rgb, 1));
|
||||
imageStore(gMetallicRoughness, pixelLocation, vec4(metallicRoughness, 0, 1));
|
||||
return;
|
||||
//return;
|
||||
if (/*color.a!=-1&&*/ debugBVH == vec3(0))
|
||||
{
|
||||
// imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1));
|
||||
|
|
|
@ -99,7 +99,10 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr
|
|||
qDebug() << painterPath;
|
||||
bound = painterPath.boundingRect();
|
||||
qDebug() << bound;
|
||||
elementTrans.center = glm::vec2(
|
||||
|
||||
// TODO 改用矩阵
|
||||
|
||||
/* elementTrans.center = glm::vec2(
|
||||
(2 * bound.center().x() - screenSize.width()) / screenSize.width(),
|
||||
(2 * bound.center().y() - screenSize.height()) / screenSize.height()
|
||||
);
|
||||
|
@ -114,7 +117,7 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr
|
|||
nowLayer->property.flipVertically
|
||||
);
|
||||
qDebug() << elementTrans.scale.x << elementTrans.scale.y;
|
||||
painting.addElement(element, elementTrans);
|
||||
painting.addElement(element, elementTrans);*/
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <ThirdPartyLib/qquick/qquicksvgparser_p.h>
|
||||
#include <util/PaintingUtil.h>
|
||||
#include "Painting/MaterialStyleStroke.h"
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
using namespace Renderer;
|
||||
using std::vector;
|
||||
|
@ -100,7 +101,7 @@ void Renderer::Model::loadModel(QString path)
|
|||
void Renderer::Model::unloadModel()
|
||||
{
|
||||
paintingMap.clear();
|
||||
for(auto& i: paintingLoaded)
|
||||
for (auto& i : paintingLoaded)
|
||||
vtManager->deleteVirtualTexture(i.second);
|
||||
paintingLoaded.clear();
|
||||
texturesLoaded.clear();
|
||||
|
@ -280,13 +281,13 @@ GLuint Renderer::Model::loadPainting(std::string path)
|
|||
|
||||
if (path == "0.json")
|
||||
{
|
||||
painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,-0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
painting.addElement(*element[2], ElementTransform{ glm::vec2(0.50,-0.45), glm::vec2(0.6,0.7) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
//painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,-0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
//painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
//painting.addElement(*element[2], ElementTransform{ glm::vec2(0.50,-0.45), glm::vec2(0.6,0.7) / 2.f, 0, glm::bvec2(false), 0 });
|
||||
}
|
||||
else if (path == "1.json")
|
||||
{
|
||||
painting.backgroundColor = QColor(196, 81, 35);
|
||||
//painting.backgroundColor = QColor(196, 81, 35);
|
||||
float widths[] = { 0.22, 0.22 * 0.25 / 0.15, 0.22 * 0.25 / 0.15 };
|
||||
QPainterPath painterPaths[6];
|
||||
for (int i = 0; i < 6; i++)
|
||||
|
@ -322,14 +323,39 @@ GLuint Renderer::Model::loadPainting(std::string path)
|
|||
std::make_shared<StyleStrokeRadialGradient>(widths[1], StrokeType::kRightSide),
|
||||
std::make_shared<StyleStrokeRadialGradient>(widths[2], StrokeType::kLeftSide),
|
||||
};
|
||||
vector<std::shared_ptr<Element>> element = {
|
||||
std::make_shared<Element>(Element{ contours[0].first, style[0], contours[0].second}),
|
||||
std::make_shared<Element>(Element{ contours[1].first, style[1], contours[1].second}),
|
||||
std::make_shared<Element>(Element{ contours[2].first, style[2], contours[2].second}),
|
||||
std::map<float, Material> materialMap = {
|
||||
{0.09, Material{QColor(255,255,255),0,0.8}},
|
||||
{0.63, Material{QColor(165,176,207),0,0.8}},
|
||||
{1.00, Material{QColor(58,64,151),0,0.8}}
|
||||
};
|
||||
painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.25), 0, glm::bvec2(false), 0 });
|
||||
painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.535,0.33), glm::vec2(0.15), 0, glm::bvec2(false), 0 });
|
||||
painting.addElement(*element[2], ElementTransform{ glm::vec2(-0.535,0.23), glm::vec2(0.15), 0, glm::bvec2(false), 0 });
|
||||
vector<std::shared_ptr<BaseElement>> element = {
|
||||
std::make_shared<BaseElement>(contours[0].first, std::make_shared<MaterialStyleStroke>(
|
||||
widths[0], StrokeType::kLeftSide, StrokeEndType::kFlat, std::make_shared<StrokeRadialGradient>(materialMap, false))),
|
||||
std::make_shared<BaseElement>(contours[1].first, std::make_shared<MaterialStyleStroke>(
|
||||
widths[1], StrokeType::kRightSide, StrokeEndType::kFlat, std::make_shared<StrokeRadialGradient>(materialMap, false))),
|
||||
std::make_shared<BaseElement>(contours[2].first, std::make_shared<MaterialStyleStroke>(
|
||||
widths[2], StrokeType::kLeftSide, StrokeEndType::kFlat, std::make_shared<StrokeRadialGradient>(materialMap, false))),
|
||||
};
|
||||
|
||||
QTransform trans = QTransform::fromScale(0.3, 0.3).inverted();
|
||||
glm::mat3x2 mat(trans.m11(), trans.m12(), trans.m21(), trans.m22(), trans.m31(), trans.m32());
|
||||
|
||||
trans = QTransform::fromTranslate(0.5, 0).scale(0.3, 0.3).inverted();
|
||||
glm::mat3x2 mat2(trans.m11(), trans.m12(), trans.m21(), trans.m22(), trans.m31(), trans.m32());
|
||||
//mat = glm::mat3x2(11, 22, 33, 44, 55, 66);
|
||||
//mat2 = glm::mat3x2(1, 2, 3, 4, 5, 6);
|
||||
|
||||
qDebug() << std::format("\n{} {} {}\n {} {} {}\n{} {} {}",
|
||||
trans.m11(), trans.m21(), trans.m31(),
|
||||
trans.m12(), trans.m22(), trans.m32(),
|
||||
trans.m13(), trans.m23(), trans.m33()).c_str();
|
||||
|
||||
//painting.addElement(*element[0], ElementTransform{ glm::vec4(-1,-1,1,1), mat, 0});
|
||||
painting.addElement(*element[1], ElementTransform{ glm::vec4(-1,-1,0,1), mat, 0 });
|
||||
painting.addElement(*element[2], ElementTransform{ glm::vec4(0,-1,1,1), mat2, 0 });
|
||||
//painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.25), 0, glm::bvec2(false), 0 });
|
||||
//painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.535,0.33), glm::vec2(0.15), 0, glm::bvec2(false), 0 });
|
||||
//painting.addElement(*element[2], ElementTransform{ glm::vec2(-0.535,0.23), glm::vec2(0.15), 0, glm::bvec2(false), 0 });
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -337,7 +363,7 @@ GLuint Renderer::Model::loadPainting(std::string path)
|
|||
{
|
||||
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.025), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 });
|
||||
//painting.addElement(*element[i % 3], ElementTransform{ glm::vec2(x,y), glm::vec2(0.025), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#include "Element.h"
|
||||
|
||||
void Renderer::ElementTransform::applyTransformStyle(const TransformStyle& t)
|
||||
{
|
||||
center += t.translation;
|
||||
scale *= t.scale;
|
||||
rotation += t.rotation;
|
||||
flip ^= t.flip;
|
||||
}
|
||||
|
||||
Renderer::ElementTransform Renderer::ElementTransform::appliedTransformStyle(const TransformStyle& t) const
|
||||
{
|
||||
ElementTransform result = *this;
|
||||
result.applyTransformStyle(t);
|
||||
return result;
|
||||
}
|
||||
//void Renderer::ElementTransform::applyTransformStyle(const TransformStyle& t)
|
||||
//{
|
||||
// /*center += t.translation;
|
||||
// scale *= t.scale;
|
||||
// rotation += t.rotation;
|
||||
// flip ^= t.flip;*/
|
||||
//}
|
||||
//
|
||||
//Renderer::ElementTransform Renderer::ElementTransform::appliedTransformStyle(const TransformStyle& t) const
|
||||
//{
|
||||
// ElementTransform result = *this;
|
||||
// result.applyTransformStyle(t);
|
||||
// return result;
|
||||
//}
|
||||
|
|
|
@ -18,14 +18,15 @@ namespace Renderer
|
|||
|
||||
struct ElementTransform
|
||||
{
|
||||
glm::vec2 center;
|
||||
//glm::vec2 size;
|
||||
glm::vec2 scale; /// 相对于画布
|
||||
float rotation; /// 角度制
|
||||
glm::bvec2 flip;
|
||||
//glm::vec2 center;
|
||||
//glm::vec2 scale; /// 相对于画布
|
||||
//float rotation; /// 角度制
|
||||
//glm::bvec2 flip;
|
||||
glm::vec4 bound; /// 包围盒,不影响变换
|
||||
glm::mat3x2 transform; /// 逆变换
|
||||
GLuint zIndex;
|
||||
|
||||
void applyTransformStyle(const TransformStyle& t);
|
||||
ElementTransform appliedTransformStyle(const TransformStyle& t) const;
|
||||
//void applyTransformStyle(const TransformStyle& t);
|
||||
//ElementTransform appliedTransformStyle(const TransformStyle& t) const;
|
||||
};
|
||||
}
|
|
@ -53,87 +53,40 @@ void Renderer::Painting::addElement(ElementWithTransform elementWithTransform)
|
|||
elementPool.insert({ element, 0 });
|
||||
}
|
||||
elements.push_back(elementWithTransform);
|
||||
elementTransformPool.emplace(elementWithTransform.transform.transform, 0);
|
||||
}
|
||||
|
||||
void Renderer::Painting::addElement(const Element& element, const ElementTransform& transform)
|
||||
void Renderer::Painting::addElement(const BaseElement& element, const ElementTransform& transform)
|
||||
{
|
||||
auto contour = element.contour;
|
||||
auto it = elementStyleMap.find(element.style);
|
||||
if (it == elementStyleMap.end())
|
||||
{
|
||||
std::vector<BaseStyle> baseStyles;
|
||||
for (auto& style : element.style->toBaseStyles())
|
||||
{
|
||||
auto [iter, _] = styleSet.insert(style.material);
|
||||
baseStyles.push_back(BaseStyle{ style.transform, *iter });
|
||||
}
|
||||
it = elementStyleMap.insert({ element.style, baseStyles }).first;
|
||||
}
|
||||
for (int i = 0; i < it->second.size(); i++)
|
||||
{
|
||||
auto& style = it->second[i];
|
||||
ElementTransform trans = transform;
|
||||
trans.applyTransformStyle(*style.transform);
|
||||
trans.zIndex = trans.zIndex * 10 + i;
|
||||
|
||||
addElement(ElementWithTransform{ BaseElement{element.contour, style.material, element.ratio}, trans });
|
||||
}
|
||||
addElement({ element , transform });
|
||||
}
|
||||
|
||||
Renderer::BaseTransform::BaseTransform(ElementTransform t)
|
||||
: bound(glm::vec4(t.center - t.scale, t.center + t.scale))
|
||||
, rotation(t.rotation)
|
||||
, flip(t.flip)
|
||||
, zIndex(t.zIndex)
|
||||
BvhTreeData Painting::encodeElementLeaf(const ElementWithTransform& e)
|
||||
{
|
||||
}
|
||||
|
||||
void Renderer::Painting::addElement(std::shared_ptr<Element> element, QVector4D bound, float rotation, int zIndex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BvhTreeData Painting::encodeElementLeaf(ElementWithTransform e)
|
||||
{
|
||||
glm::vec4 bound;
|
||||
switch (e.element.style->type())
|
||||
{
|
||||
case MaterialStyleType::kStroke:
|
||||
{
|
||||
auto w = std::static_pointer_cast<MaterialStyleStroke>(e.element.style)->getHalfWidth();
|
||||
glm::vec2 size = e.element.ratio < 1 ? glm::vec2(e.element.ratio, 1) : glm::vec2(1, 1 / e.element.ratio);
|
||||
glm::vec2 scale = size * e.transform.scale;
|
||||
bound = glm::vec4(e.transform.center - scale, e.transform.center + scale);
|
||||
break;
|
||||
}
|
||||
case MaterialStyleType::kFill:
|
||||
{
|
||||
bound = glm::vec4(e.transform.center - e.transform.scale, e.transform.center + e.transform.scale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//bound = glm::vec4(e.transform.center - e.transform.scale, e.transform.center + e.transform.scale);
|
||||
GLuint rightSon = (GLuint)(glm::mod(e.transform.rotation, 360.f) / 360.f * (1 << 16))
|
||||
+ (e.transform.flip.x << 16) + (e.transform.flip.y << 17) + (e.transform.zIndex << 18);
|
||||
return BvhTreeData(QVector4D(bound.x, bound.y, bound.z, bound.w), elementPool[e.element], rightSon);
|
||||
QVector4D bound(e.transform.bound.x, e.transform.bound.y, e.transform.bound.z, e.transform.bound.w);
|
||||
GLuint rightSon = elementPool[e.element] + (e.transform.zIndex << 18);
|
||||
return { bound, elementTransformPool[e.transform.transform], rightSon };
|
||||
}
|
||||
|
||||
void Painting::generateBuffers(QOpenGLFunctions_4_5_Core* glFunc)
|
||||
{
|
||||
qDebug() << "Element Count: " << elementPool.size();
|
||||
qDebug() << "Coutour Count: " << contourPool.size();
|
||||
qDebug() << "Contour Count: " << contourPool.size();
|
||||
qDebug() << " Style Count: " << stylePool.size();
|
||||
|
||||
bvhChildren.clear();
|
||||
bvhBounds.clear();
|
||||
elementTransform.clear();
|
||||
elementOffsets.clear();
|
||||
elementIndex.clear();
|
||||
elementData.clear();
|
||||
|
||||
for (int index = 0; auto & i : elementPool)
|
||||
{
|
||||
i.second = index++;
|
||||
}
|
||||
for (int index = 0; auto & i : elementTransformPool)
|
||||
i.second = index++;
|
||||
|
||||
|
||||
|
||||
std::vector<BvhTreeData> rootBvhTreeData;
|
||||
for (auto& i : elements)
|
||||
|
@ -162,30 +115,35 @@ void Painting::generateBuffers(QOpenGLFunctions_4_5_Core* glFunc)
|
|||
elementData.insert(elementData.end(), encodedStyle.begin(), encodedStyle.end());
|
||||
}
|
||||
|
||||
for (auto & i : elementTransformPool)
|
||||
elementTransform.emplace_back(i.first);
|
||||
|
||||
for (auto& i : elementPool)
|
||||
{
|
||||
//qDebug() <<"element:" << i.second;
|
||||
//std::shared_ptr<ContourBuffer> contourBuffer = i.first.style->type() == MaterialStyleType::kStroke ? contourPool[i.first.contour].second : contourPool[i.first.contour].first;
|
||||
auto& contourBuffer = contourPool[{i.first.contour, i.first.style->type()}];
|
||||
elementOffsets.push_back({ contourBuffer.bvhOffset, stylePool[i.first.style], contourBuffer.pointsOffset, contourBuffer.linesOffset, glm::floatBitsToUint(i.first.ratio) });
|
||||
elementOffsets.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(6, buffers.data());
|
||||
glFunc->glCreateBuffers(7, buffers.data());
|
||||
GLuint& bvhSSBO = buffers[0];
|
||||
GLuint& bvhBoundSSBO = buffers[1];
|
||||
GLuint& elementOffsetSSBO = buffers[2];
|
||||
GLuint& elementIndexSSBO = buffers[3];
|
||||
GLuint& elementDataSSBO = buffers[4];
|
||||
GLuint& backgroundColorUBO = buffers[5];
|
||||
GLuint& elementTransformSSBO = buffers[2];
|
||||
GLuint& elementOffsetSSBO = buffers[3];
|
||||
GLuint& elementIndexSSBO = buffers[4];
|
||||
GLuint& elementDataSSBO = buffers[5];
|
||||
GLuint& backgroundColorUBO = buffers[6];
|
||||
|
||||
glFunc->glNamedBufferData(buffers[0], bvhChildren.size() * sizeof(bvhChildren[0]), bvhChildren.data(), GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[1], bvhBounds.size() * sizeof(bvhBounds[0]), bvhBounds.data(), GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[2], elementOffsets.size() * sizeof(elementOffsets[0]), elementOffsets.data(), GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[3], elementIndex.size() * sizeof(elementIndex[0]), elementIndex.data(), GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[4], elementData.size() * sizeof(elementData[0]), elementData.data(), GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[2], elementTransform.size() * sizeof(elementTransform[0]), elementTransform.data(), GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[3], elementOffsets.size() * sizeof(elementOffsets[0]), elementOffsets.data(), GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[4], elementIndex.size() * sizeof(elementIndex[0]), elementIndex.data(), GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[5], elementData.size() * sizeof(elementData[0]), elementData.data(), GL_STATIC_READ);
|
||||
glm::vec3 color(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF());
|
||||
glFunc->glNamedBufferData(buffers[5], sizeof(glm::vec3), &color, GL_STATIC_READ);
|
||||
glFunc->glNamedBufferData(buffers[6], sizeof(glm::vec3), &color, GL_STATIC_READ);
|
||||
}
|
||||
|
||||
GLuint Renderer::Painting::getElementCount()
|
||||
|
@ -223,3 +181,17 @@ bool Renderer::Painting::CompareMaterialStyle::operator()(const std::shared_ptr<
|
|||
else
|
||||
return left < right;
|
||||
}
|
||||
|
||||
std::size_t Renderer::Painting::HashMat3x2::operator()(const glm::mat3x2& mat) const
|
||||
{
|
||||
std::size_t result = 0;
|
||||
constexpr long long P = 998244353;
|
||||
long long base = 1;
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
result += base * mat[i][j];
|
||||
base *= P;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -15,24 +15,13 @@ namespace Renderer
|
|||
{
|
||||
std::shared_ptr<Contour> contour;
|
||||
std::shared_ptr<MaterialStyle> style;
|
||||
float ratio; /// ¿í¸ß±È
|
||||
bool operator<(const BaseElement& e) const;
|
||||
};
|
||||
|
||||
struct BaseTransform
|
||||
{
|
||||
glm::vec4 bound;
|
||||
float rotation;
|
||||
glm::bvec2 flip;
|
||||
GLuint zIndex;
|
||||
BaseTransform(ElementTransform t);
|
||||
};
|
||||
|
||||
struct ElementWithTransform
|
||||
{
|
||||
BaseElement element;
|
||||
ElementTransform transform;
|
||||
//BaseTransform transform;
|
||||
};
|
||||
|
||||
struct ContourBuffer
|
||||
|
@ -52,7 +41,6 @@ namespace Renderer
|
|||
GLuint styleOffset;
|
||||
GLuint pointsOffset;
|
||||
GLuint linesOffset;
|
||||
GLuint ratio;
|
||||
};
|
||||
|
||||
class Painting
|
||||
|
@ -60,16 +48,16 @@ namespace Renderer
|
|||
public:
|
||||
std::vector<GLuint> bvhChildren;
|
||||
std::vector<QVector4D> bvhBounds;
|
||||
std::vector<glm::mat3x2> elementTransform;
|
||||
std::vector<ElementOffset> elementOffsets;
|
||||
std::vector<GLuint> elementIndex;
|
||||
std::vector<GLfloat> elementData;
|
||||
int paintingId = 0;
|
||||
std::array<GLuint, 6> buffers;
|
||||
std::array<GLuint, 7> buffers;
|
||||
QColor backgroundColor;
|
||||
|
||||
Painting(QColor backgroundColor = Qt::white);
|
||||
void addElement(const Element& element, const ElementTransform& transform);
|
||||
void addElement(std::shared_ptr<Element> element, QVector4D bound, float rotation, int zIndex);
|
||||
void addElement(const BaseElement& element, const ElementTransform& transform);
|
||||
void generateBuffers(QOpenGLFunctions_4_5_Core* glFunc);
|
||||
GLuint getElementCount();
|
||||
private:
|
||||
|
@ -77,14 +65,15 @@ namespace Renderer
|
|||
std::unordered_map<std::tuple<std::shared_ptr<Contour>, MaterialStyleType>, ContourBuffer, ContourHash> contourPool;
|
||||
struct CompareMaterialStyle { bool operator()(const std::shared_ptr<MaterialStyle>&, const std::shared_ptr<MaterialStyle>&) const; };
|
||||
std::set<std::shared_ptr<MaterialStyle>, CompareMaterialStyle> styleSet;
|
||||
std::unordered_map<std::shared_ptr<ElementStyle>, std::vector<BaseStyle>> elementStyleMap;
|
||||
std::unordered_map<std::shared_ptr<MaterialStyle>, GLuint> stylePool;
|
||||
struct HashMat3x2 { std::size_t operator()(const glm::mat3x2&) const; };
|
||||
std::unordered_map<glm::mat3x2, GLuint, HashMat3x2> elementTransformPool;
|
||||
std::map<BaseElement, GLuint> elementPool;
|
||||
std::vector<ElementWithTransform> elements;
|
||||
|
||||
void addElement(ElementWithTransform element);
|
||||
void insertContourBuffer(ContourBuffer& buffer);
|
||||
BvhTreeData encodeElementLeaf(ElementWithTransform e);
|
||||
BvhTreeData encodeElementLeaf(const ElementWithTransform& e);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -88,13 +88,23 @@ QRectF calcBoundingRect(const QPainterPath& path, const std::vector<BaseStyle>&
|
|||
{
|
||||
QRectF bound = path.boundingRect();
|
||||
|
||||
ElementTransform originTransform{ glm::vec2(bound.center().x(), bound.center().y()), glm::vec2(bound.width(), bound.height()), 0, glm::bvec2(false), 0 };
|
||||
//ElementTransform originTransform{ glm::vec2(bound.center().x(), bound.center().y()), glm::vec2(bound.width(), bound.height()), 0, glm::bvec2(false), 0 };
|
||||
|
||||
glm::vec2 leftTop(std::numeric_limits<float>::max()), rightBottom(std::numeric_limits<float>::min());
|
||||
|
||||
for (auto& baseStyle : styles)
|
||||
{
|
||||
BaseTransform transform(originTransform.appliedTransformStyle(*baseStyle.transform));
|
||||
struct BaseTransform
|
||||
{
|
||||
glm::vec4 bound;
|
||||
float rotation = 0;
|
||||
glm::bvec2 flip = glm::bvec2(false);
|
||||
GLuint zIndex = 0;
|
||||
};
|
||||
//BaseTransform transform(originTransform.appliedTransformStyle(*baseStyle.transform));
|
||||
glm::vec2 center(bound.center().x(), bound.center().y());
|
||||
glm::vec2 scale(bound.width(), bound.height());
|
||||
BaseTransform transform{ glm::vec4(center - scale, center + scale) };
|
||||
if (baseStyle.material->type() == MaterialStyleType::kStroke)
|
||||
{
|
||||
float halfWidth = std::static_pointer_cast<MaterialStyleStroke>(baseStyle.material)->getHalfWidth();
|
||||
|
|
|
@ -124,9 +124,9 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai
|
|||
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++)
|
||||
for (int i = 0; i < 6; i++)
|
||||
glMain->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]);
|
||||
glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[5]);
|
||||
glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[6]);
|
||||
|
||||
for (auto level = levels - 1; level < levels; ++level)
|
||||
{
|
||||
|
@ -170,8 +170,10 @@ void Renderer::VirtualTextureManager::deleteVirtualTexture(std::uint16_t id)
|
|||
{
|
||||
auto& painting = getPaintingHandle(id);
|
||||
glMain->DeleteTextures(2, (GLuint*)&painting);
|
||||
glMain->DeleteBuffers(7, painting.buffers.data());
|
||||
painting.baseColor = 0;
|
||||
painting.metallicRoughness = 0;
|
||||
painting.buffers.fill(0);
|
||||
}
|
||||
|
||||
Renderer::PaintingHandle& Renderer::VirtualTextureManager::getPaintingHandle(std::uint16_t id)
|
||||
|
@ -207,9 +209,9 @@ void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pag
|
|||
if (commit)
|
||||
{
|
||||
program.bind();
|
||||
for (int i = 0; i < 5; i++)
|
||||
for (int i = 0; i < 6; i++)
|
||||
gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]);
|
||||
glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[5]);
|
||||
glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[6]);
|
||||
gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(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);
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Renderer
|
|||
{
|
||||
GLuint baseColor;
|
||||
GLuint metallicRoughness;
|
||||
std::array<GLuint, 6> buffers;
|
||||
std::array<GLuint, 7> buffers;
|
||||
};
|
||||
|
||||
class VirtualTextureManager
|
||||
|
|
Loading…
Reference in New Issue