diff --git a/src/examples/CustomTransform.cpp b/src/examples/CustomTransform.cpp old mode 100644 new mode 100755 index 9cc188e2..a7e3322e --- a/src/examples/CustomTransform.cpp +++ b/src/examples/CustomTransform.cpp @@ -154,6 +154,7 @@ void drawGLview(Evas_Object *obj) void transitGlCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress) { tvgUpdateCmds(glCanvas.get(), progress); + elm_glview_changed_set((Evas_Object*)effect); } diff --git a/src/examples/DirectUpdate.cpp b/src/examples/DirectUpdate.cpp old mode 100644 new mode 100755 index b12355d9..9dbac342 --- a/src/examples/DirectUpdate.cpp +++ b/src/examples/DirectUpdate.cpp @@ -127,6 +127,7 @@ void drawGLview(Evas_Object *obj) void transitGlCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress) { tvgUpdateCmds(glCanvas.get(), progress); + elm_glview_changed_set((Evas_Object*)effect); } diff --git a/src/examples/GradientTransform.cpp b/src/examples/GradientTransform.cpp old mode 100644 new mode 100755 index fe067400..9a821d06 --- a/src/examples/GradientTransform.cpp +++ b/src/examples/GradientTransform.cpp @@ -182,6 +182,7 @@ void drawGLview(Evas_Object *obj) void transitGlCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress) { tvgUpdateCmds(glCanvas.get(), progress); + elm_glview_changed_set((Evas_Object*)effect); } diff --git a/src/examples/SceneTransform.cpp b/src/examples/SceneTransform.cpp old mode 100644 new mode 100755 index 9b696793..6d5219bf --- a/src/examples/SceneTransform.cpp +++ b/src/examples/SceneTransform.cpp @@ -178,6 +178,7 @@ void drawGLview(Evas_Object *obj) void transitGlCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress) { tvgUpdateCmds(glCanvas.get(), progress); + elm_glview_changed_set((Evas_Object*)effect); } diff --git a/src/examples/Transform.cpp b/src/examples/Transform.cpp old mode 100644 new mode 100755 index 8a9ac6fc..930100d5 --- a/src/examples/Transform.cpp +++ b/src/examples/Transform.cpp @@ -145,6 +145,7 @@ void drawGLview(Evas_Object *obj) void transitGlCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress) { tvgUpdateCmds(glCanvas.get(), progress); + elm_glview_changed_set((Evas_Object*)effect); } diff --git a/src/examples/Update.cpp b/src/examples/Update.cpp old mode 100644 new mode 100755 index 8ebe428a..e1d55214 --- a/src/examples/Update.cpp +++ b/src/examples/Update.cpp @@ -106,6 +106,7 @@ void drawGLview(Evas_Object *obj) void transitGlCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress) { tvgUpdateCmds(glCanvas.get(), progress); + elm_glview_changed_set((Evas_Object*)effect); } diff --git a/src/lib/gl_engine/tvgGlCommon.h b/src/lib/gl_engine/tvgGlCommon.h old mode 100644 new mode 100755 index 31dd1028..986f57c7 --- a/src/lib/gl_engine/tvgGlCommon.h +++ b/src/lib/gl_engine/tvgGlCommon.h @@ -57,7 +57,7 @@ struct GlShape const Shape* shape = nullptr; float viewWd; float viewHt; - RenderUpdateFlag updateFlag; + RenderUpdateFlag updateFlag = None; unique_ptr geometry; }; diff --git a/src/lib/gl_engine/tvgGlGeometry.cpp b/src/lib/gl_engine/tvgGlGeometry.cpp old mode 100644 new mode 100755 index 7af492eb..3965d8c2 --- a/src/lib/gl_engine/tvgGlGeometry.cpp +++ b/src/lib/gl_engine/tvgGlGeometry.cpp @@ -24,6 +24,10 @@ #include "tvgGlGpuBuffer.h" #include "tvgGlGeometry.h" +#define NORMALIZED_TOP_3D 1.0f +#define NORMALIZED_BOTTOM_3D -1.0f +#define NORMALIZED_LEFT_3D -1.0f +#define NORMALIZED_RIGHT_3D 1.0f uint32_t GlGeometry::getPrimitiveCount() { @@ -172,12 +176,12 @@ bool GlGeometry::generateAAPoints(TVG_UNUSED const Shape& shape, float strokeWd, else normalInfo[i].normalF = GlPoint(0, 0); - if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient)) + if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) { aaPts[i].fillOuterBlur = extendEdge(aaPts[i].orgPt, normalInfo[i].normalF, blurDir * stroke); aaPts[i].fillOuter = extendEdge(aaPts[i].fillOuterBlur, normalInfo[i].normalF, blurDir*antiAliasWidth); } - if (flag & RenderUpdateFlag::Stroke) + if (flag & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { aaPts[i].strokeOuterBlur = aaPts[i].orgPt; aaPts[i].strokeOuter = extendEdge(aaPts[i].strokeOuterBlur, normalInfo[i].normalF, blurDir*antiAliasWidth); @@ -200,7 +204,7 @@ bool GlGeometry::tesselate(TVG_UNUSED const Shape& shape, float viewWd, float vi VertexDataArray& fill = shapeGeometry.mFill; VertexDataArray& stroke = shapeGeometry.mStroke; - if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient) ) + if (flag & (RenderUpdateFlag::Color | RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform) ) { uint32_t i = 0; for (size_t pt = 0; pt < aaPts.size(); ++pt) @@ -221,7 +225,7 @@ bool GlGeometry::tesselate(TVG_UNUSED const Shape& shape, float viewWd, float vi addQuadIndices(i, fill.indices); } } - if (flag & RenderUpdateFlag::Stroke) + if (flag & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { uint32_t i = 0; for (size_t pt = 1; pt < aaPts.size(); ++pt) @@ -383,3 +387,23 @@ void GlGeometry::decomposeCubicCurve(GlPrimitive& primitve, const GlPoint& pt1, decomposeCubicCurve(primitve, p1234, p234, p34, pt2, min, max); } + +void GlGeometry::updateTransform(const RenderTransform* transform, float w, float h) +{ + if (transform) + { + mTransform.x = transform->x; + mTransform.y = transform->y; + mTransform.angle = transform->degree; + mTransform.scale = transform->scale; + } + + mTransform.w = w; + mTransform.h = h; + GET_TRANSFORMATION(NORMALIZED_LEFT_3D, NORMALIZED_TOP_3D, mTransform.matrix); +} + +float* GlGeometry::getTransforMatrix() +{ + return mTransform.matrix; +} \ No newline at end of file diff --git a/src/lib/gl_engine/tvgGlGeometry.h b/src/lib/gl_engine/tvgGlGeometry.h old mode 100644 new mode 100755 index 2fb83f5c..735873be --- a/src/lib/gl_engine/tvgGlGeometry.h +++ b/src/lib/gl_engine/tvgGlGeometry.h @@ -27,6 +27,44 @@ #include #include "tvgGlCommon.h" +#define PI 3.1415926535897932384626433832795f + +#define MVP_MATRIX() \ + float mvp[4*4] = { \ + mTransform.scale, 0.0, 0.0f, 0.0f, \ + 0.0, mTransform.scale, 0.0f, 0.0f, \ + 0.0f, 0.0f, mTransform.scale, 0.0f, \ + (mTransform.x * 2.0f) * (mTransform.scale / mTransform.w), -(mTransform.y * 2.0f) * (mTransform.scale / mTransform.h), 0.0f, 1.0f \ + }; + +#define ROTATION_MATRIX(xPivot, yPivot) \ + auto radian = mTransform.angle / 180.0f * PI; \ + auto cosVal = cosf(radian); \ + auto sinVal = sinf(radian); \ + float rotate[4*4] = { \ + cosVal, -sinVal, 0.0f, 0.0f, \ + sinVal, cosVal, 0.0f, 0.0f,\ + 0.0f, 0.0f, 1.0f, 0.0f, \ + (xPivot * (1.0f - cosVal)) - (yPivot * sinVal), (yPivot *(1.0f - cosVal)) + (xPivot * sinVal), 0.0f, 1.0f \ + }; + +#define MULTIPLY_MATRIX(A, B, transform) \ + for(auto i = 0; i < 4; ++i) \ + { \ + for(auto j = 0; j < 4; ++j) \ + { \ + float sum = 0.0; \ + for (auto k = 0; k < 4; ++k) \ + sum += A[k*4+i] * B[j*4+k]; \ + transform[j*4+i] = sum; \ + } \ + } + +#define GET_TRANSFORMATION(xPivot, yPivot, transform) \ + MVP_MATRIX(); \ + ROTATION_MATRIX(xPivot, yPivot); \ + MULTIPLY_MATRIX(mvp, rotate, transform); + class GlPoint { public: @@ -183,6 +221,18 @@ struct GlPrimitive bool mIsClosed = false; }; +struct GlTransform +{ + float x = 0.0f; + float y = 0.0f; + float angle = 0.0f; + float scale = 1.0f; + float w; + float h; + + float matrix[16]; +}; + class GlGpuBuffer; class GlGeometry @@ -196,6 +246,8 @@ public: bool tesselate(TVG_UNUSED const Shape &shape, float viewWd, float viewHt, RenderUpdateFlag flag); void disableVertex(uint32_t location); void draw(const uint32_t location, const uint32_t primitiveIndex, RenderUpdateFlag flag); + void updateTransform(const RenderTransform* transform, float w, float h); + float* getTransforMatrix(); private: GlPoint normalizePoint(const GlPoint &pt, float viewWd, float viewHt); @@ -213,6 +265,7 @@ private: unique_ptr mGpuBuffer; vector mPrimitives; + GlTransform mTransform; }; #endif /* _TVG_GL_GEOMETRY_H_ */ diff --git a/src/lib/gl_engine/tvgGlProgram.cpp b/src/lib/gl_engine/tvgGlProgram.cpp old mode 100644 new mode 100755 index 63ee42b6..9a44d988 --- a/src/lib/gl_engine/tvgGlProgram.cpp +++ b/src/lib/gl_engine/tvgGlProgram.cpp @@ -137,6 +137,10 @@ void GlProgram::setUniform4Value(int32_t location, int count, const float* value GL_CHECK(glUniform4fv(location, count, values)); } +void GlProgram::setUniform4x4Value(int32_t location, int count, const float* values) +{ + GL_CHECK(glUniformMatrix4fv(location, count, GL_FALSE, &values[0])); +} void GlProgram::linkProgram(std::shared_ptr shader) { diff --git a/src/lib/gl_engine/tvgGlProgram.h b/src/lib/gl_engine/tvgGlProgram.h old mode 100644 new mode 100755 index 173c5cdf..495e7c21 --- a/src/lib/gl_engine/tvgGlProgram.h +++ b/src/lib/gl_engine/tvgGlProgram.h @@ -45,6 +45,7 @@ public: 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); + void setUniform4x4Value(int32_t location, int count, const float* values); private: diff --git a/src/lib/gl_engine/tvgGlPropertyInterface.cpp b/src/lib/gl_engine/tvgGlPropertyInterface.cpp old mode 100644 new mode 100755 index af011eba..eeba8819 --- a/src/lib/gl_engine/tvgGlPropertyInterface.cpp +++ b/src/lib/gl_engine/tvgGlPropertyInterface.cpp @@ -33,7 +33,7 @@ VertexProperty PropertyInterface::mEmptyProperty; /* External Class Implementation */ /************************************************************************/ -VertexProperty& PropertyInterface::addProperty(GlRenderTask* rTask, std::shared_ptr prog, std::string name, uint32_t propFormatSize, VertexProperty::PropertyType propType) +VertexProperty& PropertyInterface::addProperty(GlRenderTask* rTask, std::shared_ptr prog, std::string name, uint32_t propFormatSize, VertexProperty::PropertyType propType, VertexProperty::DataType dataType) { std::map* vertexProperty = nullptr; int32_t id; @@ -52,7 +52,7 @@ VertexProperty& PropertyInterface::addProperty(GlRenderTask* rTask, std::shared_ } if (id != -1) { - VertexProperty property = { id, name, propType, VertexProperty::DataType::FLOAT }; + VertexProperty property = { id, name, propType, dataType }; property.propertyValues.setStride(propFormatSize); if (vertexProperty) { @@ -64,6 +64,21 @@ VertexProperty& PropertyInterface::addProperty(GlRenderTask* rTask, std::shared_ } +void PropertyInterface::setProperty(GlRenderTask* rTask, int32_t propId, int32_t count, float* data) +{ + std::map::iterator itr = rTask->getUniformVertexProperty().find(propId); + if (itr->second.propertyId == -1) + { + return; + } + VertexProperty& prop = itr->second; + + for (int i = 0; i < count; ++i) + { + prop.propertyValues.set(data[i]); + } +} + int32_t PropertyInterface::getPropertyId(GlRenderTask* rTask, std::string name) { std::map& vertexProperty = rTask->getUniformVertexProperty(); diff --git a/src/lib/gl_engine/tvgGlPropertyInterface.h b/src/lib/gl_engine/tvgGlPropertyInterface.h old mode 100644 new mode 100755 index 6c09e6df..ef037fb0 --- a/src/lib/gl_engine/tvgGlPropertyInterface.h +++ b/src/lib/gl_engine/tvgGlPropertyInterface.h @@ -36,15 +36,21 @@ if (var->propertyId != -1) \ location = var->propertyId +#define ADD_UNIFORM_PROPERTY_2(var, rtask, prog, varName, formatSize, location, datatype) \ + var = &PropertyInterface::addProperty(rtask, prog, varName, formatSize, VertexProperty::PropertyType::UNIFORM, datatype); \ + 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 +#define FORMAT_SIZE_MAT_4x4 16 class PropertyInterface { public: - static VertexProperty& addProperty(GlRenderTask* rTask, std::shared_ptr prog, std::string name, uint32_t propFormatSize, VertexProperty::PropertyType propType); + static VertexProperty& addProperty(GlRenderTask* rTask, std::shared_ptr prog, std::string name, uint32_t propFormatSize, VertexProperty::PropertyType propType, VertexProperty::DataType dataType = VertexProperty::DataType::FLOAT); template static void setProperty(GlRenderTask* rTask, std::string name, float first, Args... args) { @@ -65,9 +71,10 @@ public: } VertexProperty& prop = itr->second; - prop.dataType = VertexProperty::DataType::FLOAT; prop.propertyValues.set(first, args...); } + + static void setProperty(GlRenderTask* rTask, int32_t propId, int32_t count, float* data); 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); diff --git a/src/lib/gl_engine/tvgGlRenderTask.cpp b/src/lib/gl_engine/tvgGlRenderTask.cpp old mode 100644 new mode 100755 index fc474161..00035260 --- a/src/lib/gl_engine/tvgGlRenderTask.cpp +++ b/src/lib/gl_engine/tvgGlRenderTask.cpp @@ -37,6 +37,7 @@ GlRenderTask::GlRenderTask(RenderTypes renderType, shared_ptr shader) VertexProperty* prop = nullptr; ADD_ATTRIBUTE_PROPERTY(prop, this, mProgram, "aLocation", FORMAT_SIZE_VEC_4, mLocVertexAttribute); + ADD_UNIFORM_PROPERTY_2(prop, this, mProgram, "uTransform", FORMAT_SIZE_MAT_4x4, mLocTransform, VertexProperty::DataType::MATRIX); } @@ -82,6 +83,20 @@ int32_t GlRenderTask::getLocationPropertyId() const } +int32_t GlRenderTask::getTransformLocationPropertyId() const +{ + return mLocTransform; +} + + +void GlRenderTask::setTransform(int count, float* transform) +{ + if (mLocTransform != -1) + { + PropertyInterface::setProperty(this, mLocTransform, count, transform); + } +} + void GlRenderTask::uploadValues() { for (auto& property : mUniformPropertyBuffer) @@ -122,6 +137,10 @@ void GlRenderTask::uploadValues() } break; } + case VertexProperty::DataType::MATRIX: { + mProgram->setUniform4x4Value(property.second.propertyId, propertyVal.getCount(), propertyVal.getData()); + break; + } } } } diff --git a/src/lib/gl_engine/tvgGlRenderTask.h b/src/lib/gl_engine/tvgGlRenderTask.h old mode 100644 new mode 100755 index d753bcc2..6343237d --- a/src/lib/gl_engine/tvgGlRenderTask.h +++ b/src/lib/gl_engine/tvgGlRenderTask.h @@ -48,6 +48,8 @@ public: std::map& getAttributeVertexProperty(); std::map& getUniformVertexProperty(); int32_t getLocationPropertyId() const; + int32_t getTransformLocationPropertyId() const; + void setTransform(int count, float* transform_matrix); void uploadValues(); private: @@ -58,7 +60,8 @@ private: std::map mAttributePropertyBuffer; std::map mUniformPropertyBuffer; - int32_t mLocVertexAttribute; + int32_t mLocVertexAttribute = -1; + int32_t mLocTransform = -1; }; class GlColorRenderTask : public GlRenderTask @@ -81,14 +84,14 @@ public: 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); - + int32_t getTransformLocationPropertyId() const; private: int32_t mLocPrimitiveSize = -1; int32_t mLocCanvasSize = -1; int32_t mLocNoise = -1; int32_t mLocStopCnt = -1; - int32_t mLocStops; - int32_t mLocStopColors; + int32_t mLocStops = -1; + int32_t mLocStopColors = -1; }; class GlLinearGradientRenderTask : public GlGradientRenderTask diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp old mode 100644 new mode 100755 index b5bbb880..1e75e756 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -135,20 +135,31 @@ bool GlRenderer::renderShape(RenderData data, TVG_UNUSED Compositor* cmp) uint32_t primitiveCount = sdata->geometry->getPrimitiveCount(); for (uint32_t i = 0; i < primitiveCount; ++i) { - if (flags & RenderUpdateFlag::Gradient) + if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) { const Fill* gradient = sdata->shape->fill(); - drawPrimitive(*sdata, gradient, i, RenderUpdateFlag::Gradient); + if (gradient != nullptr) + { + drawPrimitive(*sdata, gradient, i, RenderUpdateFlag::Gradient); + } } - else if (flags & RenderUpdateFlag::Color) + + if(flags & (RenderUpdateFlag::Color | RenderUpdateFlag::Transform)) { sdata->shape->fillColor(&r, &g, &b, &a); - drawPrimitive(*sdata, r, g, b, a, i, RenderUpdateFlag::Color); + if (a > 0) + { + drawPrimitive(*sdata, r, g, b, a, i, RenderUpdateFlag::Color); + } } - if (flags & RenderUpdateFlag::Stroke) + + if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { sdata->shape->strokeColor(&r, &g, &b, &a); - drawPrimitive(*sdata, r, g, b, a, i, RenderUpdateFlag::Stroke); + if (a > 0) + { + drawPrimitive(*sdata, r, g, b, a, i, RenderUpdateFlag::Stroke); + } } } @@ -173,7 +184,7 @@ RenderData GlRenderer::prepare(TVG_UNUSED const Picture& picture, TVG_UNUSED Ren } -RenderData GlRenderer::prepare(const Shape& shape, RenderData data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, Array& clips, RenderUpdateFlag flags) +RenderData GlRenderer::prepare(const Shape& shape, RenderData data, const RenderTransform* transform, TVG_UNUSED uint32_t opacity, Array& clips, RenderUpdateFlag flags) { //prepare shape data GlShape* sdata = static_cast(data); @@ -204,7 +215,9 @@ RenderData GlRenderer::prepare(const Shape& shape, RenderData data, TVG_UNUSED c return sdata; } - if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke | RenderUpdateFlag::Gradient) ) + sdata->geometry->updateTransform(transform, sdata->viewWd, sdata->viewHt); + + if (sdata->updateFlag & (RenderUpdateFlag::Color | RenderUpdateFlag::Stroke | RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform) ) { if (!sdata->geometry->decomposeOutline(shape)) return sdata; if (!sdata->geometry->generateAAPoints(shape, static_cast(strokeWd), sdata->updateFlag)) return sdata; @@ -272,8 +285,10 @@ void GlRenderer::drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, GlColorRenderTask* renderTask = static_cast(mRenderTasks[GlRenderTask::RenderTypes::RT_Color].get()); assert(renderTask); renderTask->load(); + float* matrix = sdata.geometry->getTransforMatrix(); PropertyInterface::clearData(renderTask); renderTask->setColor(r, g, b, a); + renderTask->setTransform(FORMAT_SIZE_MAT_4x4, matrix); int32_t vertexLoc = renderTask->getLocationPropertyId(); renderTask->uploadValues(); sdata.geometry->draw(vertexLoc, primitiveIndex, flag); @@ -292,6 +307,8 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, uint32_t primit } GlGradientRenderTask* rTask = nullptr; GlSize size = sdata.geometry->getPrimitiveSize(primitiveIndex); + float* matrix = sdata.geometry->getTransforMatrix(); + switch (fill->id()) { case FILL_ID_LINEAR: { float x1, y1, x2, y2; @@ -327,6 +344,7 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, uint32_t primit rTask->setCanvasSize(sdata.viewWd, sdata.viewHt); rTask->setNoise(NOISE_LEVEL); rTask->setStopCount((int)stopCnt); + rTask->setTransform(FORMAT_SIZE_MAT_4x4, matrix); 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); diff --git a/src/lib/gl_engine/tvgGlRendererProperties.h b/src/lib/gl_engine/tvgGlRendererProperties.h old mode 100644 new mode 100755 index 9aa56df0..c6b85fcf --- a/src/lib/gl_engine/tvgGlRendererProperties.h +++ b/src/lib/gl_engine/tvgGlRendererProperties.h @@ -91,7 +91,8 @@ public: enum class DataType { INT = 0, - FLOAT + FLOAT, + MATRIX }; enum class PropertyType { diff --git a/src/lib/gl_engine/tvgGlShaderSrc.cpp b/src/lib/gl_engine/tvgGlShaderSrc.cpp old mode 100644 new mode 100755 index 63d796eb..b349b357 --- a/src/lib/gl_engine/tvgGlShaderSrc.cpp +++ b/src/lib/gl_engine/tvgGlShaderSrc.cpp @@ -26,12 +26,13 @@ #define TVG_COMPOSE_SHADER(shader) #shader 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 + attribute mediump vec4 aLocation; \n + uniform highp mat4 uTransform; \n + varying highp float vOpacity; \n + void main() \n + { \n + gl_Position = uTransform * vec4(aLocation.xy, 0.0, 1.0); \n + vOpacity = aLocation.z; \n }); const char* COLOR_FRAG_SHADER = TVG_COMPOSE_SHADER( @@ -46,10 +47,11 @@ const char* GRADIENT_VERT_SHADER = TVG_COMPOSE_SHADER( attribute highp vec4 aLocation; \n varying highp float vOpacity; \n varying highp vec2 vPos; \n +uniform highp mat4 uTransform; \n \n void main() \n { \n - gl_Position = vec4(aLocation.xy, 0.0, 1.0); \n + gl_Position = uTransform * 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 });