Developer Documentation
ACG::VertexDeclaration Class Reference

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

#include <OpenFlipper/libs_required/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
 
bool operator== (const VertexDeclaration &_other) const
 
bool operator!= (const VertexDeclaration &_other) const
 

Static Public Member Functions

static size_t getGLTypeSize (unsigned int _type)
 
static size_t 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 268 of file VertexDeclaration.hh.

Member Function Documentation

◆ activateFixedFunction()

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 361 of file VertexDeclaration.cc.

◆ activateShaderPipeline()

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 429 of file VertexDeclaration.cc.

◆ addElement() [1/3]

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

append one element to declaration

Definition at line 115 of file VertexDeclaration.cc.

◆ addElement() [2/3]

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 120 of file VertexDeclaration.cc.

◆ addElement() [3/3]

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 142 of file VertexDeclaration.cc.

◆ addElements()

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

append multiple element declarations

Definition at line 166 of file VertexDeclaration.cc.

◆ clear()

void ACG::VertexDeclaration::clear ( )

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

Definition at line 570 of file VertexDeclaration.cc.

◆ deactivateFixedFunction()

void ACG::VertexDeclaration::deactivateFixedFunction ( ) const

disables vertex attributes to prevent any draw related crashes

Definition at line 407 of file VertexDeclaration.cc.

◆ deactivateShaderPipeline()

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

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

Definition at line 486 of file VertexDeclaration.cc.

◆ findElementByUsage()

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

find element ptr by usage, return 0 if not found

Definition at line 534 of file VertexDeclaration.cc.

◆ findElementIdByUsage()

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

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

Definition at line 525 of file VertexDeclaration.cc.

◆ getElement()

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

get the i'th vertex element desc

Definition at line 519 of file VertexDeclaration.cc.

◆ getElementSize()

size_t ACG::VertexDeclaration::getElementSize ( const VertexElement _pElement)
static

get size of one vertex element

Definition at line 349 of file VertexDeclaration.cc.

◆ getGLTypeSize()

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

get size of GL_FLOAT, GL_INT ...

Definition at line 315 of file VertexDeclaration.cc.

◆ getNumElements()

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

get num of vertex elements

Definition at line 309 of file VertexDeclaration.cc.

◆ getVertexStride()

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

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

Definition at line 545 of file VertexDeclaration.cc.

◆ operator!=()

bool ACG::VertexDeclaration::operator!= ( const VertexDeclaration _other) const
inline

comparison operator

Definition at line 365 of file VertexDeclaration.hh.

◆ operator==()

bool ACG::VertexDeclaration::operator== ( const VertexDeclaration _other) const

comparison operator

Definition at line 640 of file VertexDeclaration.cc.

◆ setVertexStride()

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

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

Definition at line 564 of file VertexDeclaration.cc.

◆ supportsInstancedArrays()

bool ACG::VertexDeclaration::supportsInstancedArrays ( )
static

Check hw support for streaming instance data from vbo

Definition at line 655 of file VertexDeclaration.cc.

◆ toString()

QString ACG::VertexDeclaration::toString ( ) const

Returns a string describing the vertex format for debugging purpose.

Definition at line 580 of file VertexDeclaration.cc.

◆ updateOffsets()

void ACG::VertexDeclaration::updateOffsets ( )
private

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

Definition at line 233 of file VertexDeclaration.cc.

◆ updateShaderInputName()

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

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

Definition at line 282 of file VertexDeclaration.cc.


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