3

I have an OpenGL scene with thousands of vertices and would like to pass them as VBOs/IBOs. Executing the glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxVertices) command reveals a limitation of 2048 max amount of vertices, despite the fact I have a recent video card. In addition to that, an array in C is limited to an int, hence 32k vertices max.

How can I work around these limitations to anyway display all my objects ?

Laurent Crivello
  • 3,809
  • 6
  • 45
  • 89
  • An array in C is limited to an int? – Flexo Aug 19 '11 at 14:38
  • When I use something else than an integer in the brackets (e.g. MyArray[double_variable]), it tells me "Array subscript is not an integer". – Laurent Crivello Aug 19 '11 at 14:56
  • 2
    `double`s can't be an array index, but `long` can be. `int` and `long` are both integers. It's rare for `int` to be as small as 16 bits on platforms with recent videos cards too. – Flexo Aug 19 '11 at 15:02
  • What OpenGL implementation and platform/compiler is this? – Dr. Snoopy Aug 19 '11 at 15:55
  • You must be developing on exceedingly old hardware to get a 2048 size on `GL_MAX_ELEMENTS_VERTICES`. – Nicol Bolas Aug 19 '11 at 18:08
  • Not really, on an iMac from 2010... – Laurent Crivello Aug 19 '11 at 18:56
  • `MAX_ELEMENTS_VERTICES` and `MAX_ELEMENTS_INDICES` are only suggestions, they are not hard limits. [The OpenGL spec](http://www.opengl.org/registry/doc/glspec44.core.pdf) (page 329) states that if you keep your sizes/ranges below those limits, you will get optimal performance. If you exceed those suggestions, you may get reduced performance. – doug65536 Feb 03 '14 at 19:21

3 Answers3

5

The GL_MAX_ELEMENTS_VERTICES constant only applies to the glDrawRangeElements call and even then values larger than that will surely not make glDrawRangeElements slower than glDrawElements. It is not a good idea to manually split your batches into smaller parts, as batches should be as large as possible and draw calls as few as possible. Just forget about this value, it has no real meaning anymore.

And by the way, I'm quite sure your int can hold values much larger than 32k, as on modern platforms (at least those with a graphics device that supports VBOs) an int should be at least 32bits wide (and therefore be able to hold values like 2G/4G). Although on an embedded device (using OpenGL ES) you might still be limited to 16bit vertex indices.

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
  • Thanks, but an array in C only accepts an integer as index, hence 32k elements. How can I reach your 2M then ? – Laurent Crivello Aug 19 '11 at 15:36
  • 1
    @Laurent Like I (and awoodland's comment) said, an `int` being only 16 bits wide (which is equivalent to a +/-32k range) in C is very unlikely on a modern platform, where it should usually be at least 32 bits wide (meaning a +/- 2G range, not only 2M). Where did you get this information about an `int` only being 16 bits? – Christian Rau Aug 19 '11 at 15:45
  • Thanks, it starts slowly to make sense to me ! I don't know where I get this int limit to 32k, maybe in the past indeed. I am developing on Cocoa/Xcode. Let me try with int anyway then. – Laurent Crivello Aug 19 '11 at 16:45
  • @Christian Rau: Can you confirm that GL_MAX_ELEMENTS_VERTICES and GL_MAX_ELEMENTS_INDICES are not used anymore? What else would you use to decide when to split up draw calls? What would you use in OpenGL ES? See my question [here](https://gamedev.stackexchange.com/questions/142490/how-and-when-to-split-draw-calls-in-opengl-and-opengl-es). – Bim Jun 16 '17 at 18:48
2

Doesn't GL_MAX_ELEMENTS_VERTICES just tell you the most vertices that can be passed to a single call of glDrawRangeElements? Is there a reason you can't split your scene into bits and render the bits one by one?

Rupert Swarbrick
  • 2,793
  • 16
  • 26
  • 1
    So basically I could have a VBO of 30k elements for example and pass it piece by piece using glDrawRangeElement ? – Laurent Crivello Aug 19 '11 at 15:12
  • Yep, I think so. See the docs: http://www.opengl.org/sdk/docs/man/xhtml/glDrawRangeElements.xml To avoid the possible reduced performance, you just have to give it bounds for where the indices you're using lie. – Rupert Swarbrick Aug 19 '11 at 15:15
1

Divide your total number of vertices by 2048 and create than many VBOs

void glGenBuffersARB(GLsizei n, GLuint* ids)

So n would be (total / 2048)+1 and ids would be a GLuint array containing (total / 2048)+1

Louis Ricci
  • 20,804
  • 5
  • 48
  • 62
  • Thanks. Should I then do the glBindBuffer, glBufferData, glVertexPointer and glDrawElements for each single VBO, or is it sufficient that I run them once ? – Laurent Crivello Aug 19 '11 at 14:54