// --------------------------------------------------------------------------------------------- // /// Vertex type used to render a cube struct CubeVertex { /// Describes the elements each vertex contains /// An array containing a description for each element in a vertex public: static const std::array &Describe() { using namespace Nuclex::Graphics; static const std::array result = { VertexElement("Position", VertexElementType::Float3), VertexElement("TextureCoordinates", VertexElementType::Float2) }; return result; } /// Initializes a new cube vertex with the given coordinates /// X coordinate the vertex will be initialized with /// Y coordinate the vertex will be initialized with /// Z coordinate the vertex will be initialized with /// U texture coordinate the vertex will be initialized with /// V texture coordinate the vertex will be initialized with public: CubeVertex(float x, float y, float z, float u, float v) : Position(x, y, z), TextureCoordinates(u, v) {} /// Position of the vertex in 3D space public: Position3 Position; /// Texture coordinates for the polygon at the location of the vertex public: Position2 TextureCoordinates; }; // --------------------------------------------------------------------------------------------- // /// A vertex buffer that stores the vertices for a cube typedef Nuclex::Graphics::Rasterization::VertexBuffer CubeVertexBuffer; /// Constructs a cube in a vertex buffer /// A vertex buffer containing the vertices for a cube inline std::shared_ptr BuildCubeVertexBuffer() { const std::size_t vertexCount = 8; // A cube has 8 corners :o) std::shared_ptr vertexBuffer( new CubeVertexBuffer(vertexCount) ); // Filling a vertex buffer is very simple. If the vertex buffer is already being // observed, you can call SuppressNotifications() followed by ResumeNotifications() // to avoid the overhead of many short-time locks or fill the vertex buffer in one // go by using the Write(bufferStartIndex, vertex *, vertexCount) method, of course. vertexBuffer->Append(CubeVertex(-0.5f, -0.5f, -0.5f, 0.0f, 0.0f)); vertexBuffer->Append(CubeVertex(-0.5f, -0.5f, 0.5f, 0.0f, 0.0f)); vertexBuffer->Append(CubeVertex(-0.5f, 0.5f, -0.5f, 0.0f, 0.0f)); vertexBuffer->Append(CubeVertex(-0.5f, 0.5f, 0.5f, 0.0f, 0.0f)); vertexBuffer->Append(CubeVertex( 0.5f, -0.5f, -0.5f, 0.0f, 0.0f)); vertexBuffer->Append(CubeVertex( 0.5f, -0.5f, 0.5f, 0.0f, 0.0f)); vertexBuffer->Append(CubeVertex( 0.5f, 0.5f, -0.5f, 0.0f, 0.0f)); vertexBuffer->Append(CubeVertex( 0.5f, 0.5f, 0.5f, 0.0f, 0.0f)); return vertexBuffer; } // --------------------------------------------------------------------------------------------- // /// An index buffer that defines how to connect the cube's vertices typedef Nuclex::Graphics::Rasterization::IndexBuffer CubeIndexBuffer; /// Constructs a cube in a vertex buffer /// A vertex buffer containing the vertices for a cube inline std::shared_ptr BuildCubeIndexBuffer() { const std::size_t indexCount = 6 * 6; // 6 sides with 2 triangles (6 vertices) each std::shared_ptr indexBuffer( new CubeIndexBuffer(indexCount) ); // The process of filling an index buffer works exactly the same as it does // for a vertex buffer. You should call SuppressNotifications() followed by // ResumeNotifications() if you modify live index buffers or use the // Write(bufferStartIndex, index *, indexCount) method. indexBuffer->Append(0).Append(2).Append(1); // -x indexBuffer->Append(1).Append(2).Append(3); indexBuffer->Append(4).Append(5).Append(6); // +x indexBuffer->Append(5).Append(7).Append(6); indexBuffer->Append(0).Append(1).Append(5); // -y indexBuffer->Append(0).Append(5).Append(4); indexBuffer->Append(2).Append(6).Append(7); // +y indexBuffer->Append(2).Append(7).Append(3); indexBuffer->Append(0).Append(4).Append(6); // -z indexBuffer->Append(0).Append(6).Append(2); indexBuffer->Append(1).Append(3).Append(7); // +z indexBuffer->Append(1).Append(7).Append(5); return indexBuffer; } // --------------------------------------------------------------------------------------------- //