Browse Source

Ability to specify index range in Mesh::setIndexBuffer().

pull/7/head
Vladimír Vondruš 13 years ago
parent
commit
f07e4743f9
  1. 2
      src/DebugTools/ObjectRenderer.cpp
  2. 40
      src/Mesh.cpp
  3. 43
      src/Mesh.h

2
src/DebugTools/ObjectRenderer.cpp

@ -161,7 +161,7 @@ template<std::uint8_t dimensions> ObjectRenderer<dimensions>::ObjectRenderer(Sce
->addInterleavedVertexBuffer(vertexBuffer, 0, ->addInterleavedVertexBuffer(vertexBuffer, 0,
typename Shaders::VertexColorShader<dimensions>::Position(), typename Shaders::VertexColorShader<dimensions>::Position(),
typename Shaders::VertexColorShader<dimensions>::Color()) typename Shaders::VertexColorShader<dimensions>::Color())
->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte); ->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 0, Renderer<dimensions>::positions.size());
ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); ResourceManager::instance()->set<Mesh>(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
} }

40
src/Mesh.cpp

@ -49,7 +49,12 @@ std::size_t Mesh::indexSize(IndexType type) {
CORRADE_INTERNAL_ASSERT(false); CORRADE_INTERNAL_ASSERT(false);
} }
Mesh::Mesh(Primitive primitive): _primitive(primitive), _vertexCount(0), _indexCount(0), indexOffset(0), indexType(IndexType::UnsignedInt), indexBuffer(nullptr) { Mesh::Mesh(Primitive primitive): _primitive(primitive), _vertexCount(0), _indexCount(0)
#ifndef MAGNUM_TARGET_GLES2
, indexStart(0), indexEnd(0)
#endif
, indexOffset(0), indexType(IndexType::UnsignedInt), indexBuffer(nullptr)
{
(this->*createImplementation)(); (this->*createImplementation)();
} }
@ -61,7 +66,11 @@ Mesh::~Mesh() {
(this->*destroyImplementation)(); (this->*destroyImplementation)();
} }
Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), _indexCount(other._indexCount), indexOffset(other.indexOffset), indexType(other.indexType), indexBuffer(other.indexBuffer), attributes(std::move(other.attributes)) Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), _indexCount(other._indexCount)
#ifndef MAGNUM_TARGET_GLES2
, indexStart(other.indexStart), indexEnd(other.indexEnd)
#endif
, indexOffset(other.indexOffset), indexType(other.indexType), indexBuffer(other.indexBuffer), attributes(std::move(other.attributes))
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
, integerAttributes(std::move(other.integerAttributes)) , integerAttributes(std::move(other.integerAttributes))
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -79,6 +88,10 @@ Mesh& Mesh::operator=(Mesh&& other) {
_primitive = other._primitive; _primitive = other._primitive;
_vertexCount = other._vertexCount; _vertexCount = other._vertexCount;
_indexCount = other._indexCount; _indexCount = other._indexCount;
#ifndef MAGNUM_TARGET_GLES2
indexStart = other.indexStart;
indexEnd = other.indexEnd;
#endif
indexOffset = other.indexOffset; indexOffset = other.indexOffset;
indexType = other.indexType; indexType = other.indexType;
indexBuffer = other.indexBuffer; indexBuffer = other.indexBuffer;
@ -95,9 +108,16 @@ Mesh& Mesh::operator=(Mesh&& other) {
return *this; return *this;
} }
Mesh* Mesh::setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type) { Mesh* Mesh::setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type, GLuint start, GLuint end) {
indexOffset = offset; indexOffset = offset;
indexType = type; indexType = type;
#ifndef MAGNUM_TARGET_GLES2
indexStart = start;
indexEnd = end;
#else
static_cast<void>(start);
static_cast<void>(end);
#endif
(this->*bindIndexBufferImplementation)(buffer); (this->*bindIndexBufferImplementation)(buffer);
return this; return this;
} }
@ -109,10 +129,18 @@ void Mesh::draw() {
(this->*bindImplementation)(); (this->*bindImplementation)();
/* Non-indexed mesh */ /* Non-indexed mesh */
if(!_indexCount) glDrawArrays(static_cast<GLenum>(_primitive), 0, _vertexCount); if(!_indexCount)
glDrawArrays(static_cast<GLenum>(_primitive), 0, _vertexCount);
#ifndef MAGNUM_TARGET_GLES2
/* Indexed mesh with specified range */
else if(indexEnd)
glDrawRangeElements(static_cast<GLenum>(_primitive), indexStart, indexEnd, _indexCount, static_cast<GLenum>(indexType), reinterpret_cast<GLvoid*>(indexOffset));
#endif
/* Indexed mesh */ /* Indexed mesh without specified range */
else glDrawElements(static_cast<GLenum>(_primitive), _indexCount, static_cast<GLenum>(indexType), reinterpret_cast<GLvoid*>(indexOffset)); else
glDrawElements(static_cast<GLenum>(_primitive), _indexCount, static_cast<GLenum>(indexType), reinterpret_cast<GLvoid*>(indexOffset));
(this->*unbindImplementation)(); (this->*unbindImplementation)();
} }

43
src/Mesh.h

@ -117,7 +117,7 @@ Buffer *vertexBuffer, *indexBuffer;
Mesh* mesh; Mesh* mesh;
// Fill vertex buffer with position data // Fill vertex buffer with position data
static constexpr Point3D positions[30] = { static constexpr Point3D positions[300] = {
// ... // ...
}; };
vertexBuffer->setData(positions, Buffer::Usage::StaticDraw); vertexBuffer->setData(positions, Buffer::Usage::StaticDraw);
@ -128,11 +128,11 @@ static constexpr GLubyte indices[75] = {
}; };
indexBuffer->setData(indices, Buffer::Usage::StaticDraw); indexBuffer->setData(indices, Buffer::Usage::StaticDraw);
// Set primitive, index count, add the buffers // Set primitive, index count, specify the buffers
mesh->setPrimitive(Mesh::Primitive::Triangles) mesh->setPrimitive(Mesh::Primitive::Triangles)
->setIndexCount(75) ->setIndexCount(75)
->addVertexBuffer(vertexBuffer, 0, MyShader::Position()) ->addVertexBuffer(vertexBuffer, 0, MyShader::Position())
->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte); ->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 176, 229);
@endcode @endcode
@code @code
@ -204,6 +204,10 @@ calls to @fn_gl{BindBuffer} and @fn_gl{BindVertexArray}. See documentation of
addVertexBuffer(), addInterleavedVertexBuffer(), addVertexBufferStride() for addVertexBuffer(), addInterleavedVertexBuffer(), addVertexBufferStride() for
more information. more information.
If index range is specified in setIndexBuffer(), range-based version of
drawing commands are used on desktop OpenGL and OpenGL ES 3.0. See also draw()
for more information.
@todo Support for indirect draw buffer (OpenGL 4.0, @extension{ARB,draw_indirect}) @todo Support for indirect draw buffer (OpenGL 4.0, @extension{ARB,draw_indirect})
@todo Redo in a way that allows glMultiDrawArrays, glDrawArraysInstanced etc. @todo Redo in a way that allows glMultiDrawArrays, glDrawArraysInstanced etc.
*/ */
@ -671,13 +675,39 @@ class MAGNUM_EXPORT Mesh {
* @param buffer Index buffer * @param buffer Index buffer
* @param offset Offset into the buffer * @param offset Offset into the buffer
* @param type Index data type * @param type Index data type
* @param start Minimum array index contained in the buffer
* @param end Maximum array index contained in the buffer
* @return Pointer to self (for method chaining) * @return Pointer to self (for method chaining)
* *
* The smaller range is specified with @p start and @p end the less
* memory operations are needed (and possibly some optimizations),
* improving draw performance. Specifying `0` for both parameters
* behaves the same as setIndexBuffer(Buffer*, GLintptr, IndexType).
* On OpenGL ES 2.0 this function behaves always as
* setIndexBuffer(Buffer*, GLintptr, IndexType), as this functionality
* is not available there.
* @see setIndexCount(), MeshTools::compressIndices(), * @see setIndexCount(), MeshTools::compressIndices(),
* @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if * @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if
* @extension{APPLE,vertex_array_object} is available) * @extension{APPLE,vertex_array_object} is available)
*/ */
Mesh* setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type); Mesh* setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type, GLuint start, GLuint end);
/**
* @brief Set index buffer
* @param buffer Index buffer
* @param offset Offset into the buffer
* @param type Index data type
* @return Pointer to self (for method chaining)
*
* Prefer to use setIndexBuffer(Buffer*, GLintptr, IndexType, GLuint, GLuint)
* for better performance.
* @see setIndexCount(), MeshTools::compressIndices(),
* @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if
* @extension{APPLE,vertex_array_object} is available)
*/
inline Mesh* setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type) {
return setIndexBuffer(buffer, offset, type, 0, 0);
}
/** /**
* @brief Draw the mesh * @brief Draw the mesh
@ -688,7 +718,7 @@ class MAGNUM_EXPORT Mesh {
* @see @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer}, * @see @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer},
* @fn_gl{VertexAttribPointer}, @fn_gl{DisableVertexAttribArray} * @fn_gl{VertexAttribPointer}, @fn_gl{DisableVertexAttribArray}
* or @fn_gl{BindVertexArray} (if @extension{APPLE,vertex_array_object} * or @fn_gl{BindVertexArray} (if @extension{APPLE,vertex_array_object}
* is available), @fn_gl{DrawArrays} or @fn_gl{DrawElements} * is available), @fn_gl{DrawArrays} or @fn_gl{DrawElements}/@fn_gl{DrawRangeElements}.
*/ */
void draw(); void draw();
@ -868,6 +898,9 @@ class MAGNUM_EXPORT Mesh {
GLuint vao; GLuint vao;
Primitive _primitive; Primitive _primitive;
GLsizei _vertexCount, _indexCount; GLsizei _vertexCount, _indexCount;
#ifndef MAGNUM_TARGET_GLES2
GLuint indexStart, indexEnd;
#endif
GLintptr indexOffset; GLintptr indexOffset;
IndexType indexType; IndexType indexType;
Buffer* indexBuffer; Buffer* indexBuffer;

Loading…
Cancel
Save