Commit 27d91969 authored by Robert Menzel's avatar Robert Menzel

cleanups, comments, naming

parent 3819f1c5
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// Copyright (c) 2011, 2012 Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
#ifndef ACGL_OPENGL_OBJECTS_ARRAYBUFFER_HH
#define ACGL_OPENGL_OBJECTS_ARRAYBUFFER_HH
/*
/**
* An ArrayBuffer holds an array of per-vertex data. In its simplest form an
* array of one attribute, for example the vertex position or texture-coordinate.
* An ArrayBuffer however can also hold multiple attributes in an interleaved
......@@ -22,9 +22,8 @@
* called VertexBufferObjects, VBOs. The original extension that introduced
* these two new buffer types was called ARB_vertex_buffer_object but the buffers
* itself are called ArrayBuffer and ElementArrayBuffer.
*/
/***************************************************************************************************************
*
***************************************************************************************************************
* Attributes:
*************
*
......
......@@ -6,7 +6,7 @@
#ifndef ACGL_OPENGL_OBJECTS_BUFFER_HH
#define ACGL_OPENGL_OBJECTS_BUFFER_HH
/*
/**
* A generic OpenGL Buffer Object
*
* Mostly an OpenGL Buffer Wrapper: names of OpenGL calls are stripped of the
......
......@@ -6,7 +6,7 @@
#ifndef ACGL_OPENGL_OBJECTS_ELEMENTBUFFERDATA_HH
#define ACGL_OPENGL_OBJECTS_ELEMENTBUFFERDATA_HH
/*
/**
* An ElementArrayBuffer is an index into ArrayBuffers and defines which
* elements of that array should be drawn in which order.
*
......
......@@ -6,7 +6,7 @@
#ifndef ACGL_OPENGL_OBJECTS_FRAMEBUFFEROBJECT_HH
#define ACGL_OPENGL_OBJECTS_FRAMEBUFFEROBJECT_HH
/*
/**
* This FrameBufferObject class encapsulates an OpenGL frame buffer object (FBO).
* A FrameBufferObject is a target for rendering and thus consists of different "layers":
*
......
......@@ -16,7 +16,7 @@
namespace ACGL{
namespace OpenGL{
/*
/**
* A generic OpenGL asynchronous query, target types can be:
* SAMPLES_PASSED
* ANY_SAMPLES_PASSED
......@@ -87,7 +87,7 @@ protected:
};
ACGL_SMARTPOINTER_TYPEDEFS(AsynchronousQuery)
/*
/**
* Occlusion queries count the fragments that pass the z-test.
*
* There are two variants:
......@@ -122,7 +122,7 @@ ACGL_SMARTPOINTER_TYPEDEFS(OcclusionQuery)
#if (ACGL_OPENGL_VERSION >= 33)
/*
/**
* TimerQueries can get the GPU timestamp and measure GPU execution speed.
*
* Only available since OpenGL 3.3 or GL_ARB_timer_query (on OpenGL 3.2)
......@@ -152,7 +152,7 @@ ACGL_SMARTPOINTER_TYPEDEFS(TimerQuery)
#endif // OpenGL >= 3.3
#if (ACGL_OPENGL_VERSION >= 31)
/*
/**
* Primitive queries count the number of processed geometry. Sounds trivial as the app should
* know the number from the glDraw* calls, but this query will also count geometry generated
* by geometry/tessellation shaders.
......
......@@ -6,8 +6,12 @@
#ifndef ACGL_OPENGL_OBJECTS_RENDERBUFFER_HH
#define ACGL_OPENGL_OBJECTS_RENDERBUFFER_HH
/*
/**
* An OpenGL RenderBuffer that can be used with FBOs.
*
* A RenderBuffer is an alternative to a texture as a render target if the later
* usage as a texture is not needed (e.g. as a depth attachment if only the
* color attachments are needed from the offscreen renderpass).
*/
#include <ACGL/ACGL.hh>
......
......@@ -18,7 +18,7 @@
namespace ACGL{
namespace OpenGL{
/*
/**
* OpenGL Sampler Objects (needs OpenGL 3.3)
*
* A Sampler holds information about how to sample in textures (bi-linear, anisotrophic, wrap modes etc).
......
......@@ -6,7 +6,7 @@
#ifndef ACGL_OPENGL_OBJECTS_SHADER_HH
#define ACGL_OPENGL_OBJECTS_SHADER_HH
/*
/**
* A Shader ist just one OpenGL shader like a fragment or vertex shader. To use these
* a ShaderProgram is needed that links together multiple Shaders for the different
* pipelinestages.
......
......@@ -6,7 +6,7 @@
#ifndef ACGL_OPENGL_OBJECTS_SHADERPROGRAM_HH
#define ACGL_OPENGL_OBJECTS_SHADERPROGRAM_HH
/*
/**
* A ShaderProgram is a wrapper around an OpenGL Program: A combination of Shaders
* that are linked together to controll the programmable pipeline stages.
*
......
......@@ -6,7 +6,7 @@
#ifndef ACGL_OPENGL_OBJECTS_TEXTURE_HH
#define ACGL_OPENGL_OBJECTS_TEXTURE_HH
/*
/**
* A Texture wrapps the OpenGL texture. To fill these with data from image files a
* matching TextureControllerFile* is needed.
*/
......
......@@ -6,13 +6,14 @@
#ifndef ACGL_OPENGL_OBJECTS_UNIFORM_BUFFER_HH
#define ACGL_OPENGL_OBJECTS_UNIFORM_BUFFER_HH
/*
/**
* A uniform buffer is an OpenGL buffer object bound to a uniform buffer location.
* It can be used:
* provide the same set of uniforms to different ShaderPrograms without setting
the values multiple times
* set multiple uniform variables at once by mapping the buffer into the CPU
memory, memset all values and unmap it.
memory, memset all values and unmap it (quickest way to change a lot of uniforms).
* quick switching between multiple sets of uniforms (e.g. material properties).
*
* To be used, uniforms must be organized in a uniform block, this block has to be bound
* to the same location the uniform buffer gets bound to (quite similar to textures).
......@@ -23,6 +24,8 @@
* Otherwise the exact memory layout must be known, which can be queried by OpenGL, but which
* is also well defined in the case of std140-blocks (see OpenGL spec).
*
* In contrast to ShaderPrograms, nothing has to be activated before setUniform can be called
* here.
*/
#include <ACGL/ACGL.hh>
......@@ -39,10 +42,6 @@
namespace ACGL{
namespace OpenGL{
/**
* An OpenGL Uniform Buffer Object that can be used to share blocks of uniforms between multiple ShaderPrograms.
*/
class UniformBuffer : public Buffer
{
// ========================================================================================================= \/
......@@ -61,6 +60,13 @@ public:
// ============================================================================================ GETTERS \/
// ==================================================================================================== \/
public:
/** returns the byte offset of a uniform within the buffer
* Needed to upload the new value of the uniform.
* Initially the UniformBuffer does not know any locations as it is just unstructured memory with no
* intrinsic meaning, so the locations have to be queried from the matching ShaderProgram and provided
* to the UniformBuffer. This is optional, the application can also know the layout and upload the data
* without storing/querying the mappings to/from the buffer.
*/
GLint getUniformOffset (const std::string& _nameInShader) const {
if (!uniformNameToOffsetMap) return -1;
return uniformNameToOffsetMap->getLocation(_nameInShader);
......@@ -74,14 +80,14 @@ public:
//! reserve a number of bytes on the GPU for uniforms
inline void reserveMemory(GLsizeiptr _size){ setData( _size, NULL, GL_STREAM_DRAW ); }
// for scalar types:
//! uniform setters for scalar types: can only work if the offset-uniformname mapping was set before via setUniformOffsets()
inline void setUniform (const std::string &_nameInShader, GLfloat _v) { setUniformScalar<GLfloat> (_nameInShader, _v); }
inline void setUniform (const std::string &_nameInShader, GLint _v) { setUniformScalar<GLint> (_nameInShader, _v); }
inline void setUniform (const std::string &_nameInShader, GLuint _v) { setUniformScalar<GLuint> (_nameInShader, _v); }
inline void setUniform (const std::string &_nameInShader, GLboolean _v) { setUniformScalar<GLboolean>(_nameInShader, _v); }
inline void setUniform (const std::string &_nameInShader, GLdouble _v) { setUniformScalar<GLdouble> (_nameInShader, _v); }
// for GLM types:
//! uniform setters for glm types: can only work if the offset-uniformname mapping was set before via setUniformOffsets()
template <typename T>
void setUniform (const std::string &_nameInShader, T _v) {
GLint offset = getUniformOffset( _nameInShader );
......@@ -96,7 +102,7 @@ public:
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
private:
// for scalar types:
// template for scalar types: private as the setUniform() functions above map to this
template <typename T>
void setUniformScalar (const std::string &_nameInShader, T _v) {
GLint offset = getUniformOffset( _nameInShader );
......
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// Copyright (c) 2011, 2012 Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
......@@ -21,6 +21,9 @@
* and vertex attribute pointer calls (glVertexAttribPointer).
* Binding a VAO will restore that state (saving a lot of gl calls to do that
* manually).
*
* Note: Primitive restart state (enable/disable, primitive restart index) is NOT
* part of the VAO state!
*/
#include <ACGL/ACGL.hh>
......@@ -87,6 +90,22 @@ public:
// ============================================================================================ SETTERS \/
// ==================================================================================================== \/
public:
/**
* Sets the default mode of drawing.
* Must be one of: GL_POINTS
* GL_LINE_STRIP
* GL_LINE_LOOP
* GL_LINES
* GL_TRIANGLE_STRIP
* GL_TRIANGLES_FAN
* GL_TRIANGLES
* OpenGL >= 3.2 : GL_LINE_STRIP_ADJACENCY
* GL_LINES_ADJACENCY
* GL_TRIANGLE_STRIP_ADJACENCY
* GL_TRIANGLES_ADJACENCY
* OpenGL >= 4.0 : GL_PATCHES
*
*/
inline void setMode(GLenum _mode) { mMode = _mode; }
// ==================================================================================================== \/
......@@ -112,24 +131,9 @@ public:
* 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 )
{
enable();
mpElementArrayBuffer = _elementArrayBuffer;
if (mpElementArrayBuffer) // could be set to NULL!
{
mpElementArrayBuffer->bind();
}
else
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
disable();
}
void attachElementArrayBuffer( const SharedElementArrayBuffer& _elementArrayBuffer );
//! sets the EAB to NULL if there was one
inline void detachElementArrayBuffer() { attachElementArrayBuffer( SharedElementArrayBuffer() ); }
/**
......@@ -139,8 +143,8 @@ public:
* An attribute location of -1 indicates that the attribute should remain unbound for now
*/
inline void attachAttribute( const SharedArrayBuffer& _arrayBuffer,
uint32_t _arrayBufferAttribute,
GLint _attributeLocation = -1)
uint32_t _arrayBufferAttribute,
GLint _attributeLocation = -1)
{
Attribute newAttribute = { _arrayBuffer, _arrayBufferAttribute, _attributeLocation };
attachAttribute( newAttribute );
......@@ -153,150 +157,32 @@ public:
* An attribute location of -1 indicates that the attribute should remain unbound for now
*/
inline void attachAttribute( const SharedArrayBuffer& _arrayBuffer,
const std::string& _arrayBufferAttributeName,
GLint _attributeLocation = -1)
const std::string& _arrayBufferAttributeName,
GLint _attributeLocation = -1)
{
attachAttribute(_arrayBuffer,
_arrayBuffer->getAttributeIndexByName(_arrayBufferAttributeName),
_attributeLocation);
}
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 );
enable();
setAttributePointer( _attribute );
disable();
}
void attachAttribute( const Attribute &_attribute );
/**
* Attaches all attributes defined by an ArrayBuffer
* The attributes are attached to the default location of -1, indicating they should remain unbound for now
* Afterwards, you might want to automatically wire up the attributes with a ShaderProgram, using setAttributeLocationsByShaderProgram
*/
void attachAllAttributes( const SharedArrayBuffer& _arrayBuffer )
{
ArrayBuffer::AttributeVec attributes = _arrayBuffer->getAttributes();
for(ArrayBuffer::AttributeVec::size_type i = 0; i < attributes.size(); ++i)
{
attachAttribute(_arrayBuffer, (GLint) i);
}
}
void attachAllAttributes( const SharedArrayBuffer& _arrayBuffer );
/**
* 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;
}
void detachAttribute( GLint _location );
/**
* 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;
}
/**
* Return true if setAttributeMappingsByShaderProgram(_shaderProgram) would do nothing.
* That means the VAO and ShaderProgram have already matching layouts.
*/
bool mappingsMatchShaderProgram( const SharedShaderProgram &_shaderProgram ) const
{
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 (mAttributes[i].location != shaderLocation) return false;
}
return true;
}
/**
* 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 setAttributeLocationsByShaderProgram( const SharedShaderProgram &_shaderProgram )
{
// TODO: deprecate
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)
{
enable();
// disable all attributes
GLint maxAttributes;
glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &maxAttributes );
for (GLint i = 0; i < maxAttributes; ++i)
glDisableVertexAttribArray( i );
// set all attributes:
for (uint32_t i = 0; i < mAttributes.size(); ++i)
{
setAttributePointer(mAttributes[i]);
}
disable();
}
}*/
void detachAttribute( const std::string &_name );
/**
* Query the attribute locations based on the attribute names in the ArrayBuffers.
......@@ -323,9 +209,9 @@ public:
//! Nothing has to be prepared for a render call
inline void render (void)
{
enable();
storeOldVAOandBind();
draw();
disable();
restoreOldVAO();
}
//! Will select the matching draw call. Remember to bind() first!
......@@ -370,18 +256,10 @@ public:
drawArrays(mAttributes[0].arrayBuffer->getElements());
}
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
private:
SharedElementArrayBuffer mpElementArrayBuffer; // optional EAB
AttributeVec mAttributes; // vertex attributes
GLuint mObjectName; // OpenGL object name
GLenum mMode; // primitive type to render (e.g. GL_TRIANGLES)
//! Bind this VAO and remember the previously bound VAO
//! Note: every call to this method must be paired with a corresponding call to disable()
inline void enable(void)
inline void storeOldVAOandBind(void)
{
// remember old VAO
glGetIntegerv( GL_VERTEX_ARRAY_BINDING, &mPreviousVAOName );
......@@ -389,12 +267,20 @@ private:
}
//! Bind the VAO that was bound before the most recent enable() call
inline void disable(void)
inline void restoreOldVAO(void)
{
if (mObjectName != (GLuint)mPreviousVAOName) glBindVertexArray((GLuint)mPreviousVAOName);
}
GLint mPreviousVAOName; // the VAO that was bound before the last enable() call
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
private:
SharedElementArrayBuffer mpElementArrayBuffer; // optional EAB
AttributeVec mAttributes; // vertex attributes
GLuint mObjectName; // OpenGL object name
GLenum mMode; // primitive type to render (e.g. GL_TRIANGLES)
GLint mPreviousVAOName; // the VAO that was bound before the last enable() call
};
ACGL_SMARTPOINTER_TYPEDEFS(VertexArrayObject)
......
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011, Computer Graphics Group RWTH Aachen University //
// Copyright (c) 2011, 2012 Computer Graphics Group RWTH Aachen University //
// All rights reserved. //
////////////////////////////////////////////////////////////////////////////////
......@@ -9,6 +9,87 @@
using namespace ACGL;
using namespace ACGL::OpenGL;
void VertexArrayObject::attachElementArrayBuffer( const SharedElementArrayBuffer& _elementArrayBuffer )
{
storeOldVAOandBind();
mpElementArrayBuffer = _elementArrayBuffer;
if (mpElementArrayBuffer) // could be set to NULL!
{
mpElementArrayBuffer->bind();
}
else
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
restoreOldVAO();
}
void VertexArrayObject::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 );
storeOldVAOandBind();
setAttributePointer( _attribute );
restoreOldVAO();
}
void VertexArrayObject::attachAllAttributes( const SharedArrayBuffer& _arrayBuffer )
{
ArrayBuffer::AttributeVec attributes = _arrayBuffer->getAttributes();
for(ArrayBuffer::AttributeVec::size_type i = 0; i < attributes.size(); ++i)
{
attachAttribute(_arrayBuffer, (GLint) i);
}
}
void VertexArrayObject::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 VertexArrayObject::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;
}
bool VertexArrayObject::isValid(void) const
{
GLsizei elements = 0;
......@@ -74,7 +155,7 @@ void VertexArrayObject::setAttributeLocations( ConstSharedLocationMappings _loca
// if two attributes exchange there position...
if (fullUpdateNeeded)
{
enable();
storeOldVAOandBind();
// disable all attributes
for (GLint i = 0; i < maxAttributes; ++i)
......@@ -86,7 +167,7 @@ void VertexArrayObject::setAttributeLocations( ConstSharedLocationMappings _loca
setAttributePointer(mAttributes[i]);
}
disable();
restoreOldVAO();
}
}
......
Markdown is supported
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