vertex arrays and textures

Ok, in the beginner forum noone had an answer, so here is my question again:

If you use vertex arrays, you can specify normals, colors, texture-coordinates, etc. per vertex. BUT how do you specify which TEXTURE to use?? It is possible to use glBindTexture, to draw multiple polys with this one texture, but i want to draw many textures with DIFFERENT textures. Up to now, i would do it by drawing all polys that use texture 1 via glDrawArrays, then switch to the next texture, then use glDrawArrays again, bla bla bla. But this would make vertex arrays nearly useless, because i would have to switch to the next texture after every single polygon! (I don´t have them sorted by texture.)
There must be another way, so how do you do it?

Jan.

You can not switch textures within an vertex array flush. Why do you think the most new engines use only one basetexture per object? So that they don’t need that many API calls and can let the GPU keep working.

But this would make vertex arrays nearly useless, because i would have to switch to the next texture after every single polygon!

If you are too lazy to switch your brain on to find a solution for this that’s half right. Where by glArrayElement is still faster than immediate mode. Vertex Arrays are FAR faster than immediate mode. If you use video or AGP memory for them anyway. But you can’t await of OpenGL to compensate the matter that you are not open to write just one single line of code more than needed.

Following things you can do:

Possibility 1:
If you draw a landscape for example and you have only some less different textures you can create X independent arrays (one for each texture) and always store the new vertices in the adapting array. When it’s filled then you can flush all the way:
select texture 0
draw array 0
select texture 1
draw array 1

Possibility 2:
Kicking your 3D graphician into his butt to texturize the models again so that only still one texture is used per object. Then simply storing all models in a queue and sorting them by quicksort before they’re flushed.

Possibility 3:
Would at least help a bit: Sorting your textures within the model, when it’s loaded.

I think the most people use possibility 2… me as well. If you have already many models done then… you have a bunch of work now.

Hm… reading your post I am still waiting for the day someone asks, why OpenGL can’t automatically play a sound, when a primitive is drawn…

For the case you should also be too lazy to write a quicksort yourself, here some code you can modify by your needs:

void C09AphLyxMemoryBank::QuickSortChains(C09AphLyxMemoryChain *data,int from,int to)
{
if(from==to)
return;

int Lo,Hi,Mid;
C09AphLyxMemoryChain T;

Lo = from;
Hi = to;
Mid = (int)data[(Lo + Hi)/2].mlpPointer;

do
{
while((int)data[Lo].mlpPointer < Mid)
Lo++;
while((int)data[Hi].mlpPointer > Mid)
Hi–;

  if(Lo <= Hi)
  {
  	T=data[Lo];
  	data[Lo] = data[Hi];
  	data[Hi] = T;
  	Lo++;
  	Hi--;
  };

} while( !(Lo > Hi));

if(Hi > from)
QuickSortChains(data, from, Hi);
if(Lo < to)
QuickSortChains(data, Lo, to);
};

BlackJack

Thanks, Black Jack.
Well, i never heard that engines allow only one texture per object, because i know only WorldCraft and that allows multiple textures per object.
Of course i am able to make a workaround, but as everybody else i first would like to know, if there is another solution, so i don´t have to make a workaround, that might me less effective. To your concerns i might have to recreate my whole program: No, i don´t have work i now have to change, because i am just beginning to use VAR and i am not working on a big project.
Also thanks for the quicksort algorithm, i don´t need it, because i am able to write a sorting algorithm, but maybe other people who read this might take use of it.
Another thing: I won´t ask you why OpenGL cannot play sounds, i use OpenAL for that. However i think OpenGL should be able to check for mouse and keyboard input.

I really thank you for your post, but next time please don´t write such things, they can really **** someone ***:

If you are too lazy to switch your brain on to find a solution for this that’s half right.

But you can’t await of OpenGL to compensate the matter that you are not open to write just one single line of code more than needed.

Hm… reading your post I am still waiting for the day someone asks, why OpenGL can’t automatically play a sound, when a primitive is drawn…

For the case you should also be too lazy to write a quicksort yourself, here some code you can modify by your needs:

Jan.

You do know what the ‘GL’ part of OpenGL means, do you?

However, what do you think about grouping polys by material and render them like the following pseudo-code?

// welcome to the mesh render function
//
// each mesh has several submeshes
// each submesh has a different material

// set all pointers (vertices, normals, texcoords, vertex colors, blah, blah, blah)
glVertexPointer(…);
glEnableClientState(GL_VERTEX_ARRAY);

glBlahPointer(…);
glEnableClientState(GL_BLAH);

for (list::iterator it=submeshes.begin(); it!=submeshes.end(); ++it) {
somewhereinthecurrentnamespace::sceneManager->setCurrentMaterial((*it).materialID);

glDrawElements(GL_TRIANGLES, (it).numberOfFaces3, GL_UNSIGNED_SHORT, Indices + (*it).whereShouldOpenGLstartReadingInThisArray);
}

If this all seems like blah to you, read it another time.

> However i think OpenGL should be able to check for mouse and keyboard input.
GLUT

Never heard of irony???

I really thank you for your post, but next time please don´t write such things, they can really **** someone ***

Sorry, but when I read your post it sounded very much the way for me : “I could do this… but don’t like to… and that I could do as well… but why should I, can’t OpenGL do all that for me” and people thinking that way make me pissed off in general . Ever heard the sentense “Stupid question - Stupid answer?” btw.?

BlackJack

[This message has been edited by BlackJack (edited 07-28-2002).]

You have to sort by texture. Typically, that’s done in the exporter from your art tool.

When you talk about multi-texturing, that’s multiple texture units pulling different textures and blending them for the same polygon. Look into ActiveTexture() and ClientActiveTexture() and TexEnv() for more information about how to set this up. You can’t rely on there being more than two texture units on currently popular cards, though – although some modern cards go to 8. The work-around is to multi-pass the same array with different textures.

Once your art pipe and rendering reaches this level of sophistication, it’s time to start thinking about materials (“shaders”) rather than individual textures. The basic render loop then becomes:

determine visible objects
determine materials used by visible objects
for each used material
determine number of passes needed
foreach pass for this material
set state
for each object piece using the material
render the object piece with the material

Addition: I realize that it may not be obvious from the above comment: When you export your model, you have to break the model into pieces; one piece per material. This “piece” typically consists of a vertex array, an index array, and a reference to a material. Whether you stick the material descriptions themselves in the same file, or in a separate file, is up to you, although separate file is usually more flexible as it makes mix-and-match easier. Of course, it makes “plunking the thing into the world” a little harder as you have to specify both a geometry file and a material description to make it render.

[This message has been edited by jwatte (edited 07-28-2002).]

Hm, you are right, i could sort the objects by material, but my problem is, that i want to use BSP-Trees. And when i use a BSP-Tree it only works when i really stick to the order. This means that i am not able to sort the objects by material, otherwise my sort-by-depth wouldn´t be right anymore. I thought if it is possible to create the BSP-Tree in a way, that some subtrees content only objects with one texture, so i could at least optimize it a bit, but i think this is very hard to do.
So this was one reason for my question. id and all the other developers use BSP-Trees and they use vertex-arrays. I thought that they just walk their tree, store the needed order of drawing in an array and in the end they call glDrawElements, or so, to draw the polys in the specific order. But this is impossible when you need to switch the texture often. And i thought that it might be much faster if gl switches the textures automatically for every poly as when i do it per hand. I didn´t mean the question in the way “how can i have less work?” but in the way “is there a way which yields a better performance?”.
So maybe you understand me better now.

Jan.