CUGL 3.0
Cornell University Game Library
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Protected Attributes | List of all members
cugl::graphics::VertexBuffer Class Reference

#include <CUVertexBuffer.h>

Inheritance diagram for cugl::graphics::VertexBuffer:
cugl::graphics::InstanceBuffer

Classes

class  AttribData
 

Public Member Functions

 VertexBuffer ()
 
 ~VertexBuffer ()
 
virtual void dispose ()
 
virtual bool init (GLsizei size, GLsizei stride)
 
void bind ()
 
void unbind ()
 
virtual void attach (const std::shared_ptr< Shader > &shader)
 
std::shared_ptr< Shaderdetach ()
 
std::shared_ptr< ShadergetShader () const
 
bool isBound () const
 
GLsizei getCapacity () const
 
GLsizei getStride () const
 
void loadVertexData (const void *data, GLsizei size, GLenum usage=GL_STREAM_DRAW)
 
void loadIndexData (const void *data, GLsizei size, GLenum usage=GL_STREAM_DRAW)
 
void draw (GLenum mode, GLsizei count, GLint offset=0)
 
void drawDirect (GLenum mode, GLint first, GLsizei count)
 
virtual void setupAttribute (const std::string name, GLint size, GLenum type, GLboolean norm, GLsizei offset)
 
void enableAttribute (const std::string name)
 
void disableAttribute (const std::string name)
 

Static Public Member Functions

static std::shared_ptr< VertexBufferalloc (GLsizei size, GLsizei stride)
 

Protected Attributes

GLsizei _size
 
GLsizei _stride
 
GLuint _vertArray
 
GLuint _vertBuffer
 
GLuint _indxBuffer
 
std::shared_ptr< Shader_shader
 
std::unordered_map< std::string, bool > _enabled
 
std::unordered_map< std::string, AttribData_attributes
 

Detailed Description

This class defines a vertex buffer for drawing with a shader.

What we are calling a vertex buffer is technically a vertex array plus its associated buffers in OpenGL. A vertex buffer receives vertices and passes them to a shader. A vertex buffer must be attached to a shader to be used. However, a vertex buffer can swap shaders at any time, which is why this class is separated out.

Unlike Texture and UniformBuffer, a vertex buffer does not have a true many one relationship with a Shader object. A vertex buffer can only be connected to one shader at a time and vice versa. So we model this as a direct connection. As vertex buffers push data to a shader, the dependency requires that a shader be linked to a vertex buffer object.

This class tries to remain loosely coupled with its shader. If the vertex buffer has attributes lacking in the shader, they will be ignored. If it is missing attributes that the shader expects, the shader will use the default value for the type.

Constructor & Destructor Documentation

◆ VertexBuffer()

cugl::graphics::VertexBuffer::VertexBuffer ( )

Creates an uninitialized vertex buffer.

You must initialize the vertex buffer to allocate buffer memory.

◆ ~VertexBuffer()

cugl::graphics::VertexBuffer::~VertexBuffer ( )

Deletes this vertex buffer, disposing all resources.

Member Function Documentation

◆ alloc()

static std::shared_ptr< VertexBuffer > cugl::graphics::VertexBuffer::alloc ( GLsizei  size,
GLsizei  stride 
)
inlinestatic

Returns a new vertex buffer to support the given stride.

The stride is the size of a single piece of vertex data. The vertex buffer needs this value to set attribute locations. Since changing this value fundamentally changes the type of data that can be sent to this vertex buffer, it is set at buffer creation and cannot be changed.

It is possible for the stride to be 0, but only if the shader consists of a single attribute. Using stride 0 is not recommended.

For performance reasons, we also require that the vertex buffer specify a maximum size. This size is applied to both vertex and index data. So it should be the maximum of both. Size is specified in terms of maximum elements, not bytes.

Parameters
sizeThe maximum number of elements in this buffer
strideThe size of a single piece of vertex data
Returns
a new vertex buffer to support the given stride.

◆ attach()

virtual void cugl::graphics::VertexBuffer::attach ( const std::shared_ptr< Shader > &  shader)
virtual

Attaches the given shader to this vertex buffer.

This method will link all enabled attributes in this vertex buffer (warning about any attributes that are missing from the shader). It will also immediately bind both the vertex buffer and the shader, making them ready to use.

Parameters
shaderThe shader to attach

Reimplemented in cugl::graphics::InstanceBuffer.

◆ bind()

void cugl::graphics::VertexBuffer::bind ( )

Binds this vertex buffer, making it active.

If this vertex buffer has an attached shader, this will bind the shader as well. Once bound, all vertex data and uniforms will be sent to the associated shader.

A vertex buffer can be bound without being attached to a shader. However, if it is actively attached to a shader, this method will bind that shader as well.

◆ detach()

std::shared_ptr< Shader > cugl::graphics::VertexBuffer::detach ( )

Returns the previously active shader, after detaching it.

This method will unbind the vertex buffer, but not the shader.

Returns
The previously active shader (or null if none)

◆ disableAttribute()

void cugl::graphics::VertexBuffer::disableAttribute ( const std::string  name)

Disables the given attribute

Attributes are immediately enabled once they are set-up. This method allows you to temporarily turn off an attribute. If that attribute is required by the shader, it will use the default value for the type instead.

Parameters
nameThe attribute to disable.

◆ dispose()

virtual void cugl::graphics::VertexBuffer::dispose ( )
virtual

Deletes the vertex buffer, freeing all resources.

You must reinitialize the vertex buffer to use it.

Reimplemented in cugl::graphics::InstanceBuffer.

◆ draw()

void cugl::graphics::VertexBuffer::draw ( GLenum  mode,
GLsizei  count,
GLint  offset = 0 
)

Draws to the active framebuffer using this vertex buffer

This draw command will use the index buffer to stream the vertices in order. Any call to this command will use the current texture and uniforms. If the texture and/or uniforms need to be changed, then this draw command will need to be broken up into chunks. Use the optional parameter offset to chunk up the draw calls without having to reload data.

The drawing mode can be any of GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN or GL_TRIANGLES. These are the only modes accepted by both OpenGL and OpenGLES. See the OpenGL documentation for the number of indices required for each type. In practice the Poly2 class is designed to support GL_POINTS, GL_LINES, and GL_TRIANGLES only.

This method will only succeed if this buffer is actively bound.

Parameters
modeThe OpenGLES drawing mode
countThe number of vertices to draw
offsetThe initial index to start with

◆ drawDirect()

void cugl::graphics::VertexBuffer::drawDirect ( GLenum  mode,
GLint  first,
GLsizei  count 
)

Draws to the active framebuffer using this vertex buffer

This draw command will ignore the index buffer and draw the vertices in the order that they were loaded. Any call to this command will use the current texture and uniforms. If the texture and/or uniforms need to be changed, then this draw command will need to be broken up into chunks. Use the initial offset parameter to chunk up the draw calls without having to reload data.

The drawing mode can be any of GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN or GL_TRIANGLES. These are the only modes accepted by both OpenGL and OpenGLES. See the OpenGL documentation for the number of indices required for each type. In practice the Poly2 class is designed to support GL_POINTS, GL_LINES, and GL_TRIANGLES only.

This method will only succeed if this buffer is actively bound.

Parameters
modeThe OpenGLES drawing mode
firstThe initial vertex to start with
countThe number of vertices to draw

◆ enableAttribute()

void cugl::graphics::VertexBuffer::enableAttribute ( const std::string  name)

Enables the given attribute

Attributes are immediately enabled once they are set-up. This method is only needed if the attribute was previously disabled. It will have no effect if the active shader does not support this attribute.

Parameters
nameThe attribute to enable.

◆ getCapacity()

GLsizei cugl::graphics::VertexBuffer::getCapacity ( ) const
inline

Returns the maximum capacity of this buffer.

The size determines the number of elements that can be loaded with either loadVertexData or loadIndexData.

Returns
the maximum capacity of this buffer.

◆ getShader()

std::shared_ptr< Shader > cugl::graphics::VertexBuffer::getShader ( ) const
inline

Returns the shader currently attached to this vertex buffer.

Returns
the shader currently attached to this vertex buffer.

◆ getStride()

GLsizei cugl::graphics::VertexBuffer::getStride ( ) const
inline

Returns the stride of this vertex buffer

The data loaded is expected to have the size of the vertex buffer stride. If it does not, strange things will happen.

Returns
the stride of this vertex buffer

◆ init()

virtual bool cugl::graphics::VertexBuffer::init ( GLsizei  size,
GLsizei  stride 
)
virtual

Initializes this vertex buffer to support the given stride.

The stride is the size of a single piece of vertex data. The vertex buffer needs this value to set attribute locations. Since changing this value fundamentally changes the type of data that can be sent to this vertex buffer, it is set at buffer creation and cannot be changed.

It is possible for the stride to be 0, but only if the shader consists of a single attribute. Using stride 0 is not recommended.

For performance reasons, we also require that the vertex buffer specify a maximum size. This size is applied to both vertex and index data. So it should be the maximum of both. Size is specified in terms of maximum elements, not bytes.

Parameters
sizeThe maximum number of elements in this buffer
strideThe size of a single piece of vertex data
Returns
true if initialization was successful.

Reimplemented in cugl::graphics::InstanceBuffer.

◆ isBound()

bool cugl::graphics::VertexBuffer::isBound ( ) const

Returns true if this vertex is currently bound.

Returns
true if this vertex is currently bound.

◆ loadIndexData()

void cugl::graphics::VertexBuffer::loadIndexData ( const void *  data,
GLsizei  size,
GLenum  usage = GL_STREAM_DRAW 
)

Loads the given vertex buffer with indices.

The indices loaded are those that will be used at the next call to draw. Frequent reloading of indices is to be discouraged (though it is faster than swapping to another vertex buffer). Instead, indices should be loaded once (if possible) and draw calls should make use of the offset parameter.

The indices loaded are expected to refer to valid vertex positions. If they do not, strange things will happen.

The usage is one of GL_STATIC_DRAW, GL_STREAM_DRAW, or GL_DYNAMIC_DRAW. Static drawing should be reserved for vertices and/or indices that do not change (so all animation happens in uniforms). Given the high speed of CPU processing, this approach should only be taken for large meshes that can amortize the uniform changes. For quads and other simple meshes, you should always choose GL_STREAM_DRAW and push as much computation to the CPU as possible.

This method will only succeed if this buffer is actively bound.

Parameters
dataThe indices to load
sizeThe number of indices to load
usageThe type of data load

◆ loadVertexData()

void cugl::graphics::VertexBuffer::loadVertexData ( const void *  data,
GLsizei  size,
GLenum  usage = GL_STREAM_DRAW 
)

Loads the given vertex buffer with data.

The data loaded is the data that will be used at the next call to either draw or drawDirect. Frequent reloading of vertices is to be discouraged (though it is faster than swapping to another vertex buffer). Instead, data should be loaded once (if possible) and draw calls should make use of the offset parameter.

The data loaded is expected to have the size of the vertex buffer stride. If it does not, strange things will happen.

The usage is one of GL_STATIC_DRAW, GL_STREAM_DRAW, or GL_DYNAMIC_DRAW. Static drawing should be reserved for vertices and/or indices that do not change (so all animation happens in uniforms). Given the high speed of CPU processing, this approach should only be taken for large meshes that can amortize the uniform changes. For quads and other simple meshes, you should always choose GL_STREAM_DRAW.

This method will only succeed if this buffer is actively bound.

Parameters
dataThe data to load
sizeThe number of vertices to load
usageThe type of data load

◆ setupAttribute()

virtual void cugl::graphics::VertexBuffer::setupAttribute ( const std::string  name,
GLint  size,
GLenum  type,
GLboolean  norm,
GLsizei  offset 
)
virtual

Initializes an attribute, assigning is a size, type and offset.

This method is necessary for the vertex buffer to convey data to the shader. Without it, the shader will used default values for the attribute rather than data from the vertex buffer.

It is safe to call this method even when the shader is not attached. The values will be cached and will be used to link this buffer to the shader when the shader is attached. This also means that a vertex buffer can swap shaders without having to reinitialize attributes. If a shader is attached, the attribute will be enabled immediately.

If the attribute does not refer to one supported by the active shader, then it will be ignored (e.g. the effect is the same as disabling the attribute).

The attribute type can be one of GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT, GL_HALF_FLOAT, GL_FLOAT, GL_FIXED, or GL_INT_2_10_10_10_REV. Doubles are not supported by OpenGLES.

The attribute offset is measured in bytes from the start of the vertex data structure (for a single vertex).

Parameters
nameThe attribute name
sizeThe attribute size in byte.
typeThe attribute type
normWhether to normalize the value (floating point only)
offsetThe attribute offset in the vertex data structure

◆ unbind()

void cugl::graphics::VertexBuffer::unbind ( )

Unbinds this vertex buffer, making it no longer active.

A vertex buffer can be unbound without being attached to a shader. Furthermore, if it is actively attached to a shader, this method will NOT unbind the shader. This allows for fast(er) switching between buffers of the same shader.

Once unbound, all vertex data and uniforms will be ignored. In addition, all uniforms and samplers are potentially invalidated. These values should be set again when the vertex buffer is next bound.

Member Data Documentation

◆ _attributes

std::unordered_map<std::string, AttribData> cugl::graphics::VertexBuffer::_attributes
protected

The settings for each attribute

◆ _enabled

std::unordered_map<std::string, bool> cugl::graphics::VertexBuffer::_enabled
protected

The enabled attributes

◆ _indxBuffer

GLuint cugl::graphics::VertexBuffer::_indxBuffer
protected

The index buffer for drawing a shape

◆ _shader

std::shared_ptr<Shader> cugl::graphics::VertexBuffer::_shader
protected

The shader currently attached to this vertex buffer

◆ _size

GLsizei cugl::graphics::VertexBuffer::_size
protected

The max size (both vertices and indices of this buffer

◆ _stride

GLsizei cugl::graphics::VertexBuffer::_stride
protected

The data stride of this buffer (0 if there is only one attribute)

◆ _vertArray

GLuint cugl::graphics::VertexBuffer::_vertArray
protected

The array buffer for drawing a the shape

◆ _vertBuffer

GLuint cugl::graphics::VertexBuffer::_vertBuffer
protected

The vertex buffer for drawing a shape


The documentation for this class was generated from the following file: