mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-26 16:16:46 +00:00
gl_engine: gradient implementation
Change-Id: If2413328437847d52ba1badc3b5c510fdd47ccd3
This commit is contained in:
parent
5f100b8cff
commit
af190033bb
16 changed files with 1028 additions and 132 deletions
5
src/lib/gl_engine/meson.build
Normal file → Executable file
5
src/lib/gl_engine/meson.build
Normal file → Executable file
|
@ -3,13 +3,18 @@ source_file = [
|
||||||
'tvgGlGeometry.h',
|
'tvgGlGeometry.h',
|
||||||
'tvgGlGpuBuffer.h',
|
'tvgGlGpuBuffer.h',
|
||||||
'tvgGlProgram.h',
|
'tvgGlProgram.h',
|
||||||
|
'tvgGlPropertyInterface.h',
|
||||||
'tvgGlRenderer.h',
|
'tvgGlRenderer.h',
|
||||||
|
'tvgGlRendererProperties.h',
|
||||||
|
'tvgGlRenderTask.h',
|
||||||
'tvgGlShader.h',
|
'tvgGlShader.h',
|
||||||
'tvgGlShaderSrc.h',
|
'tvgGlShaderSrc.h',
|
||||||
'tvgGlGeometry.cpp',
|
'tvgGlGeometry.cpp',
|
||||||
'tvgGlGpuBuffer.cpp',
|
'tvgGlGpuBuffer.cpp',
|
||||||
'tvgGlProgram.cpp',
|
'tvgGlProgram.cpp',
|
||||||
|
'tvgGlPropertyInterface.cpp',
|
||||||
'tvgGlRenderer.cpp',
|
'tvgGlRenderer.cpp',
|
||||||
|
'tvgGlRenderTask.cpp',
|
||||||
'tvgGlShader.cpp',
|
'tvgGlShader.cpp',
|
||||||
'tvgGlShaderSrc.cpp',
|
'tvgGlShaderSrc.cpp',
|
||||||
]
|
]
|
||||||
|
|
1
src/lib/gl_engine/tvgGlCommon.h
Normal file → Executable file
1
src/lib/gl_engine/tvgGlCommon.h
Normal file → Executable file
|
@ -24,6 +24,7 @@
|
||||||
#define _TVG_GL_COMMON_H_
|
#define _TVG_GL_COMMON_H_
|
||||||
|
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
#define GL_CHECK(x) \
|
#define GL_CHECK(x) \
|
||||||
|
|
103
src/lib/gl_engine/tvgGlGeometry.cpp
Normal file → Executable file
103
src/lib/gl_engine/tvgGlGeometry.cpp
Normal file → Executable file
|
@ -33,6 +33,17 @@ uint32_t GlGeometry::getPrimitiveCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const GlSize GlGeometry::getPrimitiveSize(const uint32_t primitiveIndex) const
|
||||||
|
{
|
||||||
|
if (primitiveIndex >= mPrimitives.size())
|
||||||
|
{
|
||||||
|
return GlSize();
|
||||||
|
}
|
||||||
|
GlSize size = mPrimitives[primitiveIndex].mBottomRight - mPrimitives[primitiveIndex].mTopLeft;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GlGeometry::decomposeOutline(const Shape &shape)
|
bool GlGeometry::decomposeOutline(const Shape &shape)
|
||||||
{
|
{
|
||||||
const PathCommand *cmds = nullptr;
|
const PathCommand *cmds = nullptr;
|
||||||
|
@ -46,43 +57,63 @@ bool GlGeometry::decomposeOutline(const Shape &shape)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
GlPrimitive* curPrimitive = nullptr;
|
GlPrimitive* curPrimitive = nullptr;
|
||||||
|
GlPoint min = { FLT_MAX, FLT_MAX };
|
||||||
|
GlPoint max = { 0.0f, 0.0f };
|
||||||
|
|
||||||
for (size_t i = 0; i < cmdCnt; ++i)
|
for (size_t i = 0; i < cmdCnt; ++i)
|
||||||
{
|
{
|
||||||
switch (*(cmds + i))
|
switch (*(cmds + i)) {
|
||||||
{
|
case PathCommand::Close: {
|
||||||
case PathCommand::Close:
|
if (curPrimitive)
|
||||||
{
|
|
||||||
if (curPrimitive && curPrimitive->mAAPoints.size() > 0 &&
|
|
||||||
(curPrimitive->mAAPoints[0].orgPt != curPrimitive->mAAPoints.back().orgPt) )
|
|
||||||
{
|
{
|
||||||
curPrimitive->mAAPoints.push_back(curPrimitive->mAAPoints[0].orgPt);
|
if (curPrimitive->mAAPoints.size() > 0 &&
|
||||||
|
(curPrimitive->mAAPoints[0].orgPt != curPrimitive->mAAPoints.back().orgPt))
|
||||||
|
{
|
||||||
|
curPrimitive->mAAPoints.push_back(curPrimitive->mAAPoints[0].orgPt);
|
||||||
|
}
|
||||||
|
curPrimitive->mIsClosed = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PathCommand::MoveTo:
|
case PathCommand::MoveTo: {
|
||||||
mPrimitives.push_back(GlPrimitive());
|
|
||||||
curPrimitive = &mPrimitives.back();
|
|
||||||
__attribute__ ((fallthrough));
|
|
||||||
case PathCommand::LineTo:
|
|
||||||
{
|
|
||||||
if (curPrimitive)
|
if (curPrimitive)
|
||||||
{
|
{
|
||||||
addPoint(*curPrimitive, pts[0]);
|
curPrimitive->mTopLeft = min;
|
||||||
|
curPrimitive->mBottomRight = max;
|
||||||
|
if (curPrimitive->mAAPoints.size() > 2 &&
|
||||||
|
(curPrimitive->mAAPoints[0].orgPt == curPrimitive->mAAPoints.back().orgPt))
|
||||||
|
{
|
||||||
|
curPrimitive->mIsClosed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mPrimitives.push_back(GlPrimitive());
|
||||||
|
curPrimitive = &mPrimitives.back();
|
||||||
|
}
|
||||||
|
__attribute__ ((fallthrough));
|
||||||
|
case PathCommand::LineTo: {
|
||||||
|
if (curPrimitive)
|
||||||
|
{
|
||||||
|
addPoint(*curPrimitive, pts[0], min, max);
|
||||||
}
|
}
|
||||||
pts++;
|
pts++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PathCommand::CubicTo:
|
case PathCommand::CubicTo: {
|
||||||
{
|
|
||||||
if (curPrimitive)
|
if (curPrimitive)
|
||||||
{
|
{
|
||||||
decomposeCubicCurve(*curPrimitive, curPrimitive->mAAPoints.back().orgPt, pts[0], pts[1], pts[2]);
|
decomposeCubicCurve(*curPrimitive, curPrimitive->mAAPoints.back().orgPt, pts[0], pts[1], pts[2], min, max);
|
||||||
}
|
}
|
||||||
pts += 3;
|
pts += 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (curPrimitive)
|
||||||
|
{
|
||||||
|
curPrimitive->mTopLeft = min;
|
||||||
|
curPrimitive->mBottomRight = max;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,20 +138,30 @@ bool GlGeometry::generateAAPoints(TVG_UNUSED const Shape &shape, float strokeWd,
|
||||||
|
|
||||||
size_t fPoint = 0;
|
size_t fPoint = 0;
|
||||||
size_t sPoint = 1;
|
size_t sPoint = 1;
|
||||||
for (size_t i = 0; i < nPoints; ++i)
|
for (size_t i = 0; i < nPoints - 1; ++i)
|
||||||
{
|
{
|
||||||
fPoint = i;
|
fPoint = i;
|
||||||
sPoint = i + 1;
|
sPoint = i + 1;
|
||||||
if (fPoint == nPoints - 1)
|
if (shapeGeometry.mIsClosed && sPoint == nPoints - 1)
|
||||||
|
{
|
||||||
sPoint = 0;
|
sPoint = 0;
|
||||||
|
}
|
||||||
|
|
||||||
GlPoint normal = getNormal(aaPts[fPoint].orgPt, aaPts[sPoint].orgPt);
|
GlPoint normal = getNormal(aaPts[fPoint].orgPt, aaPts[sPoint].orgPt);
|
||||||
|
|
||||||
normalInfo[fPoint].normal1 = normal;
|
normalInfo[fPoint].normal1 = normal;
|
||||||
normalInfo[sPoint].normal2 = normal;
|
normalInfo[sPoint].normal2 = normal;
|
||||||
}
|
}
|
||||||
normalInfo[0].normal2 = normalInfo[0].normal1;
|
if (shapeGeometry.mIsClosed)
|
||||||
normalInfo[nPoints - 1].normal1 = normalInfo[nPoints - 1].normal2;
|
{
|
||||||
|
normalInfo[nPoints - 1].normal1 = normalInfo[0].normal1;
|
||||||
|
normalInfo[nPoints - 1].normal2 = normalInfo[0].normal2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
normalInfo[nPoints - 1].normal1 = normalInfo[nPoints - 1].normal2;
|
||||||
|
normalInfo[0].normal2 = normalInfo[0].normal1;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < nPoints; ++i)
|
for (uint32_t i = 0; i < nPoints; ++i)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +174,7 @@ bool GlGeometry::generateAAPoints(TVG_UNUSED const Shape &shape, float strokeWd,
|
||||||
else
|
else
|
||||||
normalInfo[i].normalF = GlPoint(0, 0);
|
normalInfo[i].normalF = GlPoint(0, 0);
|
||||||
|
|
||||||
if (flag & RenderUpdateFlag::Color)
|
if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient))
|
||||||
{
|
{
|
||||||
aaPts[i].fillOuterBlur = extendEdge(aaPts[i].orgPt, normalInfo[i].normalF, blurDir * stroke);
|
aaPts[i].fillOuterBlur = extendEdge(aaPts[i].orgPt, normalInfo[i].normalF, blurDir * stroke);
|
||||||
aaPts[i].fillOuter = extendEdge(aaPts[i].fillOuterBlur, normalInfo[i].normalF, blurDir*antiAliasWidth);
|
aaPts[i].fillOuter = extendEdge(aaPts[i].fillOuterBlur, normalInfo[i].normalF, blurDir*antiAliasWidth);
|
||||||
|
@ -161,7 +202,7 @@ bool GlGeometry::tesselate(TVG_UNUSED const Shape &shape, float viewWd, float vi
|
||||||
VertexDataArray& fill = shapeGeometry.mFill;
|
VertexDataArray& fill = shapeGeometry.mFill;
|
||||||
VertexDataArray& stroke = shapeGeometry.mStroke;
|
VertexDataArray& stroke = shapeGeometry.mStroke;
|
||||||
|
|
||||||
if (flag & RenderUpdateFlag::Color)
|
if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient) )
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
for (size_t pt = 0; pt < aaPts.size(); ++pt)
|
for (size_t pt = 0; pt < aaPts.size(); ++pt)
|
||||||
|
@ -229,7 +270,7 @@ void GlGeometry::draw(const uint32_t location, const uint32_t primitiveIndex, Re
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VertexDataArray& geometry = (flag == RenderUpdateFlag::Color) ? mPrimitives[primitiveIndex].mFill : mPrimitives[primitiveIndex].mStroke;
|
VertexDataArray& geometry = (flag == RenderUpdateFlag::Stroke) ? mPrimitives[primitiveIndex].mStroke : mPrimitives[primitiveIndex].mFill;
|
||||||
|
|
||||||
updateBuffer(location, geometry);
|
updateBuffer(location, geometry);
|
||||||
GL_CHECK(glDrawElements(GL_TRIANGLES, geometry.indices.size(), GL_UNSIGNED_INT, geometry.indices.data()));
|
GL_CHECK(glDrawElements(GL_TRIANGLES, geometry.indices.size(), GL_UNSIGNED_INT, geometry.indices.data()));
|
||||||
|
@ -280,8 +321,12 @@ GlPoint GlGeometry::extendEdge(const GlPoint &pt, const GlPoint &normal, float s
|
||||||
return (pt + tmp);
|
return (pt + tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlGeometry::addPoint(GlPrimitive& primitve, const GlPoint &pt)
|
void GlGeometry::addPoint(GlPrimitive& primitve, const GlPoint &pt, GlPoint &min, GlPoint &max)
|
||||||
{
|
{
|
||||||
|
if (pt.x < min.x) min.x = pt.x;
|
||||||
|
if (pt.y < min.y) min.y = pt.y;
|
||||||
|
if (pt.x > max.x) max.x = pt.x;
|
||||||
|
if (pt.y > max.y) max.y = pt.y;
|
||||||
primitve.mAAPoints.push_back(GlPoint(pt.x, pt.y));
|
primitve.mAAPoints.push_back(GlPoint(pt.x, pt.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,11 +365,11 @@ bool GlGeometry::isBezierFlat(const GlPoint &p1, const GlPoint &c1, const GlPoin
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlGeometry::decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2)
|
void GlGeometry::decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2, GlPoint &min, GlPoint &max)
|
||||||
{
|
{
|
||||||
if (isBezierFlat(pt1, cpt1, cpt2, pt2))
|
if (isBezierFlat(pt1, cpt1, cpt2, pt2))
|
||||||
{
|
{
|
||||||
addPoint(primitve, pt2);
|
addPoint(primitve, pt2, min, max);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GlPoint p12 = (pt1 + cpt1) * 0.5f;
|
GlPoint p12 = (pt1 + cpt1) * 0.5f;
|
||||||
|
@ -336,7 +381,7 @@ void GlGeometry::decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1,
|
||||||
|
|
||||||
GlPoint p1234 = (p123 + p234) * 0.5f;
|
GlPoint p1234 = (p123 + p234) * 0.5f;
|
||||||
|
|
||||||
decomposeCubicCurve(primitve, pt1, p12, p123, p1234);
|
decomposeCubicCurve(primitve, pt1, p12, p123, p1234, min, max);
|
||||||
decomposeCubicCurve(primitve, p1234, p234, p34, pt2);
|
decomposeCubicCurve(primitve, p1234, p234, p34, pt2, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/lib/gl_engine/tvgGlGeometry.h
Normal file → Executable file
14
src/lib/gl_engine/tvgGlGeometry.h
Normal file → Executable file
|
@ -128,6 +128,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef GlPoint GlSize;
|
||||||
|
|
||||||
struct SmoothPoint
|
struct SmoothPoint
|
||||||
{
|
{
|
||||||
GlPoint orgPt;
|
GlPoint orgPt;
|
||||||
|
@ -174,6 +176,9 @@ struct GlPrimitive
|
||||||
vector<SmoothPoint> mAAPoints;
|
vector<SmoothPoint> mAAPoints;
|
||||||
VertexDataArray mFill;
|
VertexDataArray mFill;
|
||||||
VertexDataArray mStroke;
|
VertexDataArray mStroke;
|
||||||
|
GlPoint mTopLeft;
|
||||||
|
GlPoint mBottomRight;
|
||||||
|
bool mIsClosed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GlGpuBuffer;
|
class GlGpuBuffer;
|
||||||
|
@ -183,9 +188,10 @@ class GlGeometry
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint32_t getPrimitiveCount();
|
uint32_t getPrimitiveCount();
|
||||||
|
const GlSize getPrimitiveSize(const uint32_t primitiveIndex) const;
|
||||||
bool decomposeOutline(const Shape& shape);
|
bool decomposeOutline(const Shape& shape);
|
||||||
bool generateAAPoints(const Shape& shape, float strokeWd, RenderUpdateFlag flag);
|
bool generateAAPoints(TVG_UNUSED const Shape& shape, float strokeWd, RenderUpdateFlag flag);
|
||||||
bool tesselate(const Shape &shape, float viewWd, float viewHt, RenderUpdateFlag flag);
|
bool tesselate(TVG_UNUSED const Shape &shape, float viewWd, float viewHt, RenderUpdateFlag flag);
|
||||||
void disableVertex(uint32_t location);
|
void disableVertex(uint32_t location);
|
||||||
void draw(const uint32_t location, const uint32_t primitiveIndex, RenderUpdateFlag flag);
|
void draw(const uint32_t location, const uint32_t primitiveIndex, RenderUpdateFlag flag);
|
||||||
|
|
||||||
|
@ -196,11 +202,11 @@ private:
|
||||||
float dotProduct(const GlPoint &p1, const GlPoint &p2);
|
float dotProduct(const GlPoint &p1, const GlPoint &p2);
|
||||||
GlPoint extendEdge(const GlPoint &pt, const GlPoint &normal, float scalar);
|
GlPoint extendEdge(const GlPoint &pt, const GlPoint &normal, float scalar);
|
||||||
|
|
||||||
void addPoint(GlPrimitive& primitve, const GlPoint &pt);
|
void addPoint(GlPrimitive& primitve, const GlPoint &pt, GlPoint &min, GlPoint &max);
|
||||||
void addTriangleFanIndices(uint32_t &curPt, vector<uint32_t> &indices);
|
void addTriangleFanIndices(uint32_t &curPt, vector<uint32_t> &indices);
|
||||||
void addQuadIndices(uint32_t &curPt, vector<uint32_t> &indices);
|
void addQuadIndices(uint32_t &curPt, vector<uint32_t> &indices);
|
||||||
bool isBezierFlat(const GlPoint &p1, const GlPoint &c1, const GlPoint &c2, const GlPoint &p2);
|
bool isBezierFlat(const GlPoint &p1, const GlPoint &c1, const GlPoint &c2, const GlPoint &p2);
|
||||||
void decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2);
|
void decomposeCubicCurve(GlPrimitive& primitve, const GlPoint &pt1, const GlPoint &cpt1, const GlPoint &cpt2, const GlPoint &pt2, GlPoint &min, GlPoint &max);
|
||||||
void updateBuffer(const uint32_t location, const VertexDataArray& vertexArray);
|
void updateBuffer(const uint32_t location, const VertexDataArray& vertexArray);
|
||||||
|
|
||||||
unique_ptr<GlGpuBuffer> mGpuBuffer;
|
unique_ptr<GlGpuBuffer> mGpuBuffer;
|
||||||
|
|
84
src/lib/gl_engine/tvgGlProgram.cpp
Normal file → Executable file
84
src/lib/gl_engine/tvgGlProgram.cpp
Normal file → Executable file
|
@ -26,17 +26,7 @@
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
|
|
||||||
|
|
||||||
static std::vector<string> gStdAttributes = {
|
|
||||||
"aLocation"
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::vector<string> gStdUniforms = {
|
|
||||||
"uColor"
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t GlProgram::mCurrentProgram = 0;
|
uint32_t GlProgram::mCurrentProgram = 0;
|
||||||
map<string, int32_t> GlProgram::mAttributeBuffer;
|
|
||||||
map<string, int32_t> GlProgram::mUniformBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
unique_ptr<GlProgram> GlProgram::gen(std::shared_ptr<GlShader> shader)
|
unique_ptr<GlProgram> GlProgram::gen(std::shared_ptr<GlShader> shader)
|
||||||
|
@ -48,17 +38,6 @@ unique_ptr<GlProgram> GlProgram::gen(std::shared_ptr<GlShader> shader)
|
||||||
GlProgram::GlProgram(std::shared_ptr<GlShader> shader)
|
GlProgram::GlProgram(std::shared_ptr<GlShader> shader)
|
||||||
{
|
{
|
||||||
linkProgram(shader);
|
linkProgram(shader);
|
||||||
load();
|
|
||||||
|
|
||||||
for (auto name : gStdAttributes)
|
|
||||||
{
|
|
||||||
getAttributeLocation(name.c_str());
|
|
||||||
}
|
|
||||||
for (auto name : gStdUniforms)
|
|
||||||
{
|
|
||||||
getUniformLocation(name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,38 +72,63 @@ void GlProgram::unload()
|
||||||
|
|
||||||
int32_t GlProgram::getAttributeLocation(const char* name)
|
int32_t GlProgram::getAttributeLocation(const char* name)
|
||||||
{
|
{
|
||||||
if (mAttributeBuffer.find(name) != mAttributeBuffer.end())
|
|
||||||
{
|
|
||||||
return mAttributeBuffer[name];
|
|
||||||
}
|
|
||||||
GL_CHECK(int32_t location = glGetAttribLocation(mCurrentProgram, name));
|
GL_CHECK(int32_t location = glGetAttribLocation(mCurrentProgram, name));
|
||||||
if (location != -1)
|
|
||||||
{
|
|
||||||
mAttributeBuffer[name] = location;
|
|
||||||
}
|
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int32_t GlProgram::getUniformLocation(const char* name)
|
int32_t GlProgram::getUniformLocation(const char* name)
|
||||||
{
|
{
|
||||||
if (mUniformBuffer.find(name) != mUniformBuffer.end())
|
|
||||||
{
|
|
||||||
return mUniformBuffer[name];
|
|
||||||
}
|
|
||||||
GL_CHECK(int32_t location = glGetUniformLocation(mCurrentProgram, name));
|
GL_CHECK(int32_t location = glGetUniformLocation(mCurrentProgram, name));
|
||||||
if (location != -1)
|
|
||||||
{
|
|
||||||
mUniformBuffer[name] = location;
|
|
||||||
}
|
|
||||||
return location;
|
return location;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GlProgram::setUniformValue(int32_t location, float r, float g, float b, float a)
|
void GlProgram::setUniform1Value(int32_t location, int count, const int* values)
|
||||||
{
|
{
|
||||||
glUniform4f(location, r, g, b, a);
|
GL_CHECK(glUniform1iv(location, count, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlProgram::setUniform2Value(int32_t location, int count, const int* values)
|
||||||
|
{
|
||||||
|
GL_CHECK(glUniform2iv(location, count, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlProgram::setUniform3Value(int32_t location, int count, const int* values)
|
||||||
|
{
|
||||||
|
GL_CHECK(glUniform3iv(location, count, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlProgram::setUniform4Value(int32_t location, int count, const int* values)
|
||||||
|
{
|
||||||
|
GL_CHECK(glUniform4iv(location, count, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlProgram::setUniform1Value(int32_t location, int count, const float* values)
|
||||||
|
{
|
||||||
|
GL_CHECK(glUniform1fv(location, count, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlProgram::setUniform2Value(int32_t location, int count, const float* values)
|
||||||
|
{
|
||||||
|
GL_CHECK(glUniform2fv(location, count, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlProgram::setUniform3Value(int32_t location, int count, const float* values)
|
||||||
|
{
|
||||||
|
GL_CHECK(glUniform3fv(location, count, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlProgram::setUniform4Value(int32_t location, int count, const float* values)
|
||||||
|
{
|
||||||
|
GL_CHECK(glUniform4fv(location, count, values));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
13
src/lib/gl_engine/tvgGlProgram.h
Normal file → Executable file
13
src/lib/gl_engine/tvgGlProgram.h
Normal file → Executable file
|
@ -36,10 +36,17 @@ public:
|
||||||
~GlProgram();
|
~GlProgram();
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
void unload();
|
static void unload();
|
||||||
int32_t getAttributeLocation(const char* name);
|
int32_t getAttributeLocation(const char* name);
|
||||||
int32_t getUniformLocation(const char* name);
|
int32_t getUniformLocation(const char* name);
|
||||||
void setUniformValue(int32_t location, float r, float g, float b, float a);
|
void setUniform1Value(int32_t location, int count, const int* values);
|
||||||
|
void setUniform2Value(int32_t location, int count, const int* values);
|
||||||
|
void setUniform3Value(int32_t location, int count, const int* values);
|
||||||
|
void setUniform4Value(int32_t location, int count, const int* values);
|
||||||
|
void setUniform1Value(int32_t location, int count, const float* values);
|
||||||
|
void setUniform2Value(int32_t location, int count, const float* values);
|
||||||
|
void setUniform3Value(int32_t location, int count, const float* values);
|
||||||
|
void setUniform4Value(int32_t location, int count, const float* values);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -47,8 +54,6 @@ private:
|
||||||
uint32_t mProgramObj;
|
uint32_t mProgramObj;
|
||||||
static uint32_t mCurrentProgram;
|
static uint32_t mCurrentProgram;
|
||||||
|
|
||||||
static std::map<string, int32_t> mAttributeBuffer;
|
|
||||||
static std::map<string, int32_t> mUniformBuffer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _TVG_GL_PROGRAM_H_ */
|
#endif /* _TVG_GL_PROGRAM_H_ */
|
||||||
|
|
83
src/lib/gl_engine/tvgGlPropertyInterface.cpp
Executable file
83
src/lib/gl_engine/tvgGlPropertyInterface.cpp
Executable file
|
@ -0,0 +1,83 @@
|
||||||
|
#include "tvgGlPropertyInterface.h"
|
||||||
|
#include "tvgGlRenderTask.h"
|
||||||
|
|
||||||
|
VertexProperty PropertyInterface::mEmptyProperty;
|
||||||
|
|
||||||
|
VertexProperty& PropertyInterface::addProperty(GlRenderTask* rTask, std::shared_ptr<GlProgram> prog, std::string name, uint32_t propFormatSize, VertexProperty::PropertyType propType)
|
||||||
|
{
|
||||||
|
std::map<int32_t, VertexProperty>* vertexProperty = nullptr;
|
||||||
|
int32_t id;
|
||||||
|
switch (propType) {
|
||||||
|
case VertexProperty::PropertyType::ATTRIBUTE: {
|
||||||
|
id = prog->getAttributeLocation(name.c_str());
|
||||||
|
vertexProperty = &rTask->getAttributeVertexProperty();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VertexProperty::PropertyType::UNIFORM: {
|
||||||
|
id = prog->getUniformLocation(name.c_str());
|
||||||
|
vertexProperty = &rTask->getUniformVertexProperty();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (id != -1)
|
||||||
|
{
|
||||||
|
VertexProperty property = { id, name, propType, VertexProperty::DataType::FLOAT };
|
||||||
|
property.propertyValues.setStride(propFormatSize);
|
||||||
|
if (vertexProperty)
|
||||||
|
{
|
||||||
|
(*vertexProperty)[id] = property;
|
||||||
|
return (*vertexProperty)[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mEmptyProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t PropertyInterface::getPropertyId(GlRenderTask* rTask, std::string name)
|
||||||
|
{
|
||||||
|
std::map<int32_t, VertexProperty>& vertexProperty = rTask->getUniformVertexProperty();
|
||||||
|
for (auto& property : vertexProperty)
|
||||||
|
{
|
||||||
|
if (property.second.propertyName == name)
|
||||||
|
{
|
||||||
|
return property.second.propertyId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VertexProperty& PropertyInterface::getProperty(GlRenderTask* rTask, std::string name)
|
||||||
|
{
|
||||||
|
std::map<int32_t, VertexProperty>& vertexProperty = rTask->getUniformVertexProperty();
|
||||||
|
for (auto& property : vertexProperty)
|
||||||
|
{
|
||||||
|
if (property.second.propertyName == name)
|
||||||
|
{
|
||||||
|
return property.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mEmptyProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VertexProperty& PropertyInterface::getProperty(GlRenderTask* rTask, int32_t propId)
|
||||||
|
{
|
||||||
|
std::map<int32_t, VertexProperty>& vertexProperty = rTask->getUniformVertexProperty();
|
||||||
|
if (vertexProperty.find(propId) != vertexProperty.end())
|
||||||
|
{
|
||||||
|
return vertexProperty[propId];
|
||||||
|
}
|
||||||
|
return mEmptyProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PropertyInterface::clearData(GlRenderTask* rTask)
|
||||||
|
{
|
||||||
|
std::map<int32_t, VertexProperty>& vertexProperty = rTask->getUniformVertexProperty();
|
||||||
|
for (auto& prop : vertexProperty)
|
||||||
|
{
|
||||||
|
prop.second.propertyValues.clear();
|
||||||
|
}
|
||||||
|
}
|
64
src/lib/gl_engine/tvgGlPropertyInterface.h
Executable file
64
src/lib/gl_engine/tvgGlPropertyInterface.h
Executable file
|
@ -0,0 +1,64 @@
|
||||||
|
#ifndef _TVG_GL_PROPERTY_INTERFACE_H_
|
||||||
|
#define _TVG_GL_PROPERTY_INTERFACE_H_
|
||||||
|
|
||||||
|
#include "tvgGlRendererProperties.h"
|
||||||
|
#include "tvgGlRenderTask.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#define ADD_ATTRIBUTE_PROPERTY(var, rtask, prog, varName, formatSize, location) \
|
||||||
|
var = &PropertyInterface::addProperty(rtask, prog, varName, formatSize, VertexProperty::PropertyType::ATTRIBUTE); \
|
||||||
|
if (var->propertyId != -1) \
|
||||||
|
location = var->propertyId
|
||||||
|
|
||||||
|
#define ADD_UNIFORM_PROPERTY(var, rtask, prog, varName, formatSize, location) \
|
||||||
|
var = &PropertyInterface::addProperty(rtask, prog, varName, formatSize, VertexProperty::PropertyType::UNIFORM); \
|
||||||
|
if (var->propertyId != -1) \
|
||||||
|
location = var->propertyId
|
||||||
|
|
||||||
|
#define FORMAT_SIZE_FLOAT 1
|
||||||
|
#define FORMAT_SIZE_VEC_2 2
|
||||||
|
#define FORMAT_SIZE_VEC_3 3
|
||||||
|
#define FORMAT_SIZE_VEC_4 4
|
||||||
|
|
||||||
|
class PropertyInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static VertexProperty& addProperty(GlRenderTask* rTask, std::shared_ptr<GlProgram> prog, std::string name, uint32_t propFormatSize, VertexProperty::PropertyType propType);
|
||||||
|
template<typename... Args>
|
||||||
|
static void setProperty(GlRenderTask* rTask, std::string name, float first, Args... args)
|
||||||
|
{
|
||||||
|
VertexProperty& prop = getProperty(rTask, name);
|
||||||
|
if (prop.propertyId == -1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setProperty(prop.propertyId, first, args...);
|
||||||
|
}
|
||||||
|
template<typename... Args>
|
||||||
|
static void setProperty(GlRenderTask* rTask, int32_t propId, float first, Args... args)
|
||||||
|
{
|
||||||
|
std::map<int32_t, VertexProperty>::iterator itr = rTask->getUniformVertexProperty().find(propId);
|
||||||
|
if (itr->second.propertyId == -1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
VertexProperty& prop = itr->second;
|
||||||
|
|
||||||
|
prop.dataType = VertexProperty::DataType::FLOAT;
|
||||||
|
prop.propertyValues.set(first, args...);
|
||||||
|
}
|
||||||
|
static int32_t getPropertyId(GlRenderTask* rTask, std::string name);
|
||||||
|
static VertexProperty& getProperty(GlRenderTask* rTask, std::string name);
|
||||||
|
static VertexProperty& getProperty(GlRenderTask* rTask, int32_t propId);
|
||||||
|
static void clearData(GlRenderTask* rTask);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PropertyInterface() {}
|
||||||
|
static VertexProperty mEmptyProperty;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _TVG_GL_PROPERTY_INTERFACE_H_ */
|
267
src/lib/gl_engine/tvgGlRenderTask.cpp
Executable file
267
src/lib/gl_engine/tvgGlRenderTask.cpp
Executable file
|
@ -0,0 +1,267 @@
|
||||||
|
#include "tvgGlCommon.h"
|
||||||
|
#include "tvgGlShaderSrc.h"
|
||||||
|
#include "tvgGlRenderTask.h"
|
||||||
|
#include "tvgGlPropertyInterface.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
|
||||||
|
|
||||||
|
GlRenderTask::GlRenderTask(RenderTypes renderType, shared_ptr<GlShader> shader)
|
||||||
|
{
|
||||||
|
mRenderType = renderType;
|
||||||
|
mProgram = GlProgram::gen(shader);
|
||||||
|
load();
|
||||||
|
|
||||||
|
VertexProperty* prop = nullptr;
|
||||||
|
ADD_ATTRIBUTE_PROPERTY(prop, this, mProgram, "aLocation", FORMAT_SIZE_VEC_4, mLocVertexAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GlRenderTask::RenderTypes GlRenderTask::getRenderType()
|
||||||
|
{
|
||||||
|
return mRenderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlRenderTask::load()
|
||||||
|
{
|
||||||
|
mProgram->load();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlRenderTask::unload()
|
||||||
|
{
|
||||||
|
GlProgram::unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<GlProgram> GlRenderTask::getProgram()
|
||||||
|
{
|
||||||
|
return mProgram;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::map<int32_t, VertexProperty>& GlRenderTask::getAttributeVertexProperty()
|
||||||
|
{
|
||||||
|
return mAttributePropertyBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::map<int32_t, VertexProperty>& GlRenderTask::getUniformVertexProperty()
|
||||||
|
{
|
||||||
|
return mUniformPropertyBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32_t GlRenderTask::getLocationPropertyId() const
|
||||||
|
{
|
||||||
|
return mLocVertexAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlRenderTask::uploadValues()
|
||||||
|
{
|
||||||
|
for (auto& property : mUniformPropertyBuffer)
|
||||||
|
{
|
||||||
|
PropertyValue& propertyVal = property.second.propertyValues;
|
||||||
|
switch (property.second.dataType) {
|
||||||
|
case VertexProperty::DataType::INT: {
|
||||||
|
switch (propertyVal.getStride()) {
|
||||||
|
case 1:
|
||||||
|
mProgram->setUniform1Value(property.second.propertyId, propertyVal.getCount(), (const int*)propertyVal.getData());
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mProgram->setUniform2Value(property.second.propertyId, propertyVal.getCount(), (const int*)propertyVal.getData());
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mProgram->setUniform3Value(property.second.propertyId, propertyVal.getCount(), (const int*)propertyVal.getData());
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
mProgram->setUniform4Value(property.second.propertyId, propertyVal.getCount(), (const int*)propertyVal.getData());
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VertexProperty::DataType::FLOAT: {
|
||||||
|
switch (propertyVal.getStride()) {
|
||||||
|
case 1:
|
||||||
|
mProgram->setUniform1Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData());
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mProgram->setUniform2Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData());
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mProgram->setUniform3Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData());
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
mProgram->setUniform4Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData());
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<GlColorRenderTask> GlColorRenderTask::gen()
|
||||||
|
{
|
||||||
|
return std::make_shared<GlColorRenderTask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GlColorRenderTask::GlColorRenderTask()
|
||||||
|
:GlRenderTask(GlRenderTask::RenderTypes::RT_Color, GlShader::gen(COLOR_VERT_SHADER, COLOR_FRAG_SHADER))
|
||||||
|
{
|
||||||
|
VertexProperty* prop = nullptr;
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "uColor", FORMAT_SIZE_VEC_4, mLocColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlColorRenderTask::setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
|
{
|
||||||
|
if (mLocColor != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocColor, r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GlGradientRenderTask::GlGradientRenderTask(GlRenderTask::RenderTypes renderType, std::shared_ptr<GlShader> shader)
|
||||||
|
:GlRenderTask(renderType, shader)
|
||||||
|
{
|
||||||
|
VertexProperty* prop = nullptr;
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "uSize", FORMAT_SIZE_VEC_2, mLocPrimitiveSize);
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "uCanvasSize", FORMAT_SIZE_VEC_2, mLocCanvasSize);
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "noise_level", FORMAT_SIZE_FLOAT, mLocNoise);
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "nStops", FORMAT_SIZE_FLOAT, mLocStopCnt);
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "stopPoints", FORMAT_SIZE_FLOAT, mLocStops);
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "stopColors", FORMAT_SIZE_VEC_4, mLocStopColors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlGradientRenderTask::setPrimitveSize(float width, float height)
|
||||||
|
{
|
||||||
|
if (mLocPrimitiveSize != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocPrimitiveSize, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlGradientRenderTask::setCanvasSize(float width, float height)
|
||||||
|
{
|
||||||
|
if (mLocCanvasSize != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocCanvasSize, width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlGradientRenderTask::setNoise(float noise)
|
||||||
|
{
|
||||||
|
if (mLocNoise != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocNoise, noise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlGradientRenderTask::setStopCount(int32_t count)
|
||||||
|
{
|
||||||
|
if (mLocStopCnt != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocStopCnt, (float)count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlGradientRenderTask::setStopColor(int index, float stopVal, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||||
|
{
|
||||||
|
if (index < MAX_GRADIENT_STOPS && mLocStops != -1 && mLocStopColors != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocStops, stopVal);
|
||||||
|
PropertyInterface::setProperty(this, mLocStopColors, r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<GlLinearGradientRenderTask> GlLinearGradientRenderTask::gen()
|
||||||
|
{
|
||||||
|
return std::make_shared<GlLinearGradientRenderTask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GlLinearGradientRenderTask::GlLinearGradientRenderTask()
|
||||||
|
:GlGradientRenderTask(GlRenderTask::RenderTypes::RT_LinGradient, GlShader::gen(GRADIENT_VERT_SHADER, LINEAR_GRADIENT_FRAG_SHADER))
|
||||||
|
{
|
||||||
|
VertexProperty* prop = nullptr;
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "gradStartPos", FORMAT_SIZE_VEC_2, mLocStartPos);
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "gradEndPos", FORMAT_SIZE_VEC_2, mLocEndPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlLinearGradientRenderTask::setStartPosition(float posX, float posY)
|
||||||
|
{
|
||||||
|
if (mLocStartPos != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocStartPos, posX, posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlLinearGradientRenderTask::setEndPosition(float posX, float posY)
|
||||||
|
{
|
||||||
|
if (mLocEndPos != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocEndPos, posX, posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<GlRadialGradientRenderTask> GlRadialGradientRenderTask::gen()
|
||||||
|
{
|
||||||
|
return std::make_shared<GlRadialGradientRenderTask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GlRadialGradientRenderTask::GlRadialGradientRenderTask()
|
||||||
|
:GlGradientRenderTask(GlRenderTask::RenderTypes::RT_RadGradient, GlShader::gen(GRADIENT_VERT_SHADER, RADIAL_GRADIENT_FRAG_SHADER))
|
||||||
|
{
|
||||||
|
VertexProperty* prop = nullptr;
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "gradStartPos", FORMAT_SIZE_VEC_2, mLocStartPos);
|
||||||
|
ADD_UNIFORM_PROPERTY(prop, this, getProgram(), "stRadius", FORMAT_SIZE_FLOAT, mLocStRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GlRadialGradientRenderTask::~GlRadialGradientRenderTask()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlRadialGradientRenderTask::setStartPosition(float posX, float posY)
|
||||||
|
{
|
||||||
|
if (mLocStartPos != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocStartPos, posX, posY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlRadialGradientRenderTask::setStartRadius(float radius)
|
||||||
|
{
|
||||||
|
if (mLocStRadius != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocStRadius, radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlRadialGradientRenderTask::setEndRadius(float radius)
|
||||||
|
{
|
||||||
|
if (mLocEdRadius != -1)
|
||||||
|
{
|
||||||
|
PropertyInterface::setProperty(this, mLocEdRadius, radius);
|
||||||
|
}
|
||||||
|
}
|
108
src/lib/gl_engine/tvgGlRenderTask.h
Executable file
108
src/lib/gl_engine/tvgGlRenderTask.h
Executable file
|
@ -0,0 +1,108 @@
|
||||||
|
#ifndef _TVG_GL_RENDER_TASK_H_
|
||||||
|
#define _TVG_GL_RENDER_TASK_H_
|
||||||
|
|
||||||
|
#include "tvgGlShader.h"
|
||||||
|
#include "tvgGlProgram.h"
|
||||||
|
#include "tvgGlRendererProperties.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#define MAX_GRADIENT_STOPS 4
|
||||||
|
|
||||||
|
class GlRenderTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum RenderTypes
|
||||||
|
{
|
||||||
|
RT_Color = 0,
|
||||||
|
RT_LinGradient,
|
||||||
|
RT_RadGradient,
|
||||||
|
|
||||||
|
RT_None,
|
||||||
|
};
|
||||||
|
|
||||||
|
GlRenderTask(RenderTypes renderType, std::shared_ptr<GlShader> shader);
|
||||||
|
RenderTypes getRenderType();
|
||||||
|
|
||||||
|
void load();
|
||||||
|
static void unload();
|
||||||
|
std::shared_ptr<GlProgram> getProgram();
|
||||||
|
std::map<int32_t, VertexProperty>& getAttributeVertexProperty();
|
||||||
|
std::map<int32_t, VertexProperty>& getUniformVertexProperty();
|
||||||
|
int32_t getLocationPropertyId() const;
|
||||||
|
void uploadValues();
|
||||||
|
|
||||||
|
private:
|
||||||
|
RenderTypes mRenderType;
|
||||||
|
|
||||||
|
uint32_t propertyFormatSize;
|
||||||
|
std::shared_ptr<GlProgram> mProgram;
|
||||||
|
std::map<int32_t, VertexProperty> mAttributePropertyBuffer;
|
||||||
|
std::map<int32_t, VertexProperty> mUniformPropertyBuffer;
|
||||||
|
|
||||||
|
int32_t mLocVertexAttribute;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GlColorRenderTask : public GlRenderTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<GlColorRenderTask> gen();
|
||||||
|
GlColorRenderTask();
|
||||||
|
void setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t mLocColor = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GlGradientRenderTask : public GlRenderTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GlGradientRenderTask(GlRenderTask::RenderTypes renderType, std::shared_ptr<GlShader> shader);
|
||||||
|
void setPrimitveSize(float width, float height);
|
||||||
|
void setCanvasSize(float width, float height);
|
||||||
|
void setNoise(float noise);
|
||||||
|
void setStopCount(int32_t count);
|
||||||
|
void setStopColor(int index, float stopVal, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t mLocPrimitiveSize = -1;
|
||||||
|
int32_t mLocCanvasSize = -1;
|
||||||
|
int32_t mLocNoise = -1;
|
||||||
|
int32_t mLocStopCnt = -1;
|
||||||
|
int32_t mLocStops;
|
||||||
|
int32_t mLocStopColors;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GlLinearGradientRenderTask : public GlGradientRenderTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<GlLinearGradientRenderTask> gen();
|
||||||
|
GlLinearGradientRenderTask();
|
||||||
|
void setStartPosition(float posX, float posY);
|
||||||
|
void setEndPosition(float posX, float posY);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t mLocStartPos = -1;
|
||||||
|
int32_t mLocEndPos = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GlRadialGradientRenderTask : public GlGradientRenderTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<GlRadialGradientRenderTask> gen();
|
||||||
|
GlRadialGradientRenderTask();
|
||||||
|
~GlRadialGradientRenderTask();
|
||||||
|
void setStartPosition(float posX, float posY);
|
||||||
|
void setStartRadius(float radius);
|
||||||
|
void setEndRadius(float radius);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t mLocStartPos = -1;
|
||||||
|
int32_t mLocStRadius = -1;
|
||||||
|
int32_t mLocEdRadius = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _TVG_GL_RENDER_TASK_H_ */
|
136
src/lib/gl_engine/tvgGlRenderer.cpp
Normal file → Executable file
136
src/lib/gl_engine/tvgGlRenderer.cpp
Normal file → Executable file
|
@ -24,6 +24,7 @@
|
||||||
#include "tvgGlGeometry.h"
|
#include "tvgGlGeometry.h"
|
||||||
#include "tvgGlCommon.h"
|
#include "tvgGlCommon.h"
|
||||||
#include "tvgGlRenderer.h"
|
#include "tvgGlRenderer.h"
|
||||||
|
#include "tvgGlPropertyInterface.h"
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Internal Class Implementation */
|
/* Internal Class Implementation */
|
||||||
|
@ -42,6 +43,8 @@ static void _termEngine()
|
||||||
/* External Class Implementation */
|
/* External Class Implementation */
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
|
#define NOISE_LEVEL 0.5f
|
||||||
|
|
||||||
bool GlRenderer::clear()
|
bool GlRenderer::clear()
|
||||||
{
|
{
|
||||||
//TODO: (Request) to clear target
|
//TODO: (Request) to clear target
|
||||||
|
@ -65,16 +68,21 @@ bool GlRenderer::target(TVG_UNUSED uint32_t* buffer, uint32_t stride, uint32_t w
|
||||||
bool GlRenderer::flush()
|
bool GlRenderer::flush()
|
||||||
{
|
{
|
||||||
GL_CHECK(glFinish());
|
GL_CHECK(glFinish());
|
||||||
mColorProgram->unload();
|
GlRenderTask::unload();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool GlRenderer::preRender()
|
bool GlRenderer::preRender()
|
||||||
{
|
{
|
||||||
// Blend function for pre multiplied alpha
|
if (mRenderTasks.size() == 0)
|
||||||
GL_CHECK(glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
{
|
||||||
|
initShaders();
|
||||||
|
}
|
||||||
|
GlRenderTask::unload();
|
||||||
|
|
||||||
|
// Blend function for straight alpha
|
||||||
|
GL_CHECK(glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
|
||||||
GL_CHECK(glEnable(GL_BLEND));
|
GL_CHECK(glEnable(GL_BLEND));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -98,19 +106,23 @@ bool GlRenderer::render(const Shape& shape, void *data)
|
||||||
|
|
||||||
GL_CHECK(glViewport(0, 0, sdata->viewWd, sdata->viewHt));
|
GL_CHECK(glViewport(0, 0, sdata->viewWd, sdata->viewHt));
|
||||||
|
|
||||||
uint32_t geometryCnt = sdata->geometry->getPrimitiveCount();
|
uint32_t primitiveCount = sdata->geometry->getPrimitiveCount();
|
||||||
for (uint32_t i = 0; i < geometryCnt; ++i)
|
for (uint32_t i = 0; i < primitiveCount; ++i)
|
||||||
{
|
{
|
||||||
mColorProgram->load();
|
if (flags & RenderUpdateFlag::Gradient)
|
||||||
if (flags & RenderUpdateFlag::Color)
|
{
|
||||||
|
const Fill* gradient = shape.fill();
|
||||||
|
drawPrimitive(*sdata, gradient, i, RenderUpdateFlag::Gradient);
|
||||||
|
}
|
||||||
|
else if (flags & RenderUpdateFlag::Color)
|
||||||
{
|
{
|
||||||
shape.fill(&r, &g, &b, &a);
|
shape.fill(&r, &g, &b, &a);
|
||||||
drawPrimitive(*(sdata->geometry), (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f, i, RenderUpdateFlag::Color);
|
drawPrimitive(*sdata, r, g, b, a, i, RenderUpdateFlag::Color);
|
||||||
}
|
}
|
||||||
if (flags & RenderUpdateFlag::Stroke)
|
if (flags & RenderUpdateFlag::Stroke)
|
||||||
{
|
{
|
||||||
shape.strokeColor(&r, &g, &b, &a);
|
shape.strokeColor(&r, &g, &b, &a);
|
||||||
drawPrimitive(*(sdata->geometry), (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f, i, RenderUpdateFlag::Stroke);
|
drawPrimitive(*sdata, r, g, b, a, i, RenderUpdateFlag::Stroke);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,8 +155,6 @@ void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const Rende
|
||||||
|
|
||||||
if (sdata->updateFlag == RenderUpdateFlag::None) return sdata;
|
if (sdata->updateFlag == RenderUpdateFlag::None) return sdata;
|
||||||
|
|
||||||
initShaders();
|
|
||||||
|
|
||||||
sdata->geometry = make_unique<GlGeometry>();
|
sdata->geometry = make_unique<GlGeometry>();
|
||||||
|
|
||||||
//invisible?
|
//invisible?
|
||||||
|
@ -153,9 +163,14 @@ void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const Rende
|
||||||
shape.strokeColor(nullptr, nullptr, nullptr, &alphaS);
|
shape.strokeColor(nullptr, nullptr, nullptr, &alphaS);
|
||||||
auto strokeWd = shape.strokeWidth();
|
auto strokeWd = shape.strokeWidth();
|
||||||
|
|
||||||
if (alphaF == 0 && alphaS == 0) return sdata;
|
if ( ((sdata->updateFlag & RenderUpdateFlag::Gradient) == 0) &&
|
||||||
|
((sdata->updateFlag & RenderUpdateFlag::Color) && alphaF == 0) &&
|
||||||
|
((sdata->updateFlag & RenderUpdateFlag::Stroke) && alphaS == 0) )
|
||||||
|
{
|
||||||
|
return sdata;
|
||||||
|
}
|
||||||
|
|
||||||
if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke) )
|
if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke | RenderUpdateFlag::Gradient) )
|
||||||
{
|
{
|
||||||
if (!sdata->geometry->decomposeOutline(shape)) return sdata;
|
if (!sdata->geometry->decomposeOutline(shape)) return sdata;
|
||||||
if (!sdata->geometry->generateAAPoints(shape, static_cast<float>(strokeWd), sdata->updateFlag)) return sdata;
|
if (!sdata->geometry->generateAAPoints(shape, static_cast<float>(strokeWd), sdata->updateFlag)) return sdata;
|
||||||
|
@ -198,10 +213,7 @@ GlRenderer* GlRenderer::gen()
|
||||||
|
|
||||||
GlRenderer::~GlRenderer()
|
GlRenderer::~GlRenderer()
|
||||||
{
|
{
|
||||||
if (mColorProgram.get())
|
mRenderTasks.clear();
|
||||||
{
|
|
||||||
mColorProgram.reset(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
--rendererCnt;
|
--rendererCnt;
|
||||||
if (!initEngine) _termEngine();
|
if (!initEngine) _termEngine();
|
||||||
|
@ -210,21 +222,85 @@ GlRenderer::~GlRenderer()
|
||||||
|
|
||||||
void GlRenderer::initShaders()
|
void GlRenderer::initShaders()
|
||||||
{
|
{
|
||||||
if (!mColorProgram.get())
|
// Solid Color Renderer
|
||||||
{
|
mRenderTasks.push_back(GlColorRenderTask::gen());
|
||||||
shared_ptr<GlShader> shader = GlShader::gen(COLOR_VERT_SHADER, COLOR_FRAG_SHADER);
|
|
||||||
mColorProgram = GlProgram::gen(shader);
|
// Linear Gradient Renderer
|
||||||
}
|
mRenderTasks.push_back(GlLinearGradientRenderTask::gen());
|
||||||
mColorProgram->load();
|
|
||||||
mColorUniformLoc = mColorProgram->getUniformLocation("uColor");
|
// Radial Gradient Renderer
|
||||||
mVertexAttrLoc = mColorProgram->getAttributeLocation("aLocation");
|
mRenderTasks.push_back(GlRadialGradientRenderTask::gen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GlRenderer::drawPrimitive(GlGeometry& geometry, float r, float g, float b, float a, uint32_t primitiveIndex, RenderUpdateFlag flag)
|
void GlRenderer::drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint32_t primitiveIndex, RenderUpdateFlag flag)
|
||||||
{
|
{
|
||||||
mColorProgram->setUniformValue(mColorUniformLoc, r, g, b, a);
|
GlColorRenderTask* renderTask = static_cast<GlColorRenderTask*>(mRenderTasks[GlRenderTask::RenderTypes::RT_Color].get());
|
||||||
geometry.draw(mVertexAttrLoc, primitiveIndex, flag);
|
assert(renderTask);
|
||||||
geometry.disableVertex(mVertexAttrLoc);
|
renderTask->load();
|
||||||
|
PropertyInterface::clearData(renderTask);
|
||||||
|
renderTask->setColor(r, g, b, a);
|
||||||
|
int32_t vertexLoc = renderTask->getLocationPropertyId();
|
||||||
|
renderTask->uploadValues();
|
||||||
|
sdata.geometry->draw(vertexLoc, primitiveIndex, flag);
|
||||||
|
sdata.geometry->disableVertex(vertexLoc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, uint32_t primitiveIndex, RenderUpdateFlag flag)
|
||||||
|
{
|
||||||
|
const Fill::ColorStop* stops = nullptr;
|
||||||
|
auto stopCnt = fill->colorStops(&stops);
|
||||||
|
if (stopCnt < 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GlGradientRenderTask* rTask = nullptr;
|
||||||
|
GlSize size = sdata.geometry->getPrimitiveSize(primitiveIndex);
|
||||||
|
switch (fill->id()) {
|
||||||
|
case FILL_ID_LINEAR: {
|
||||||
|
float x1, y1, x2, y2;
|
||||||
|
GlLinearGradientRenderTask *renderTask = static_cast<GlLinearGradientRenderTask*>(mRenderTasks[GlRenderTask::RenderTypes::RT_LinGradient].get());
|
||||||
|
assert(renderTask);
|
||||||
|
rTask = renderTask;
|
||||||
|
renderTask->load();
|
||||||
|
PropertyInterface::clearData(renderTask);
|
||||||
|
const LinearGradient* grad = static_cast<const LinearGradient*>(fill);
|
||||||
|
grad->linear(&x1, &y1, &x2, &y2);
|
||||||
|
renderTask->setStartPosition(x1, y1);
|
||||||
|
renderTask->setEndPosition(x2, y2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FILL_ID_RADIAL: {
|
||||||
|
float x1, y1, r1;
|
||||||
|
GlRadialGradientRenderTask *renderTask = static_cast<GlRadialGradientRenderTask*>(mRenderTasks[GlRenderTask::RenderTypes::RT_RadGradient].get());
|
||||||
|
assert(renderTask);
|
||||||
|
rTask = renderTask;
|
||||||
|
renderTask->load();
|
||||||
|
PropertyInterface::clearData(renderTask);
|
||||||
|
const RadialGradient* grad = static_cast<const RadialGradient*>(fill);
|
||||||
|
grad->radial(&x1, &y1, &r1);
|
||||||
|
renderTask->setStartPosition(x1, y1);
|
||||||
|
renderTask->setStartRadius(r1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rTask)
|
||||||
|
{
|
||||||
|
int32_t vertexLoc = rTask->getLocationPropertyId();
|
||||||
|
rTask->setPrimitveSize(size.x, size.y);
|
||||||
|
rTask->setCanvasSize(sdata.viewWd, sdata.viewHt);
|
||||||
|
rTask->setNoise(NOISE_LEVEL);
|
||||||
|
rTask->setStopCount((int)stopCnt);
|
||||||
|
for (uint32_t i = 0; i < stopCnt; ++i)
|
||||||
|
{
|
||||||
|
rTask->setStopColor(i, stops[i].offset, stops[i].r, stops[i].g, stops[i].b, stops[i].a);
|
||||||
|
}
|
||||||
|
|
||||||
|
rTask->uploadValues();
|
||||||
|
sdata.geometry->draw(vertexLoc, primitiveIndex, flag);
|
||||||
|
sdata.geometry->disableVertex(vertexLoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
9
src/lib/gl_engine/tvgGlRenderer.h
Normal file → Executable file
9
src/lib/gl_engine/tvgGlRenderer.h
Normal file → Executable file
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
#include "tvgGlCommon.h"
|
#include "tvgGlCommon.h"
|
||||||
#include "tvgGlProgram.h"
|
#include "tvgGlProgram.h"
|
||||||
|
#include "tvgGlRenderTask.h"
|
||||||
|
|
||||||
class GlRenderer : public RenderMethod
|
class GlRenderer : public RenderMethod
|
||||||
{
|
{
|
||||||
|
@ -50,11 +50,10 @@ private:
|
||||||
~GlRenderer();
|
~GlRenderer();
|
||||||
|
|
||||||
void initShaders();
|
void initShaders();
|
||||||
void drawPrimitive(GlGeometry& geometry, float r, float g, float b, float a, uint32_t primitiveIndex, RenderUpdateFlag flag);
|
void drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint32_t primitiveIndex, RenderUpdateFlag flag);
|
||||||
|
void drawPrimitive(GlShape& sdata, const Fill* fill, uint32_t primitiveIndex, RenderUpdateFlag flag);
|
||||||
|
|
||||||
unique_ptr<GlProgram> mColorProgram = nullptr;
|
vector<shared_ptr<GlRenderTask>> mRenderTasks;
|
||||||
int32_t mColorUniformLoc = 0;
|
|
||||||
uint32_t mVertexAttrLoc = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _TVG_GL_RENDERER_H_ */
|
#endif /* _TVG_GL_RENDERER_H_ */
|
||||||
|
|
92
src/lib/gl_engine/tvgGlRendererProperties.h
Executable file
92
src/lib/gl_engine/tvgGlRendererProperties.h
Executable file
|
@ -0,0 +1,92 @@
|
||||||
|
#ifndef _TVG_GL_RENDER_PROPERTIES_H_
|
||||||
|
#define _TVG_GL_RENDER_PROPERTIES_H_
|
||||||
|
|
||||||
|
#include "tvgGlShader.h"
|
||||||
|
#include "tvgGlProgram.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class PropertyValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setStride(uint32_t s)
|
||||||
|
{
|
||||||
|
stride = s;
|
||||||
|
if (values.capacity() == values.size())
|
||||||
|
{
|
||||||
|
values.reserve(values.size() + stride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getStride() const
|
||||||
|
{
|
||||||
|
return stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getSize() const
|
||||||
|
{
|
||||||
|
return values.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getCount() const
|
||||||
|
{
|
||||||
|
return (values.size() / stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
values.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const float* getData()
|
||||||
|
{
|
||||||
|
return values.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(float v)
|
||||||
|
{
|
||||||
|
values.push_back(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void set(float first, Args... args)
|
||||||
|
{
|
||||||
|
if (values.capacity() == values.size())
|
||||||
|
{
|
||||||
|
values.reserve(values.size() + stride);
|
||||||
|
}
|
||||||
|
set(first);
|
||||||
|
set(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<float> values;
|
||||||
|
uint32_t stride = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexProperty
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class DataType
|
||||||
|
{
|
||||||
|
INT = 0,
|
||||||
|
FLOAT
|
||||||
|
};
|
||||||
|
enum class PropertyType
|
||||||
|
{
|
||||||
|
ATTRIBUTE = 0,
|
||||||
|
UNIFORM
|
||||||
|
};
|
||||||
|
|
||||||
|
int32_t propertyId = -1;
|
||||||
|
std::string propertyName = "";
|
||||||
|
PropertyType propType = PropertyType::UNIFORM;
|
||||||
|
DataType dataType = DataType::FLOAT;
|
||||||
|
PropertyValue propertyValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _TVG_GL_RENDER_PROPERTIES_H_ */
|
174
src/lib/gl_engine/tvgGlShaderSrc.cpp
Normal file → Executable file
174
src/lib/gl_engine/tvgGlShaderSrc.cpp
Normal file → Executable file
|
@ -22,23 +22,161 @@
|
||||||
|
|
||||||
#include "tvgGlShaderSrc.h"
|
#include "tvgGlShaderSrc.h"
|
||||||
|
|
||||||
const char* COLOR_VERT_SHADER =
|
#include <string>
|
||||||
"attribute highp vec4 aLocation; \n"
|
|
||||||
"uniform highp vec4 uColor; \n"
|
|
||||||
"varying highp vec4 vcolor; \n"
|
|
||||||
"varying highp float vOpacity; \n"
|
|
||||||
"void main() \n"
|
|
||||||
"{ \n"
|
|
||||||
" gl_Position = vec4(aLocation.xy, 0.0, 1.0); \n"
|
|
||||||
" vcolor = uColor; \n"
|
|
||||||
" vOpacity = aLocation.z; \n"
|
|
||||||
"} \n";
|
|
||||||
|
|
||||||
const char* COLOR_FRAG_SHADER =
|
#define TVG_COMPOSE_SHADER(shader) #shader
|
||||||
"varying highp vec4 vcolor; \n"
|
|
||||||
"varying highp float vOpacity; \n"
|
|
||||||
"void main() \n"
|
|
||||||
"{ \n"
|
|
||||||
" gl_FragColor = vec4(vcolor.xyz, vcolor.w*vOpacity); \n"
|
|
||||||
"} \n";
|
|
||||||
|
|
||||||
|
const char* COLOR_VERT_SHADER = TVG_COMPOSE_SHADER(
|
||||||
|
attribute mediump vec4 aLocation; \n
|
||||||
|
varying highp float vOpacity; \n
|
||||||
|
void main() \n
|
||||||
|
{ \n
|
||||||
|
gl_Position = vec4(aLocation.xy, 0.0, 1.0); \n
|
||||||
|
vOpacity = aLocation.z; \n
|
||||||
|
});
|
||||||
|
|
||||||
|
const char* COLOR_FRAG_SHADER = TVG_COMPOSE_SHADER(
|
||||||
|
uniform highp vec4 uColor; \n
|
||||||
|
varying highp float vOpacity; \n
|
||||||
|
void main() \n
|
||||||
|
{ \n
|
||||||
|
gl_FragColor = vec4(uColor.xyz, uColor.w*vOpacity); \n
|
||||||
|
});
|
||||||
|
|
||||||
|
const char* GRADIENT_VERT_SHADER = TVG_COMPOSE_SHADER(
|
||||||
|
attribute highp vec4 aLocation; \n
|
||||||
|
varying highp float vOpacity; \n
|
||||||
|
varying highp vec2 vPos; \n
|
||||||
|
\n
|
||||||
|
void main() \n
|
||||||
|
{ \n
|
||||||
|
gl_Position = vec4(aLocation.xy, 0.0, 1.0); \n
|
||||||
|
vOpacity = aLocation.z; \n
|
||||||
|
vPos = vec2((aLocation.x + 1.0) / 2.0, ((-1.0 * aLocation.y) +1.0) / 2.0); \n
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
std::string STR_GRADIENT_FRAG_COMMON_VARIABLES = TVG_COMPOSE_SHADER(
|
||||||
|
precision highp float; \n
|
||||||
|
const int MAX_STOP_COUNT = 4; \n
|
||||||
|
uniform highp vec2 uSize; \n
|
||||||
|
uniform highp vec2 uCanvasSize; \n
|
||||||
|
uniform float nStops; \n
|
||||||
|
uniform float noise_level; \n
|
||||||
|
uniform float stopPoints[MAX_STOP_COUNT]; \n
|
||||||
|
uniform vec4 stopColors[MAX_STOP_COUNT]; \n
|
||||||
|
varying highp vec2 vPos; \n
|
||||||
|
varying highp float vOpacity; \n
|
||||||
|
);
|
||||||
|
|
||||||
|
std::string STR_GRADIENT_FRAG_COMMON_FUNCTIONS = TVG_COMPOSE_SHADER(
|
||||||
|
float gradientStep(float edge0, float edge1, float x) \n
|
||||||
|
{ \n
|
||||||
|
// linear \n
|
||||||
|
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); \n
|
||||||
|
return x; \n
|
||||||
|
} \n
|
||||||
|
\n
|
||||||
|
vec4 gradient(float t) \n
|
||||||
|
{ \n
|
||||||
|
vec4 col = vec4(0.0); \n
|
||||||
|
int i = 0; \n
|
||||||
|
int count = int(nStops); \n
|
||||||
|
if (t <= stopPoints[0]) \n
|
||||||
|
{ \n
|
||||||
|
col += stopColors[0]; \n
|
||||||
|
} \n
|
||||||
|
else if (t >= stopPoints[count - 1]) \n
|
||||||
|
{ \n
|
||||||
|
col += stopColors[count - 1]; \n
|
||||||
|
} \n
|
||||||
|
else \n
|
||||||
|
{ \n
|
||||||
|
for (i = 0; i < count - 1; ++i) \n
|
||||||
|
{ \n
|
||||||
|
if (t > stopPoints[i] && t < stopPoints[i + 1]) \n
|
||||||
|
{ \n
|
||||||
|
col += (stopColors[i] * (1. - gradientStep(stopPoints[i], stopPoints[i + 1], t))); \n
|
||||||
|
col += (stopColors[i + 1] * gradientStep(stopPoints[i], stopPoints[i + 1], t)); \n
|
||||||
|
break; \n
|
||||||
|
} \n
|
||||||
|
} \n
|
||||||
|
} \n
|
||||||
|
\n
|
||||||
|
return col; \n
|
||||||
|
} \n
|
||||||
|
\n
|
||||||
|
highp vec3 ScreenSpaceDither(vec2 vScreenPos) \n
|
||||||
|
{ \n
|
||||||
|
highp vec3 vDither = vec3(dot(vec2(171.0, 231.0), vScreenPos.xy)); \n
|
||||||
|
vDither.rgb = fract(vDither.rgb / vec3(103.0, 71.0, 97.0)); \n
|
||||||
|
return vDither.rgb / 255.0; \n
|
||||||
|
});
|
||||||
|
|
||||||
|
std::string STR_LINEAR_GRADIENT_VARIABLES = TVG_COMPOSE_SHADER(
|
||||||
|
uniform highp vec2 gradStartPos; \n
|
||||||
|
uniform highp vec2 gradEndPos; \n
|
||||||
|
);
|
||||||
|
|
||||||
|
std::string STR_LINEAR_GRADIENT_MAIN = TVG_COMPOSE_SHADER(
|
||||||
|
void main() \n
|
||||||
|
{ \n
|
||||||
|
highp vec2 pos = vec2(vPos.x * uCanvasSize.x, vPos.y * uCanvasSize.y); \n
|
||||||
|
highp vec2 spos = vec2(pos.x / uSize.x, pos.y / uSize.y); \n
|
||||||
|
highp vec2 st = gradStartPos / (uSize.xy); \n
|
||||||
|
highp vec2 ed = gradEndPos / (uSize.xy); \n
|
||||||
|
\n
|
||||||
|
highp vec2 ba = ed - st; \n
|
||||||
|
\n
|
||||||
|
highp float t = dot(spos - st, ba) / dot(ba, ba); \n
|
||||||
|
\n
|
||||||
|
//t = smoothstep(0.0, 1.0, clamp(t, 0.0, 1.0)); \n
|
||||||
|
t = clamp(t, 0.0, 1.0); \n
|
||||||
|
\n
|
||||||
|
vec4 color = gradient(t); \n
|
||||||
|
\n
|
||||||
|
highp vec3 noise = 8.0 * noise_level * ScreenSpaceDither(pos); \n
|
||||||
|
vec4 finalCol = vec4(color.xyz + noise, color.w); \n
|
||||||
|
gl_FragColor = vec4(finalCol.xyz, finalCol.w* vOpacity); \n
|
||||||
|
});
|
||||||
|
|
||||||
|
std::string STR_RADIAL_GRADIENT_VARIABLES = TVG_COMPOSE_SHADER(
|
||||||
|
uniform highp vec2 gradStartPos; \n
|
||||||
|
uniform highp float stRadius; \n
|
||||||
|
);
|
||||||
|
|
||||||
|
std::string STR_RADIAL_GRADIENT_MAIN = TVG_COMPOSE_SHADER(
|
||||||
|
void main() \n
|
||||||
|
{ \n
|
||||||
|
highp vec2 pos = vec2(vPos.x * uCanvasSize.x, vPos.y * uCanvasSize.y); \n
|
||||||
|
highp vec2 spos = vec2(pos.x / uSize.x, pos.y / uSize.y); \n
|
||||||
|
\n
|
||||||
|
highp float ba = stRadius; \n
|
||||||
|
highp float d = distance(gradStartPos, pos); \n
|
||||||
|
d = (d / ba); \n
|
||||||
|
\n
|
||||||
|
//float t = smoothstep(0.0, 1.0, clamp(d, 0.0, 1.0)); \n
|
||||||
|
float t = clamp(d, 0.0, 1.0); \n
|
||||||
|
\n
|
||||||
|
vec4 color = gradient(t); \n
|
||||||
|
\n
|
||||||
|
highp vec3 noise = 8.0 * noise_level * ScreenSpaceDither(pos); \n
|
||||||
|
vec4 finalCol = vec4(color.xyz + noise, color.w); \n
|
||||||
|
gl_FragColor = vec4(finalCol.xyz, finalCol.w * vOpacity); \n
|
||||||
|
});
|
||||||
|
|
||||||
|
std::string STR_LINEAR_GRADIENT_FRAG_SHADER =
|
||||||
|
STR_GRADIENT_FRAG_COMMON_VARIABLES +
|
||||||
|
STR_LINEAR_GRADIENT_VARIABLES +
|
||||||
|
STR_GRADIENT_FRAG_COMMON_FUNCTIONS +
|
||||||
|
STR_LINEAR_GRADIENT_MAIN;
|
||||||
|
|
||||||
|
const char* LINEAR_GRADIENT_FRAG_SHADER = STR_LINEAR_GRADIENT_FRAG_SHADER.c_str();
|
||||||
|
|
||||||
|
std::string STR_RADIAL_GRADIENT_FRAG_SHADER =
|
||||||
|
STR_GRADIENT_FRAG_COMMON_VARIABLES +
|
||||||
|
STR_RADIAL_GRADIENT_VARIABLES +
|
||||||
|
STR_GRADIENT_FRAG_COMMON_FUNCTIONS +
|
||||||
|
STR_RADIAL_GRADIENT_MAIN;
|
||||||
|
|
||||||
|
const char* RADIAL_GRADIENT_FRAG_SHADER = STR_RADIAL_GRADIENT_FRAG_SHADER.c_str();
|
||||||
|
|
3
src/lib/gl_engine/tvgGlShaderSrc.h
Normal file → Executable file
3
src/lib/gl_engine/tvgGlShaderSrc.h
Normal file → Executable file
|
@ -25,5 +25,8 @@
|
||||||
|
|
||||||
extern const char* COLOR_VERT_SHADER;
|
extern const char* COLOR_VERT_SHADER;
|
||||||
extern const char* COLOR_FRAG_SHADER;
|
extern const char* COLOR_FRAG_SHADER;
|
||||||
|
extern const char* GRADIENT_VERT_SHADER;
|
||||||
|
extern const char* LINEAR_GRADIENT_FRAG_SHADER;
|
||||||
|
extern const char* RADIAL_GRADIENT_FRAG_SHADER;
|
||||||
|
|
||||||
#endif /* _TVG_GL_SHADERSRC_H_ */
|
#endif /* _TVG_GL_SHADERSRC_H_ */
|
||||||
|
|
2
src/lib/tvgGlCanvas.cpp
Normal file → Executable file
2
src/lib/tvgGlCanvas.cpp
Normal file → Executable file
|
@ -67,7 +67,7 @@ Result GlCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
|
||||||
auto renderer = static_cast<GlRenderer*>(Canvas::pImpl.get()->renderer);
|
auto renderer = static_cast<GlRenderer*>(Canvas::pImpl.get()->renderer);
|
||||||
if (!renderer) return Result::MemoryCorruption;
|
if (!renderer) return Result::MemoryCorruption;
|
||||||
|
|
||||||
if (!renderer->target(buffer, stride, w, h, 0)) return Result::Unknown;
|
if (!renderer->target(buffer, stride, w, h)) return Result::Unknown;
|
||||||
|
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue