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 "BufferState.h"
#include "MeshState.h"
#include "ShaderProgramState.h"
#include "TextureState.h"
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() {
delete texture;
delete shaderProgram;
delete mesh;
delete buffer;
}

2
src/Implementation/State.h

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

3
src/IndexedMesh.cpp

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

21
src/Mesh.cpp

@ -20,6 +20,8 @@
#include "Buffer.h"
#include "Context.h"
#include "Extensions.h"
#include "Implementation/MeshState.h"
#include "Implementation/State.h"
using namespace std;
@ -31,6 +33,14 @@ Mesh::BindAttributeImplementation Mesh::bindAttributeImplementation = &Mesh::bin
Mesh::BindImplementation Mesh::bindImplementation = &Mesh::bindImplementationDefault;
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) {
other.vao = 0;
}
@ -57,6 +67,11 @@ void Mesh::draw() {
unbind();
}
void Mesh::bindVAO(GLuint vao) {
GLuint& current = Context::current()->state()->mesh->currentVAO;
if(current != vao) glBindVertexArray(current = vao);
}
void Mesh::bind() {
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
void Mesh::bindAttributeImplementationVAO(const Attribute& attribute) {
glBindVertexArray(vao);
bindVAO(vao);
vertexAttribPointer(attribute);
}
#endif
@ -137,7 +152,7 @@ void Mesh::bindImplementationDefault() {
#ifndef MAGNUM_TARGET_GLES
void Mesh::bindImplementationVAO() {
glBindVertexArray(vao);
bindVAO(vao);
}
#endif
@ -148,7 +163,7 @@ void Mesh::unbindImplementationDefault() {
#ifndef MAGNUM_TARGET_GLES
void Mesh::unbindImplementationVAO() {
glBindVertexArray(0);
bindVAO(0);
}
#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
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)
@ -354,9 +355,7 @@ class MAGNUM_EXPORT Mesh {
* @see @fn_gl{DeleteVertexArrays} (if
* @extension{APPLE,vertex_array_object} is available)
*/
inline virtual ~Mesh() {
(this->*destroyImplementation)();
}
virtual ~Mesh();
/** @brief Move assignment */
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);
static void MAGNUM_LOCAL bindVAO(GLuint vao);
void MAGNUM_LOCAL bind();
inline void unbind() {
@ -591,7 +592,7 @@ class MAGNUM_EXPORT Mesh {
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL destroyImplementationVAO();
#endif
static DestroyImplementation destroyImplementation;
static MAGNUM_LOCAL DestroyImplementation destroyImplementation;
typedef void(Mesh::*BindAttributeImplementation)(const Attribute&);
void MAGNUM_LOCAL bindAttributeImplementationDefault(const Attribute& attribute);

Loading…
Cancel
Save