diff --git a/examples/Texmap.cpp b/examples/Texmap.cpp deleted file mode 100644 index b796ec72..00000000 --- a/examples/Texmap.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2020 - 2024 the ThorVG project. All rights reserved. - - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "Example.h" - -/************************************************************************/ -/* ThorVG Drawing Contents */ -/************************************************************************/ - -struct UserExample : tvgexam::Example -{ - bool content(tvg::Canvas* canvas, uint32_t w, uint32_t h) override - { - if (!canvas) return false; - - //Background - auto shape = tvg::Shape::gen(); - shape->appendRect(0, 0, w, h); - shape->fill(255, 255, 255); - - canvas->push(std::move(shape)); - - //Raw Image - string path(EXAMPLE_DIR"/image/rawimage_200x300.raw"); - - ifstream file(path, ios::binary); - if (!file.is_open()) return false; - auto data = (uint32_t*)malloc(sizeof(uint32_t) * (200*300)); - file.read(reinterpret_cast(data), sizeof (uint32_t) * 200 * 300); - file.close(); - - //Picture - auto picture = tvg::Picture::gen(); - if (!tvgexam::verify(picture->load(data, 200, 300, true))) return false; - - //Composing Meshes - tvg::Polygon triangles[4]; - triangles[0].vertex[0] = {{100, 125}, {0, 0}}; - triangles[0].vertex[1] = {{300, 100}, {0.5, 0}}; - triangles[0].vertex[2] = {{200, 550}, {0, 1}}; - - triangles[1].vertex[0] = {{300, 100}, {0.5, 0}}; - triangles[1].vertex[1] = {{350, 450}, {0.5, 1}}; - triangles[1].vertex[2] = {{200, 550}, {0, 1}}; - - triangles[2].vertex[0] = {{300, 100}, {0.5, 0}}; - triangles[2].vertex[1] = {{500, 200}, {1, 0}}; - triangles[2].vertex[2] = {{350, 450}, {0.5, 1}}; - - triangles[3].vertex[0] = {{500, 200}, {1, 0}}; - triangles[3].vertex[1] = {{450, 450}, {1, 1}}; - triangles[3].vertex[2] = {{350, 450}, {0.5, 1}}; - - if (!tvgexam::verify(picture->mesh(triangles, 4))) return false; - - //Masking + Opacity - auto picture2 = tvg::cast(picture->duplicate()); - picture2->translate(400, 400); - picture2->opacity(200); - - auto mask = tvg::Shape::gen(); - mask->appendCircle(700, 700, 200, 200); - mask->fill(255, 255, 255); - picture2->composite(std::move(mask), tvg::CompositeMethod::AlphaMask); - - canvas->push(std::move(picture)); - canvas->push(std::move(picture2)); - - free(data); - - return true; - } -}; - - -/************************************************************************/ -/* Entry Point */ -/************************************************************************/ - -int main(int argc, char **argv) -{ - return tvgexam::main(new UserExample, argc, argv, 1024, 1024); -} \ No newline at end of file diff --git a/examples/TvgSaver.cpp b/examples/TvgSaver.cpp index e10152e5..577ecd0f 100644 --- a/examples/TvgSaver.cpp +++ b/examples/TvgSaver.cpp @@ -28,35 +28,6 @@ using namespace std; /* ThorVG Saving Contents */ /************************************************************************/ -unique_ptr tvgTexmap(uint32_t * data, int width, int height) -{ - auto texmap = tvg::Picture::gen(); - if (!tvgexam::verify(texmap->load(data, width, height, true))) return nullptr; - texmap->translate(100, 100); - - //Composing Meshes - tvg::Polygon triangles[4]; - triangles[0].vertex[0] = {{100, 125}, {0, 0}}; - triangles[0].vertex[1] = {{300, 100}, {0.5, 0}}; - triangles[0].vertex[2] = {{200, 550}, {0, 1}}; - - triangles[1].vertex[0] = {{300, 100}, {0.5, 0}}; - triangles[1].vertex[1] = {{350, 450}, {0.5, 1}}; - triangles[1].vertex[2] = {{200, 550}, {0, 1}}; - - triangles[2].vertex[0] = {{300, 100}, {0.5, 0}}; - triangles[2].vertex[1] = {{500, 200}, {1, 0}}; - triangles[2].vertex[2] = {{350, 450}, {0.5, 1}}; - - triangles[3].vertex[0] = {{500, 200}, {1, 0}}; - triangles[3].vertex[1] = {{450, 450}, {1, 1}}; - triangles[3].vertex[2] = {{350, 450}, {0.5, 1}}; - - texmap->mesh(triangles, 4); - - return texmap; -} - unique_ptr tvgClippedImage(uint32_t * data, int width, int height) { auto image = tvg::Picture::gen(); @@ -193,10 +164,6 @@ void exportTvg() file.read(reinterpret_cast(data), sizeof(uint32_t) * width * height); file.close(); - //texmap image - auto texmap = tvgTexmap(data, width, height); - scene->push(std::move(texmap)); - //clipped image auto image = tvgClippedImage(data, width, height); scene->push(std::move(image)); diff --git a/examples/meson.build b/examples/meson.build index 8c48a4dd..2d1da477 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -65,7 +65,6 @@ source_file = [ 'StrokeMiterlimit.cpp', 'StrokeTrim.cpp', 'Svg.cpp', - 'Texmap.cpp', 'Text.cpp', 'Transform.cpp', 'Tvg.cpp', diff --git a/inc/thorvg.h b/inc/thorvg.h index 8fb8b677..e3f7243a 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -256,34 +256,6 @@ struct Matrix }; -/** - * @brief A data structure representing a texture mesh vertex - * - * @param pt The vertex coordinate - * @param uv The normalized texture coordinate in the range (0.0..1.0, 0.0..1.0) - * - * @note Experimental API - */ -struct Vertex -{ - Point pt; - Point uv; -}; - - -/** - * @brief A data structure representing a triangle in a texture mesh - * - * @param vertex The three vertices that make up the polygon - * - * @note Experimental API - */ -struct Polygon -{ - Vertex vertex[3]; -}; - - /** * @class Paint * @@ -1359,41 +1331,6 @@ public: */ const Paint* paint(uint32_t id) noexcept; - /** - * @brief Sets or removes the triangle mesh to deform the image. - * - * If a mesh is provided, the transform property of the Picture will apply to the triangle mesh, and the - * image data will be used as the texture. - * - * If @p triangles is @c nullptr, or @p triangleCnt is 0, the mesh will be removed. - * - * Only raster image types are supported at this time (png, jpg). Vector types like svg and tvg do not support. - * mesh deformation. However, if required you should be able to render a vector image to a raster image and then apply a mesh. - * - * @param[in] triangles An array of Polygons(triangles) that make up the mesh, or null to remove the mesh. - * @param[in] triangleCnt The number of Polygons(triangles) provided, or 0 to remove the mesh. - * - * @note The Polygons are copied internally, so modifying them after calling Mesh::mesh has no affect. - * @warning Please do not use it, this API is not official one. It could be modified in the next version. - * - * @note Experimental API - */ - Result mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept; - - /** - * @brief Return the number of triangles in the mesh, and optionally get a pointer to the array of triangles in the mesh. - * - * @param[out] triangles Optional. A pointer to the array of Polygons used by this mesh. - * - * @return The number of polygons in the array. - * - * @note Modifying the triangles returned by this method will modify them directly within the mesh. - * @warning Please do not use it, this API is not official one. It could be modified in the next version. - * - * @note Experimental API - */ - uint32_t mesh(const Polygon** triangles) const noexcept; - /** * @brief Creates a new Picture object. * diff --git a/src/loaders/tvg/tvgTvgBinInterpreter.cpp b/src/loaders/tvg/tvgTvgBinInterpreter.cpp index 2332aeeb..f35ed066 100644 --- a/src/loaders/tvg/tvgTvgBinInterpreter.cpp +++ b/src/loaders/tvg/tvgTvgBinInterpreter.cpp @@ -418,21 +418,6 @@ static bool _parsePicture(TvgBinBlock block, Paint* paint) return true; } - case TVG_TAG_PICTURE_MESH: { - if (block.length < 1 * SIZE(uint32_t)) return false; - - auto ptr = block.data; - uint32_t meshCnt; - READ_UI32(&meshCnt, ptr); - ptr += SIZE(uint32_t); - - auto size = meshCnt * SIZE(Polygon); - if (block.length != SIZE(uint32_t) + size) return false; - - picture->mesh((Polygon*) ptr, meshCnt); - - return true; - } //Base Paint Properties default: { if (_parsePaintProperty(block, picture)) return true; diff --git a/src/renderer/gl_engine/tvgGlGeometry.cpp b/src/renderer/gl_engine/tvgGlGeometry.cpp index 11d68076..a4c9a6d4 100644 --- a/src/renderer/gl_engine/tvgGlGeometry.cpp +++ b/src/renderer/gl_engine/tvgGlGeometry.cpp @@ -58,115 +58,57 @@ bool GlGeometry::tesselate(const RenderShape& rshape, RenderUpdateFlag flag) return true; } -bool GlGeometry::tesselate(const Surface* image, const RenderMesh* mesh, RenderUpdateFlag flag) +bool GlGeometry::tesselate(const Surface* image, RenderUpdateFlag flag) { if (flag & RenderUpdateFlag::Image) { fillVertex.clear(); fillIndex.clear(); - if (mesh && mesh->triangleCnt) { - fillVertex.reserve(mesh->triangleCnt * 3 * 5); - fillIndex.reserve(mesh->triangleCnt * 3); + fillVertex.reserve(5 * 4); + fillIndex.reserve(6); - uint32_t index = 0; - for (uint32_t i = 0; i < mesh->triangleCnt; i++) { - fillVertex.push(mesh->triangles[i].vertex[0].pt.x); - fillVertex.push(mesh->triangles[i].vertex[0].pt.y); + float left = 0.f; + float top = 0.f; + float right = image->w; + float bottom = image->h; - fillVertex.push(mesh->triangles[i].vertex[0].uv.x); - fillVertex.push(mesh->triangles[i].vertex[0].uv.y); + // left top point + fillVertex.push(left); + fillVertex.push(top); - fillVertex.push(mesh->triangles[i].vertex[1].pt.x); - fillVertex.push(mesh->triangles[i].vertex[1].pt.y); + fillVertex.push(0.f); + fillVertex.push(1.f); + // left bottom point + fillVertex.push(left); + fillVertex.push(bottom); - fillVertex.push(mesh->triangles[i].vertex[1].uv.x); - fillVertex.push(mesh->triangles[i].vertex[1].uv.y); + fillVertex.push(0.f); + fillVertex.push(0.f); + // right top point + fillVertex.push(right); + fillVertex.push(top); - fillVertex.push(mesh->triangles[i].vertex[2].pt.x); - fillVertex.push(mesh->triangles[i].vertex[2].pt.y); + fillVertex.push(1.f); + fillVertex.push(1.f); + // right bottom point + fillVertex.push(right); + fillVertex.push(bottom); - fillVertex.push(mesh->triangles[i].vertex[2].uv.x); - fillVertex.push(mesh->triangles[i].vertex[2].uv.y); + fillVertex.push(1.f); + fillVertex.push(0.f); - fillIndex.push(index); - fillIndex.push(index + 1); - fillIndex.push(index + 2); - index += 3; - } + fillIndex.push(0); + fillIndex.push(1); + fillIndex.push(2); - float left = mesh->triangles[0].vertex[0].pt.x; - float top = mesh->triangles[0].vertex[0].pt.y; - float right = mesh->triangles[0].vertex[0].pt.x; - float bottom = mesh->triangles[0].vertex[0].pt.y; + fillIndex.push(2); + fillIndex.push(1); + fillIndex.push(3); - for (uint32_t i = 0; i < mesh->triangleCnt; i++) { - left = min(left, mesh->triangles[i].vertex[0].pt.x); - left = min(left, mesh->triangles[i].vertex[1].pt.x); - left = min(left, mesh->triangles[i].vertex[2].pt.x); - top = min(top, mesh->triangles[i].vertex[0].pt.y); - top = min(top, mesh->triangles[i].vertex[1].pt.y); - top = min(top, mesh->triangles[i].vertex[2].pt.y); - - right = max(right, mesh->triangles[i].vertex[0].pt.x); - right = max(right, mesh->triangles[i].vertex[1].pt.x); - right = max(right, mesh->triangles[i].vertex[2].pt.x); - bottom = max(bottom, mesh->triangles[i].vertex[0].pt.y); - bottom = max(bottom, mesh->triangles[i].vertex[1].pt.y); - bottom = max(bottom, mesh->triangles[i].vertex[2].pt.y); - } - - mBounds.x = static_cast(left); - mBounds.y = static_cast(top); - mBounds.w = static_cast(right - left); - mBounds.h = static_cast(bottom - top); - - } else { - fillVertex.reserve(5 * 4); - fillIndex.reserve(6); - - float left = 0.f; - float top = 0.f; - float right = image->w; - float bottom = image->h; - - // left top point - fillVertex.push(left); - fillVertex.push(top); - - fillVertex.push(0.f); - fillVertex.push(1.f); - // left bottom point - fillVertex.push(left); - fillVertex.push(bottom); - - fillVertex.push(0.f); - fillVertex.push(0.f); - // right top point - fillVertex.push(right); - fillVertex.push(top); - - fillVertex.push(1.f); - fillVertex.push(1.f); - // right bottom point - fillVertex.push(right); - fillVertex.push(bottom); - - fillVertex.push(1.f); - fillVertex.push(0.f); - - fillIndex.push(0); - fillIndex.push(1); - fillIndex.push(2); - - fillIndex.push(2); - fillIndex.push(1); - fillIndex.push(3); - - mBounds.x = 0; - mBounds.y = 0; - mBounds.w = image->w; - mBounds.h = image->h; - } + mBounds.x = 0; + mBounds.y = 0; + mBounds.w = image->w; + mBounds.h = image->h; } return true; diff --git a/src/renderer/gl_engine/tvgGlGeometry.h b/src/renderer/gl_engine/tvgGlGeometry.h index 5e74d92b..0e3cfea0 100644 --- a/src/renderer/gl_engine/tvgGlGeometry.h +++ b/src/renderer/gl_engine/tvgGlGeometry.h @@ -190,7 +190,7 @@ public: ~GlGeometry(); bool tesselate(const RenderShape& rshape, RenderUpdateFlag flag); - bool tesselate(const Surface* image, const RenderMesh* mesh, RenderUpdateFlag flag); + bool tesselate(const Surface* image, RenderUpdateFlag flag); void disableVertex(uint32_t location); bool draw(GlRenderTask* task, GlStageBuffer* gpuBuffer, RenderUpdateFlag flag); void updateTransform(const Matrix& m); diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index ef98115c..1a30a018 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -1099,7 +1099,7 @@ static GLuint _genTexture(Surface* image) } -RenderData GlRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +RenderData GlRenderer::prepare(Surface* image, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { if (flags == RenderUpdateFlag::None) return data; @@ -1115,14 +1115,14 @@ RenderData GlRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderDat sdata->texId = _genTexture(image); sdata->opacity = opacity; sdata->texColorSpace = image->cs; - sdata->texFlipY = (mesh && mesh->triangleCnt) ? 0 : 1; + sdata->texFlipY = 1; sdata->geometry = make_unique(); } sdata->geometry->updateTransform(transform); sdata->geometry->setViewport(mViewport); - sdata->geometry->tesselate(image, mesh, flags); + sdata->geometry->tesselate(image, flags); if (!clips.empty()) sdata->clips.push(clips); diff --git a/src/renderer/gl_engine/tvgGlRenderer.h b/src/renderer/gl_engine/tvgGlRenderer.h index 84fb0597..63ab80fc 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.h +++ b/src/renderer/gl_engine/tvgGlRenderer.h @@ -54,7 +54,7 @@ public: }; RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; - RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(Surface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; bool preRender() override; bool renderShape(RenderData data) override; bool renderImage(RenderData data) override; diff --git a/src/renderer/sw_engine/tvgSwCommon.h b/src/renderer/sw_engine/tvgSwCommon.h index d25c1389..5478f8f2 100644 --- a/src/renderer/sw_engine/tvgSwCommon.h +++ b/src/renderer/sw_engine/tvgSwCommon.h @@ -519,7 +519,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline); SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid); void strokeFree(SwStroke* stroke); -bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); +bool imagePrepare(SwImage* image, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias); void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid); void imageReset(SwImage* image); @@ -564,7 +564,7 @@ void mpoolRetDashOutline(SwMpool* mpool, unsigned idx); bool rasterCompositor(SwSurface* surface); bool rasterGradientShape(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity); bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); -bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox& bbox, uint8_t opacity); +bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& bbox, uint8_t opacity); bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); bool rasterGradientStroke(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity); bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h); diff --git a/src/renderer/sw_engine/tvgSwImage.cpp b/src/renderer/sw_engine/tvgSwImage.cpp index 488f3ff3..d2c02bb9 100644 --- a/src/renderer/sw_engine/tvgSwImage.cpp +++ b/src/renderer/sw_engine/tvgSwImage.cpp @@ -34,7 +34,7 @@ static inline bool _onlyShifted(const Matrix& m) } -static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix& transform, SwMpool* mpool, unsigned tid) +static bool _genOutline(SwImage* image, const Matrix& transform, SwMpool* mpool, unsigned tid) { image->outline = mpoolReqOutline(mpool, tid); auto outline = image->outline; @@ -45,48 +45,12 @@ static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix& tr outline->closed.reserve(1); Point to[4]; - if (mesh->triangleCnt > 0) { - // TODO: Optimise me. We appear to calculate this exact min/max bounding area in multiple - // places. We should be able to re-use one we have already done? Also see: - // tvgPicture.h --> bounds - // tvgSwRasterTexmap.h --> _rasterTexmapPolygonMesh - // - // TODO: Should we calculate the exact path(s) of the triangle mesh instead? - // i.e. copy tvgSwShape.capp -> _genOutline? - // - // TODO: Cntrs? - auto triangles = mesh->triangles; - auto min = triangles[0].vertex[0].pt; - auto max = triangles[0].vertex[0].pt; - - for (uint32_t i = 0; i < mesh->triangleCnt; ++i) { - if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x; - else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x; - if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y; - else if (triangles[i].vertex[0].pt.y > max.y) max.y = triangles[i].vertex[0].pt.y; - - if (triangles[i].vertex[1].pt.x < min.x) min.x = triangles[i].vertex[1].pt.x; - else if (triangles[i].vertex[1].pt.x > max.x) max.x = triangles[i].vertex[1].pt.x; - if (triangles[i].vertex[1].pt.y < min.y) min.y = triangles[i].vertex[1].pt.y; - else if (triangles[i].vertex[1].pt.y > max.y) max.y = triangles[i].vertex[1].pt.y; - - if (triangles[i].vertex[2].pt.x < min.x) min.x = triangles[i].vertex[2].pt.x; - else if (triangles[i].vertex[2].pt.x > max.x) max.x = triangles[i].vertex[2].pt.x; - if (triangles[i].vertex[2].pt.y < min.y) min.y = triangles[i].vertex[2].pt.y; - else if (triangles[i].vertex[2].pt.y > max.y) max.y = triangles[i].vertex[2].pt.y; - } - to[0] = {min.x, min.y}; - to[1] = {max.x, min.y}; - to[2] = {max.x, max.y}; - to[3] = {min.x, max.y}; - } else { - auto w = static_cast(image->w); - auto h = static_cast(image->h); - to[0] = {0, 0}; - to[1] = {w, 0}; - to[2] = {w, h}; - to[3] = {0, h}; - } + auto w = static_cast(image->w); + auto h = static_cast(image->h); + to[0] = {0, 0}; + to[1] = {w, 0}; + to[2] = {w, h}; + to[3] = {0, h}; for (int i = 0; i < 4; i++) { outline->pts.push(mathTransform(&to[i], transform)); @@ -108,7 +72,7 @@ static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix& tr /* External Class Implementation */ /************************************************************************/ -bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) +bool imagePrepare(SwImage* image, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) { image->direct = _onlyShifted(transform); @@ -126,7 +90,7 @@ bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix& transfor else image->scaled = false; } - if (!_genOutline(image, mesh, transform, mpool, tid)) return false; + if (!_genOutline(image, transform, mpool, tid)) return false; return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, image->direct); } diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index 5c82b12a..fe20282a 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -1987,13 +1987,12 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint } -bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox& bbox, uint8_t opacity) +bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& bbox, uint8_t opacity) { //Outside of the viewport, skip the rendering if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast(surface->w) || bbox.min.y >= static_cast(surface->h)) return true; - if (mesh && mesh->triangleCnt > 0) return _rasterTexmapPolygonMesh(surface, image, mesh, transform, &bbox, opacity); - else return _rasterImage(surface, image, transform, bbox, opacity); + return _rasterImage(surface, image, transform, bbox, opacity); } diff --git a/src/renderer/sw_engine/tvgSwRasterTexmap.h b/src/renderer/sw_engine/tvgSwRasterTexmap.h index c1241534..5c9d9da6 100644 --- a/src/renderer/sw_engine/tvgSwRasterTexmap.h +++ b/src/renderer/sw_engine/tvgSwRasterTexmap.h @@ -1134,69 +1134,4 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const } #endif return _apply(surface, aaSpans); -} - - -/* - Provide any number of triangles to draw a mesh using the supplied image. - Indexes are not used, so each triangle (Polygon) vertex has to be defined, even if they copy the previous one. - Example: - - 0 -- 1 0 -- 1 0 - | / | --> | / / | - | / | | / / | - 2 -- 3 2 1 -- 2 - - Should provide two Polygons, one for each triangle. - // TODO: region? -*/ -static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox* region, uint8_t opacity) -{ - if (surface->channelSize == sizeof(uint8_t)) { - TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon mesh!"); - return false; - } - - //Exceptions: No dedicated drawing area? - if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false; - - // Step polygons once to transform - auto transformedTris = (Polygon*)malloc(sizeof(Polygon) * mesh->triangleCnt); - float ys = FLT_MAX, ye = -1.0f; - for (uint32_t i = 0; i < mesh->triangleCnt; i++) { - transformedTris[i] = mesh->triangles[i]; - transformedTris[i].vertex[0].pt *= transform; - transformedTris[i].vertex[1].pt *= transform; - transformedTris[i].vertex[2].pt *= transform; - - if (transformedTris[i].vertex[0].pt.y < ys) ys = transformedTris[i].vertex[0].pt.y; - else if (transformedTris[i].vertex[0].pt.y > ye) ye = transformedTris[i].vertex[0].pt.y; - if (transformedTris[i].vertex[1].pt.y < ys) ys = transformedTris[i].vertex[1].pt.y; - else if (transformedTris[i].vertex[1].pt.y > ye) ye = transformedTris[i].vertex[1].pt.y; - if (transformedTris[i].vertex[2].pt.y < ys) ys = transformedTris[i].vertex[2].pt.y; - else if (transformedTris[i].vertex[2].pt.y > ye) ye = transformedTris[i].vertex[2].pt.y; - - // Convert normalized UV coordinates to image coordinates - transformedTris[i].vertex[0].uv.x *= (float)image->w; - transformedTris[i].vertex[0].uv.y *= (float)image->h; - transformedTris[i].vertex[1].uv.x *= (float)image->w; - transformedTris[i].vertex[1].uv.y *= (float)image->h; - transformedTris[i].vertex[2].uv.x *= (float)image->w; - transformedTris[i].vertex[2].uv.y *= (float)image->h; - } - - // Get AA spans and step polygons again to draw - if (auto aaSpans = _AASpans(ys, ye, image, region)) { - for (uint32_t i = 0; i < mesh->triangleCnt; i++) { - _rasterPolygonImage(surface, image, region, transformedTris[i], aaSpans, opacity); - } -#if 0 - if (_compositing(surface) && _masking(surface) && !_direct(surface->compositor->method)) { - _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox); - } -#endif - _apply(surface, aaSpans); - } - free(transformedTris); - return true; -} +} \ No newline at end of file diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index e6a7c24c..c49c26da 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -203,7 +203,6 @@ struct SwImageTask : SwTask { SwImage image; Surface* source; //Image source - const RenderMesh* mesh = nullptr; //Should be valid ptr in action bool clip(SwRle* target) override { @@ -236,10 +235,9 @@ struct SwImageTask : SwTask imageReset(&image); if (!image.data || image.w == 0 || image.h == 0) goto end; - if (!imagePrepare(&image, mesh, transform, clipRegion, bbox, mpool, tid)) goto end; + if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid)) goto end; - // TODO: How do we clip the triangle mesh? Only clip non-meshed images for now - if (mesh->triangleCnt == 0 && clips.count > 0) { + if (clips.count > 0) { if (!imageGenRle(&image, bbox, false)) goto end; if (image.rle) { //Clear current task memorypool here if the clippers would use the same memory pool @@ -423,7 +421,7 @@ bool SwRenderer::renderImage(RenderData data) if (task->opacity == 0) return true; - return rasterImage(surface, &task->image, task->mesh, task->transform, task->bbox, task->opacity); + return rasterImage(surface, &task->image, task->transform, task->bbox, task->opacity); } @@ -632,7 +630,7 @@ bool SwRenderer::endComposite(Compositor* cmp) //Default is alpha blending if (p->method == CompositeMethod::None) { Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1}; - return rasterImage(surface, &p->image, nullptr, m, p->bbox, p->opacity); + return rasterImage(surface, &p->image, m, p->bbox, p->opacity); } return true; @@ -697,7 +695,7 @@ void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Arr } -RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +RenderData SwRenderer::prepare(Surface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { //prepare task auto task = static_cast(data); @@ -705,7 +703,6 @@ RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderD else task->done(); task->source = surface; - task->mesh = mesh; return prepareCommon(task, transform, clips, opacity, flags); } diff --git a/src/renderer/sw_engine/tvgSwRenderer.h b/src/renderer/sw_engine/tvgSwRenderer.h index ee4d9be1..fcd8ad46 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.h +++ b/src/renderer/sw_engine/tvgSwRenderer.h @@ -37,7 +37,7 @@ class SwRenderer : public RenderMethod { public: RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; - RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(Surface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; bool preRender() override; bool renderShape(RenderData data) override; bool renderImage(RenderData data) override; diff --git a/src/renderer/tvgPicture.cpp b/src/renderer/tvgPicture.cpp index 3297ff11..16268d52 100644 --- a/src/renderer/tvgPicture.cpp +++ b/src/renderer/tvgPicture.cpp @@ -205,23 +205,6 @@ Result Picture::size(float* w, float* h) const noexcept } -Result Picture::mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept -{ - if (!triangles && triangleCnt > 0) return Result::InvalidArguments; - if (triangles && triangleCnt == 0) return Result::InvalidArguments; - - pImpl->mesh(triangles, triangleCnt); - return Result::Success; -} - - -uint32_t Picture::mesh(const Polygon** triangles) const noexcept -{ - if (triangles) *triangles = pImpl->rm.triangles; - return pImpl->rm.triangleCnt; -} - - const Paint* Picture::paint(uint32_t id) noexcept { struct Value diff --git a/src/renderer/tvgPicture.h b/src/renderer/tvgPicture.h index c87e2474..3a4880ca 100644 --- a/src/renderer/tvgPicture.h +++ b/src/renderer/tvgPicture.h @@ -63,7 +63,6 @@ struct Picture::Impl Surface* surface = nullptr; //bitmap picture uses RenderData rd = nullptr; //engine data float w = 0, h = 0; - RenderMesh rm; //mesh data Picture* picture = nullptr; bool resizing = false; bool needComp = false; //need composition @@ -102,7 +101,7 @@ struct Picture::Impl auto scale = sx < sy ? sx : sy; auto m = transform * Matrix{scale, 0, 0, 0, scale, 0, 0, 0, 1}; - rd = renderer->prepare(surface, &rm, rd, m, clips, opacity, flag); + rd = renderer->prepare(surface, rd, m, clips, opacity, flag); } else if (paint) { if (resizing) { loader->resize(paint, w, h); @@ -116,37 +115,10 @@ struct Picture::Impl bool bounds(float* x, float* y, float* w, float* h, bool stroking) { - if (rm.triangleCnt > 0) { - auto triangles = rm.triangles; - auto min = triangles[0].vertex[0].pt; - auto max = triangles[0].vertex[0].pt; - - for (uint32_t i = 0; i < rm.triangleCnt; ++i) { - if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x; - else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x; - if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y; - else if (triangles[i].vertex[0].pt.y > max.y) max.y = triangles[i].vertex[0].pt.y; - - if (triangles[i].vertex[1].pt.x < min.x) min.x = triangles[i].vertex[1].pt.x; - else if (triangles[i].vertex[1].pt.x > max.x) max.x = triangles[i].vertex[1].pt.x; - if (triangles[i].vertex[1].pt.y < min.y) min.y = triangles[i].vertex[1].pt.y; - else if (triangles[i].vertex[1].pt.y > max.y) max.y = triangles[i].vertex[1].pt.y; - - if (triangles[i].vertex[2].pt.x < min.x) min.x = triangles[i].vertex[2].pt.x; - else if (triangles[i].vertex[2].pt.x > max.x) max.x = triangles[i].vertex[2].pt.x; - if (triangles[i].vertex[2].pt.y < min.y) min.y = triangles[i].vertex[2].pt.y; - else if (triangles[i].vertex[2].pt.y > max.y) max.y = triangles[i].vertex[2].pt.y; - } - if (x) *x = min.x; - if (y) *y = min.y; - if (w) *w = max.x - min.x; - if (h) *h = max.y - min.y; - } else { - if (x) *x = 0; - if (y) *y = 0; - if (w) *w = this->w; - if (h) *h = this->h; - } + if (x) *x = 0; + if (y) *y = 0; + if (w) *w = this->w; + if (h) *h = this->h; return true; } @@ -181,19 +153,6 @@ struct Picture::Impl return load(loader); } - void mesh(const Polygon* triangles, const uint32_t triangleCnt) - { - if (triangles && triangleCnt > 0) { - this->rm.triangleCnt = triangleCnt; - this->rm.triangles = (Polygon*)malloc(sizeof(Polygon) * triangleCnt); - memcpy(this->rm.triangles, triangles, sizeof(Polygon) * triangleCnt); - } else { - free(this->rm.triangles); - this->rm.triangles = nullptr; - this->rm.triangleCnt = 0; - } - } - Paint* duplicate(Paint* ret) { if (ret) TVGERR("RENDERER", "TODO: duplicate()"); @@ -216,12 +175,6 @@ struct Picture::Impl dup->h = h; dup->resizing = resizing; - if (rm.triangleCnt > 0) { - dup->rm.triangleCnt = rm.triangleCnt; - dup->rm.triangles = (Polygon*)malloc(sizeof(Polygon) * rm.triangleCnt); - memcpy(dup->rm.triangles, rm.triangles, sizeof(Polygon) * rm.triangleCnt); - } - return picture; } diff --git a/src/renderer/tvgRender.h b/src/renderer/tvgRender.h index c5dfb156..b0ee42db 100644 --- a/src/renderer/tvgRender.h +++ b/src/renderer/tvgRender.h @@ -86,15 +86,15 @@ struct Compositor uint8_t opacity; }; -struct RenderMesh +struct Vertex { - Polygon* triangles = nullptr; - uint32_t triangleCnt = 0; + Point pt; + Point uv; +}; - ~RenderMesh() - { - free(triangles); - } +struct Polygon +{ + Vertex vertex[3]; }; struct RenderRegion @@ -287,7 +287,7 @@ public: virtual ~RenderMethod() {} virtual RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; - virtual RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; + virtual RenderData prepare(Surface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; virtual bool preRender() = 0; virtual bool renderShape(RenderData data) = 0; virtual bool renderImage(RenderData data) = 0; diff --git a/src/renderer/wg_engine/tvgWgGeometry.cpp b/src/renderer/wg_engine/tvgWgGeometry.cpp index aa3a55b2..e6de6ff6 100755 --- a/src/renderer/wg_engine/tvgWgGeometry.cpp +++ b/src/renderer/wg_engine/tvgWgGeometry.cpp @@ -279,26 +279,6 @@ void WgGeometryData::appendBlitBox() } -void WgGeometryData::appendMesh(const RenderMesh* rmesh) -{ - assert(rmesh); - positions.pts.reserve(rmesh->triangleCnt * 3); - texCoords.reserve(rmesh->triangleCnt * 3); - indexes.reserve(rmesh->triangleCnt * 3); - for (uint32_t i = 0; i < rmesh->triangleCnt; i++) { - positions.appendPoint(rmesh->triangles[i].vertex[0].pt); - positions.appendPoint(rmesh->triangles[i].vertex[1].pt); - positions.appendPoint(rmesh->triangles[i].vertex[2].pt); - texCoords.push(rmesh->triangles[i].vertex[0].uv); - texCoords.push(rmesh->triangles[i].vertex[1].uv); - texCoords.push(rmesh->triangles[i].vertex[2].uv); - indexes.push(i*3 + 0); - indexes.push(i*3 + 1); - indexes.push(i*3 + 2); - } -} - - void WgGeometryData::appendStrokeDashed(const WgPolyline* polyline, const RenderStroke *stroke) { assert(stroke); diff --git a/src/renderer/wg_engine/tvgWgGeometry.h b/src/renderer/wg_engine/tvgWgGeometry.h index a97c2849..c9d4bf2b 100755 --- a/src/renderer/wg_engine/tvgWgGeometry.h +++ b/src/renderer/wg_engine/tvgWgGeometry.h @@ -117,7 +117,6 @@ struct WgGeometryData void appendCircle(WgPoint center, float radius); void appendImageBox(float w, float h); void appendBlitBox(); - void appendMesh(const RenderMesh* rmesh); void appendStrokeDashed(const WgPolyline* polyline, const RenderStroke *stroke); void appendStrokeJoin(const WgPoint& v0, const WgPoint& v1, const WgPoint& v2, StrokeJoin join, float halfWidth, float miterLimit); diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index 3ebee08a..56eabc08 100755 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -514,7 +514,6 @@ void WgRenderDataShapePool::release(WgContext& context) void WgRenderDataPicture::release(WgContext& context) { - meshData.release(context); imageData.release(context); context.pipelines->layouts.releaseBindGroup(bindGroupPicture); WgRenderDataPaint::release(context); diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index b14910a9..5ce90ef6 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -110,7 +110,7 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const } -RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +RenderData WgRenderer::prepare(Surface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { // get or create render data shape auto renderDataPicture = (WgRenderDataPicture*)data; @@ -127,8 +127,7 @@ RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderD // update image data if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Image)) { WgGeometryData geometryData; - if (mesh->triangleCnt == 0) geometryData.appendImageBox(surface->w, surface->h); - else geometryData.appendMesh(mesh); + geometryData.appendImageBox(surface->w, surface->h); mContext.pipelines->layouts.releaseBindGroup(renderDataPicture->bindGroupPicture); renderDataPicture->meshData.release(mContext); renderDataPicture->meshData.update(mContext, &geometryData); diff --git a/src/renderer/wg_engine/tvgWgRenderer.h b/src/renderer/wg_engine/tvgWgRenderer.h index c5e8f67e..f077df55 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.h +++ b/src/renderer/wg_engine/tvgWgRenderer.h @@ -29,7 +29,7 @@ class WgRenderer : public RenderMethod { public: RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; - RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(Surface* surface, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; bool preRender() override; bool renderShape(RenderData data) override; bool renderImage(RenderData data) override; diff --git a/src/savers/tvg/tvgTvgSaver.cpp b/src/savers/tvg/tvgTvgSaver.cpp index 08a57999..c56c8d80 100644 --- a/src/savers/tvg/tvgTvgSaver.cpp +++ b/src/savers/tvg/tvgTvgSaver.cpp @@ -635,20 +635,6 @@ TvgBinCounter TvgSaver::serializePicture(const Picture* picture, const Matrix* p cnt += writeData(pixels, imgSize); cnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter); - //mesh: currently only available in bitmap image. - const Polygon* triangles = nullptr; - auto triangleCnt = picture->mesh(&triangles); - if (triangles && triangleCnt > 0) { - TvgBinCounter triangleCntSize = SIZE(triangleCnt); - TvgBinCounter trianglesSize = triangleCnt * SIZE(triangles[0]); - - writeTag(TVG_TAG_PICTURE_MESH); - writeCount(triangleCntSize + trianglesSize); - cnt += writeData(&triangleCnt, triangleCntSize); - cnt += writeData(triangles, trianglesSize); - cnt += SIZE(TvgBinTag) + SIZE(TvgBinCounter); - } - //Bitmap picture needs the transform info. cnt += writeTransform(cTransform, TVG_TAG_PAINT_TRANSFORM); diff --git a/test/resources/tag.tvg b/test/resources/tag.tvg index 0a212831..610f1d5f 100644 Binary files a/test/resources/tag.tvg and b/test/resources/tag.tvg differ diff --git a/test/testPicture.cpp b/test/testPicture.cpp index c0c64073..21b087b5 100644 --- a/test/testPicture.cpp +++ b/test/testPicture.cpp @@ -98,67 +98,6 @@ TEST_CASE("Load RAW file and render", "[tvgPicture]") free(data); } -TEST_CASE("Texture mesh", "[tvgPicture]") -{ - auto picture = Picture::gen(); - REQUIRE(picture); - - ifstream file(TEST_DIR"/rawimage_200x300.raw"); - if (!file.is_open()) return; - auto data = (uint32_t*)malloc(sizeof(uint32_t) * (200*300)); - file.read(reinterpret_cast(data), sizeof (uint32_t) * 200 * 300); - file.close(); - - REQUIRE(picture->load(data, 200, 300, false) == Result::Success); - - //Composing Meshes - tvg::Polygon triangles[4]; - triangles[0].vertex[0] = {{100, 125}, {0, 0}}; - triangles[0].vertex[1] = {{300, 100}, {0.5, 0}}; - triangles[0].vertex[2] = {{200, 550}, {0, 1}}; - - triangles[1].vertex[0] = {{300, 100}, {0.5, 0}}; - triangles[1].vertex[1] = {{350, 450}, {0.5, 1}}; - triangles[1].vertex[2] = {{200, 550}, {0, 1}}; - - triangles[2].vertex[0] = {{300, 100}, {0.5, 0}}; - triangles[2].vertex[1] = {{500, 200}, {1, 0}}; - triangles[2].vertex[2] = {{350, 450}, {0.5, 1}}; - - triangles[3].vertex[0] = {{500, 200}, {1, 0}}; - triangles[3].vertex[1] = {{450, 450}, {1, 1}}; - triangles[3].vertex[2] = {{350, 450}, {0.5, 1}}; - - //Negative cases - const tvg::Polygon* triangles2 = nullptr; - REQUIRE(picture->mesh(nullptr, 4) == tvg::Result::InvalidArguments); - REQUIRE(picture->mesh(nullptr) == 0); - REQUIRE(picture->mesh(&triangles2) == 0); - REQUIRE(picture->mesh(triangles, 0) == tvg::Result::InvalidArguments); - REQUIRE(picture->mesh(nullptr) == 0); - REQUIRE(picture->mesh(&triangles2) == 0); - - //Positive cases - REQUIRE(picture->mesh(triangles, 4) == tvg::Result::Success); - REQUIRE(picture->mesh(nullptr) == 4); - REQUIRE(picture->mesh(&triangles2) == 4); - - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 3; j++) { - REQUIRE(triangles[i].vertex[j].pt.x == triangles2[i].vertex[j].pt.x); - REQUIRE(triangles[i].vertex[j].pt.y == triangles2[i].vertex[j].pt.y); - REQUIRE(triangles[i].vertex[j].uv.x == triangles2[i].vertex[j].uv.x); - REQUIRE(triangles[i].vertex[j].uv.y == triangles2[i].vertex[j].uv.y); - } - } - - REQUIRE(picture->mesh(nullptr, 0) == tvg::Result::Success); - REQUIRE(picture->mesh(nullptr) == 0); - REQUIRE(picture->mesh(&triangles2) == 0); - - free(data); -} - TEST_CASE("Picture Size", "[tvgPicture]") { auto picture = Picture::gen();