From 2ec3ed36736106dfec447e84fccaa1d7352e0b70 Mon Sep 17 00:00:00 2001 From: gered Date: Mon, 1 Apr 2013 17:14:05 -0400 Subject: [PATCH] update VertexBuffer to use Initialize() methods to setup itself instead of the constructor. vertex attributes are now passed as an array instead of using "Add" methods --- src/framework/graphics/vertexbuffer.cpp | 309 ++++++++++++------------ src/framework/graphics/vertexbuffer.h | 211 +++++++--------- 2 files changed, 240 insertions(+), 280 deletions(-) diff --git a/src/framework/graphics/vertexbuffer.cpp b/src/framework/graphics/vertexbuffer.cpp index 68274f3..9e63bdf 100644 --- a/src/framework/graphics/vertexbuffer.cpp +++ b/src/framework/graphics/vertexbuffer.cpp @@ -7,8 +7,7 @@ const unsigned int FLOATS_PER_GPU_ATTRIB_SLOT = 4; const unsigned int MAX_GPU_ATTRIB_SLOTS = 8; -VertexBuffer::VertexBuffer(BUFFEROBJECT_USAGE usage) - : BufferObject(BUFFEROBJECT_TYPE_VERTEX, usage) +VertexBuffer::VertexBuffer() { STACK_TRACE; m_numVertices = 0; @@ -20,6 +19,8 @@ VertexBuffer::VertexBuffer(BUFFEROBJECT_USAGE usage) m_position3Offset = 0; m_normalOffset = 0; m_texCoordOffset = 0; + m_numAttributes = 0; + m_attribs = NULL; m_numGPUAttributeSlotsUsed = 0; } @@ -28,200 +29,186 @@ VertexBuffer::~VertexBuffer() STACK_TRACE; } -BOOL VertexBuffer::AddAttribute(uint32_t size, VERTEX_ATTRIBS standardType) +BOOL VertexBuffer::Initialize(const VERTEX_ATTRIBS *attributes, uint32_t numAttributes, uint32_t numVertices, BUFFEROBJECT_USAGE usage) { STACK_TRACE; - ASSERT(standardType == VERTEX_GENERIC || HasStandardAttrib(standardType) == FALSE); - ASSERT(size <= 16); + return Initialize(NULL, attributes, numAttributes, numVertices, usage); +} - if (standardType != VERTEX_GENERIC && HasStandardAttrib(standardType)) +BOOL VertexBuffer::Initialize(GraphicsDevice *graphicsDevice, const VERTEX_ATTRIBS *attributes, uint32_t numAttributes, uint32_t numVertices, BUFFEROBJECT_USAGE usage) +{ + STACK_TRACE; + ASSERT(m_buffer.size() == 0); + if (m_buffer.size() > 0) return FALSE; - if (size > 16) + + if (!BufferObject::Initialize(graphicsDevice, BUFFEROBJECT_TYPE_VERTEX, usage)) return FALSE; - - // using integer division that rounds up (so given size = 13, result is 4, not 3) - uint32_t numGPUAttributeSlotsUsed = (size + (FLOATS_PER_GPU_ATTRIB_SLOT - 1)) / FLOATS_PER_GPU_ATTRIB_SLOT; - ASSERT(m_numGPUAttributeSlotsUsed + numGPUAttributeSlotsUsed <= MAX_GPU_ATTRIB_SLOTS); - if (m_numGPUAttributeSlotsUsed + numGPUAttributeSlotsUsed > MAX_GPU_ATTRIB_SLOTS) + + if (!SetSizesAndOffsets(attributes, numAttributes)) return FALSE; - - VertexBufferAttribute newAttrib; - newAttrib.standardType = standardType; - newAttrib.size = size; - newAttrib.offset = m_elementWidth; - - switch (standardType) - { - case VERTEX_POS_2D: - ASSERT(size == 2); - if (size != 2) - return FALSE; - m_position2Offset = newAttrib.offset; - break; - case VERTEX_POS_3D: - ASSERT(size == 3); - if (size != 3) - return FALSE; - m_position3Offset = newAttrib.offset; - break; - case VERTEX_NORMAL: - ASSERT(size == 3); - if (size != 3) - return FALSE; - m_normalOffset = newAttrib.offset; - break; - case VERTEX_COLOR: - ASSERT(size == 4); - if (size != 4) - return FALSE; - m_colorOffset = newAttrib.offset; - break; - case VERTEX_TEXCOORD: - ASSERT(size == 2); - if (size != 2) - return FALSE; - m_texCoordOffset = newAttrib.offset; - break; - case VERTEX_GENERIC: - break; - } - - m_attribs.push_back(newAttrib); - - m_elementWidth += size; - m_numGPUAttributeSlotsUsed += numGPUAttributeSlotsUsed; - SetBit(standardType, m_standardTypeAttribs); - + + Resize(numVertices); + return TRUE; } -BOOL VertexBuffer::AddAttribute(VERTEX_ATTRIBS standardType) +BOOL VertexBuffer::Initialize(const VertexBuffer *source) { STACK_TRACE; - ASSERT(standardType != VERTEX_GENERIC); - if (standardType == VERTEX_GENERIC) - return FALSE; - - ASSERT(HasStandardAttrib(standardType) == FALSE); - if (HasStandardAttrib(standardType)) - return FALSE; - - BOOL result = FALSE; - - switch (standardType) - { - case VERTEX_POS_2D: - result = AddAttribute(ATTRIB_SIZE_VEC2, VERTEX_POS_2D); - break; - case VERTEX_POS_3D: - result = AddAttribute(ATTRIB_SIZE_VEC3, VERTEX_POS_3D); - break; - case VERTEX_NORMAL: - result = AddAttribute(ATTRIB_SIZE_VEC3, VERTEX_NORMAL); - break; - case VERTEX_COLOR: - result = AddAttribute(ATTRIB_SIZE_VEC4, VERTEX_COLOR); - break; - case VERTEX_TEXCOORD: - result = AddAttribute(ATTRIB_SIZE_VEC2, VERTEX_TEXCOORD); - break; - case VERTEX_GENERIC: - break; - } - - return result; + return Initialize(NULL, source); } -BOOL VertexBuffer::CopyAttributesFrom(const VertexBuffer *source) +BOOL VertexBuffer::Initialize(GraphicsDevice *graphicsDevice, const VertexBuffer *source) { STACK_TRACE; - ASSERT(source != NULL); - if (source == NULL) - return FALSE; - - ASSERT(source->GetNumAttributes() != 0); ASSERT(m_buffer.size() == 0); - - if (source->GetNumAttributes() == 0) - return FALSE; if (m_buffer.size() > 0) return FALSE; - m_attribs.clear(); - for (uint32_t i = 0; i < source->GetNumAttributes(); ++i) + ASSERT(source != NULL); + if (source == NULL) + return FALSE; + + ASSERT(source->GetNumElements() > 0); + if (source->GetNumElements() == 0) + return FALSE; + + if (!BufferObject::Initialize(graphicsDevice, BUFFEROBJECT_TYPE_VERTEX, source->GetUsage())) + return FALSE; + + uint32_t numAttribs = source->GetNumAttributes(); + VERTEX_ATTRIBS *attribs = new VERTEX_ATTRIBS[numAttribs]; + for (uint32_t i = 0; i < numAttribs; ++i) + attribs[i] = source->GetAttributeInfo(i)->standardType; + + BOOL success = SetSizesAndOffsets(attribs, numAttribs); + if (success) { - const VertexBufferAttribute *sourceAttrib = source->GetAttributeInfo(i); - AddAttribute(sourceAttrib->size, sourceAttrib->standardType); + Resize(source->GetNumElements()); + Copy(source, 0); } - - return TRUE; + + SAFE_DELETE_ARRAY(attribs); + + return success; } -int32_t VertexBuffer::GetIndexOfStandardAttrib(VERTEX_ATTRIBS standardAttrib) const +BOOL VertexBuffer::SetSizesAndOffsets(const VERTEX_ATTRIBS *attributes, uint32_t numAttributes) { STACK_TRACE; - ASSERT(standardAttrib != VERTEX_GENERIC); - if (standardAttrib == VERTEX_GENERIC) - return -1; - - for (uint32_t i = 0; i < m_attribs.size(); ++i) + ASSERT(attributes != NULL); + ASSERT(numAttributes > 0); + ASSERT(m_buffer.size() == 0); + ASSERT(m_attribs == NULL); + + if (attributes == NULL) + return FALSE; + if (numAttributes == 0) + return FALSE; + if (m_buffer.size() > 0) + return FALSE; + if (m_attribs != NULL) + return FALSE; + + uint32_t numGpuSlotsUsed = 0; + uint32_t offset = 0; + + VertexBufferAttribute *attribsInfo = new VertexBufferAttribute[numAttributes]; + BOOL success = TRUE; + + for (uint32_t i = 0; i < numAttributes; ++i) { - if (m_attribs[i].standardType == standardAttrib) + VERTEX_ATTRIBS attrib = attributes[i]; + + // TODO: endianness + uint8_t size = (uint8_t)attrib; // low byte + uint8_t standardTypeBitMask = (uint8_t)((uint16_t)attrib >> 8); + + // using integer division that rounds up (so given size = 13, result is 4, not 3) + uint32_t thisAttribsGpuSlotSize = ((uint32_t)size + (FLOATS_PER_GPU_ATTRIB_SLOT - 1)) / FLOATS_PER_GPU_ATTRIB_SLOT; + ASSERT(numGpuSlotsUsed + thisAttribsGpuSlotSize <= MAX_GPU_ATTRIB_SLOTS); + if (numGpuSlotsUsed + thisAttribsGpuSlotSize > MAX_GPU_ATTRIB_SLOTS) + { + success = FALSE; + break; + } + + if (standardTypeBitMask > 0) + { + // ensure no duplicate standard attribute types are specified + ASSERT(IsBitSet(standardTypeBitMask, m_standardTypeAttribs) == FALSE); + if (IsBitSet(standardTypeBitMask, m_standardTypeAttribs)) + { + success = FALSE; + break; + } + + SetBit(standardTypeBitMask, m_standardTypeAttribs); + + // record offset position for each standard type attribute + switch ((VERTEX_STANDARD_ATTRIBS)attrib) + { + case VERTEX_STD_POS_2D: m_position2Offset = offset; break; + case VERTEX_STD_POS_3D: m_position3Offset = offset; break; + case VERTEX_STD_NORMAL: m_normalOffset = offset; break; + case VERTEX_STD_COLOR: m_colorOffset = offset; break; + case VERTEX_STD_TEXCOORD: m_texCoordOffset = offset; break; + } + } + + // set attribute info + attribsInfo[i].offset = offset; + attribsInfo[i].size = size; + attribsInfo[i].standardType = attrib; + + // advance to the next spot + m_elementWidth += size; + offset += size; + numGpuSlotsUsed += thisAttribsGpuSlotSize; + } + + if (!success) + { + SAFE_DELETE_ARRAY(attribsInfo) + m_attribs = NULL; + m_numAttributes = 0; + m_elementWidth = 0; + + m_position2Offset = 0; + m_position3Offset = 0; + m_normalOffset = 0; + m_colorOffset = 0; + m_texCoordOffset = 0; + } + else + { + m_attribs = attribsInfo; + m_numAttributes = numAttributes; + } + + return success; +} + +int32_t VertexBuffer::GetIndexOfStandardAttrib(VERTEX_STANDARD_ATTRIBS standardAttrib) const +{ + STACK_TRACE; + for (uint32_t i = 0; i < m_numAttributes; ++i) + { + if ((uint32_t)m_attribs[i].standardType == (uint32_t)standardAttrib) return (int32_t)i; } return -1; } -BOOL VertexBuffer::Create(uint32_t numVertices) -{ - STACK_TRACE; - ASSERT(m_attribs.size() > 0); - ASSERT(m_buffer.size() == 0); - ASSERT(m_elementWidth > 0); - - if (m_attribs.size() == 0) - return FALSE; - if (m_buffer.size() > 0) - return FALSE; - if (m_elementWidth == 0) - return FALSE; - - Resize(numVertices); - - return TRUE; -} - -BOOL VertexBuffer::CreateCopyOf(const VertexBuffer *source) -{ - STACK_TRACE; - ASSERT(source != NULL); - if (source == NULL) - return FALSE; - - ASSERT(source->GetNumElements() != 0); - ASSERT(m_buffer.size() == 0); - - if (source->GetNumElements() == 0) - return FALSE; - if (m_buffer.size() > 0) - return FALSE; - - BOOL attribCopyResult = CopyAttributesFrom(source); - if (!attribCopyResult) - return FALSE; - - Resize(source->GetNumElements()); - - memcpy(&m_buffer[0], source->GetBuffer(), GetNumElements() * GetElementWidthInBytes()); - - return TRUE; -} - - void VertexBuffer::Resize(uint32_t numVertices) { STACK_TRACE; + ASSERT(numVertices > 0); + if (numVertices == 0) + return; + m_buffer.resize(numVertices * m_elementWidth, 0.0f); m_numVertices = numVertices; diff --git a/src/framework/graphics/vertexbuffer.h b/src/framework/graphics/vertexbuffer.h index ad70943..8930d8d 100644 --- a/src/framework/graphics/vertexbuffer.h +++ b/src/framework/graphics/vertexbuffer.h @@ -16,6 +16,8 @@ #include "vertexattribs.h" +class GraphicsDevice; + /** * Wraps management of an array of vertices stored either completely * in main memory (client-side) or in video memory. @@ -23,75 +25,67 @@ class VertexBuffer : public BufferObject { public: - /** - * Creates an uninitialized vertex buffer object. - * @param usage the expected usage pattern of this vertex buffer - */ - VertexBuffer(BUFFEROBJECT_USAGE usage); - - /** - * Creates a vertex buffer. - * @param source the source buffer to copy during creation of this buffer - */ - VertexBuffer(const VertexBuffer *source); - + VertexBuffer(); virtual ~VertexBuffer(); - + /** - * Adds an attribute to the vertex buffer. - * @param size the size of the attribute's data (specified in number of floats) - * @param standardType the standard type mapping for ease of use (allowing - * use of special get/set methods for type safety) + * Initializes the vertex buffer. + * @param attributes the vertex attributes this buffer will contain + * @param numAttributes the number of vertex attributes + * @param numVertices the initial number of vertices this buffer will contain + * @param usage the expected usage pattern of this vertex buffer * @return TRUE if successful, FALSE if not */ - BOOL AddAttribute(uint32_t size, VERTEX_ATTRIBS standardType = VERTEX_GENERIC); + BOOL Initialize(const VERTEX_ATTRIBS *attributes, uint32_t numAttributes, uint32_t numVertices, BUFFEROBJECT_USAGE usage); /** - * Adds an attribute to the vertex buffer. - * @param size the size of the attribute's data - * @param standardType the standard type mapping for ease of use (allowing - * use of special get/set methods for type safety) + * Initializes the vertex buffer. + * @param graphicsDevice the graphics device to use to create this buffer + * on the GPU + * @param attributes the vertex attributes this buffer will contain + * @param numAttributes the number of vertex attributes + * @param numVertices the initial number of vertices this buffer will contain + * @param usage the expected usage pattern of this vertex buffer * @return TRUE if successful, FALSE if not */ - BOOL AddAttribute(VERTEX_ATTRIB_SIZES size, VERTEX_ATTRIBS standardType = VERTEX_GENERIC); + BOOL Initialize(GraphicsDevice *graphicsDevice, const VERTEX_ATTRIBS *attributes, uint32_t numAttributes, uint32_t numVertices, BUFFEROBJECT_USAGE usage); + + /** + * Initializes the vertex buffer. + * @param source the source buffer to create this buffer from. it's + * properties and vertex data will be used to create this one + * @return TRUE if successful, FALSE if not + */ + BOOL Initialize(const VertexBuffer *source); /** - * Adds an attribute which will be used for one of the standard types of - * data (e.g. 2D/3D vertex position, color, texture coordinates, etc). The - * other attribute information, like size, will be automatically set. - * @param standardType the standard type of the attribute. Cannot be - * VERTEX_GENERIC. + * Initializes the vertex buffer. + * @param graphicsDevice the graphics device to use to create this buffer + * on the GPU + * @param source the source buffer to create this buffer from. it's + * properties and vertex data will be used to create this one * @return TRUE if successful, FALSE if not */ - BOOL AddAttribute(VERTEX_ATTRIBS standardType); - - /** - * Sets this vertex buffer's attributes to match those from a source - * vertex buffer. Any existing attribute information that has been set - * in this vertex buffer will be cleared. - * @param source the source buffer to copy attribute information from - * @return TRUE if successful, FALSE if not - */ - BOOL CopyAttributesFrom(const VertexBuffer *source); + BOOL Initialize(GraphicsDevice *graphicsDevice, const VertexBuffer *source); /** * @return the number of attributes in this vertex buffer */ - uint32_t GetNumAttributes() const { return m_attribs.size(); } + uint32_t GetNumAttributes() const { return m_numAttributes; } /** * Returns information about the specified attribute. * @param index the index of the attribute to get information about * @return the attribute's information */ - const VertexBufferAttribute* GetAttributeInfo(uint32_t index) const { return &m_attribs[index]; } + const VertexBufferAttribute* GetAttributeInfo(uint32_t index) const { return &m_attribs[index]; } /** * @return the standard attributes included in this buffer's data. Note * that this is not necessarily all of the attributes contained in * this buffer. */ - uint32_t GetStandardAttribs() const { return m_standardTypeAttribs; } + uint32_t GetStandardAttribs() const { return m_standardTypeAttribs; } /** * Checks whether this buffer's vertex data includes the specified standard @@ -100,93 +94,74 @@ public: * @return TRUE if the vertex data in this buffer contains this standard * attribute */ - BOOL HasStandardAttrib(VERTEX_ATTRIBS standardAttrib) const { return (m_standardTypeAttribs & standardAttrib) > 0; } + BOOL HasStandardAttrib(VERTEX_STANDARD_ATTRIBS standardAttrib) const { return (m_standardTypeAttribs & (uint32_t)standardAttrib) > 0; } /** * Returns the index of the specified standard attribute. * @param standardAttrib the standard attribute to get the index of * @return the index of the attribute, or -1 if it is not present */ - int32_t GetIndexOfStandardAttrib(VERTEX_ATTRIBS standardAttrib) const; - - /** - * Allocates the client-side memory buffer for this vertex buffer. All - * attributes must have been added via AddAttribute() before this call. No - * more can be added after this call. - * @param numVertices the initial number of vertices this buffer should hold - * @return TRUE if successful, FALSE if not - */ - BOOL Create(uint32_t numVertices); - - /** - * Sets up attributes and data to match a source vertex buffer, making an - * exact copy. Any existing attribute definitions made via AddAttribute() - * before this call will be ignored. No more attributes can be added after - * this call. - * @param source the source buffer to copy - * @return TRUE if successful, FALSE if not - */ - BOOL CreateCopyOf(const VertexBuffer *source); + int32_t GetIndexOfStandardAttrib(VERTEX_STANDARD_ATTRIBS standardAttrib) const; /** * @return the offset from the start of a single vertex's data that the * color attribute starts at (in floats) */ - uint32_t GetColorOffset() const { return m_colorOffset; } + uint32_t GetColorOffset() const { return m_colorOffset; } /** * @return the offset from the start of a single vertex's data that the * 3D position attribute starts at (in floats) */ - uint32_t GetPosition3Offset() const { return m_position3Offset; } + uint32_t GetPosition3Offset() const { return m_position3Offset; } /** * @return the offset from the start of a single vertex's data that the * 2D position attribute starts at (in floats) */ - uint32_t GetPosition2Offset() const { return m_position2Offset; } + uint32_t GetPosition2Offset() const { return m_position2Offset; } /** * @return the offset from the start of a single vertex's data that the * normal attribute starts at (in floats) */ - uint32_t GetNormalOffset() const { return m_normalOffset; } + uint32_t GetNormalOffset() const { return m_normalOffset; } /** * @return the offset from the start of a single vertex's data that the * texture coordinate attribute starts at (in floats) */ - uint32_t GetTexCoordOffset() const { return m_texCoordOffset; } + uint32_t GetTexCoordOffset() const { return m_texCoordOffset; } /** * @return the offset from the start of a single vertex's data that the * color attribute starts at (in bytes) */ - uint32_t GetColorOffsetBytes() const { return m_colorOffset * sizeof(float); } + uint32_t GetColorOffsetBytes() const { return m_colorOffset * sizeof(float); } /** * @return the offset from the start of a single vertex's data that the * 3D position attribute starts at (in bytes) */ - uint32_t GetPosition3OffsetBytes() const { return m_position3Offset * sizeof(float); } + uint32_t GetPosition3OffsetBytes() const { return m_position3Offset * sizeof(float); } /** * @return the offset from the start of a single vertex's data that the * 2D position attribute starts at (in bytes) */ - uint32_t GetPosition2OffsetBytes() const { return m_position2Offset * sizeof(float); } + uint32_t GetPosition2OffsetBytes() const { return m_position2Offset * sizeof(float); } /** * @return the offset from the start of a single vertex's data that the * normal attribute starts at (in bytes) */ - uint32_t GetNormalOffsetBytes() const { return m_normalOffset * sizeof(float); } + uint32_t GetNormalOffsetBytes() const { return m_normalOffset * sizeof(float); } /** * @return the offset from the start of a single vertex's data that the * texture coordinate attribute starts at (in bytes) */ - uint32_t GetTexCoordOffsetBytes() const { return m_texCoordOffset * sizeof(float); } + uint32_t GetTexCoordOffsetBytes() const { return m_texCoordOffset * sizeof(float); } /** * @param index the vertex to get the color data for @@ -237,27 +212,27 @@ public: /** * @return the current vertex's color data */ - Color GetCurrentColor() const { return GetColor(GetCurrentPosition()); } + Color GetCurrentColor() const { return GetColor(GetCurrentPosition()); } /** * @return the current vertex's 3D position data */ - Vector3 GetCurrentPosition3() const { return GetPosition3(GetCurrentPosition()); } + Vector3 GetCurrentPosition3() const { return GetPosition3(GetCurrentPosition()); } /** * @return the current vertex's 2D position data */ - Vector2 GetCurrentPosition2() const { return GetPosition2(GetCurrentPosition()); } + Vector2 GetCurrentPosition2() const { return GetPosition2(GetCurrentPosition()); } /** * @return the current vertex's normal data */ - Vector3 GetCurrentNormal() const { return GetNormal(GetCurrentPosition()); } + Vector3 GetCurrentNormal() const { return GetNormal(GetCurrentPosition()); } /** * @return the current vertex's texture coordinate data */ - Vector2 GetCurrentTexCoord() const { return GetTexCoord(GetCurrentPosition()); } + Vector2 GetCurrentTexCoord() const { return GetTexCoord(GetCurrentPosition()); } void GetCurrent1f(uint32_t attrib, float &x) const { Get1f(attrib, GetCurrentPosition(), x); } float GetCurrent1f(uint32_t attrib) const { return Get1f(attrib, GetCurrentPosition()); } @@ -377,7 +352,7 @@ public: * Sets the current vertex's color attribute. * @param color the new color attribute to set */ - void SetCurrentColor(const Color &color) { SetColor(GetCurrentPosition(), color); } + void SetCurrentColor(const Color &color) { SetColor(GetCurrentPosition(), color); } /** * Sets the current vertex's color attribute. @@ -385,7 +360,7 @@ public: * @param g green component of the color attribute to set * @param b blue component of the color attribute to set */ - void SetCurrentColor(float r, float g, float b) { SetColor(GetCurrentPosition(), r, g, b); } + void SetCurrentColor(float r, float g, float b) { SetColor(GetCurrentPosition(), r, g, b); } /** * Sets the current vertex's color attribute. @@ -394,13 +369,13 @@ public: * @param b blue component of the color attribute to set * @param a alpha component of the color attribute to set */ - void SetCurrentColor(float r, float g, float b, float a) { SetColor(GetCurrentPosition(), r, g, b, a); } + void SetCurrentColor(float r, float g, float b, float a) { SetColor(GetCurrentPosition(), r, g, b, a); } /** * Sets the current vertex's 3D position attribute. * @param position the new 3D position attribute to set */ - void SetCurrentPosition3(const Vector3 &position) { SetPosition3(GetCurrentPosition(), position); } + void SetCurrentPosition3(const Vector3 &position) { SetPosition3(GetCurrentPosition(), position); } /** * Sets the current vertex's 3D position attribute. @@ -408,26 +383,26 @@ public: * @param y Y coordinate of the 3D position attribute to set * @param z Z coordinate of the 3D position attribute to set */ - void SetCurrentPosition3(float x, float y, float z) { SetPosition3(GetCurrentPosition(), x, y, z); } + void SetCurrentPosition3(float x, float y, float z) { SetPosition3(GetCurrentPosition(), x, y, z); } /** * Sets the current vertex's 2D position attribute. * @param position the new 2D position attribute to set */ - void SetCurrentPosition2(const Vector2 &position) { SetPosition2(GetCurrentPosition(), position); } + void SetCurrentPosition2(const Vector2 &position) { SetPosition2(GetCurrentPosition(), position); } /** * Sets the current vertex's 2D position attribute. * @param x X coordinate of the 2D position attribute to set * @param y Y coordinate of the 2D position attribute to set */ - void SetCurrentPosition2(float x, float y) { SetPosition2(GetCurrentPosition(), x, y); } + void SetCurrentPosition2(float x, float y) { SetPosition2(GetCurrentPosition(), x, y); } /** * Sets the current vertex's normal attribute. * @param position the new normal attribute to set */ - void SetCurrentNormal(const Vector3 &normal) { SetNormal(GetCurrentPosition(), normal); } + void SetCurrentNormal(const Vector3 &normal) { SetNormal(GetCurrentPosition(), normal); } /** * Sets the current vertex's normal attribute. @@ -435,30 +410,30 @@ public: * @param y Y coordinate of the normal attribute to set * @param z Z coordinate of the normal attribute to set */ - void SetCurrentNormal(float x, float y, float z) { SetNormal(GetCurrentPosition(), x, y, z); } + void SetCurrentNormal(float x, float y, float z) { SetNormal(GetCurrentPosition(), x, y, z); } /** * Sets the current vertex's texture coordinate attribute. * @param texCoord the new texture coordinate attribute to set */ - void SetCurrentTexCoord(const Vector2 &texCoord) { SetTexCoord(GetCurrentPosition(), texCoord); } + void SetCurrentTexCoord(const Vector2 &texCoord) { SetTexCoord(GetCurrentPosition(), texCoord); } /** * Sets the current vertex's texture coordinate attribute. * @param x U coordinate of the texture coordinate attribute to set * @param y V coordinate of the texture coordinate attribute to set */ - void SetCurrentTexCoord(float x, float y) { SetTexCoord(GetCurrentPosition(), x, y); } + void SetCurrentTexCoord(float x, float y) { SetTexCoord(GetCurrentPosition(), x, y); } - void SetCurrent1f(uint32_t attrib, float x) { Set1f(attrib, GetCurrentPosition(), x); } - void SetCurrent2f(uint32_t attrib, float x, float y) { Set2f(attrib, GetCurrentPosition(), x, y); } - void SetCurrent2f(uint32_t attrib, const Vector2 &v) { Set2f(attrib, GetCurrentPosition(), v); } - void SetCurrent3f(uint32_t attrib, float x, float y, float z) { Set3f(attrib, GetCurrentPosition(), x, y, z); } - void SetCurrent3f(uint32_t attrib, const Vector3 &v) { Set3f(attrib, GetCurrentPosition(), v); } - void SetCurrent4f(uint32_t attrib, float x, float y, float z, float w) { Set4f(attrib, GetCurrentPosition(), x, y, z, w); } - void SetCurrent4f(uint32_t attrib, const Color &c) { Set4f(attrib, GetCurrentPosition(), c); } - void SetCurrent9f(uint32_t attrib, const Matrix3x3 &m) { Set9f(attrib, GetCurrentPosition(), m); } - void SetCurrent16f(uint32_t attrib, const Matrix4x4 &m) { Set16f(attrib, GetCurrentPosition(), m); } + void SetCurrent1f(uint32_t attrib, float x) { Set1f(attrib, GetCurrentPosition(), x); } + void SetCurrent2f(uint32_t attrib, float x, float y) { Set2f(attrib, GetCurrentPosition(), x, y); } + void SetCurrent2f(uint32_t attrib, const Vector2 &v) { Set2f(attrib, GetCurrentPosition(), v); } + void SetCurrent3f(uint32_t attrib, float x, float y, float z) { Set3f(attrib, GetCurrentPosition(), x, y, z); } + void SetCurrent3f(uint32_t attrib, const Vector3 &v) { Set3f(attrib, GetCurrentPosition(), v); } + void SetCurrent4f(uint32_t attrib, float x, float y, float z, float w) { Set4f(attrib, GetCurrentPosition(), x, y, z, w); } + void SetCurrent4f(uint32_t attrib, const Color &c) { Set4f(attrib, GetCurrentPosition(), c); } + void SetCurrent9f(uint32_t attrib, const Matrix3x3 &m) { Set9f(attrib, GetCurrentPosition(), m); } + void SetCurrent16f(uint32_t attrib, const Matrix4x4 &m) { Set16f(attrib, GetCurrentPosition(), m); } /** * Moves the current vertex position to the next position. @@ -487,18 +462,18 @@ public: /** * Moves the current vertex position to the beginning of the buffer. */ - void MoveToStart() { m_currentVertex = 0; } + void MoveToStart() { m_currentVertex = 0; } /** * Moves the current vertex position to the end of the buffer. */ - void MoveToEnd() { m_currentVertex = GetNumElements() - 1; } + void MoveToEnd() { m_currentVertex = GetNumElements() - 1; } /** * Moves the current vertex position to the position specified. * @param index the position to move to */ - void MoveTo(uint32_t index) { m_currentVertex = index; } + void MoveTo(uint32_t index) { m_currentVertex = index; } /** * Resizes the buffer capacity to hold the specified number of vertices. @@ -525,39 +500,41 @@ public: /** * @return the number of vertices contained in this buffer */ - uint32_t GetNumElements() const { return m_numVertices; } + uint32_t GetNumElements() const { return m_numVertices; } /** * @return the size in bytes of each vertex in this buffer object */ - size_t GetElementWidthInBytes() const { return m_elementWidth * sizeof(float); } + size_t GetElementWidthInBytes() const { return m_elementWidth * sizeof(float); } /** * @return pointer to this buffer object's raw data */ - const void* GetBuffer() const { return &m_buffer[0]; } + const void* GetBuffer() const { return &m_buffer[0]; } /** * @return the current position in the buffer */ - uint32_t GetCurrentPosition() const { return m_currentVertex; } + uint32_t GetCurrentPosition() const { return m_currentVertex; } /** * @return the number of vertex spaces left between the current position * and the end of the buffer */ - uint32_t GetRemainingSpace() const { return (GetNumElements() - 1) - GetCurrentPosition(); } + uint32_t GetRemainingSpace() const { return (GetNumElements() - 1) - GetCurrentPosition(); } private: - BOOL IsBufferAllocated() const { return m_buffer.size() > 0; } + BOOL SetSizesAndOffsets(const VERTEX_ATTRIBS *attributes, uint32_t numAttributes); + + BOOL IsBufferAllocated() const { return m_buffer.size() > 0; } - uint32_t GetVertexPosition(uint32_t index) const { return (index * m_elementWidth); } - uint32_t GetColorBufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_colorOffset; } - uint32_t GetPosition3BufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_position3Offset; } - uint32_t GetPosition2BufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_position2Offset; } - uint32_t GetNormalBufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_normalOffset; } - uint32_t GetTexCoordBufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_texCoordOffset; } - uint32_t GetGenericBufferPosition(uint32_t attrib, uint32_t index) const { return GetVertexPosition(index) + m_attribs[attrib].offset; } + uint32_t GetVertexPosition(uint32_t index) const { return (index * m_elementWidth); } + uint32_t GetColorBufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_colorOffset; } + uint32_t GetPosition3BufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_position3Offset; } + uint32_t GetPosition2BufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_position2Offset; } + uint32_t GetNormalBufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_normalOffset; } + uint32_t GetTexCoordBufferPosition(uint32_t index) const { return GetVertexPosition(index) + m_texCoordOffset; } + uint32_t GetGenericBufferPosition(uint32_t attrib, uint32_t index) const { return GetVertexPosition(index) + m_attribs[attrib].offset; } uint32_t m_numVertices; uint32_t m_currentVertex; @@ -572,16 +549,12 @@ private: uint32_t m_texCoordOffset; // --- - stl::vector m_attribs; + VertexBufferAttribute *m_attribs; + uint32_t m_numAttributes; uint32_t m_numGPUAttributeSlotsUsed; stl::vector m_buffer; }; -inline BOOL VertexBuffer::AddAttribute(VERTEX_ATTRIB_SIZES size, VERTEX_ATTRIBS standardType) -{ - return AddAttribute((uint32_t)size, standardType); -} - inline Color VertexBuffer::GetColor(uint32_t index) const { uint32_t p = GetColorBufferPosition(index);