Commit a33e18c6 authored by Robert Menzel's avatar Robert Menzel
Browse files

Added VertexArrayObject class

* First version of VertexArrayObjects
* added VAO related functions to the DSA extension
parent 0e984a53
#ifndef ACGL_OPENGL_EXT_DIRECT_STATE_ACCESS_HH
#define ACGL_OPENGL_EXT_DIRECT_STATE_ACCESS_HH
/*
* Direct state access (DSA for short) makes it easyer to change OpenGL objects because it does not
* Direct state access (DSA for short) makes it easier to change OpenGL objects because it does not
* require this object to be bound at that moment.
* Let's look at one example:
*
......@@ -38,7 +38,7 @@ void initDirectStateAccessFunctions();
} // ACGL
//
// On some windows configurations ACGLAPIENTRYcan be defined wrong which leads to compile
// On some windows configurations ACGLAPIENTRY can be defined wrong which leads to compile
// errors when setting the function pointers.
// Also, if there is no GLEW, we have to define this anyway!
//
......@@ -699,6 +699,12 @@ void ACGLAPIENTRY glTextureSubImage1DEMULATION (GLuint texture, GLenum target, G
void ACGLAPIENTRY glTextureSubImage2DEMULATION (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
void ACGLAPIENTRY glTextureSubImage3DEMULATION (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
GLboolean ACGLAPIENTRY glUnmapNamedBufferEMULATION (GLuint buffer);
void ACGLAPIENTRY glVertexArrayVertexAttribIOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArrayVertexAttribOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);
// DSA equivalents for deprecated functions:
#ifndef ACGL_OPENGL_PROFILE_CORE
void ACGLAPIENTRY glVertexArrayVertexOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArrayColorOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArrayEdgeFlagOffsetEMULATION (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArrayFogCoordOffsetEMULATION (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
......@@ -707,11 +713,6 @@ void ACGLAPIENTRY glVertexArrayMultiTexCoordOffsetEMULATION (GLuint vaobj, GLuin
void ACGLAPIENTRY glVertexArrayNormalOffsetEMULATION (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArraySecondaryColorOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArrayTexCoordOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArrayVertexAttribIOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArrayVertexAttribOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);
void ACGLAPIENTRY glVertexArrayVertexOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset);
#ifndef ACGL_OPENGL_PROFILE_CORE
void ACGLAPIENTRY glDisableClientStateIndexedEMULATION (GLenum array, GLuint index);
void ACGLAPIENTRY glDisableClientStateiEMULATION (GLenum array, GLuint index);
void ACGLAPIENTRY glEnableClientStateIndexedEMULATION (GLenum array, GLuint index);
......@@ -752,7 +753,7 @@ void ACGLAPIENTRY glMultiTexGenfvEMULATION (GLenum texunit, GLenum coord, GLenum
void ACGLAPIENTRY glMultiTexGeniEMULATION (GLenum texunit, GLenum coord, GLenum pname, GLint param);
void ACGLAPIENTRY glMultiTexGenivEMULATION (GLenum texunit, GLenum coord, GLenum pname, const GLint* params);
void ACGLAPIENTRY glPushClientAttribDefaultEMULATION (GLbitfield mask);
#endif
#endif // no deprecated in CORE profile builds
} // OpenGL
} // ACGL
......
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#ifndef ACGL_OPENGL_OBJECTS_VERTEXARRAYOBJECT_HH
#define ACGL_OPENGL_OBJECTS_VERTEXARRAYOBJECT_HH
/**
* A VertexArrayObject is a predefined combination of (multiple) attributes of
* (multiple) ArrayBuffers and optionally one ElementArrayBuffer.
*
* It's only present in OpenGL 3.0 onwards. For older implementations (or
* embedded systems) see VertexBufferObject which is a softwareimplementation
* of the same idea).
* Alternatively, there are the GL_APPLE_vertex_array_object and
* GL_ARB_vertex_array_object extensions for OpenGL 2.1.
* OES_vertex_array_object for OpenGL ES (e.g. iOS 4.0+)
*
* A VAO will cache the enabled vertex attributes (set with glEnableVertexAttribArray)
* and vertex attribute pointer calls (glVertexAttribPointer).
* Binding a VAO will restore that state (saving a lot of gl calls to do that
* manually).
*/
#include <ACGL/ACGL.hh>
#include <ACGL/OpenGL/GL.hh>
#if (ACGL_OPENGL_VERSION >= 30)
#include <ACGL/Base/Macros.hh>
#include <ACGL/OpenGL/Tools.hh>
#include <ACGL/OpenGL/Objects/ArrayBuffer.hh>
#include <ACGL/OpenGL/Objects/ElementArrayBuffer.hh>
#include <ACGL/OpenGL/Objects/ShaderProgram.hh>
#include <vector>
#include <tr1/memory>
namespace ACGL{
namespace OpenGL{
class VertexArrayObject
{
ACGL_NOT_COPYABLE(VertexArrayObject)
// ==================================================================================================== \/
// ============================================================================================ STRUCTS \/
// ==================================================================================================== \/
public:
struct Attribute
{
SharedArrayBuffer arrayBuffer; // the ArrayBuffer to use
int32_t attributeID; // the attribute from that ArrayBuffer
GLint location; // a location the in-attribute from a shader is bound to
// more Attribute properties can be looked up in the ArrayBuffer (like the name)
};
// ========================================================================================================= \/
// ============================================================================================ CONSTRUCTORS \/
// ========================================================================================================= \/
public:
VertexArrayObject()
: mObjectName(0),
mpElementArrayBuffer(),
mAttributes()
{
glGenVertexArrays(1, &mObjectName);
if (openGLCriticalErrorOccured() ) {
ACGL::Utils::error() << "could not generate vertex array object!" << std::endl;
}
}
virtual ~VertexArrayObject(void)
{
// as always, OpenGL will ignore object name 0
glDeleteVertexArrays(1, &mObjectName);
}
// ==================================================================================================== \/
// ============================================================================================ GETTERS \/
// ==================================================================================================== \/
public:
inline GLuint operator() (void) const { return mObjectName; }
inline GLuint getObjectName(void) const { return mObjectName; }
// ==================================================================================================== \/
// ============================================================================================ METHODS \/
// ==================================================================================================== \/
public:
/**
* Will check if the VAO looks ok (e.g. there is at least one ArrayBuffer and all ArrayBuffers
* have the same number of elements).
* A failed test will output an error but won't have other consequences.
*/
bool isValid(void) const;
/**
* Set the given ElementArrayBuffer, if a NULL pointer is given, an existing EAB will get unset.
* Will restore the previously bound VAO (DSA style)
*/
void attachElementArrayBuffer( const SharedElementArrayBuffer& _elementArrayBuffer )
{
// query old VAO
GLint oldVAO; glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &oldVAO );
mpElementArrayBuffer = _elementArrayBuffer;
bind();
if (mpElementArrayBuffer) { // could be set to NULL!
mpElementArrayBuffer->bind();
} else {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
// restore old VAO
glBindVertexArray( oldVAO ); openGLRareError();
}
inline void detachElementArrayBuffer() { attachElementArrayBuffer( SharedElementArrayBuffer() ); }
/**
* Will set the attribute _arrayBufferAttribute of ArrayBuffer _arrayBuffer to the given attribute location.
* If that location was already used it will get overwritten.
* The _attributeLocation has to be lower than GL_MAX_VERTEX_ATTRIBS
*/
void attachAttribute( const SharedArrayBuffer &_arrayBuffer,
uint32_t _arrayBufferAttribute,
GLuint _attributeLocation)
{
Attribute newAttribute = { _arrayBuffer, _arrayBufferAttribute, _attributeLocation };
attachAttribute( newAttribute );
}
void attachAttribute( const Attribute &_attribute )
{
GLint maxAttributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttributes); // TODO: clever caching
if (mAttributes.size() >= (uint32_t) maxAttributes) {
ACGL::Utils::error() << "can't attach attribute " << _attribute.arrayBuffer->getAttributes()[_attribute.attributeID].name
<< " - maximum number of attributes reached: " << maxAttributes << std::endl;
return;
}
mAttributes.push_back( _attribute );
// query old VAO
GLint oldVAO; glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &oldVAO );
bind();
glEnableVertexAttribArray( _attribute.location );
_attribute.arrayBuffer->setAttributePointer( _attribute.attributeID, _attribute.location );
// restore old VAO
glBindVertexArray( oldVAO ); openGLRareError();
}
/**
* Will detach the first found Attribute with the given attribute location.
*/
void detachAttribute( GLint _location )
{
for (AttributeVec::size_type i = 0; i < mAttributes.size(); ++i)
{
if (mAttributes[i].location == _location) {
// the other pointer data is still set, but that isn't relevant if the attribute itself is deactivated
glDisableVertexArrayAttribEXT( mObjectName, mAttributes[i].location );
mAttributes.erase( mAttributes.begin()+i );
return;
}
}
// if we got here, no Attribute of the given name exists
ACGL::Utils::warning() << "can't detach attribute with location " << _location << " - no such Attribute" << std::endl;
}
/**
* Will detach the first found Attribute with the given name.
*/
void detachAttribute( const std::string &_name )
{
for (AttributeVec::size_type i = 0; i < mAttributes.size(); ++i)
{
if (mAttributes[i].arrayBuffer->getAttributes()[ mAttributes[i].attributeID ].name == _name) {
// the other pointer data is still set, but that isn't relevant if the attribute itself is deactivated
glDisableVertexArrayAttribEXT( mObjectName, mAttributes[i].location );
mAttributes.erase( mAttributes.begin()+i );
return;
}
}
// if we got here, no Attribute of the given name exists
ACGL::Utils::warning() << "can't detach attribute " << _name << " - no such Attribute" << std::endl;
}
/**
* Query the attribute locations based on the attribute names in the ArrayBuffers and the ShaderProgram
* If they match, use the location reported from the ShaderProgram.
*/
void setAttributeMappingsByShaderProgram( const ConstSharedShaderProgram &_shaderProgram )
{
bool fullUpdateNeeded = false;
for (AttributeVec::size_type i = 0; i < mAttributes.size(); ++i)
{
std::string attributeName = mAttributes[i].arrayBuffer->getAttributes()[ mAttributes[i].attributeID ].name;
GLint shaderLocation = _shaderProgram->getAttributeLocation( attributeName );
if (shaderLocation == -1) {
ACGL::Utils::error() << "can't update VAO mappings, attribute " << attributeName << " does not exist in shader" << std::endl;
continue; // try to match as much as possible
}
if (mAttributes[i].location != shaderLocation) {
mAttributes[i].location = shaderLocation;
fullUpdateNeeded = true;
}
}
// why the full update? setting the new location right when a change is detected will get problamatic
// if two attributes exchange there position...
if (fullUpdateNeeded) {
// query old VAO
GLint oldVAO; glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &oldVAO );
bind();
GLint maxAttributes;
glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &maxAttributes );
// disable all attributes
for (GLint i = 0; i < maxAttributes; ++i) glDisableVertexAttribArray( i );
// set all attributes:
for (uint32_t i = 0; i < mAttributes.size(); ++i) {
glEnableVertexAttribArray( mAttributes[i].location );
mAttributes[i].arrayBuffer->setAttributePointer( mAttributes[i].attributeID, mAttributes[i].location );
}
// restore old VAO
glBindVertexArray( oldVAO ); openGLRareError();
}
}
// ===================================================================================================== \/
// ============================================================================================ WRAPPERS \/
// ===================================================================================================== \/
public:
//! Bind this VAO
inline void bind(void) const
{
glBindVertexArray( mObjectName );
}
inline void enable (void) const { bind(); }
inline void disable (void) const { glBindVertexArray(0); }
//! Nothing has to be prepared for a render call
//! Note: the previously bound VAO will not get restored, instead VAO 0 will get bound
inline void render (void) const
{
enable();
draw();
disable();
}
//! Will select the matching draw call. Remember to enable first!
void draw(void) const
{
if(mpElementArrayBuffer)
drawElements();
else
drawArrays();
openGLRareError();
}
//! Can be called directly instead of draw() iff the caller knows this is the correct call!
inline void drawElements(void) const
{
mpElementArrayBuffer->draw();
}
//! Can be called directly instead of draw() iff the caller knows this is the correct call!
inline void drawArrays(void) const
{
mAttributes[0].arrayBuffer->draw();
}
// ===================================================================================================== \/
// ============================================================================================ TYPEDEFS \/
// ===================================================================================================== \/
protected:
typedef std::vector< Attribute > AttributeVec;
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
protected:
GLuint mObjectName; // OpenGL object name
SharedElementArrayBuffer mpElementArrayBuffer; // optional EAB
AttributeVec mAttributes; // vertex attributes
};
ACGL_SHARED_TYPEDEF(VertexArrayObject)
} // OpenGL
} // ACGL
#endif // OpenGL 3.0
#endif // ACGL_OPENGL_OBJECTS_VERTEXARRAYOBJECT_HH
......@@ -673,11 +673,9 @@ void glCopyTextureImage2DEMULATION (GLuint texture, GLenum target, GLint level,
void glCopyTextureSubImage1DEMULATION (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glCopyTextureSubImage2DEMULATION (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glCopyTextureSubImage3DEMULATION (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glDisableVertexArrayAttribEMULATION (GLuint vaobj, GLuint index) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glEnableVertexArrayEMULATION (GLuint vaobj, GLenum array) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glDisableVertexArrayEMULATION (GLuint vaobj, GLenum array) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glEnableVertexArrayAttribEMULATION (GLuint vaobj, GLuint index) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glEnableVertexArrayEMULATION (GLuint vaobj, GLenum array) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glFlushMappedNamedBufferRangeEMULATION (GLuint buffer, GLintptr offset, GLsizeiptr length) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glFramebufferDrawBufferEMULATION (GLuint framebuffer, GLenum mode) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glFramebufferDrawBuffersEMULATION (GLuint framebuffer, GLsizei n, const GLenum* bufs) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
......@@ -1217,6 +1215,70 @@ void glTextureSubImage1DEMULATION (GLuint texture, GLenum target, GLint level, G
void glTextureSubImage2DEMULATION (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glTextureSubImage3DEMULATION (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
GLboolean glUnmapNamedBufferEMULATION (GLuint buffer) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; return GL_FALSE; }
//
// Vertex Array Object related functions
//
#if (ACGL_OPENGL_VERSION < 30)
void glVertexArrayVertexAttribIOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "VertexArrayObjects are not supported pre OpenGL 3" << std::endl; }
void glVertexArrayVertexAttribOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "VertexArrayObjects are not supported pre OpenGL 3" << std::endl; }
void glEnableVertexArrayAttribEMULATION (GLuint vaobj, GLuint index) { ACGL::Utils::error() << "VertexArrayObjects are not supported pre OpenGL 3" << std::endl; }
void glDisableVertexArrayAttribEMULATION (GLuint vaobj, GLuint index) { ACGL::Utils::error() << "VertexArrayObjects are not supported pre OpenGL 3" << std::endl; }
#else
#define VAO_PREFIX GLint oldVAO; \
glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &oldVAO ); \
glBindVertexArray( vaobj );
#define VAO_POSTFIX if ((GLuint)oldVAO != vaobj) {\
glBindVertexArray( oldVAO );\
} \
openGLRareError();
void glVertexArrayVertexAttribIOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset)
{
VAO_PREFIX;
GLint oldArrayBuffer;
glGetIntegerv( GL_ARRAY_BUFFER_BINDING, &oldArrayBuffer );
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexAttribIPointer( index, size, type, stride, (void*) offset );
glBindBuffer(GL_ARRAY_BUFFER, oldArrayBuffer);
VAO_POSTFIX;
}
void glVertexArrayVertexAttribOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset)
{
VAO_PREFIX;
GLint oldArrayBuffer;
glGetIntegerv( GL_ARRAY_BUFFER_BINDING, &oldArrayBuffer );
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexAttribPointer( index, size, type, normalized, stride, (void*) offset );
glBindBuffer(GL_ARRAY_BUFFER, oldArrayBuffer);
VAO_POSTFIX;
}
void glEnableVertexArrayAttribEMULATION (GLuint vaobj, GLuint index)
{
VAO_PREFIX;
glEnableVertexAttribArray( index );
VAO_POSTFIX;
}
void glDisableVertexArrayAttribEMULATION (GLuint vaobj, GLuint index)
{
VAO_PREFIX;
glDisableVertexAttribArray( index );
VAO_POSTFIX;
}
#endif
#ifndef ACGL_OPENGL_PROFILE_CORE
void glVertexArrayVertexOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glVertexArrayColorOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glVertexArrayEdgeFlagOffsetEMULATION (GLuint vaobj, GLuint buffer, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glVertexArrayFogCoordOffsetEMULATION (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
......@@ -1225,12 +1287,6 @@ void glVertexArrayMultiTexCoordOffsetEMULATION (GLuint vaobj, GLuint buffer, GLe
void glVertexArrayNormalOffsetEMULATION (GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glVertexArraySecondaryColorOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glVertexArrayTexCoordOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glVertexArrayVertexAttribIOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glVertexArrayVertexAttribOffsetEMULATION (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
void glVertexArrayVertexOffsetEMULATION (GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset) { ACGL::Utils::error() << "NOT IMPLEMENTED YET" << std::endl; }
#ifndef ACGL_OPENGL_PROFILE_CORE
#define GET_MULTI_TEX_PREFIX int savedActiveTexture, savedClientActiveTexture; \
glGetIntegerv(GL_ACTIVE_TEXTURE, &savedActiveTexture); \
......
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#include <ACGL/OpenGL/Objects/VertexArrayObject.hh>
#if (ACGL_OPENGL_VERSION >= 30)
using namespace ACGL;
using namespace ACGL::OpenGL;
bool VertexArrayObject::isValid(void) const
{
GLenum mode;
GLsizei elements = 0;
if (mAttributes.size() > 0)
{
mode = mAttributes[0].arrayBuffer->getMode();
elements = mAttributes[0].arrayBuffer->getElements();
} else {
Utils::error() << "VertexArrayObject has no attributes attached" << std::endl;
return false;
}
if (mpElementArrayBuffer)
{
mode = mpElementArrayBuffer->getMode();
elements = mpElementArrayBuffer->getElements();
}
for (AttributeVec::size_type i = 0; i < mAttributes.size(); ++i)
{
if (mAttributes[0].arrayBuffer->getMode() != mode) {
Utils::error() << "VertexArrayObject validation failed: Attribute "<< i << " has different mode."<< std::endl;
return false;
}
if (mAttributes[0].arrayBuffer->getElements() != elements) {
Utils::error() << "VertexArrayObject validation failed: Attribute "<< i << " has different number of elements."<< std::endl;
return false;
}
}
return true;
}
#endif // (ACGL_OPENGL_VERSION >= 30)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment