Compare commits

..

No commits in common. "23f14cb764bbd763fd71b93b78d6d2156bb9ec18" and "e1dc0e4065875cb6a814085f251830252cb97339" have entirely different histories.

13 changed files with 131 additions and 321 deletions

View File

@ -893,56 +893,21 @@ bool angleLargeThanPi(vec2 a, vec2 b)
/************************************************************************************/ /************************************************************************************/
void drawLine(in float d, inout uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness) void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 metallicRoughness)
{ {
elementColor = vec4(1); elementColor = vec4(1);
metallicRoughness = vec2(0.8); metallicRoughness = vec2(0.8);
uint headUint = floatBitsToUint(style[styleIndex+1]); // switch(int(elementData[styleIndex+3]))
vec4 head = unpackUnorm4x8(headUint); switch (0)
switch (int(head.a*100)%10)
//switch (2)
{ {
/// Plain
case 0: { case 0: {
metallicRoughness = head.rg; elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 2])).rgb, 1);
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex+2])).rgb, 1); metallicRoughness = vec2(unpackUnorm4x8(floatBitsToUint(style[styleIndex + 1])).rg);
break; break;
} }
/// RadialGradient
case 1: { case 1: {
uint size = headUint%(1<<15); elementColor = vec4(mix(vec3(0), vec3(1), d), 1);
bool gradual = (headUint&(1<<15))!=0; metallicRoughness = vec2(0, 0.8);
uint lastData = floatBitsToUint(style[styleIndex+2+0*2]);
float lastLevel = 0;
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex+3+0*2])).rgb, 1);
for(uint i = 0; i < size; i++)
{
uint data = floatBitsToUint(style[styleIndex+2+i*2]);
float level = unpackUnorm2x16(data).y;
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(style[styleIndex+3+i*2])).rgb, 1);
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
if (d <= level)
{
if(gradual)
{
float a = (d-lastLevel)/(level-lastLevel);
elementColor = mix(lastColor, currentColor, a);
metallicRoughness = mix(lastMetallicRoughness, currentMetallicRoughness, a);
}
else
{
elementColor = currentColor;
metallicRoughness = currentMetallicRoughness;
}
break;
}
lastMetallicRoughness = currentMetallicRoughness;
lastColor = currentColor;
lastLevel = level;
}
break; break;
} }
case 2: { case 2: {
@ -1022,9 +987,8 @@ void main()
else // Stroke else // Stroke
{ {
float minDistance = 1e38; float minDistance = 1e38;
vec4 styleHead = unpackUnorm4x8(floatBitsToUint(style[styleIndex+1])); // float lineType = elementData[styleIndex+4];
float lineType = floor(styleHead.b*10); float lineType = 2;
//float lineType = 2;
int debugBegin = 0; int debugBegin = 0;
for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++) for (uint pathIndex = 0; pathIndex < pathSize; pathIndex++)
{ {

View File

@ -898,72 +898,40 @@ void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 me
{ {
elementColor = vec4(1); elementColor = vec4(1);
metallicRoughness = vec2(0.8); metallicRoughness = vec2(0.8);
uint headUint = floatBitsToUint(elementData[styleIndex+1]); //switch(int(elementData[styleIndex+3]))
vec4 head = unpackUnorm4x8(headUint); switch(0)
switch (int(head.a*100)%10)
//switch (2)
{ {
/// Plain case 0:
case 0: { {
metallicRoughness = head.rg; elementColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex+2])).rgb,1);
elementColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex+2])).rgb, 1); metallicRoughness = vec2(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex+1])).rg);
break; break;
} }
/// RadialGradient case 1:
case 1: {
uint size = headUint%(1<<15);
bool gradual = (headUint&(1<<15))!=0;
uint lastData = floatBitsToUint(elementData[styleIndex+2+0*2]);
float lastLevel = 0;
vec2 lastMetallicRoughness = unpackUnorm4x8(lastData).rg;
vec4 lastColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex+3+0*2])).rgb, 1);
for(uint i = 0; i < size; i++)
{ {
uint data = floatBitsToUint(elementData[styleIndex+2+i*2]); elementColor = vec4(mix(vec3(0), vec3(1), d), 1);
float level = unpackUnorm2x16(data).y; metallicRoughness = vec2(0,0.8);
vec4 currentColor = vec4(unpackUnorm4x8(floatBitsToUint(elementData[styleIndex+3+i*2])).rgb, 1);
vec2 currentMetallicRoughness = unpackUnorm4x8(data).rg;
if (d <= level)
{
if(gradual)
{
float a = (d-lastLevel)/(level-lastLevel);
elementColor = mix(lastColor, currentColor, a);
metallicRoughness = mix(lastMetallicRoughness, currentMetallicRoughness, a);
}
else
{
elementColor = currentColor;
metallicRoughness = currentMetallicRoughness;
}
break; break;
} }
lastMetallicRoughness = currentMetallicRoughness; case 2:
lastColor = currentColor; {
lastLevel = level; float levels[] = {0.25,0.5,0.75};
} vec3 colors[] = {vec3(1,0,0), vec3(0,1,0), vec3(0,0,1), vec3(1,1,0)};
break;
}
case 2: {
float levels[] = {0.25, 0.5, 0.75};
vec3 colors[] = {vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1), vec3(1, 1, 0)};
int i = 0; int i = 0;
while (i < 3) while(i<3)
{ {
if (d < levels[i]) if(d<levels[i])
{ {
elementColor = vec4(colors[i], 1); elementColor = vec4(colors[i], 1);
metallicRoughness = vec2(0, 0.8); metallicRoughness = vec2(0,0.8);
break; break;
} }
i++; i++;
} }
if (i == 3) if(i==3)
{ {
elementColor = vec4(colors[i], 1); elementColor = vec4(colors[i], 1);
metallicRoughness = vec2(0, 0.8); metallicRoughness = vec2(0,0.8);
} }
break; break;
} }

View File

@ -392,13 +392,12 @@ GLuint Renderer::Model::loadPainting(std::string path)
vector<std::shared_ptr<ElementStyle>> style = { vector<std::shared_ptr<ElementStyle>> style = {
std::make_shared<ElementStyleFillDemo>(), std::make_shared<ElementStyleFillDemo>(),
std::make_shared<ElementStyleStrokeDemo>(0.02), std::make_shared<ElementStyleStrokeDemo>(0.02)
std::make_shared<ElementStyleStrokeRadialGradientDemo>(0.02)
}; };
vector<std::shared_ptr<Element>> element = { vector<std::shared_ptr<Element>> element = {
std::make_shared<Element>(Element{ contour[0], style[0]}), std::make_shared<Element>(Element{ contour[0], style[0]}),
std::make_shared<Element>(Element{ contour[1], style[2]}), std::make_shared<Element>(Element{ contour[1], style[1]}),
std::make_shared<Element>(Element{ contour[2], style[0]}), std::make_shared<Element>(Element{ contour[2], style[0]}),
}; };
Painting painting; Painting painting;

View File

@ -18,23 +18,5 @@ Renderer::ElementStyleStrokeDemo::ElementStyleStrokeDemo(float width)
std::vector<BaseStyle> Renderer::ElementStyleStrokeDemo::toBaseStyles() const std::vector<BaseStyle> Renderer::ElementStyleStrokeDemo::toBaseStyles() const
{ {
return { BaseStyle(std::make_shared<TransformStyle>(), return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(width, StrokeType::kBothSides, StrokeEndType::kRound, std::make_shared<StrokePlain>(QColor(0, 0, 255), 0, 0.8))) }; std::make_shared<MaterialStyleStroke>(width, StrokeType::kLeftSide, StrokeEndType::kRound, std::make_shared<StrokePlain>(QColor(0, 0, 255), 0, 0.8))) };
}
Renderer::ElementStyleStrokeRadialGradientDemo::ElementStyleStrokeRadialGradientDemo(float width)
: width(width)
{
}
std::vector<BaseStyle> Renderer::ElementStyleStrokeRadialGradientDemo::toBaseStyles() const
{
std::map<float, Material> materialMap = {
{0.25, Material{QColor(255,0,0)}},
{0.50, Material{QColor(0,255,0)}},
{0.75, Material{QColor(0,0,255)}},
{1.00, Material{QColor(255,255,0)}},
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(width, StrokeType::kLeftSide, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
} }

View File

@ -31,14 +31,4 @@ namespace Renderer
protected: protected:
float width; float width;
}; };
class ElementStyleStrokeRadialGradientDemo : public ElementStyle
{
public:
ElementStyleStrokeRadialGradientDemo(float width);
virtual std::vector<BaseStyle> toBaseStyles() const override;
protected:
float width;
};
} }

View File

@ -1,5 +1,4 @@
#include "MaterialStyleStroke.h" #include "MaterialStyleStroke.h"
#include <QDebug>
using namespace Renderer; using namespace Renderer;
@ -8,11 +7,6 @@ Renderer::StrokePlain::StrokePlain(QColor color, float metallic, float roughness
{ {
} }
Renderer::StrokePlain::StrokePlain(const Material& material)
: material(material)
{
}
MaterialStrokeType Renderer::StrokePlain::type() const MaterialStrokeType Renderer::StrokePlain::type() const
{ {
return MaterialStrokeType::kPlain; return MaterialStrokeType::kPlain;
@ -30,43 +24,8 @@ bool Renderer::StrokePlain::operator==(const MaterialStroke& m) const
&& material == static_cast<const StrokePlain&>(m).material; && material == static_cast<const StrokePlain&>(m).material;
} }
Renderer::StrokeRadialGradient::StrokeRadialGradient(const std::map<float, Material>& materialMap, bool gradual)
: materialMap(materialMap), gradual(gradual)
{
}
MaterialStrokeType Renderer::StrokeRadialGradient::type() const
{
return MaterialStrokeType::kRadialGradient;
}
std::vector<GLfloat> Renderer::StrokeRadialGradient::encoded() const
{
GLuint head = materialMap.size() + (gradual ? (1 << 15) : 0);
std::vector<GLfloat> result = { glm::uintBitsToFloat(head) };
for (auto& pair : materialMap)
{
auto [color, metallicRoughness] = pair.second.toVec();
GLuint i = glm::packUnorm4x8(glm::vec4(metallicRoughness, 0, 0));
glm::vec2 v = glm::unpackUnorm2x16(i);
v.y = pair.first;
result.push_back(glm::uintBitsToFloat(glm::packUnorm2x16(v)));
result.push_back(glm::uintBitsToFloat(glm::packUnorm4x8(color)));
qDebug() << pair.first;
}
return result;
}
bool Renderer::StrokeRadialGradient::operator==(const MaterialStroke& m) const
{
return type() == m.type()
&& gradual == static_cast<const StrokeRadialGradient&>(m).gradual
&& materialMap == static_cast<const StrokeRadialGradient&>(m).materialMap;
}
Renderer::MaterialStyleStroke::MaterialStyleStroke(float width, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke) Renderer::MaterialStyleStroke::MaterialStyleStroke(float width, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke)
: halfWidth(width/2), strokeType(strokeType), endType(endType), materialStroke(materialStroke) : width(width), strokeType(strokeType), endType(endType), materialStroke(materialStroke)
{ {
} }
@ -77,11 +36,11 @@ MaterialStyleType Renderer::MaterialStyleStroke::type() const
std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const
{ {
std::vector<GLfloat> v = { halfWidth }; std::vector<GLfloat> v = { width };
auto encoded = materialStroke->encoded(); auto encoded = materialStroke->encoded();
glm::vec4 head = glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[0])); glm::vec4 head = glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[0]));
head.b = (float)strokeType / 10. + (float)endType / 100.; head.b = (float)strokeType / 10. + (float)endType / 100.;
head.a = 0.6 /*ʹµÃpackºóСÓÚ0*/ + (float)materialStroke->type() / 100.; head.a = 1; /// Ô¤Áô
encoded[0] = glm::uintBitsToFloat(glm::packUnorm4x8(head)); encoded[0] = glm::uintBitsToFloat(glm::packUnorm4x8(head));
v.insert(v.end(), encoded.begin(), encoded.end()); v.insert(v.end(), encoded.begin(), encoded.end());
return v; return v;
@ -92,9 +51,9 @@ bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
return type() == m.type() && *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke; return type() == m.type() && *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke;
} }
float Renderer::MaterialStyleStroke::getHalfWidth() const float Renderer::MaterialStyleStroke::getWidth() const
{ {
return halfWidth; return width;
} }

View File

@ -3,7 +3,7 @@
namespace Renderer namespace Renderer
{ {
enum class MaterialStrokeType { kPlain = 0, kRadialGradient = 1, kLinearGradient = 2 }; enum class MaterialStrokeType { kPlain, kLinearGradient, kRadialGradient};
class MaterialStroke class MaterialStroke
{ {
@ -17,7 +17,6 @@ namespace Renderer
{ {
public: public:
StrokePlain(QColor color, float metallic, float roughness); StrokePlain(QColor color, float metallic, float roughness);
StrokePlain(const Material& material);
virtual MaterialStrokeType type() const override; virtual MaterialStrokeType type() const override;
virtual std::vector<GLfloat> encoded() const override; virtual std::vector<GLfloat> encoded() const override;
virtual bool operator==(const MaterialStroke&) const override; virtual bool operator==(const MaterialStroke&) const override;
@ -28,13 +27,12 @@ namespace Renderer
class StrokeRadialGradient : public MaterialStroke class StrokeRadialGradient : public MaterialStroke
{ {
public: public:
StrokeRadialGradient(const std::map<float, Material>& materialMap, bool gradual); StrokeRadialGradient(QColor color, float metallic, float roughness);
virtual MaterialStrokeType type() const override; virtual MaterialStrokeType type() const override;
virtual std::vector<GLfloat> encoded() const override; virtual std::vector<GLfloat> encoded() const override;
virtual bool operator==(const MaterialStroke&) const override; virtual bool operator==(const MaterialStroke&) const override;
std::map<float, Material> materialMap; //std::map<
bool gradual = true;
}; };
enum class StrokeType { kBothSides = 2, kLeftSide = 1, kRightSide = 0 }; enum class StrokeType { kBothSides = 2, kLeftSide = 1, kRightSide = 0 };
@ -47,9 +45,9 @@ namespace Renderer
virtual MaterialStyleType type() const override; virtual MaterialStyleType type() const override;
virtual std::vector<GLfloat> encoded() const override; virtual std::vector<GLfloat> encoded() const override;
virtual bool operator==(const MaterialStyle&) const override; virtual bool operator==(const MaterialStyle&) const override;
float getHalfWidth() const; float getWidth() const;
protected: protected:
float halfWidth; float width;
StrokeType strokeType; StrokeType strokeType;
StrokeEndType endType; StrokeEndType endType;
std::shared_ptr<MaterialStroke> materialStroke; std::shared_ptr<MaterialStroke> materialStroke;

View File

@ -43,7 +43,7 @@ void Renderer::Painting::addElement(ElementWithTransform elementWithTransform)
{ {
qDebug() << "Build LineTree-------------------------------------------------------------------------------------------------------"; qDebug() << "Build LineTree-------------------------------------------------------------------------------------------------------";
LineTree lineTree(maxLineCount); LineTree lineTree(maxLineCount);
lineTree.buildLineTree(*element.contour, std::static_pointer_cast<MaterialStyleStroke>(element.style)->getHalfWidth()); lineTree.buildLineTree(*element.contour, std::static_pointer_cast<MaterialStyleStroke>(element.style)->getWidth());
ContourBuffer elementBuffer; ContourBuffer elementBuffer;
std::vector<BvhTreeData> bvhLeaves = lineTree.getPointLineAndBvhTree(elementBuffer.pointBuffer, elementBuffer.lineBuffer); std::vector<BvhTreeData> bvhLeaves = lineTree.getPointLineAndBvhTree(elementBuffer.pointBuffer, elementBuffer.lineBuffer);
BvhTree bvhTree; BvhTree bvhTree;

View File

@ -20,7 +20,7 @@ Renderer::ElementRenderer::ElementRenderer(QOpenGLWidget* glWidget)
void Renderer::ElementRenderer::initialize() void Renderer::ElementRenderer::initialize()
{ {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
shader = std::make_unique<QOpenGLShaderProgram>(); shader = std::make_shared<QOpenGLShaderProgram>();
if (!shader->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/element.comp")) if (!shader->addShaderFromSourceFile(QOpenGLShader::Compute, ":/Shaders/element.comp"))
qDebug() << "ERROR: " << shader->log(); qDebug() << "ERROR: " << shader->log();
if (!shader->link()) if (!shader->link())
@ -37,25 +37,30 @@ std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
switch (element.type) switch (element.type)
{ {
case QPainterPath::MoveToElement: case QPainterPath::MoveToElement:
qDebug() << "MoveToElement";
pathBuffer.push_back(glm::vec2(std::numeric_limits<float>::infinity())); pathBuffer.push_back(glm::vec2(std::numeric_limits<float>::infinity()));
pathBuffer.push_back(glm::vec2(element.x, element.y)); pathBuffer.push_back(glm::vec2(element.x, element.y));
break; break;
case QPainterPath::LineToElement: case QPainterPath::LineToElement:
qDebug() << "LineToElement";
{ {
glm::vec2 end = glm::vec2(element.x, element.y); glm::vec2 end = glm::vec2(element.x, element.y);
glm::vec2 mid = (pathBuffer.back() + end) / 2.f; glm::vec2 mid = (pathBuffer.back() + end) / 2.f;
pathBuffer.push_back(mid); pathBuffer.push_back(mid);
pathBuffer.push_back(mid); pathBuffer.push_back(mid);
pathBuffer.push_back(end); pathBuffer.push_back(end);
break;
} }
break;
case QPainterPath::CurveToElement: case QPainterPath::CurveToElement:
qDebug() << "CurveToElement";
pathBuffer.push_back(glm::vec2(element.x, element.y)); pathBuffer.push_back(glm::vec2(element.x, element.y));
break; break;
case QPainterPath::CurveToDataElement: case QPainterPath::CurveToDataElement:
qDebug() << "CurveToDataElement";
pathBuffer.push_back(glm::vec2(element.x, element.y)); pathBuffer.push_back(glm::vec2(element.x, element.y));
break; break;
} }
qDebug() << element;
} }
return pathBuffer; return pathBuffer;
} }
@ -90,8 +95,11 @@ QRectF calcBoundingRect(const QPainterPath& path, const std::vector<BaseStyle>&
BaseTransform transform(originTransform.appliedTransformStyle(*baseStyle.transform)); BaseTransform transform(originTransform.appliedTransformStyle(*baseStyle.transform));
if (baseStyle.material->type() == MaterialStyleType::kStroke) if (baseStyle.material->type() == MaterialStyleType::kStroke)
{ {
float halfWidth = std::static_pointer_cast<MaterialStyleStroke>(baseStyle.material)->getHalfWidth(); float halfWidth = std::static_pointer_cast<MaterialStyleStroke>(baseStyle.material)->getWidth() / 2;
transform.bound += glm::vec4(glm::vec2(-halfWidth), glm::vec2(halfWidth)); transform.bound.x -= halfWidth;
transform.bound.y -= halfWidth;
transform.bound.z += halfWidth;
transform.bound.w += halfWidth;
} }
glm::vec2 points[] = { glm::vec2 points[] = {
glm::vec2(transform.bound.x, transform.bound.y), glm::vec2(transform.bound.x, transform.bound.y),

View File

@ -28,7 +28,7 @@ namespace Renderer
std::pair<QImage, QPointF> drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio, bool releaseContext = true); std::pair<QImage, QPointF> drawElement(const QPainterPath& path, const ElementStyle& style, float pixelRatio, bool releaseContext = true);
protected: protected:
QOpenGLWidget* glWidget; QOpenGLWidget* glWidget;
std::unique_ptr<QOpenGLShaderProgram> shader; std::shared_ptr<QOpenGLShaderProgram> shader;
}; };
} }

View File

@ -19,9 +19,15 @@
### 场景渲染Renderer ### 场景渲染Renderer
采用 PBR (金属度-粗糙度) 材质模型,场景中存在一个方向光,可拖动滑动条调整光源方向观察材质效果 采用 PBR (金属度-粗糙度) 材质模型,场景中存在一个方向光,可拖动滑动条调整光源方向观察材质效果。
已实现BVH加速结构的建立
已实现单图元的拆分,即划分网格并生成快捷段和缠绕增量
已实现由图元数据建立完整彩绘编码 已实现由图元数据建立完整彩绘编码
已实现面的纯色样式,线的纯色、径向渐变/分层、单侧等样式 已实现线的单侧描边
待完善图元样式的编解码

View File

@ -2,79 +2,23 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#include "ElementRendererTest.h" #include "ElementRendererTest.h"
#include "Renderer/Painting/ElementStyle.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework; using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace Renderer;
namespace UnitTest namespace UnitTest
{ {
TEST_CLASS(ElementRendererTest) TEST_CLASS(ElementRendererTest)
{ {
public: public:
TEST_METHOD(TestStrokePlain) TEST_METHOD(TestMethod1)
{ {
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
char* argv[] = { (char*)"" }; char arg[] = "";
char* argv[] = { arg };
int argc = 1; int argc = 1;
QApplication a(argc, argv); QApplication a(argc, argv);
Renderer::ElementStyleStrokeDemo style(2); TestGLWidget w;
TestGLWidget w(style);
w.show();
a.exec();
}
TEST_METHOD(TestStrokeRadialGradient1)
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
char* argv[] = { (char*)"" };
int argc = 1;
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
std::map<float, Material> materialMap = {
{0.25, Material{QColor(255,0,0)}},
{0.50, Material{QColor(0,255,0)}},
{0.75, Material{QColor(0,0,255)}},
{1.00, Material{QColor(255,255,0)}},
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(4, StrokeType::kLeftSide, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
}
} style;
TestGLWidget w(style);
w.show();
a.exec();
}
TEST_METHOD(TestStrokeRadialGradient2)
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
char* argv[] = { (char*)"" };
int argc = 1;
QApplication a(argc, argv);
class StyleStrokeRadialGradient : public Renderer::ElementStyle
{
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
{
std::map<float, Material> materialMap = {
{0.50, Material{QColor(0,255,0)}},
{0.75, Material{QColor(0,0,255)}},
{1.00, Material{QColor(255,255,0)}},
};
return { BaseStyle(std::make_shared<TransformStyle>(),
std::make_shared<MaterialStyleStroke>(4, StrokeType::kLeftSide, StrokeEndType::kRound,
std::make_shared<StrokeRadialGradient>(materialMap, true))) };
}
} style;
TestGLWidget w(style);
w.show(); w.show();
a.exec(); a.exec();
} }

View File

@ -14,10 +14,8 @@ namespace UnitTest
Q_OBJECT Q_OBJECT
private: private:
Renderer::ElementRenderer renderer; Renderer::ElementRenderer renderer;
Renderer::ElementStyle& style;
public: public:
TestGLWidget(Renderer::ElementStyle& style, QWidget* parent = nullptr) TestGLWidget(QWidget* parent = nullptr) : QOpenGLWidget(parent), renderer(this) {};
: QOpenGLWidget(parent), renderer(this), style(style) {};
void initializeGL() override void initializeGL() override
{ {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
@ -29,15 +27,9 @@ namespace UnitTest
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
QPainterPath path; QPainterPath path;
QQuickSvgParser::parsePathDataFast("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", path); QQuickSvgParser::parsePathDataFast("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", path);
/*QTransform transform; auto [img, pos] = renderer.drawElement(path, Renderer::ElementStyleStrokeDemo(2), 1, false);
transform.scale(10, 10);
transform.map(path);*/
float pixelRatio = 30;
auto [img, pos] = renderer.drawElement(path, style, pixelRatio, false);
QPainter painter(this); QPainter painter(this);
painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.drawImage(pos, img);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.drawImage(QRectF(QPointF(0, 0), img.size()/devicePixelRatioF()), img);
}; };
void resizeGL(int w, int h) override {}; void resizeGL(int w, int h) override {};
}; };