Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: glDrawElements

  1. #11
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,474
    Quote Originally Posted by richman.feynard View Post
    Then I don't understand why it doesn't work now, like I said at the beginning of the thread?
    In OpenGL 3+ core profile, the last argument to glDrawElements() is an offset into the buffer currently bound to GL_ELEMENT_ARRAY_BUFFER (which, unlike other buffer bindings, is stored in the current VAO). It is an error to call glDrawElements() if no buffer is bound to that target.

    In earlier versions of OpenGL, and in the compatibility profile, if no buffer is bound to that target then the last argument is treated as a pointer to client memory.

    A similar principle applies to most other buffer bindings: OpenGL 3+ core profile requires a buffer to be bound, while the compatibility profile sources data from client memory if no buffer is bound. If you're planning on transitioning legacy code to OpenGL 3+ core profile, check the descriptions of the various targets in the glBindBuffer() documentation. Most of the functions which used to take a pointer to "bulk" data now require that data to be copied to a buffer first. The main exception is that texture data can still be sourced directly from client memory, even in the core profile; you don't have to use GL_PIXEL_UNPACK_BUFFER.

  2. #12
    Intern Newbie
    Join Date
    Mar 2017
    Posts
    47
    I think GClements gave a nice explanation to 'DrawElements' functionality. I don't know what version of OpenGL you're using, but I'll assume when you tried the code you made in your initial post, you were trying to do it in 3.3 core or above.

    I've only been learning 3.3 core, so I'll write about it from that perspective, maybe it'll help. As GClements said, the last argument in glDrawElements --3.3 core-- is an offset to the first element location (the first element you want to send for drawing, I mean) referenced in the currently bound element array buffer object (the state holding the currently bound element array buffer object is maintained by VAO's, which is why you bind a VAO before calling a drawing command like glDrawElements in your program). Here's what it says in 2.8.3 of the 3.3 core spec (DrawElementsOneInstance is equivalent to DrawElements in the spec, it's written as DrawElementsOneInstance for spec. writing purposes):

    The command 'void DrawElementsOneInstance( enum mode, sizei count, enum type, const void *indices )' ... constructs a sequence of geometric primitives by successively transferring the count elements whose indices are stored in the currently bound element array buffer (see section 2.9.7) at the offset defined by --indices-- to the GL.
    (I added the dashes to indicate that means the "indices" arugment. Same thing in later quote I mention.)

    So in 3.3 core, that last argument is like an index argument.

    -----

    I've never tried OpenGL in specifically OpenGL 2, but I took a look at the 2.1 spec. Looks like the last argument to the DrawElements function actually wants an array of indices, unlike 3.3 core, which just wants a single index. Here's what it says in 2.8 of the 2.1 spec:

    The command 'void DrawElements( enum mode, sizei count, enum type, void *indices );' constructs a sequence of geometric primitives using the count elements whose indices are stored in --indices--.
    Interestingly, looks like OpenGL 2 wants that argument to be an array. As GClements puts it, in this case, the function may treat that last argument as something you pass a pointer to client memory (which makes sense, given that you would pass an array you define in your program [which resides in what's called your client], and in passing an array in C/C++ you're technically passing a pointer to the first element of the array [C/C++ element in this sense, not OpenGL element]). I'm not really sure what GClements means about having "no buffer bound to that target", I've never tried OpenGL 2. In 3.3 core, I've found I must bind a VAO whose state includes reference to a bound element array buffer object. But nonetheless, I can see from the spec there's indication of passing an array in OpenGL 2.

    ------

    So ya, looking form the specs, there seems to be a difference in DrawElements functionality in OpenGL 2 and OpenGL 3.3 core, but this may be because of the idea of having a core profile in OpenGL 3 (OpenGL 2 doesn't have the notion of core or compatibility profiles). I glanced at the OpenGL 3.3 compatibility spec, looks like it mentions the "array" thing like in the GL 2 spec. I guess in general, the compatibility profile for 3.3 allows you to either pass an array or an index depending on whether a certain buffer object is bound (again, not sure what specifically, guessing in 3.3, it must involve whether a VAO is bound or not before the glDrawElements call). And the core profile, in attempting to be more modern, doesn't allow that "array" passing stuff.

    ------

    Overall, what I'm seeing from the specs, in OpenGL 2, for DrawElements, you pass an array. In 3.3 core, you must pass an index. So I can see how if you tried to pass an array like you did in 3.3 core, you wouldn't get the same results as in OpenGL 2. In fact, since passing an array is like passing a pointer, 3.3 core would probably just be interested in the first element of the array you passed and not care about the rest of the array.

    And In 3.3 compatibility, I think you're able to do both: either pass an array or pass an index, depending on some certain conditions. Hope that helps with clarification.

  3. #13
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,715
    Actually in 2.x you can do either.

    If a buffer object is bound to the ELEMENT_ARRAY_BUFFER binding point the last argument is interpreted as an offset into that buffer object's data store.

    If a buffer object is not bound then it's an array of elements in client memory.

    It's incorrect to say that buffer objects are a modern OpenGL feature. They've actually been around since GL 1.5 and are available to even earlier versions via extensions. What is a modern OpenGL feature is making them mandatory.
    Last edited by mhagain; 11-05-2017 at 09:10 AM.

  4. #14
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,474
    Quote Originally Posted by DragonautX View Post
    I've never tried OpenGL in specifically OpenGL 2, but I took a look at the 2.1 spec. Looks like the last argument to the DrawElements function actually wants an array of indices, unlike 3.3 core, which just wants a single index.
    All versions want an array of indices. The choice is between an array of indices stored in client memory and an array of indices stored in a buffer object.

  5. #15
    Intern Newbie
    Join Date
    Mar 2017
    Posts
    47
    (to mhagain) Oh ok, thanks for the correction. Never did any OpenGL beyond 3.3 core. That's cool how buffer objects were around even beck around the OpenGL 1 times.

  6. #16
    Intern Newbie
    Join Date
    Mar 2017
    Posts
    47
    (to GClements) That's a better way of saying it, thanks. It's nice to see a consistency of requiring an array of elements between OpenGL 2 and 3.

  7. #17
    Junior Member Newbie
    Join Date
    Jul 2017
    Posts
    14
    Thank you all for your replies.

    I'm using mac, so I don't have much choice. I first, wrote my application using GLUT and OpenGL without any extensions, that is version 2.x, I presume. Then I rewrote everything with GLUT_3_2_CORE_PROFILE, and after that version of OpenGL and GLSL became 4.1 and some parts stopped working, like I said at the beginning. I also used glWindowPos2i and glutBitmapCharacter for some simple text print, but for now it's not working, even if I use glWindowPos2iARB.

  8. #18
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,474
    Quote Originally Posted by richman.feynard View Post
    I also used glWindowPos2i and glutBitmapCharacter for some simple text print, but for now it's not working, even if I use glWindowPos2iARB.
    glutBitmapCharacter() uses glBitmap(), which isn't available in 3+ core profile. Likewise for glRasterPos() and glWindowPos(); there isn't much point when all of the functions which use the raster position have been removed.

    You'll need to use textured triangles instead.

    GLUT's utility functions (text and geometric shapes) won't work in a core profile, although its window and event management still works. Similarly, much of GLU won't work in a core profile.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •