glTexImage2d and Null data
Asked Answered
D

2

14

This is a weird question but I was wondering why glTexImage2d cares about the pixel data type and format of Null data. The signature for glTexImage2d is...

void glTexImage2D( GLenum target, GLint level, GLint internalFormat, 
           GLsizei width, GLsizei height, GLint border, GLenum format, 
           GLenum type, const GLvoid * data);

The internalFormat acts to tell the graphics driver what you want to store the data as on the gpu and the format and type tell the graphics driver what to expect from GLvoid * data. So, if I don't pass any data, by passing null for instance, why does the graphics driver care what the format and type is? So this is a weird question because sometimes it doesn't. The times when it does, and I haven't checked every single iteration but, is specifically when making a depth texture, or something I've come across recently is the Integer types, like GL_RED_INTEGER, GL_RG_INTEGER, etc. and/or their corresponding internalFormats like GL_R8I, GL_RGBA32UI. Whereas, any of the "simple" types don't have to correspond in anyway to the internalFormat, like GL_RGBA8, GL_RGBA32F, etc. For some reason, the former particular data types and formats have to be exact even if you're not passing any data. Why is that?

Dolf answered 20/11, 2013 at 20:21 Comment(0)
P
11

There are two formats in a call to glTexImage2D (...), the internal format and the format used for pixel transfer. The internal format is necessary to allocate storage for the texture, the pixel transfer format is used by GL to interpret the (optional) array of pixels you pass.

When you pass NULL for the pixel data, no pixel transfer occurs so you would think that format and type would be unnecessary. Technically, they are unnecessary in this case, but GL still validates the pair of format and type. You can use any valid pair of values you want there, since no pixel transfer operation will actually occur. All you are doing is allocating texture storage.

By the way, glTexStorage2D (...) is the modern way of allocating texture storage without pixel transfer. You can create immutable textures this way, where you cannot accidentally re-define a texture LOD by an incorrect glTexImage2D (...) call. After allocating texture storage with glTexStorage2D (...) you can feed it data by calling glTexSubImage2D (...).

Prank answered 20/11, 2013 at 21:40 Comment(0)
I
3

If you're not passing any data, it still allocates the memory on the GPU for further use. That's why you have to specify exact format; to tell GPU how much memory it has to reserve.

Inexactitude answered 20/11, 2013 at 20:24 Comment(1)
I am pretty sure he was referring to the pixel transfer format, and not the internalFormat ;) You can even get away without specifying an exact format on older implementations - it is declared as GLint instead of GLenum because you used to (GL 2.x) be able to use 1,2,3 or 4 for the internalFormat to tell GL how many components the texture image needed.Prank

© 2022 - 2024 — McMap. All rights reserved.