Passing texture data to glTexImage2D.

Hello there…

I’ve written a program that uses the wgl_arb_render_texture extension to render something to a pbuffer. After doing so, I want to use the pbuffer that I have just rendered to as a texture in two different OpenGL rendering windows (contexts).

So far no problems; I can render to the pbuffer and render two quads in both rendering windows using the pbuffer-based texture that I have just generated.

I want to use mip mapping for the textures in both rendering Windows using the GL_SGIS_generate_mipmap extension; the mip maps need to be generated whenever the pbuffer-texture is updated. And this is where things go wrong…

When I’m finished rendering something to my texture, I do the following (I’m using Borland Delphi 7, “Texture” is of type GLUInt, RTT_SIZE is the width / height of my texture in pixels):


glBindTexture(GL_TEXTURE_2D, Texture);
//Generate the actual mip maps:
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, RTT_SIZE, RTT_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, Texture);

First of all, I don’t know if I have to call “glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)” every time, but that’s probably not a problem.

And as far as the formats (GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE) in the glTexImage2D()-call are concerned: I don’t know (yet) if these are the right formats, but I will figure them out (I hope).

The problem is the “Texture” parameter that I would like to pass to the glTexImage2D()-call; I know that my texture “lives” in the “Texture” variable (and in the actual PBuffer, which I can access through Delphi’s THandle), but I cannot simply “point” glTexImage2D to it by passing it as a pointer to glTexImage2D like this:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, RTT_SIZE, RTT_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, Texture);

Or this (mind the “@”, Delphi’s memory location operator):

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, RTT_SIZE, RTT_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, @Texture);

Of course, I would not like to copy the image from the texture (pbuffer) into an auxiliary array only in order to be able to pass it to glTexImage2D; there must be some better (and more efficient) way; after all, the texture already resides in the “Texture” variable / in the pbuffer.

Any ideas on how to accomplish this? Some help would be greatly appreciated. Thanks in advance.

GRTZ,

(Sn)Ik.

[This message has been edited by VuurSnikkel (edited 03-04-2004).]

the SGIS_generate_mipmap flag should be set only once. then each time the base level of a texture is modified (with TexImage or TexSubImage), all the mipmap levels are automatically updated as well.

regarding the interaction with WGL_ARB_render_texture, information is given in the spec :

Should we specify how this extension interacts with SGIS_generate_mipmap?

No, since this is a potential ARB extension and SGIS_generate_mipmap is not. If SGIS_generate_mipmap is supported along with this extension, then if wglBindTexImageARB is called and both GENERATE_MIPMAP_SGIS and    WGL_MIPMAP_TEXTURE_ARB are TRUE, then a set of mipmaps should be generated.

Well, thanks for the reply, but…

This is just great. Both GL_GENERATE_MIPMAP_SGIS and WGL_MIPMAP_TEXTURE_ARB are set to GL_TRUE when I bind the pbuffer as a texture (I’m absolutely sure about that), but there’s still something wrong; it is clear to me that the application is indeed generating mipmaps (I can clearly see the difference with standard GL_LINEAR filtering), but one of the higher (“smaller”) mipmap levels is completely corrupted (it looks like a bunch of random pixels, I think it’s the 32x32 one).

The funny thing is that when I scale my textured quad down even further, another, even smaller, mipmap blends in (which clearly shows that GL_LINEAR_MIPMAP_LINEAR is doing its thing and that mipmaps have been generated), but this smaller one isn’t corrupted anymore; so it’s one of the in-between levels that’s corrupted… Very strange. Here’s the .exe if you want to see what I mean (just move the lower slider to the left): http://www.sickcrew.com/~inforum/vuursnikkel/mme/mipmaperror.zip .

If you haven’t got the problem (here’s a series of screenshot illustrating it: http://www.sickcrew.com/~inforum/vuursnikkel/mme/mipmaperror1.jpg through …/mipmaperror6.jpg), then it must have something to do with my drivers. Strange thing is that I’ve updated my Detonator WinXP drivers (running on an Ati Radeon 9800 Pro) a couple of days ago, so it would really be weird if it is actually a driver problem. But who knows…

If you could check if you’ve got the same problem, I would be really grateful.

GRTZ,

(Sn)Ik.

[This message has been edited by VuurSnikkel (edited 03-04-2004).]

the executables crashes with access violation at startup.

re-reading your first post, I’m not sure you got OpenGL texturing mechanism right. Excuse me if I’m wrong, but I think an explanation could help.

Textures are objects. You create an identifier with glGenTexture. Then you bind this identifier to the proper target (eg TEXTURE_2D). In your first post, you use a variable named “Texture”. This should be an integer with a valid texture ID (ie one you got from GenTexture). When your texture is bound, the associated object is “active” (or current). There is a set of parameters associated with each texture, which can be modified by glTexParam*. GL_generate_mipmap_SGIS (or whatever it is) is one of them. You usually set parameters you like at texture creation time. After that, you call TexImage/TexSubImage to load/update the actual content into the texture object. Note that the last parameter is a pointer to the data. In your first post, you seem to think that this is the adress of the object. That’s not the case. Plus “@Texture” will just give you the adress of your variable holding the identifier of the texture object, not the adress of the object itself.

To sum up :
glTexParam* affects the current (bound) texture object. This objects of course keeps track of the parameters (no need to re-set the parameters each time you use the texture).
glTexEnv affects the target texture unit. It will affect the way this unit deals will all textures.
glTexImage needs a pointer to raw data, not a pointer to a texture object (which you have no way to get anyway).

'lo again…

Hmmm, it’s starting to become clearer now. But I still have a question about the wgl_arb_render_texture extension in combination with the gl_sgis_generate_mipmaps extension: if I have created my pbuffer and have rendered contents to it and want to start using it as a texture, I assume the mipmaps are automatically generated, not? Or do I actually still have to call a command each time after updating the texture in order to get the gl_sgis_generate_mipmaps extension to do the actual generation of the mipmaps (i.e. does this extension only relieve me of actually creating each of the mipmap levels myself)? And if so, what is the fastest way to pass the raw texture (image) data that resides in the pbuffer (my offscreen texture) to the function that generates the mipmaps, because I assume that I have to pass the raw image data to that function?

Greetings and thanks for your previous replies,

(Sn)Ik.

[This message has been edited by VuurSnikkel (edited 03-06-2004).]