5

I need to cast an int (which specifies a byte offset) to a const void*. The only solution that really works for me are c-style casts:

int offset = 6*sizeof(GLfloat);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)offset);

I want to get rid of the c-style cast, but I dont't find a working solution. I tried

static_cast<void*>(&offset)

and it compiles, but that cannot be the right solution (whole output is different with this approach). What is here the right solution?

Link to documentation of glVertexAttribPointer: Link

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
Matthias Preu
  • 783
  • 2
  • 8
  • 18
  • 5
    When I see casts and/or void pointers I usually think that somebody is doing something wrong. This is usually the case. – Ed Heal Oct 05 '14 at 10:46
  • I tried reinterpret_cast but also get a non working result. @Ed Heal: How could I avoid that cast when using the OpenGL-API and a void pointer is required? – Matthias Preu Oct 05 '14 at 10:56
  • 1
    What is that last parameter and why do you think that your conversion makes sense? – Ulrich Eckhardt Oct 05 '14 at 11:06
  • Have to revise my statement regarding reinterpret_cast. I bring it to work with that, but thats as bad as a c-style cast. @UlrichEckhardt: Last parameter is const void* or const GLvoid* as you can see here: [link](https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml) – Matthias Preu Oct 05 '14 at 11:18
  • Look at [this](http://stackoverflow.com/questions/8283714/what-is-the-result-of-null-int) question. It contains a quite nice way to avoid that cast (in essence: `(char*)nullptr + offset`) – user1781290 Oct 05 '14 at 11:40
  • `reinterpret_cast(offset)` should work - it's exactly what that C-style cast means. @user1781290 Pointer arithmetic on `(char*)nullptr` is UB. – T.C. Oct 05 '14 at 12:30
  • @T.C. As is `reinterpret_cast` for any usage besides casting the value back to its original type afterwards, afaik. EDIT: Didn't want to sound offending. I just cannot think of a way to do this without invoking UB – user1781290 Oct 05 '14 at 14:03
  • @user1781290 Well, you can pass the resulting pointer along just fine. The library function would be doing the casting back. – T.C. Oct 05 '14 at 14:13
  • Hmmm, looking at the documentation, it plainly sucks. As it stands, I don't see a way to use it correctly without first looking at either the implementation or other working code. Maybe it becomes clearer to someone that's used to this library's interface, so I'd consider filing a bug report. – Ulrich Eckhardt Oct 06 '14 at 17:09
  • 2
    @UlrichEckhardt: Well, that is a classic design flaw of the OpenGL API. When introducing buffer objects, they decided to reuse the pre-existing pointer functions also for offsets in those buffers, see also Issue "Is it legal C to use pointers as offsets?" in the [GL_ARB_vertex_buffer_object spec](https://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt). Unfortunaly, this has been with us since over a decade, and is going to stay a lot longer. To make things worse, modern GL does not even accept client memory pointers anymore, so this is _only_ used for byte offsets as `void*`... – derhass Oct 06 '14 at 18:36
  • possible duplicate of [How to cast int to const GLvoid\*?](http://stackoverflow.com/questions/23177229/how-to-cast-int-to-const-glvoid) – Reto Koradi Oct 10 '14 at 02:24

2 Answers2

5

Considering that it's a hopeless case (See the link provided by derhass), the probably best approach is to concentrate the questionable code in one place, tack an appropriately snide remark onto it and at least keep the remaining code clean:

/**
 * Overload/wrapper around OpenGL's glVertexAttribIPointer, which avoids
 * code smell due to shady pointer arithmetic at the place of call.
 *
 * See also:
 * https://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt
 * https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml
 */
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset)
{
    GLvoid const* pointer = static_cast<char const*>(0) + offset;
    return glVertexAttribPointer(index, size, type, stride, offset);
}
Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
3

Use this instead of void pointer:

intptr_t

which is declared in header file file cstdint

and inter-convert from pointer by using

reinterpret_cast

Read this in case of any problem: http://msdn.microsoft.com/en-us/library/e0w9f63b.aspx