实现MaterialStyle的decoded方法
parent
03a06ce426
commit
15a41d61a5
|
@ -1,6 +1,43 @@
|
||||||
#include "BaseStyle.h"
|
#include "BaseStyle.h"
|
||||||
|
#include "MaterialStyleFill.h"
|
||||||
|
#include "MaterialStyleStroke.h"
|
||||||
|
|
||||||
using namespace Renderer;
|
using namespace Renderer;
|
||||||
|
using namespace glm;
|
||||||
|
|
||||||
|
Renderer::Material::Material(const QColor& color, float metallic, float roughness)
|
||||||
|
: color(color)
|
||||||
|
{
|
||||||
|
setMetallicF(metallic);
|
||||||
|
setRoughnessF(roughness);
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::Material::Material(const glm::vec4& color, const glm::vec2& metallicRoughness)
|
||||||
|
: color(QColor::fromRgbF(color.r, color.g, color.b, color.a))
|
||||||
|
{
|
||||||
|
setMetallicF(metallicRoughness.r);
|
||||||
|
setRoughnessF(metallicRoughness.g);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::Material::metallicF() const
|
||||||
|
{
|
||||||
|
return metallic / 255.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::Material::roughnessF() const
|
||||||
|
{
|
||||||
|
return roughness / 255.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::Material::setMetallicF(float metallic)
|
||||||
|
{
|
||||||
|
this->metallic = metallic * 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::Material::setRoughnessF(float roughness)
|
||||||
|
{
|
||||||
|
this->roughness = roughness * 255;
|
||||||
|
}
|
||||||
|
|
||||||
bool Renderer::Material::operator==(const Material& m) const
|
bool Renderer::Material::operator==(const Material& m) const
|
||||||
{
|
{
|
||||||
|
@ -9,5 +46,52 @@ bool Renderer::Material::operator==(const Material& m) const
|
||||||
|
|
||||||
std::pair<glm::vec4, glm::vec2> Renderer::Material::toVec() const
|
std::pair<glm::vec4, glm::vec2> Renderer::Material::toVec() const
|
||||||
{
|
{
|
||||||
return { glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF()), glm::vec2(metallic, roughness)};
|
return { glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF()), glm::vec2(metallicF(), roughnessF())};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vector<GLfloat>& encoded)
|
||||||
|
{
|
||||||
|
if (encoded[0] <= 0) /// MaterialStyleFill
|
||||||
|
{
|
||||||
|
std::unique_ptr<MaterialFill> materiallFill;
|
||||||
|
glm::vec4 head = glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[0]));
|
||||||
|
if (head.z == 0)
|
||||||
|
{
|
||||||
|
materiallFill = std::make_unique<FillPlain>(Material(glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[1])), glm::vec2(head.r, head.g)));
|
||||||
|
}
|
||||||
|
return std::make_unique<MaterialStyleFill>(std::move(materiallFill));
|
||||||
|
}
|
||||||
|
else /// MaterialStyleStroke
|
||||||
|
{
|
||||||
|
std::unique_ptr<MaterialStroke> materialStroke;
|
||||||
|
uint headUint = floatBitsToUint(encoded[1]);
|
||||||
|
vec4 head = unpackUnorm4x8(headUint);
|
||||||
|
StrokeType strokeType = (StrokeType)floor(head.b * 10);
|
||||||
|
StrokeEndType endType = (StrokeEndType)(int(round(head.b * 100)) % 10);
|
||||||
|
switch (int(head.a * 100) % 10)
|
||||||
|
{
|
||||||
|
/// Plain
|
||||||
|
case 0: {
|
||||||
|
materialStroke = std::make_unique<StrokePlain>(Material(glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[2])), glm::vec2(head.r, head.g)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/// RadialGradient
|
||||||
|
case 1: {
|
||||||
|
uint size = headUint % (1 << 15);
|
||||||
|
bool gradual = (headUint & (1 << 15)) != 0;
|
||||||
|
std::map<float, Material> materialMap;
|
||||||
|
for (uint i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
auto data = floatBitsToUint(encoded[2 + i * 2]);
|
||||||
|
auto level = unpackUnorm2x16(data).y;
|
||||||
|
auto color = unpackUnorm4x8(floatBitsToUint(encoded[3 + i * 2]));
|
||||||
|
auto metallicRoughness = unpackUnorm4x8(data);
|
||||||
|
materialMap.emplace(level, Material(color, glm::vec2(metallicRoughness.r, metallicRoughness.g)));
|
||||||
|
}
|
||||||
|
materialStroke = std::make_unique<StrokeRadialGradient>(materialMap, gradual);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::make_unique<MaterialStyleStroke>(encoded[0], strokeType, endType, std::move(materialStroke));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace Renderer
|
||||||
virtual std::vector<GLfloat> encoded() const = 0;
|
virtual std::vector<GLfloat> encoded() const = 0;
|
||||||
virtual std::unique_ptr<MaterialStyle> clone() const = 0;
|
virtual std::unique_ptr<MaterialStyle> clone() const = 0;
|
||||||
virtual bool operator==(const MaterialStyle&) const = 0;
|
virtual bool operator==(const MaterialStyle&) const = 0;
|
||||||
|
static std::unique_ptr<MaterialStyle> decoded(const std::vector<GLfloat>& encoded);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BaseStyle
|
struct BaseStyle
|
||||||
|
@ -36,8 +37,16 @@ namespace Renderer
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
QColor color;
|
QColor color;
|
||||||
float metallic;
|
std::uint8_t metallic;
|
||||||
float roughness;
|
std::uint8_t roughness;
|
||||||
|
|
||||||
|
Material() = default;
|
||||||
|
Material(const QColor& color, float metallic = 0, float roughness = 0.5);
|
||||||
|
Material(const glm::vec4& color, const glm::vec2& metallicRoughness);
|
||||||
|
float metallicF() const;
|
||||||
|
float roughnessF() const;
|
||||||
|
void setMetallicF(float metallic);
|
||||||
|
void setRoughnessF(float roughness);
|
||||||
bool operator==(const Material&) const;
|
bool operator==(const Material&) const;
|
||||||
std::pair<glm::vec4, glm::vec2> toVec() const;
|
std::pair<glm::vec4, glm::vec2> toVec() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
using namespace Renderer;
|
using namespace Renderer;
|
||||||
|
|
||||||
Renderer::FillPlain::FillPlain(QColor color, float metallic, float roughness)
|
Renderer::FillPlain::FillPlain(QColor color, float metallic, float roughness)
|
||||||
: color(color), metallic(metallic), roughness(roughness)
|
: material(color, metallic, roughness)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::FillPlain::FillPlain(const Material& material)
|
||||||
|
: material(material)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +19,9 @@ MaterialFillType Renderer::FillPlain::type() const
|
||||||
|
|
||||||
std::vector<GLfloat> Renderer::FillPlain::encoded() const
|
std::vector<GLfloat> Renderer::FillPlain::encoded() const
|
||||||
{
|
{
|
||||||
return { glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(metallic, roughness, 0, 1))),
|
auto pair = material.toVec();
|
||||||
glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF())))};
|
return { glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(pair.second, 0, 1))),
|
||||||
|
glm::uintBitsToFloat(glm::packUnorm4x8(pair.first))};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MaterialFill> Renderer::FillPlain::clone() const
|
std::unique_ptr<MaterialFill> Renderer::FillPlain::clone() const
|
||||||
|
@ -26,9 +32,7 @@ std::unique_ptr<MaterialFill> Renderer::FillPlain::clone() const
|
||||||
bool Renderer::FillPlain::operator==(const MaterialFill& m) const
|
bool Renderer::FillPlain::operator==(const MaterialFill& m) const
|
||||||
{
|
{
|
||||||
return type() == m.type()
|
return type() == m.type()
|
||||||
&& color == static_cast<const FillPlain&>(m).color
|
&& material == static_cast<const FillPlain&>(m).material;
|
||||||
&& metallic == static_cast<const FillPlain&>(m).metallic
|
|
||||||
&& roughness == static_cast<const FillPlain&>(m).roughness;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,13 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FillPlain(QColor color, float metallic, float roughness);
|
FillPlain(QColor color, float metallic, float roughness);
|
||||||
|
FillPlain(const Material& material);
|
||||||
virtual MaterialFillType type() const override;
|
virtual MaterialFillType type() const override;
|
||||||
virtual std::vector<GLfloat> encoded() const override;
|
virtual std::vector<GLfloat> encoded() const override;
|
||||||
virtual std::unique_ptr<MaterialFill> clone() const override;
|
virtual std::unique_ptr<MaterialFill> clone() const override;
|
||||||
virtual bool operator==(const MaterialFill&) const override;
|
virtual bool operator==(const MaterialFill&) const override;
|
||||||
|
|
||||||
QColor color;
|
Material material;
|
||||||
float metallic;
|
|
||||||
float roughness;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaterialStyleFill : public MaterialStyle
|
class MaterialStyleFill : public MaterialStyle
|
||||||
|
|
|
@ -76,8 +76,8 @@ bool Renderer::StrokeRadialGradient::operator==(const MaterialStroke& m) const
|
||||||
&& materialMap == static_cast<const StrokeRadialGradient&>(m).materialMap;
|
&& 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 halfWidth, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke)
|
||||||
: halfWidth(width/2), strokeType(strokeType), endType(endType), materialStroke(materialStroke)
|
: halfWidth(halfWidth), strokeType(strokeType), endType(endType), materialStroke(materialStroke)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const
|
||||||
|
|
||||||
std::unique_ptr<MaterialStyle> Renderer::MaterialStyleStroke::clone() const
|
std::unique_ptr<MaterialStyle> Renderer::MaterialStyleStroke::clone() const
|
||||||
{
|
{
|
||||||
return std::make_unique<MaterialStyleStroke>(halfWidth*2, strokeType, endType, materialStroke->clone());
|
return std::make_unique<MaterialStyleStroke>(halfWidth, strokeType, endType, materialStroke->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
|
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -61,7 +61,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kFlat,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kFlat,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -82,7 +82,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kLeftSide, StrokeEndType::kRound,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kLeftSide, StrokeEndType::kRound,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -103,7 +103,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kLeftSide, StrokeEndType::kFlat,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kLeftSide, StrokeEndType::kFlat,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -124,7 +124,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(160, StrokeType::kRightSide, StrokeEndType::kFlatRound,
|
std::make_shared<MaterialStyleStroke>(80, StrokeType::kRightSide, StrokeEndType::kFlatRound,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -149,7 +149,7 @@ namespace UnitTest
|
||||||
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
||||||
{
|
{
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
std::make_shared<StrokePlain>(QColor(255,255,255),1,1))) };
|
std::make_shared<StrokePlain>(QColor(255,255,255),1,1))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -170,7 +170,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "CppUnitTest.h"
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QtWidgets/QApplication>
|
||||||
|
#include "Renderer/Painting/ElementStyle.h"
|
||||||
|
#include <Renderer/Painting/MaterialStyleStroke.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
using namespace Renderer;
|
||||||
|
|
||||||
|
namespace UnitTest
|
||||||
|
{
|
||||||
|
TEST_CLASS(StyleTest)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TEST_METHOD(TestEncodeDecode)
|
||||||
|
{
|
||||||
|
std::map<float, Material> materialMap = {
|
||||||
|
{0.20, Material{QColor(255,255,255)}},
|
||||||
|
{0.60, Material{QColor(165,176,207)}},
|
||||||
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
|
};
|
||||||
|
auto style = std::make_unique<MaterialStyleStroke>(
|
||||||
|
30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
|
std::make_shared<StrokeRadialGradient>(materialMap, false)
|
||||||
|
);
|
||||||
|
/* auto style = std::make_shared<MaterialStyleStroke>(
|
||||||
|
30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
|
std::make_shared<StrokePlain>(Material(QColor(255, 255, 255)))
|
||||||
|
);*/
|
||||||
|
std::shared_ptr<MaterialStyle> decoded = MaterialStyle::decoded(style->encoded());
|
||||||
|
/* Assert::IsTrue(decoded->type() == MaterialStyleType::kStroke);
|
||||||
|
Assert::IsTrue(std::static_pointer_cast<MaterialStyleStroke>(decoded)->halfWidth == 30);
|
||||||
|
Assert::IsTrue(std::static_pointer_cast<MaterialStyleStroke>(decoded)->strokeType == StrokeType::kBothSides);
|
||||||
|
Assert::IsTrue(std::static_pointer_cast<MaterialStyleStroke>(decoded)->endType == StrokeEndType::kRound);
|
||||||
|
std::shared_ptr<MaterialStroke> materialStroke = std::static_pointer_cast<MaterialStyleStroke>(decoded)->materialStroke;
|
||||||
|
Assert::IsTrue(materialStroke->type() == MaterialStrokeType::kPlain);
|
||||||
|
Material material = std::static_pointer_cast<StrokePlain>(materialStroke)->material;
|
||||||
|
Assert::IsTrue(material == Material(QColor(255, 255, 255)));
|
||||||
|
Logger::WriteMessage(std::format("({} {} {} {}), ({} {})\n",
|
||||||
|
material.color.red(),
|
||||||
|
material.color.green(),
|
||||||
|
material.color.blue(),
|
||||||
|
material.color.alpha(),
|
||||||
|
material.metallic,
|
||||||
|
material.roughness
|
||||||
|
).c_str());*/
|
||||||
|
|
||||||
|
|
||||||
|
Assert::IsTrue(*style == *decoded);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -117,6 +117,7 @@
|
||||||
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
|
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
|
||||||
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
|
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="StyleTest.cpp" />
|
||||||
<ClCompile Include="UnitTest.cpp" />
|
<ClCompile Include="UnitTest.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -48,5 +48,8 @@
|
||||||
<ClCompile Include="PaintingTest.cpp">
|
<ClCompile Include="PaintingTest.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="StyleTest.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue