Browse Source

Mesh rework, part 5: tracking currently bound VAO.

If the VAO is already bound, not calling glBindVertexArray() again.
pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
56bc8825cc
  1. 30
      src/Implementation/MeshState.h
  2. 4
      src/Implementation/State.cpp
  3. 2
      src/Implementation/State.h
  4. 3
      src/IndexedMesh.cpp
  5. 21
      src/Mesh.cpp
  6. 11
      src/Mesh.h

30
src/Implementation/MeshState.h

@ -0,0 +1,30 @@
#ifndef Magnum_Implementation_MeshState_h
#define Magnum_Implementation_MeshState_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "Magnum.h"
namespace Magnum { namespace Implementation {
struct MeshState {
inline MeshState(): currentVAO(0) {}
GLuint currentVAO;
};
}}
#endif

4
src/Implementation/State.cpp

@ -16,16 +16,18 @@
#include "State.h" #include "State.h"
#include "BufferState.h" #include "BufferState.h"
#include "MeshState.h"
#include "ShaderProgramState.h" #include "ShaderProgramState.h"
#include "TextureState.h" #include "TextureState.h"
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
State::State(): buffer(new BufferState), shaderProgram(new ShaderProgramState), texture(new TextureState) {} State::State(): buffer(new BufferState), mesh(new MeshState), shaderProgram(new ShaderProgramState), texture(new TextureState) {}
State::~State() { State::~State() {
delete texture; delete texture;
delete shaderProgram; delete shaderProgram;
delete mesh;
delete buffer; delete buffer;
} }

2
src/Implementation/State.h

@ -20,6 +20,7 @@
namespace Magnum { namespace Implementation { namespace Magnum { namespace Implementation {
struct BufferState; struct BufferState;
struct MeshState;
struct ShaderProgramState; struct ShaderProgramState;
struct TextureState; struct TextureState;
@ -28,6 +29,7 @@ struct State {
~State(); ~State();
BufferState* const buffer; BufferState* const buffer;
MeshState* const mesh;
ShaderProgramState* const shaderProgram; ShaderProgramState* const shaderProgram;
TextureState* const texture; TextureState* const texture;
}; };

3
src/IndexedMesh.cpp

@ -63,8 +63,7 @@ void IndexedMesh::bindIndexBufferImplementationDefault() {}
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void IndexedMesh::bindIndexBufferImplementationVAO() { void IndexedMesh::bindIndexBufferImplementationVAO() {
glBindVertexArray(vao); bindVAO(vao);
_indexBuffer->bind(Buffer::Target::ElementArray); _indexBuffer->bind(Buffer::Target::ElementArray);
} }
#endif #endif

21
src/Mesh.cpp

@ -20,6 +20,8 @@
#include "Buffer.h" #include "Buffer.h"
#include "Context.h" #include "Context.h"
#include "Extensions.h" #include "Extensions.h"
#include "Implementation/MeshState.h"
#include "Implementation/State.h"
using namespace std; using namespace std;
@ -31,6 +33,14 @@ Mesh::BindAttributeImplementation Mesh::bindAttributeImplementation = &Mesh::bin
Mesh::BindImplementation Mesh::bindImplementation = &Mesh::bindImplementationDefault; Mesh::BindImplementation Mesh::bindImplementation = &Mesh::bindImplementationDefault;
Mesh::UnbindImplementation Mesh::unbindImplementation = &Mesh::unbindImplementationDefault; Mesh::UnbindImplementation Mesh::unbindImplementation = &Mesh::unbindImplementationDefault;
Mesh::~Mesh() {
/* Remove current vao from the state */
GLuint& current = Context::current()->state()->mesh->currentVAO;
if(current == vao) current = 0;
(this->*destroyImplementation)();
}
Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), attributes(other.attributes) { Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), attributes(other.attributes) {
other.vao = 0; other.vao = 0;
} }
@ -57,6 +67,11 @@ void Mesh::draw() {
unbind(); unbind();
} }
void Mesh::bindVAO(GLuint vao) {
GLuint& current = Context::current()->state()->mesh->currentVAO;
if(current != vao) glBindVertexArray(current = vao);
}
void Mesh::bind() { void Mesh::bind() {
CORRADE_ASSERT((_vertexCount == 0) == attributes.empty(), "Mesh: vertex count is non-zero, but no attributes are bound", ); CORRADE_ASSERT((_vertexCount == 0) == attributes.empty(), "Mesh: vertex count is non-zero, but no attributes are bound", );
@ -125,7 +140,7 @@ void Mesh::bindAttributeImplementationDefault(const Attribute&) {}
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Mesh::bindAttributeImplementationVAO(const Attribute& attribute) { void Mesh::bindAttributeImplementationVAO(const Attribute& attribute) {
glBindVertexArray(vao); bindVAO(vao);
vertexAttribPointer(attribute); vertexAttribPointer(attribute);
} }
#endif #endif
@ -137,7 +152,7 @@ void Mesh::bindImplementationDefault() {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Mesh::bindImplementationVAO() { void Mesh::bindImplementationVAO() {
glBindVertexArray(vao); bindVAO(vao);
} }
#endif #endif
@ -148,7 +163,7 @@ void Mesh::unbindImplementationDefault() {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void Mesh::unbindImplementationVAO() { void Mesh::unbindImplementationVAO() {
glBindVertexArray(0); bindVAO(0);
} }
#endif #endif

11
src/Mesh.h

@ -81,7 +81,8 @@ Basic workflow is to set up respective shader (see @ref AbstractShaderProgram-re
If @extension{APPLE,vertex_array_object} is supported, VAOs are used instead If @extension{APPLE,vertex_array_object} is supported, VAOs are used instead
of binding the buffers and specifying vertex attribute pointers in each of binding the buffers and specifying vertex attribute pointers in each
draw() call. draw() call. The engine tracks currently bound VAO to avoid unnecessary calls
to @fn_gl{BindVertexArray}.
@requires_gl30 Extension @extension{EXT,gpu_shader4} (for unsigned integer attributes) @requires_gl30 Extension @extension{EXT,gpu_shader4} (for unsigned integer attributes)
@ -354,9 +355,7 @@ class MAGNUM_EXPORT Mesh {
* @see @fn_gl{DeleteVertexArrays} (if * @see @fn_gl{DeleteVertexArrays} (if
* @extension{APPLE,vertex_array_object} is available) * @extension{APPLE,vertex_array_object} is available)
*/ */
inline virtual ~Mesh() { virtual ~Mesh();
(this->*destroyImplementation)();
}
/** @brief Move assignment */ /** @brief Move assignment */
Mesh& operator=(Mesh&& other); Mesh& operator=(Mesh&& other);
@ -571,6 +570,8 @@ class MAGNUM_EXPORT Mesh {
void MAGNUM_EXPORT addVertexAttribute(Buffer* buffer, GLuint location, GLint count, Type type, GLintptr offset, GLsizei stride); void MAGNUM_EXPORT addVertexAttribute(Buffer* buffer, GLuint location, GLint count, Type type, GLintptr offset, GLsizei stride);
static void MAGNUM_LOCAL bindVAO(GLuint vao);
void MAGNUM_LOCAL bind(); void MAGNUM_LOCAL bind();
inline void unbind() { inline void unbind() {
@ -591,7 +592,7 @@ class MAGNUM_EXPORT Mesh {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL destroyImplementationVAO(); void MAGNUM_LOCAL destroyImplementationVAO();
#endif #endif
static DestroyImplementation destroyImplementation; static MAGNUM_LOCAL DestroyImplementation destroyImplementation;
typedef void(Mesh::*BindAttributeImplementation)(const Attribute&); typedef void(Mesh::*BindAttributeImplementation)(const Attribute&);
void MAGNUM_LOCAL bindAttributeImplementationDefault(const Attribute& attribute); void MAGNUM_LOCAL bindAttributeImplementationDefault(const Attribute& attribute);

Loading…
Cancel
Save