Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ACGL
acgl
Commits
55d9f005
Commit
55d9f005
authored
Feb 08, 2012
by
Robert Menzel
Browse files
redone VAO mappings
parent
27d91969
Changes
8
Hide whitespace changes
Inline
Side-by-side
include/ACGL/Base/FileHelpers.hh
View file @
55d9f005
...
...
@@ -48,7 +48,7 @@ namespace FileHelpers
/*
* Splits a string at the delim char.
*/
//
void splitString(const std::string &s, char delim, std::vector<std::string> &elems);
void
splitString
(
const
std
::
string
&
s
,
char
delim
,
std
::
vector
<
std
::
string
>
&
elems
);
/*
...
...
include/ACGL/OpenGL/Objects/ArrayBuffer.hh
View file @
55d9f005
...
...
@@ -118,6 +118,9 @@ public:
//! Returns the definitions of the attributes:
inline
const
AttributeVec
&
getAttributes
(
void
)
const
{
return
mAttributes
;
}
//! Returns one attribute:
inline
Attribute
getAttribute
(
uint_t
i
)
const
{
return
mAttributes
[
i
];
}
// ==================================================================================================== \/
// ============================================================================================ METHODS \/
// ==================================================================================================== \/
...
...
include/ACGL/OpenGL/Objects/LocationMappings.hh
View file @
55d9f005
...
...
@@ -77,6 +77,8 @@ public:
//! Tells whether a mapping for a given name exists
inline
bool
exists
(
const
std
::
string
&
_name
)
const
{
return
(
getLocation
(
_name
)
!=
-
1
);
}
void
printMapping
();
// =================================================================================================== \/
// ============================================================================================ FIELDS \/
// =================================================================================================== \/
...
...
include/ACGL/OpenGL/Objects/VertexArrayObject.hh
View file @
55d9f005
...
...
@@ -54,7 +54,7 @@ public:
{
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
//
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)
};
...
...
@@ -62,7 +62,7 @@ public:
// ============================================================================================ TYPEDEFS \/
// ===================================================================================================== \/
public:
typedef
std
::
vector
<
Attribute
>
AttributeVec
;
typedef
std
::
vector
<
Attribute
>
AttributeVec
;
// position in the vector == attrib location
// ========================================================================================================= \/
// ============================================================================================ CONSTRUCTORS \/
...
...
@@ -75,9 +75,14 @@ public:
mMode
(
GL_TRIANGLES
)
{
glGenVertexArrays
(
1
,
&
mObjectName
);
GLint
maxAttributes
;
glGetIntegerv
(
GL_MAX_VERTEX_ATTRIBS
,
&
maxAttributes
);
if
(
openGLCriticalErrorOccured
()
)
{
ACGL
::
Utils
::
error
()
<<
"could not generate vertex array object!"
<<
std
::
endl
;
}
mAttributes
.
resize
(
maxAttributes
);
// reserve probably 16 slots, the size() can now be used to query the MAX_VERTEX_ATTRIBS
}
virtual
~
VertexArrayObject
(
void
)
...
...
@@ -120,13 +125,6 @@ public:
// ============================================================================================ 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)
...
...
@@ -140,21 +138,21 @@ public:
* 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
* An attribute location of -1 indicates that the attribute should
remain unbound for now
* An attribute location of -1 indicates that the attribute should
get the next free location
*/
inline
void
attachAttribute
(
const
SharedArrayBuffer
&
_arrayBuffer
,
uint32_t
_arrayBufferAttribute
,
GLint
_attributeLocation
=
-
1
)
{
Attribute
newAttribute
=
{
_arrayBuffer
,
_arrayBufferAttribute
,
_attributeLocation
};
attachAttribute
(
newAttribute
);
Attribute
newAttribute
=
{
_arrayBuffer
,
_arrayBufferAttribute
};
attachAttribute
(
newAttribute
,
_attributeLocation
);
}
/**
* Will set the attribute named _arrayBufferAttributeName 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
* An attribute location of -1 indicates that the attribute should
remain unbound for now
* An attribute location of -1 indicates that the attribute should
should get the next free location
*/
inline
void
attachAttribute
(
const
SharedArrayBuffer
&
_arrayBuffer
,
const
std
::
string
&
_arrayBufferAttributeName
,
...
...
@@ -165,19 +163,21 @@ public:
_attributeLocation
);
}
void
attachAttribute
(
const
Attribute
&
_attribute
);
//! if the location was already in use, the new attribute will replace it, if a free loc should be used but no location is free,
//! nothing will get attached.
void
attachAttribute
(
const
Attribute
&
_attribute
,
GLint
_location
);
/**
* Attaches all attributes defined by an ArrayBuffer
* The attributes are attached to the
default location of -1, indicating they should remain unbound for now
* The attributes are attached to the
next free location.
* Afterwards, you might want to automatically wire up the attributes with a ShaderProgram, using setAttributeLocationsByShaderProgram
*/
void
attachAllAttributes
(
const
SharedArrayBuffer
&
_arrayBuffer
);
/**
* Will detach the
first found
Attribute with the given attribute location.
* Will detach the Attribute with the given attribute location.
*/
void
detachAttribute
(
GLint
_location
);
void
detachAttribute
(
GL
u
int
_location
);
/**
* Will detach the first found Attribute with the given name.
...
...
@@ -190,11 +190,17 @@ public:
*/
void
setAttributeLocations
(
ConstSharedLocationMappings
_locationMappings
);
//! get a list of attribute locations and names that can be used to set up a ShaderProgram
SharedLocationMappings
getAttributeLocations
();
private:
//! Sets the vertex attribute pointer for the current VAO according to the specified attribute
data
//! Sets the vertex attribute pointer for the current VAO according to the specified attribute
(index into mAttributes)
//! Note: expects that this VAO is currently bound
//! Note: will bind the ArrayBuffer referenced by _attribute.arrayBuffer
void
setAttributePointer
(
const
Attribute
&
_attribute
);
void
setAttributePointer
(
GLuint
_index
);
//! returns a free attribute location between 0 .. MAX_ATTRIB_LOCATIONS unless no location is free, in that case returns -1
GLint
getFreeAttributeLocation
();
// ===================================================================================================== \/
// ============================================================================================ WRAPPERS \/
...
...
src/ACGL/Base/FileHelpers.cc
View file @
55d9f005
...
...
@@ -73,6 +73,8 @@ namespace FileHelpers
return false;
}
*/
// copied from stackoverflow
void
splitString
(
const
std
::
string
&
s
,
char
delim
,
std
::
vector
<
std
::
string
>
&
elems
)
{
...
...
@@ -87,7 +89,6 @@ namespace FileHelpers
elems
.
push_back
(
item
);
}
}
*/
#ifndef PLATFORM_IOS
std
::
string
getDeviceDependentPathFor
(
const
std
::
string
&
resource
)
...
...
src/ACGL/OpenGL/Objects/LocationMappings.cc
View file @
55d9f005
...
...
@@ -31,3 +31,12 @@ void LocationMappings::setLocation(const std::string& _name, GLuint _location)
}
mMappings
[
_name
]
=
_location
;
}
void
LocationMappings
::
printMapping
()
{
LocationMap
::
const_iterator
end
=
mMappings
.
end
();
for
(
LocationMap
::
const_iterator
it
=
mMappings
.
begin
();
it
!=
end
;
++
it
)
{
ACGL
::
Utils
::
debug
()
<<
"loc mapping: "
<<
it
->
first
<<
" - "
<<
it
->
second
<<
std
::
endl
;
}
}
src/ACGL/OpenGL/Objects/Sampler.cc
View file @
55d9f005
...
...
@@ -5,6 +5,8 @@
#include
<ACGL/OpenGL/Objects/Sampler.hh>
#if (ACGL_OPENGL_VERSION >= 33)
using
namespace
ACGL
::
OpenGL
;
Sampler
::
Sampler
()
...
...
@@ -46,3 +48,4 @@ void Sampler::setMaxAnisotropy( GLfloat _sampleCount )
}
}
#endif // OpenGL >= 3.3
src/ACGL/OpenGL/Objects/VertexArrayObject.cc
View file @
55d9f005
...
...
@@ -7,6 +7,7 @@
#if (ACGL_OPENGL_VERSION >= 30)
using
namespace
ACGL
;
using
namespace
ACGL
::
Utils
;
using
namespace
ACGL
::
OpenGL
;
void
VertexArrayObject
::
attachElementArrayBuffer
(
const
SharedElementArrayBuffer
&
_elementArrayBuffer
)
...
...
@@ -27,36 +28,67 @@ void VertexArrayObject::attachElementArrayBuffer( const SharedElementArrayBuffer
restoreOldVAO
();
}
void
VertexArrayObject
::
attachAttribute
(
const
Attribute
&
_attribute
)
void
VertexArrayObject
::
attachAttribute
(
const
Attribute
&
_attribute
,
GLint
_location
)
{
GLint
maxAttributes
;
glGetIntegerv
(
GL_MAX_VERTEX_ATTRIBS
,
&
maxAttributes
);
// TODO: clever caching
if
(
mAttributes
.
size
()
>=
(
uint32_t
)
maxAttributes
)
{
if
(
(
GLuint
)
_location
>=
mAttributes
.
size
())
{
ACGL
::
Utils
::
error
()
<<
"can't attach attribute "
<<
_attribute
.
arrayBuffer
->
getAttributes
()[
_attribute
.
attributeID
].
name
<<
" - maximum number of attributes
reached
: "
<<
m
ax
Attributes
<<
std
::
endl
;
<<
" - maximum number of attributes: "
<<
mAttributes
.
size
()
<<
std
::
endl
;
return
;
}
else
if
(
_location
<
0
)
{
// find a free location:
_location
=
getFreeAttributeLocation
();
if
(
_location
<
0
)
{
// no free location found
ACGL
::
Utils
::
error
()
<<
"can't attach attribute "
<<
_attribute
.
arrayBuffer
->
getAttributes
()[
_attribute
.
attributeID
].
name
<<
" - maximum number of attributes reached ( "
<<
mAttributes
.
size
()
<<
" )"
<<
std
::
endl
;
return
;
}
}
mAttributes
.
push_back
(
_attribute
);
mAttributes
[
_location
]
=
_attribute
;
storeOldVAOandBind
();
setAttributePointer
(
_
attribute
);
setAttributePointer
(
_
location
);
restoreOldVAO
();
}
GLint
VertexArrayObject
::
getFreeAttributeLocation
()
{
GLint
maxAttributes
;
glGetIntegerv
(
GL_MAX_VERTEX_ATTRIBS
,
&
maxAttributes
);
for
(
ArrayBuffer
::
AttributeVec
::
size_type
i
=
0
;
i
<
mAttributes
.
size
();
++
i
)
{
if
(
!
(
mAttributes
[
i
].
arrayBuffer
)
)
{
// no shared pointer set, no attribute set!
return
(
GLint
)
i
;
}
}
return
-
1
;
}
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
);
attachAttribute
(
_arrayBuffer
,
(
GLint
)
i
,
getFreeAttributeLocation
()
);
}
}
void
VertexArrayObject
::
detachAttribute
(
GLint
_location
)
void
VertexArrayObject
::
detachAttribute
(
GL
u
int
_location
)
{
if
(
_location
>=
mAttributes
.
size
())
{
ACGL
::
Utils
::
error
()
<<
"can't detach attribute with location "
<<
_location
<<
" - no such Attribute"
<<
std
::
endl
;
return
;
}
storeOldVAOandBind
();
mAttributes
[
_location
].
arrayBuffer
=
SharedArrayBuffer
();
glDisableVertexAttribArray
(
_location
);
restoreOldVAO
();
/*
for (AttributeVec::size_type i = 0; i < mAttributes.size(); ++i)
{
if (mAttributes[i].location == _location)
...
...
@@ -69,6 +101,7 @@ void VertexArrayObject::detachAttribute( GLint _location )
}
// 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;
*/
}
/**
...
...
@@ -80,9 +113,10 @@ void VertexArrayObject::detachAttribute( const std::string &_name )
{
if
(
mAttributes
[
i
].
arrayBuffer
->
getAttributes
()[
mAttributes
[
i
].
attributeID
].
name
==
_name
)
{
detachAttribute
(
i
);
// 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
);
//
glDisableVertexArrayAttribEXT( mObjectName, mAttributes[i].location );
//
mAttributes.erase( mAttributes.begin()+i );
return
;
}
}
...
...
@@ -90,108 +124,83 @@ void VertexArrayObject::detachAttribute( const std::string &_name )
ACGL
::
Utils
::
warning
()
<<
"can't detach attribute "
<<
_name
<<
" - no such Attribute"
<<
std
::
endl
;
}
bool
VertexArrayObject
::
isValid
(
void
)
const
{
GLsizei
elements
=
0
;
if
(
mAttributes
.
size
()
>
0
)
{
elements
=
mAttributes
[
0
].
arrayBuffer
->
getElements
();
}
else
{
Utils
::
error
()
<<
"VertexArrayObject has no attributes attached"
<<
std
::
endl
;
return
false
;
}
if
(
mpElementArrayBuffer
)
void
VertexArrayObject
::
setAttributeLocations
(
ConstSharedLocationMappings
_locationMappings
)
{
AttributeVec
oldAttributes
=
mAttributes
;
for
(
AttributeVec
::
size_type
i
=
0
;
i
<
mAttributes
.
size
();
++
i
)
{
elements
=
mpElementArrayBuffer
->
getElements
();
mAttributes
[
i
].
arrayBuffer
=
SharedArrayBuffer
();
// set to NULL
}
AttributeVec
unmatchedAttributes
;
for
(
AttributeVec
::
size_type
i
=
0
;
i
<
mAttributes
.
size
();
++
i
)
// if there is an old attribute, look up the name in the _locationMap, use the new location if the
// name is present (stored in the map), remove the attribute from the old map.
// after that, run over the unmatchedAttributes to store the remaining attributes on free slots in the map
for
(
AttributeVec
::
size_type
i
=
0
;
i
<
oldAttributes
.
size
();
++
i
)
{
if
(
mAttributes
[
0
].
arrayBuffer
->
getElements
()
!=
elements
)
{
Utils
::
error
()
<<
"VertexArrayObject validation failed: Attribute "
<<
i
<<
" has different number of elements."
<<
std
::
endl
;
return
false
;
if
(
oldAttributes
[
i
].
arrayBuffer
)
{
GLint
location
=
_locationMappings
->
getLocation
(
oldAttributes
[
i
].
arrayBuffer
->
getAttribute
(
(
int
)
oldAttributes
[
i
].
attributeID
).
name
);
if
((
location
>=
0
)
&&
((
GLuint
)
location
<
oldAttributes
.
size
()))
{
mAttributes
[
location
]
=
oldAttributes
[
i
];
//debug() << "moved loc " << oldAttributes[i].arrayBuffer->getAttribute( (int) oldAttributes[i].attributeID ).name
// << " from " << i << " to " << location << std::endl;
}
else
{
unmatchedAttributes
.
push_back
(
oldAttributes
[
i
]
);
//debug() << "unmatched " << oldAttributes[i].arrayBuffer->getAttribute( (int) oldAttributes[i].attributeID ).name
// << " at " << i << std::endl;
}
oldAttributes
[
i
].
arrayBuffer
=
SharedArrayBuffer
();
// set to NULL
}
}
for
(
AttributeVec
::
size_type
i
=
0
;
i
<
unmatchedAttributes
.
size
();
++
i
)
{
GLint
location
=
getFreeAttributeLocation
();
mAttributes
[
location
]
=
unmatchedAttributes
[
i
];
// the total attribute number hasn't changed so location must be valid
//debug() << "moved uloc " << unmatchedAttributes[i].arrayBuffer->getAttribute( (int) unmatchedAttributes[i].attributeID ).name
// << " to " << location << std::endl;
}
return
true
;
}
storeOldVAOandBind
();
// disable all attributes & set the new ones
for
(
GLuint
i
=
0
;
i
<
mAttributes
.
size
();
++
i
)
{
glDisableVertexAttribArray
(
i
);
if
(
mAttributes
[
i
].
arrayBuffer
)
setAttributePointer
(
i
);
}
restoreOldVAO
();
}
void
VertexArrayObject
::
s
etAttributeLocations
(
ConstSharedLocationMappings
_locationMappings
)
SharedLocationMappings
VertexArrayObject
::
g
etAttributeLocations
()
{
bool
fullUpdateNeeded
=
false
;
GLint
maxAttributes
;
glGetIntegerv
(
GL_MAX_VERTEX_ATTRIBS
,
&
maxAttributes
);
SharedLocationMappings
locationMap
=
SharedLocationMappings
(
new
LocationMappings
()
);
for
(
AttributeVec
::
size_type
i
=
0
;
i
<
mAttributes
.
size
();
++
i
)
{
std
::
string
attributeName
=
mAttributes
[
i
].
arrayBuffer
->
getAttributes
()[
mAttributes
[
i
].
attributeID
].
name
;
int_t
location
=
_locationMappings
->
getLocation
(
attributeName
);
if
(
location
==
-
1
)
{
// TODO: fail silently?
ACGL
::
Utils
::
error
()
<<
"can't update VAO mapping: attribute "
<<
attributeName
<<
" not specified"
<<
std
::
endl
;
continue
;
// try to match as much as possible
}
if
(
location
>=
maxAttributes
)
{
ACGL
::
Utils
::
error
()
<<
"can't update VAO mapping: location of attribute "
<<
attributeName
<<
" is too high ("
<<
location
<<
") GL_MAX_VERTEX_ATTRIBS is "
<<
maxAttributes
<<
std
::
endl
;
continue
;
// try to match as much as possible
}
if
(
mAttributes
[
i
].
location
!=
location
)
{
mAttributes
[
i
].
location
=
location
;
fullUpdateNeeded
=
true
;
if
(
mAttributes
[
i
].
arrayBuffer
)
{
//debug() << "aloc: " << mAttributes[i].arrayBuffer->getAttribute( (int) mAttributes[i].attributeID ).name << " " << i << std::endl;
locationMap
->
setLocation
(
mAttributes
[
i
].
arrayBuffer
->
getAttribute
(
(
int
)
mAttributes
[
i
].
attributeID
).
name
,
i
);
}
}
// 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
)
{
storeOldVAOandBind
();
// disable all attributes
for
(
GLint
i
=
0
;
i
<
maxAttributes
;
++
i
)
glDisableVertexAttribArray
(
i
);
// set all attributes:
for
(
uint32_t
i
=
0
;
i
<
mAttributes
.
size
();
++
i
)
{
setAttributePointer
(
mAttributes
[
i
]);
}
restoreOldVAO
();
}
return
locationMap
;
}
void
VertexArrayObject
::
setAttributePointer
(
const
Attribute
&
_attribute
)
void
VertexArrayObject
::
setAttributePointer
(
GLuint
_index
)
{
if
(
_attribute
.
location
==
-
1
)
{
// An attribute location of -1 indicates that this attribute should remain unbound for now
return
;
}
SharedArrayBuffer
arrayBuffer
=
_attribute
.
arrayBuffer
;
arrayBuffer
->
bind
();
mAttributes
[
_index
].
arrayBuffer
->
bind
();
ArrayBuffer
::
Attribute
arrayBufferAttribute
=
arrayBuffer
->
getAttribute
s
()[
_a
ttribute
.
attributeID
]
;
glVertexAttribPointer
(
_
attribute
.
location
,
ArrayBuffer
::
Attribute
arrayBufferAttribute
=
mAttributes
[
_index
].
arrayBuffer
->
getAttribute
(
mA
ttribute
s
[
_index
]
.
attributeID
)
;
glVertexAttribPointer
(
_
index
,
arrayBufferAttribute
.
size
,
arrayBufferAttribute
.
type
,
arrayBufferAttribute
.
normalized
,
arrayBuffer
->
getStride
(),
mAttributes
[
_index
].
arrayBuffer
->
getStride
(),
reinterpret_cast
<
GLvoid
*>
(
arrayBufferAttribute
.
offset
)
);
glEnableVertexAttribArray
(
_
attribute
.
location
);
glEnableVertexAttribArray
(
_
index
);
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment