Developer Documentation

Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
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 VertexElement * | getElement (unsigned int i) const
int | findElementIdByUsage (VERTEX_USAGE _usage) const
const VertexElement * | findElementByUsage (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< VertexElement > | elements_
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:

- OpenFlipper/libs_required/ACG/GL/VertexDeclaration.hh
- OpenFlipper/libs_required/ACG/GL/VertexDeclaration.cc