// --------------------------------------------------------------------------------------------- //
/// 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;
}
// --------------------------------------------------------------------------------------------- //