Developer Documentation
ACG::VertexDeclaration Class Reference

Class to define the vertex input layout. More...

#include <ACG/GL/VertexDeclaration.hh>

Public Member Functions

void addElement (const VertexElement *_pElement)
 
void addElement (unsigned int _type, unsigned int _numElements, VERTEX_USAGE _usage, const void *_pointer, const char *_shaderInputName=0, unsigned int _divisor=0, unsigned int _vbo=0)
 
void addElement (unsigned int _type, unsigned int _numElements, VERTEX_USAGE _usage, size_t _byteOffset=0, const char *_shaderInputName=0, unsigned int _divisor=0, unsigned int _vbo=0)
 
void addElements (unsigned int _numElements, const VertexElement *_pElements)
 
void clear ()
 
void activateFixedFunction () const
 
void deactivateFixedFunction () const
 
void activateShaderPipeline (GLSL::Program *_prog) const
 
void deactivateShaderPipeline (GLSL::Program *_prog) const
 
void setVertexStride (unsigned int _stride)
 
unsigned int getVertexStride (unsigned int i=0) const
 
unsigned int getNumElements () const
 
const VertexElementgetElement (unsigned int i) const
 
int findElementIdByUsage (VERTEX_USAGE _usage) const
 
const VertexElementfindElementByUsage (VERTEX_USAGE _usage) const
 
QString toString () const
 

Static Public Member Functions

static unsigned int getGLTypeSize (unsigned int _type)
 
static unsigned int getElementSize (const VertexElement *_pElement)
 
static bool supportsInstancedArrays ()
 

Private Member Functions

void updateOffsets ()
 
void updateShaderInputName (VertexElement *_pElem)
 

Private Attributes

std::vector< VertexElementelements_
 
unsigned int vertexStride_
 Offset in bytes between each vertex.
 
std::map< unsigned int, unsigned int > vertexStridesVBO_
 Map vbo to offset in bytes between each vertex in that vbo.
 
int strideUserDefined_
 Flag that indicates, whether the stride was set by user or derived automatically.
 

Detailed Description

Class to define the vertex input layout.

This class is used to specify vertex data layout (normals,positions,...).

The layout of a vertex buffer typically includes:

  • number of vertex elements
  • element usage (position, normal, ... )
  • element types (float, int, ...)
  • memory alignment
  • data pointers (only in case of system memory buffers)
  • source vertex buffers
  • divisor (step rate) for instance data
  • vertex stride

Example usage: Interleaved vertex data

Create a vertex declaration given the following vertex data:

Vertex
{
float4 pos
float3 normal
float2 texcoord
ubyte4 color
float4 tangent
float2 texcoord2
}

The accompanying vertex declaration is created as follows:

VertexDeclaration decl;
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_POSITION);
decl.addElement(GL_FLOAT, 3, VERTEX_USAGE_NORMAL);
decl.addElement(GL_FLOAT, 2, VERTEX_USAGE_TEXCOORD);
decl.addElement(GL_UNSIGNED_BYTE, 4, VERTEX_USAGE_COLOR);
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_SHADER_INPUT, 0U, "inTangent");
decl.addElement(GL_FLOAT, 2, VERTEX_USAGE_SHADER_INPUT, 0U, "inTexcoord2");

Note that the element offsets are automatically computed, but it is possible to provide them manually of course.

These elements are then available in a vertex shader with the following input semantics:

in vec4 inPosition;
...
in vec4 inTangent;
in vec2 inTexcoord2;

VERTEX_USAGE_SHADER_INPUT is ignored in fixed function pipeline


Example usage: Multiple source buffers in system memory

Given are system memory buffers as vertex data source for drawing:

float4* pVertexPositions;
ubyte4* pVertexColors;
float3* pVertexNormals;

It is important that the vertex stride is manually set to 0!! and that the element data pointers are set accordingly:

VertexDeclaration decl;
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_POSITION, pVertexPositions);
decl.addElement(GL_FLOAT, 3, VERTEX_USAGE_NORMAL, pVertexNormals);
decl.addElement(GL_UNSIGNED_BYTE, 4, VERTEX_USAGE_COLOR, pVertexColors);
decl.setVertexStride(0);

Note:

  • vertex stride = 0
  • assign data address in vertex elements and don't change the data location later
  • order of elements is not important in this case
  • mixing interleaved vbo and system memory elements in the same declaration is forbidden

Example usage: Instancing from vbo

Geometry instancing can be implemented in several ways:

  • compute instance transform procedurally from gl_InstanceID in shader
  • store per instance data in a texture and use vertex texture fetch via gl_InstanceID
  • store per instance data in a vbo and stream these as input to a vertex shader (ARB_instanced_arrays).

The first two methods can be implemented without modifying the vertex declaration, so this example focuses on the last method, in which instance data is streamed from a vbo.

Given a mesh with the following vertex elements:

Vertex
{
float4 pos
float3 normal
float2 texcoord
}

Each instance of this mesh should have a different world transform and a different color. So the per instance data is:

InstanceData
{
mat4 modelview
uint color
}

This per instance data is stored in a separate GL_ARRAY_BUFFER vbo.

So there are two vbos involved in the draw call: geometryVBO - stores static Vertex data of the mesh instanceVBO - stores InstanceData for each instance

The vertex declaration for the instanced draw call is initialized as follows:

VertexDeclaration decl;
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_POSITION, 0U, 0, 0, geometryVBO.id()); // mesh vertex data layout
decl.addElement(GL_FLOAT, 3, VERTEX_USAGE_NORMAL, 0U, 0, 0, geometryVBO.id());
decl.addElement(GL_FLOAT, 2, VERTEX_USAGE_TEXCOORD, 0U, 0, 0, geometryVBO.id());
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_SHADER_INPUT, 0U, "inModelView0", 1, instanceVBO.id()); // instance data layout
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_SHADER_INPUT, 0U, "inModelView1", 1, instanceVBO.id());
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_SHADER_INPUT, 0U, "inModelView2", 1, instanceVBO.id());
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_SHADER_INPUT, 0U, "inModelView3", 1, instanceVBO.id());
decl.addElement(GL_FLOAT, 4, VERTEX_USAGE_COLOR, 0U, 0, 1, instanceVBO.id());

The 4x4 modelview matrix has to be split up into float4 elements.

Using this setup, a call to decl.activateShaderPipeline() is enough to prepare an instanced draw call.

Finally, instancing requires a customized vertex shader that makes use of the per instance data:

..
in vec4 inModelView0;
in vec4 inModelView1;
in vec4 inModelView2;
in vec4 inModelView3;
..
void main()
{
..
vec4 posVS;
posVS.x = dot(inModelView0, inPosition);
posVS.y = dot(inModelView1, inPosition);
..
gl_Position = projection * posVS;
}

Definition at line 266 of file VertexDeclaration.hh.

Member Function Documentation

void ACG::VertexDeclaration::activateFixedFunction ( ) const

prepare OpenGL to use a vertex buffer with this declaration -> uses the fixed function pointers (glVertexPointer, glColorPointer...)

Definition at line 356 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::activateShaderPipeline ( GLSL::Program _prog) const

prepare OpenGL to use a vertex buffer with this declaration -> uses shader attribute pointers ( glVertexAttribPointer )

Definition at line 424 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::addElement ( const VertexElement _pElement)

append one element to declaration

Definition at line 110 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::addElement ( unsigned int  _type,
unsigned int  _numElements,
VERTEX_USAGE  _usage,
const void *  _pointer,
const char *  _shaderInputName = 0,
unsigned int  _divisor = 0,
unsigned int  _vbo = 0 
)

append one element to declarations, direct method

Definition at line 115 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::addElement ( unsigned int  _type,
unsigned int  _numElements,
VERTEX_USAGE  _usage,
size_t  _byteOffset = 0,
const char *  _shaderInputName = 0,
unsigned int  _divisor = 0,
unsigned int  _vbo = 0 
)

append one element to declarations, direct method

Definition at line 137 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::addElements ( unsigned int  _numElements,
const VertexElement _pElements 
)

append multiple element declarations

Definition at line 161 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::clear ( )

remove all vertex elements, also clears the user defined stride flag

Definition at line 549 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::deactivateFixedFunction ( ) const

disables vertex attributes to prevent any draw related crashes

Definition at line 402 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::deactivateShaderPipeline ( GLSL::Program _prog) const

disables this vertex declaration to prevent any draw related crashes -> calls glDisableVertexAttribArray

Definition at line 476 of file VertexDeclaration.cc.

const VertexElement * ACG::VertexDeclaration::findElementByUsage ( VERTEX_USAGE  _usage) const

find element ptr by usage, return 0 if not found

Definition at line 519 of file VertexDeclaration.cc.

int ACG::VertexDeclaration::findElementIdByUsage ( VERTEX_USAGE  _usage) const

find element id by usage, return -1 if not found

Definition at line 510 of file VertexDeclaration.cc.

const VertexElement * ACG::VertexDeclaration::getElement ( unsigned int  i) const

get the i'th vertex element desc

Definition at line 504 of file VertexDeclaration.cc.

unsigned int ACG::VertexDeclaration::getElementSize ( const VertexElement _pElement)
static

get size of one vertex element

Definition at line 344 of file VertexDeclaration.cc.

unsigned int ACG::VertexDeclaration::getGLTypeSize ( unsigned int  _type)
static

get size of GL_FLOAT, GL_INT ...

Definition at line 310 of file VertexDeclaration.cc.

unsigned int ACG::VertexDeclaration::getNumElements ( ) const

get num of vertex elements

Definition at line 304 of file VertexDeclaration.cc.

unsigned int ACG::VertexDeclaration::getVertexStride ( unsigned int  i = 0) const

get vertex size (for element i, for multi vbo support)

Definition at line 530 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::setVertexStride ( unsigned int  _stride)

set vertex stride manually, otherwise it is computed from the vertex elements

Definition at line 543 of file VertexDeclaration.cc.

bool ACG::VertexDeclaration::supportsInstancedArrays ( )
static

Check hw support for streaming instance data from vbo

Definition at line 619 of file VertexDeclaration.cc.

QString ACG::VertexDeclaration::toString ( ) const

Returns a string describing the vertex format for debugging purpose.

Definition at line 559 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::updateOffsets ( )
private

automatically computes byte offset for interleaved vertex elements and computes vertex stride

Definition at line 228 of file VertexDeclaration.cc.

void ACG::VertexDeclaration::updateShaderInputName ( VertexElement _pElem)
private

automatically sets shader input name on passed element, if not provided

Definition at line 277 of file VertexDeclaration.cc.


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