PDA

View Full Version : Optimizing indexed vertex arrays



Paulius
07-07-2005, 11:43 AM
In some formats, like Obj files, normals, vertex and texture coordinates are indexed separately and assembling a proper indexed array out of it is driving me nuts. Anybody got any ideas except bruteforcing?

technomage
08-07-2005, 08:32 AM
you will always get this problem , no matter what format you use. What I tend to do is decide on my own internal structure for verticies, normals , tex coordinates and convert the file format to that when loading the file, it might be a little more extra work, but because you've decided on your structure you can use the most optimal method to render it.

I use glVertexPointer, glTexCoordPointer rather than interlieved arrays and I make sure all the models I use can converted in to my structure when loaded.

I hope this helps?

Paulius
08-07-2005, 08:47 AM
No dood, what I meant was that assembling a vertex array (when loading) out of it without duplicate vertices only duplicate indices is giving me a hard time.

technomage
08-07-2005, 09:38 AM
Ah, well I do a manual check for duplicates and replace the index of the duplicate with the index of the one already in the array. The problem is if the texture coords/normals are different for each duplicate vertex... not sure how you would resolve that without using brute force, unless you allow duplicates with different tecture coords/normals

Paulius
08-07-2005, 09:30 PM
Okay, bruteforce it is. I went about it building a simple vertex array out of different components and onlly then extracting an indexed one out of that. Mayby someone will find this usefull.

//generate indicies
SetLength(Indicies, Count);
for j:= 0 to Count-1 do
Indicies[j]:= j;

//Reindex and mark unused vericies
SetLength(WasShifted, Count);
FillChar(WasShifted[0], Count, 0);
for j:= 2 to Count-1 do
begin
Vert1:= @Varray[j * VertSize];
for k:= 0 to j-1 do
begin
Vert2:= @Varray[Indicies[k] * VertSize];
Found:= True;
for l:= 0 to VertSize-1 do
if Vert1^[l] <> Vert2^[l] then
begin
Found:= False;
Break;
end;
if Found then
begin
WasShifted[j]:= True;
Indicies[j]:= Indicies[k];
Break;
end;
end;
end;

//Mark planed movement of useless verticies
StepVector:= nil;
SetLength(StepVector, Count);
Step:= 0;
for j:= 0 to Count-1 do
begin
StepVector[j]:= Step;
if WasShifted[j] then
Step:= Step + 1;
end;

//Defragment used vericies
for j:= 2 to Count-1 do
if not WasShifted[j] then
begin
Vert1:= @Varray[j * VertSize];
Vert2:= @Varray[(j - StepVector[j]) * VertSize];
for i:= 0 to VertSize-1 do
Vert2^[i]:= Vert1^[i];
end;
SetLength(Varray, (Count - Step) * VertSize);
//correct indicies
for j:= 0 to Count-1 do
Indicies[j]:= Indicies[j] - StepVector[Indicies[j]];

VertSize is the number of vertex components, everything else should be pretty clear.