diff --git a/src/Magnum/Primitives/Cube.h b/src/Magnum/Primitives/Cube.h index a84b85787..c62cd86e5 100644 --- a/src/Magnum/Primitives/Cube.h +++ b/src/Magnum/Primitives/Cube.h @@ -56,7 +56,11 @@ with @ref VertexFormat::Vector3 positions. The returned instance references data stored in constant memory. No normals or anything else --- use @ref cubeSolid() instead if you need these. -@image html primitives-cubesolid.png width=256px +Vertex positions of this mesh can be also generated directly in the vertex +shader using @glsl gl_VertexID @ce ([source](https://twitter.com/turanszkij/status/1141638406956617730), +adapted to exactly match the output of this function): + +@snippet Magnum/Primitives/Test/data.glsl cubeSolidStrip @see @ref cubeWireframe(), @ref MeshTools::generateTriangleStripIndices() */ diff --git a/src/Magnum/Primitives/Test/CubeTest.cpp b/src/Magnum/Primitives/Test/CubeTest.cpp index 3c0c1ad14..019dff171 100644 --- a/src/Magnum/Primitives/Test/CubeTest.cpp +++ b/src/Magnum/Primitives/Test/CubeTest.cpp @@ -26,6 +26,7 @@ #include #include "Magnum/Mesh.h" +#include "Magnum/Math/Functions.h" #include "Magnum/Math/Vector3.h" #include "Magnum/Primitives/Cube.h" #include "Magnum/Trade/MeshData.h" @@ -37,12 +38,14 @@ struct CubeTest: TestSuite::Tester { void solid(); void solidStrip(); + void solidStripGlsl(); void wireframe(); }; CubeTest::CubeTest() { addTests({&CubeTest::solid, &CubeTest::solidStrip, + &CubeTest::solidStripGlsl, &CubeTest::wireframe}); } @@ -72,6 +75,25 @@ void CubeTest::solidStrip() { (Vector3{-1.0f, -1.0f, -1.0f})); } +void CubeTest::solidStripGlsl() { + Trade::MeshData cube = Primitives::cubeSolidStrip(); + + /* Yes, really. */ + auto solidStripVertex = [](UnsignedInt gl_VertexID) { + typedef Vector3 vec3; + #define mix Math::lerp + #include "data.glsl" + #undef mix + return corner; + }; + + auto vertices = cube.attribute(Trade::MeshAttribute::Position); + for(UnsignedInt i = 0; i != cube.vertexCount(); ++i) { + CORRADE_ITERATION(i); + CORRADE_COMPARE(solidStripVertex(i), vertices[i]); + } +} + void CubeTest::wireframe() { Trade::MeshData cube = Primitives::cubeWireframe(); diff --git a/src/Magnum/Primitives/Test/data.glsl b/src/Magnum/Primitives/Test/data.glsl new file mode 100644 index 000000000..4ad329b08 --- /dev/null +++ b/src/Magnum/Primitives/Test/data.glsl @@ -0,0 +1,31 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + 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. +*/ + +/* [cubeSolidStrip] */ +int b = 1 << gl_VertexID; +vec3 corner = vec3(mix(-1.0, 1.0, bool(0xd785 & b)), + mix(-1.0, 1.0, bool(0x31e3 & b)), + mix(-1.0, 1.0, bool(0x02af & b))); +/* [cubeSolidStrip] */