Browse Source

GL: accept Mesh index offset as a pointer-sized value.

Vertex buffer offsets are like this already (and I already had a use
case with a mesh of size larger than 4 GB), with index buffers so far I
thought it's not needed, but it makes sense to do that as well -- there
can be a giant index buffer for many meshes and even though the total
drawn element count won't reach 1 billion (or 1 million, even), it can
still go over. Since it was internally already stored as a pointer-sized
value and some (but not all) code was treating it as pointer-sized, this
change just makes sense.

This also fixes "warning C4244: 'return': conversion from 'const
GLintptr' to 'Magnum::Int', possible loss of data" on MSVC, although in
a very different way.
pull/638/head
Vladimír Vondruš 2 years ago
parent
commit
b141901765
  1. 20
      src/Magnum/GL/Mesh.cpp
  2. 16
      src/Magnum/GL/Mesh.h

20
src/Magnum/GL/Mesh.cpp

@ -438,7 +438,7 @@ UnsignedInt Mesh::indexTypeSize() const {
}
#endif
Mesh& Mesh::setIndexOffset(Int offset) {
Mesh& Mesh::setIndexOffset(GLintptr offset) {
CORRADE_ASSERT(_indexBuffer.id(),
"GL::Mesh::setIndexOffset(): mesh is not indexed", *this);
_indexOffset = offset;
@ -871,7 +871,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
{
const Implementation::MeshState& state = Context::current().state().mesh;
const UnsignedInt indexByteOffset = _indexBuffer.id() ?
const GLintptr indexByteOffset = _indexBuffer.id() ?
_indexBufferOffset + indexOffset*meshIndexTypeSize(_indexType) :
0;
@ -900,7 +900,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
#else
state.drawRangeElementsBaseVertexImplementation
#endif
(GLenum(_primitive), indexStart, indexEnd, count, GLenum(_indexType), reinterpret_cast<GLvoid*>(std::size_t(indexByteOffset)), baseVertex);
(GLenum(_primitive), indexStart, indexEnd, count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexByteOffset), baseVertex);
/* Indexed mesh */
} else
@ -911,7 +911,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
#else
state.drawElementsBaseVertexImplementation
#endif
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(std::size_t(indexByteOffset)), baseVertex);
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexByteOffset), baseVertex);
}
#else
CORRADE_ASSERT_UNREACHABLE("GL::AbstractShaderProgram::draw(): indexed mesh draw with base vertex specification possible only since WebGL 2.0", );
@ -922,7 +922,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
#ifndef MAGNUM_TARGET_GLES2
/* Indexed mesh with specified range */
if(indexEnd) {
glDrawRangeElements(GLenum(_primitive), indexStart, indexEnd, count, GLenum(_indexType), reinterpret_cast<GLvoid*>(std::size_t(indexByteOffset)));
glDrawRangeElements(GLenum(_primitive), indexStart, indexEnd, count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexByteOffset));
/* Indexed mesh */
} else
@ -931,7 +931,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
static_cast<void>(indexEnd);
#endif
{
glDrawElements(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(std::size_t(indexByteOffset)));
glDrawElements(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexByteOffset));
}
}
@ -971,7 +971,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
#else
state.drawElementsInstancedBaseVertexBaseInstanceImplementation
#endif
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(std::size_t(indexByteOffset)), instanceCount, baseVertex, baseInstance);
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexByteOffset), instanceCount, baseVertex, baseInstance);
/* Indexed mesh with base vertex */
} else {
@ -980,7 +980,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
#else
state.drawElementsInstancedBaseVertexImplementation
#endif
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(std::size_t(indexByteOffset)), instanceCount, baseVertex);
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexByteOffset), instanceCount, baseVertex);
}
#else
CORRADE_ASSERT_UNREACHABLE("GL::AbstractShaderProgram::draw(): instanced indexed mesh draw with base vertex specification possible only since OpenGL ES 3.0", );
@ -996,7 +996,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
#else
state.drawElementsInstancedBaseInstanceImplementation
#endif
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(std::size_t(indexByteOffset)), instanceCount, baseInstance);
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexByteOffset), instanceCount, baseInstance);
/* Instanced mesh */
} else
@ -1007,7 +1007,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
#else
state.drawElementsInstancedImplementation
#endif
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(std::size_t(indexByteOffset)), instanceCount);
(GLenum(_primitive), count, GLenum(_indexType), reinterpret_cast<GLvoid*>(indexByteOffset), instanceCount);
}
}
}

16
src/Magnum/GL/Mesh.h

@ -753,7 +753,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
* @brief Index offset
* @m_since_latest
*/
Int indexOffset() const { return _indexOffset; }
GLintptr indexOffset() const { return _indexOffset; }
/**
* @brief Set index offset
@ -768,7 +768,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
* @p start and @p end parameters may help to improve memory access
* performance, as only a portion of vertex buffer needs to be
* acccessed. On OpenGL ES 2.0 this function behaves the same as
* @ref setIndexOffset(Int), as index range functionality is not
* @ref setIndexOffset(GLintptr), as index range functionality is not
* available there. Ignored when calling
* @ref AbstractShaderProgram::drawTransformFeedback().
*
@ -776,7 +776,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
* @see @ref setCount(), @ref isIndexed()
*/
/* MinGW/MSVC needs inline also here to avoid linkage conflicts */
inline Mesh& setIndexOffset(Int offset, UnsignedInt start, UnsignedInt end);
inline Mesh& setIndexOffset(GLintptr offset, UnsignedInt start, UnsignedInt end);
/**
* @brief Set index offset
@ -785,14 +785,14 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
*
* The offset gets multiplied by index type size and added to the base
* offset that was specified in @ref Mesh::setIndexBuffer(). Prefer to
* use @ref setIndexOffset(Int, UnsignedInt, UnsignedInt) for potential
* better performance on certain drivers. Ignored when calling
* @ref AbstractShaderProgram::drawTransformFeedback().
* use @ref setIndexOffset(GLintptr, UnsignedInt, UnsignedInt) for
* potential better performance on certain drivers. Ignored when
* calling @ref AbstractShaderProgram::drawTransformFeedback().
*
* Expects that the mesh is indexed.
* @see @ref setCount(), @ref isIndexed()
*/
Mesh& setIndexOffset(Int offset);
Mesh& setIndexOffset(GLintptr offset);
/** @brief Instance count */
Int instanceCount() const { return _instanceCount; }
@ -1443,7 +1443,7 @@ MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, MeshPrimitive value);
/** @debugoperatorenum{MeshIndexType} */
MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, MeshIndexType value);
inline Mesh& Mesh::setIndexOffset(Int first, UnsignedInt start, UnsignedInt end) {
inline Mesh& Mesh::setIndexOffset(GLintptr first, UnsignedInt start, UnsignedInt end) {
setIndexOffset(first);
#ifndef MAGNUM_TARGET_GLES2
_indexStart = start;

Loading…
Cancel
Save