Using multi-texture, vertex array, and compression

Does anyone have any expirerence (or a good website) for how to use vertex-arrays while using multi-texturing? It would be also helpfull if someone knew how to do s3tc compression, and use the textures (yes, I’ve looked at all the EXT and ARB writeups on them, and looked through all the OGL resources I know).

Multitexturing while using vertex arrays is easy. Just enable the texture coordinate array for each texture unit. Make sure you use glClientActiveTexture instead of glActiveTexture when setting texture coordinate array.

// pseudocode
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(…);
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(…);

That will assign each two texture units different sets texture coordinates, given that they point to different arrays ofcourse.

I think you need “ARB” at the end of function name and definitions, like glClientActiveTextureARB(GL_TEXTURE0_ARB), and remember to query for the GL_ARB_multitexture extension first.

[This message has been edited by Nil_z (edited 03-14-2001).]

ARB is not a requirement. Since it’s an extension, and (on Win32 at least) you have to declare a functionpointer with a name, you can choose whatever name you want, so you can skip the ARB-part if you wany

Phew, I managed to handle that one…

Joke aside. Yes, you are right, but it was pseudocode, you know, code that just shows how something is working.

Thanks for the help so far, but does this mean that I can’t use the function that draws using all the arrays automatically (I forget the function right now, but I thought it was supposed to be faster). Also, does that mean that I should draw each element by its self? That was my main trouble was that I didn’t know how to efficently use multi-texturing.

I didn’t realize the trick of the function name yes, that is a way to avoid the annoying “ARB”,“EXT”… but I can not remove the _ARB in the definition, unless I redefine it.

to HFAFiend: this is just the way to use all arrays automatically(with multitexture). you can use:
glClientActive(GL_TEXTURE0_ARB);
glTexCoordPointer(…);
glClientActive(GL_TEXTURE1_ARB);
glTexCoordPointer(…);

to specify texture coordinate for each texture stage, and use a glDrawElements() or sth. like gl***Elements() to draw the polygon with multitexture in a single call. Well, that is simple and smart

HFAFiend, do you mean by the function name glInterleavedArrays? The matter is that the function cannot use arrays with multiple texture coordinates (it has not an appropriate format). But that’s not a problem at all because glInterleavedArrays is not faster than sequence of common gl…Pointer commands.

glInterleavedArrays is just a “wrapper” for a few gl*Pointer calls. If you have an interleaved array, there is nothing that stops you from using “ordinary” vertex arrays ineatd.

Thank you all for your help, that’s what I was wondering.

You can use multiple texture coordinates using interleaved arrays. All you have to do is enable texture unit 0, then do a call like this:-

glInterleavedArrays(GL_T2F_N3F_V3F, 0, full_array);

Then enable texture unit 1, and do this:-

glInterleavedArrays(GL_T2F_V3F, 0, secondtex_array);

then…

glDrawArrays()…

secondtex_array should just contain the texture coordinates of the second texture (although you have to specify the vertex again, but it won’t be transformed (hopefully)).
It works fine…although interleaved arrays are very slow…so don’t use them.

Originally posted by kieranatwork:
It works fine…although interleaved arrays are very slow…so don’t use them.

Why do you say that? Do you mean writing individual components to an interleaved array allocated in AGP or video mem is slow? I think that would be the correct statement.

There is nothing that prevent interleaved arrays from being as fast as “ordinary” vertex arrays. Either they aren’t very optimized in your implementation, or you are using a format that is not optimized. It’s just a matter of optimization.

Originally posted by kieranatwork:
[b]You can use multiple texture coordinates using interleaved arrays. All you have to do is enable texture unit 0, then do a call like this:-

glInterleavedArrays(GL_T2F_N3F_V3F, 0, full_array);

Then enable texture unit 1, and do this:-

glInterleavedArrays(GL_T2F_V3F, 0, secondtex_array);

then…

glDrawArrays()…

secondtex_array should just contain the texture coordinates of the second texture (although you have to specify the vertex again, but it won’t be transformed (hopefully)).
[/b]

Of course, you can use glInterleavedArrays in like manner.
However, you should use the secondtex_array first and the full_array second. Otherwise your normals won’t be used, as well as your vertex data in the full_array. So for two texture units 1 and 2 your code may look something like this:

glActiveTextureARB(GL_TEXTURE0_ARB)
glBindTexture(GL_TEXTURE_2D,0)

glEnable(GL_TEXTURE_2D)

glInterleavedArrays(GL_T2F_V3F,0, secondtex_array)

glActiveTextureARB(GL_TEXTURE1_ARB)
glBindTexture(GL_TEXTURE_2D,1)

glEnable(GL_TEXTURE_2D)

glInterleavedArrays(GL_T2F_N3F_V3F, 0, full_array)

glDrawArrays()

Now you have to specify normal and vertex coordinates only in the full_array. However, the secondtex_array still contains 12 unused bytes of vertex data per each element. So if you already have an interleaved array, you may replace first call of glInterleavedArrays with glTexCoordPointer():

glClientActiveTextureARB(GL_TEXTURE0_ARB)
glTexCoordPointer(2,GL_FLOAT,0,tex_array)
…,
where tex_array is a pointer to a usual sequent array of texture coordinates. Correct me if I’m wrong.
Alexei.