aboutsummaryrefslogtreecommitdiff
path: root/apps/openmb/renderer/primitives.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apps/openmb/renderer/primitives.cpp')
-rw-r--r--apps/openmb/renderer/primitives.cpp595
1 files changed, 595 insertions, 0 deletions
diff --git a/apps/openmb/renderer/primitives.cpp b/apps/openmb/renderer/primitives.cpp
new file mode 100644
index 0000000..245f7e1
--- /dev/null
+++ b/apps/openmb/renderer/primitives.cpp
@@ -0,0 +1,595 @@
+#include "primitives.hpp"
+
+#include <vector>
+
+#include <glm/glm.hpp>
+
+namespace renderer
+{
+ namespace primitives
+ {
+ Mesh makeCube()
+ {
+
+ std::vector< float > verts = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f,
+
+ -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
+
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
+ -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+
+ 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+
+ -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+
+ -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f,
+ 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f };
+
+ Mesh m;
+ m.createFromPositions( verts, false );
+ return m;
+ }
+
+ Mesh makeTexturedCube()
+ {
+ std::vector< float > verts;
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } );
+
+ Mesh m;
+ m.createFromPosTex( verts );
+ return m;
+ }
+
+ Mesh makeGrid( int halfSize, float spacing )
+ {
+ std::vector< float > verts;
+ for ( int i = -halfSize; i <= halfSize; ++i )
+ {
+ float x = i * spacing;
+ verts.push_back( x );
+ verts.push_back( 0.0f );
+ verts.push_back( -halfSize * spacing );
+ verts.push_back( x );
+ verts.push_back( 0.0f );
+ verts.push_back( halfSize * spacing );
+ }
+
+ for ( int j = -halfSize; j <= halfSize; ++j )
+ {
+ float z = j * spacing;
+ verts.push_back( -halfSize * spacing );
+ verts.push_back( 0.0f );
+ verts.push_back( z );
+ verts.push_back( halfSize * spacing );
+ verts.push_back( 0.0f );
+ verts.push_back( z );
+ }
+
+ Mesh m;
+ m.createFromPositions( verts, true );
+ return m;
+ }
+
+ Mesh makeTexturedGrid( int width, int depth, float tileSize )
+ {
+ std::vector< float > verts;
+
+ for ( int z = 0; z < depth; ++z )
+ {
+ for ( int x = 0; x < width; ++x )
+ {
+ float x0 = ( x - width * 0.5f ) * tileSize;
+ float z0 = ( z - depth * 0.5f ) * tileSize;
+ float x1 = x0 + tileSize;
+ float z1 = z0 + tileSize;
+
+ verts.push_back( x0 );
+ verts.push_back( 0.0f );
+ verts.push_back( z0 );
+ verts.push_back( 0.0f );
+ verts.push_back( 0.0f );
+
+ verts.push_back( x1 );
+ verts.push_back( 0.0f );
+ verts.push_back( z0 );
+ verts.push_back( 1.0f );
+ verts.push_back( 0.0f );
+
+ verts.push_back( x0 );
+ verts.push_back( 0.0f );
+ verts.push_back( z1 );
+ verts.push_back( 0.0f );
+ verts.push_back( 1.0f );
+
+ verts.push_back( x0 );
+ verts.push_back( 0.0f );
+ verts.push_back( z1 );
+ verts.push_back( 0.0f );
+ verts.push_back( 1.0f );
+
+ verts.push_back( x1 );
+ verts.push_back( 0.0f );
+ verts.push_back( z0 );
+ verts.push_back( 1.0f );
+ verts.push_back( 0.0f );
+
+ verts.push_back( x1 );
+ verts.push_back( 0.0f );
+ verts.push_back( z1 );
+ verts.push_back( 1.0f );
+ verts.push_back( 1.0f );
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTex( verts );
+ return m;
+ }
+
+ Mesh makeTexturedCubeGrid( int width, int depth, float tileSize )
+ {
+ std::vector< float > verts;
+
+ auto pushFace = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv, float cx,
+ float cy, float cz, float scale )
+ {
+ for ( int i = 0; i < 6; ++i )
+ {
+ int pi = i * 3;
+ int ui = i * 2;
+ verts.push_back( cx + pos[pi + 0] * scale );
+ verts.push_back( cy + pos[pi + 1] * scale );
+ verts.push_back( cz + pos[pi + 2] * scale );
+ verts.push_back( uv[ui + 0] );
+ verts.push_back( uv[ui + 1] );
+ }
+ };
+
+ const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f };
+ const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ for ( int z = 0; z < depth; ++z )
+ {
+ for ( int x = 0; x < width; ++x )
+ {
+ float cx = ( x - width * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cz = ( z - depth * 0.5f ) * tileSize + tileSize * 0.5f;
+
+ float cy = -0.5f * tileSize;
+ float scale = tileSize;
+
+ pushFace( topPos, topUV, cx, cy, cz, scale );
+ pushFace( bottomPos, bottomUV, cx, cy, cz, scale );
+ pushFace( frontPos, frontUV, cx, cy, cz, scale );
+ pushFace( backPos, backUV, cx, cy, cz, scale );
+ pushFace( leftPos, leftUV, cx, cy, cz, scale );
+ pushFace( rightPos, rightUV, cx, cy, cz, scale );
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTex( verts );
+ return m;
+ }
+
+ Mesh makeTexturedWall( int length, int height, float tileSize, bool alongX, float fixedCoord )
+ {
+ std::vector< float > verts;
+
+ auto pushFace = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv, float cx,
+ float cy, float cz, float scale )
+ {
+ for ( int i = 0; i < 6; ++i )
+ {
+ int pi = i * 3;
+ int ui = i * 2;
+ verts.push_back( cx + pos[pi + 0] * scale );
+ verts.push_back( cy + pos[pi + 1] * scale );
+ verts.push_back( cz + pos[pi + 2] * scale );
+ verts.push_back( uv[ui + 0] );
+ verts.push_back( uv[ui + 1] );
+ }
+ };
+
+ const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f };
+ const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ if ( alongX )
+ {
+
+ for ( int lx = 0; lx < length; ++lx )
+ {
+ float cx = ( lx - length * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cz = fixedCoord;
+ for ( int hy = 0; hy < height; ++hy )
+ {
+ float cy = 0.02f * tileSize + hy * tileSize;
+ float scale = tileSize;
+ pushFace( topPos, topUV, cx, cy, cz, scale );
+ pushFace( bottomPos, bottomUV, cx, cy, cz, scale );
+ pushFace( frontPos, frontUV, cx, cy, cz, scale );
+ pushFace( backPos, backUV, cx, cy, cz, scale );
+ pushFace( leftPos, leftUV, cx, cy, cz, scale );
+ pushFace( rightPos, rightUV, cx, cy, cz, scale );
+ }
+ }
+ }
+ else
+ {
+
+ for ( int lz = 0; lz < length; ++lz )
+ {
+ float cz = ( lz - length * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cx = fixedCoord;
+ for ( int hy = 0; hy < height; ++hy )
+ {
+ float cy = 0.02f * tileSize + hy * tileSize;
+ float scale = tileSize;
+ pushFace( topPos, topUV, cx, cy, cz, scale );
+ pushFace( bottomPos, bottomUV, cx, cy, cz, scale );
+ pushFace( frontPos, frontUV, cx, cy, cz, scale );
+ pushFace( backPos, backUV, cx, cy, cz, scale );
+ pushFace( leftPos, leftUV, cx, cy, cz, scale );
+ pushFace( rightPos, rightUV, cx, cy, cz, scale );
+ }
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTex( verts );
+ return m;
+ }
+
+ Mesh makeTexturedCubeWithNormals()
+ {
+ std::vector< float > verts;
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } );
+
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f } );
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f } );
+ verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f } );
+
+ Mesh m;
+ m.createFromPosTexNormal( verts );
+ return m;
+ }
+
+ Mesh makeTexturedGridWithNormals( int width, int depth, float tileSize )
+ {
+ std::vector< float > verts;
+
+ for ( int z = 0; z < depth; ++z )
+ {
+ for ( int x = 0; x < width; ++x )
+ {
+ float x0 = ( x - width * 0.5f ) * tileSize;
+ float z0 = ( z - depth * 0.5f ) * tileSize;
+ float x1 = x0 + tileSize;
+ float z1 = z0 + tileSize;
+
+ verts.insert( verts.end(), { x0, 0.0f, z0, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { x1, 0.0f, z0, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { x0, 0.0f, z1, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+
+ verts.insert( verts.end(), { x0, 0.0f, z1, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { x1, 0.0f, z0, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } );
+ verts.insert( verts.end(), { x1, 0.0f, z1, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } );
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTexNormal( verts );
+ return m;
+ }
+
+ Mesh makeTexturedCubeGridWithNormals( int width, int depth, float tileSize )
+ {
+ std::vector< float > verts;
+
+ auto pushFaceWithNormal = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv,
+ const glm::vec3 &normal, float cx, float cy, float cz, float scale )
+ {
+ for ( int i = 0; i < 6; ++i )
+ {
+ int pi = i * 3;
+ int ui = i * 2;
+ verts.push_back( cx + pos[pi + 0] * scale );
+ verts.push_back( cy + pos[pi + 1] * scale );
+ verts.push_back( cz + pos[pi + 2] * scale );
+ verts.push_back( uv[ui + 0] );
+ verts.push_back( uv[ui + 1] );
+ verts.push_back( normal.x );
+ verts.push_back( normal.y );
+ verts.push_back( normal.z );
+ }
+ };
+
+ const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f };
+ const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ for ( int z = 0; z < depth; ++z )
+ {
+ for ( int x = 0; x < width; ++x )
+ {
+ float cx = ( x - width * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cz = ( z - depth * 0.5f ) * tileSize + tileSize * 0.5f;
+
+ float cy = -0.5f * tileSize;
+ float scale = tileSize;
+
+ pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTexNormal( verts );
+ return m;
+ }
+
+ Mesh makeTexturedWallWithNormals( int length, int height, float tileSize, bool alongX, float fixedCoord )
+ {
+ std::vector< float > verts;
+
+ auto pushFaceWithNormal = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv,
+ const glm::vec3 &normal, float cx, float cy, float cz, float scale )
+ {
+ for ( int i = 0; i < 6; ++i )
+ {
+ int pi = i * 3;
+ int ui = i * 2;
+ verts.push_back( cx + pos[pi + 0] * scale );
+ verts.push_back( cy + pos[pi + 1] * scale );
+ verts.push_back( cz + pos[pi + 2] * scale );
+ verts.push_back( uv[ui + 0] );
+ verts.push_back( uv[ui + 1] );
+ verts.push_back( normal.x );
+ verts.push_back( normal.y );
+ verts.push_back( normal.z );
+ }
+ };
+
+ const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f };
+ const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
+ -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
+ -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f };
+ const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
+ 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f };
+ const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f };
+
+ if ( alongX )
+ {
+ for ( int lx = 0; lx < length; ++lx )
+ {
+ float cx = ( lx - length * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cz = fixedCoord;
+ for ( int hy = 0; hy < height; ++hy )
+ {
+ float cy = hy * tileSize + tileSize * 0.5f;
+ float scale = tileSize;
+ pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ }
+ }
+ }
+ else
+ {
+ for ( int lz = 0; lz < length; ++lz )
+ {
+ float cz = ( lz - length * 0.5f ) * tileSize + tileSize * 0.5f;
+ float cx = fixedCoord;
+ for ( int hy = 0; hy < height; ++hy )
+ {
+ float cy = hy * tileSize + tileSize * 0.5f;
+ float scale = tileSize;
+ pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale );
+ }
+ }
+ }
+
+ Mesh m;
+ m.createFromPosTexNormal( verts );
+ return m;
+ }
+
+ } // namespace primitives
+
+} // namespace renderer