PDA

View Full Version : Multitexturing Performance


Avenger
21-05-2004, 20:15
Hoi!
Ich spiele mich schon länger mit Multitexturing bei unserem Terrain herum. Funktioniert soweit ganz gut und schaut net aus, nur haben wir einen Performanceeinbruch von 180fps auf 20fpshttp://hades.gothic.at/iforum/images/smilies/ahhh.gif
Ich weiss nicht, woran das liegen könnte. Habe den Code schon ein paar mal durchforstet, aber nichts gefunden. Hat jemand ähnliche Erfahrungen bzw. irgendwelche Hinweise?
Anbei mal der relevante Sourcecode. (der glbegin-glend block ist aus einem tutorial kopiert, da ich mal Fehler bei unseren Zeichnungsroutinen ausschliessen will)

Besten Dank für Eure Hilfe

for(i = 0; i < model.numOfObjects; i++) {

t3DObject *pObject = &(model.pObject[i]);
pObject->displayList=glGenLists(1);
glNewList(pObject->displayList,GL_COMPILE);

if(pObject->bHasTexture) {
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glColor3ub(255, 255, 255);
glBindTexture(GL_TEXTURE_2D, g_Texture[pObject->materialIDs[0]]);

if (pObject->multitexture && configuration::getMultitexturing()) {
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glColor3ub(255, 255, 255);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);


glBindTexture(GL_TEXTURE_2D, g_Texture[pObject->materialIDs[1]]);

glMatrixMode(GL_TEXTURE);
// diese skalierung könnte man auch vorher berechnen
// aber ändert nichts an performance

glLoadIdentity();
glScalef((float)configuration::getMultitexturing_S cale(), (float)configuration::getMultitexturing_Scale(), 1);

glMatrixMode(GL_MODELVIEW);
}

} else {

glDisable(GL_TEXTURE_2D);
glColor3ub(255, 255, 255);
}

glBegin(GL_TRIANGLES);
for(int j = 0; j < pObject->numOfFaces; j++) {
for(int whichVertex = 0; whichVertex < 3; whichVertex++) {
int index = pObject->pFaces[j].vertIndex[whichVertex];

glNormal3f(pObject->pNormals[ index ].x, pObject->pNormals[ index ].y, pObject->pNormals[ index ].z);

if(pObject->bHasTexture) {
if(pObject->pTexVerts) {
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y);

if (pObject->multitexture && configuration::getMultitexturing()) {
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y);
}

}
} else {

if(model.pMaterials.size() && pObject->materialIDs[0] >= 0) {
BYTE *pColor = model.pMaterials[pObject->materialIDs[0]].color;

glColor3ub(pColor[0], pColor[1], pColor[2]);
}
}

glVertex3f(pObject->pVerts[ index ].x, pObject->pVerts[ index ].y, pObject->pVerts[ index ].z);
}
}

glEnd();

if(pObject->bHasTexture) {
if (pObject->multitexture && configuration::getMultitexturing()) {
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
}
glEndList();
}

Chuck
21-05-2004, 21:20
habt ihr das ganze schon ohne die ARB_texture_env_combine extension versucht? schon klar dass das dann nicht wirklich so aussieht, wies sollte aber als test wärs mal n hint wenn da die performance wieder hochgeht. ajo und auf wasfür einer grafikkarte gibts diese performance probs?

Avenger
21-05-2004, 21:54
grad das ganze ohne die extension versucht.
keine veränderung
grafikkarten sind ati 9700 pro und ati 9600


lg avenger

Chuck
21-05-2004, 22:28
hm ok die karten dürften ned das prob sein :)

dann mal eine wilde vermutung *g*
schon versucht anstatt
glColor3ub(pColor[0], pColor[1], pColor[2]);

glColor4ub(pColor[0], pColor[1], pColor[2],255);
zu verwenden? (ati karten hams nicht gern wenn ihnen
daten in nicht 32 bit ausgerichteten blöcken serviert werden...)
[edit hoppla bei den ganzen uneingerückten ifs nicht bemerkt, dass garkeine color per vertex angegeben wird... hmm kamma wohl den vorschlag kübeln *g* bzw einfach mal n glColor4ub(0xff,0xff,0xff,0xff); da reinquetschen]

ansonsten nachgeschaut obs irgendwelche errors gibt (mit glGetError)
weiters kamma auch mal versuchen das ganze in immediate mode zu rendern (also ohne display list) und schaun wies sich da verhält.

btw ein sehr feines tool um versteckte fehler zu finden kamma hier http://glintercept.nutty.org/
downloaden (ist ne modifizierte opengl32.dll die alle gl calls mitprotokolliert und etwaige errors rausschreibt... ausserdem noch recht genial weil alle texturen die an opengl geschickt werden als bilder gespeichert werden :) )

Avenger
21-05-2004, 22:49
also das mit den colors wars nicht.
immediate mode habe ich schon vorher probiert. gleicher müll...
probier jetzt mal das glintercept aus

lg

Avenger
21-05-2004, 23:51
glinterceptor liefert auch keine fehler.
schön langsam frag ich mich wirklich, was da noch falsch sein kann...

Chuck
21-05-2004, 23:56
mhm langsam fält mir auch nix mehr ein...
wann tritt der slowdown genau auf?
reichts nur die zweite tex unit zu aktivieren?
oder muss man die texturkoordinaten für diese unit liefern damits langsamer wird
bzw wenn die tex unit deaktiviert ist und die tex koordinaten übergeben werden ist auch noch n fall den man testen sollte.

Avenger
22-05-2004, 00:05
alles schon getestet:-)
slowdown tritt schon bei programmstart auf

1) GL_TEXTURE1_ARB aktiviert, texturkoordinaten deaktiviert: ca 120 fps
2) GL_TEXTURE1_ARB deaktiviert, textkoordinaten aktiv: 20 fps
3) GL_TEXTURE1_ARB deaktiviert, textkoordinaten deaktiviert: 120fps
4) GL_TEXTURE1_ARB aktiviert, textkoordinaten aktiviert: 20 fps

Chuck
22-05-2004, 00:17
sprich erst wenn die texturkoordinaten für die zweite texture unit dazukommen wirds richtig langsam... also ehrlichgesagt ich hab nicht den leisesten schimmer was da los sein kann :( ... der einzige workaround der mir da jetzt einfällt wäre einfach ein vertex program zu schreiben (oder sich mal das texgen zeugs anschaun), das die texturkoordinaten für das terrain erzeugt (so hab ichs zumindest gemacht... dann braucht man keine einzige tex coord mehr übergeben und spart im endeffekt auch ordentlich daten ein. wobei vielleicht solltest du dir auch überlegen überhaupt komplett auf vertex buffer objects umzusteigen... die sind immer ein heisser tip für gute performance)... tut leid dass ich nicht weiterhelfen konnte :confused:

ps hier ein kleines bsp vertex program, das eigentlich für jedes terrain funzen sollt...

!!ARBvp1.0
#dieses vertexprogramm generiert texturkoordinaten für das terrain
OPTION ARB_position_invariant;
PARAM mvp[4]={state.matrix.mvp};
ATTRIB iPos=vertex.position;

OUTPUT oColor=result.color;
OUTPUT oTex0=result.texcoord[0];
OUTPUT oTex1=result.texcoord[1];


TEMP temp;

MUL temp, iPos,{0.00048828125,0.00048828125,0.00048828125,1} ;
MOV oTex0, temp;
MOV oTex1, temp;


MOV oColor, {1,1,1,1};


END

Avenger
22-05-2004, 00:24
vertex buffer objects sind bereits implementiert
allerdings selbes performance problem
vielleicht schau ich mir das mit dem vertexprogramm noch an.
besten dank jedenfalls für deine hilfe
vielleicht hat ja jemand anders noch tips.

ChrisChiu
22-05-2004, 00:25
Hoi!
Ich spiele mich schon länger mit Multitexturing bei unserem Terrain herum. Funktioniert soweit ganz gut und schaut net aus, nur haben wir einen Performanceeinbruch von 180fps auf 20fpshttp://hades.gothic.at/iforum/images/smilies/ahhh.gif
Ich weiss nicht, woran das liegen könnte. Habe den Code schon ein paar mal durchforstet, aber nichts gefunden. Hat jemand ähnliche Erfahrungen bzw. irgendwelche Hinweise?
Anbei mal der relevante Sourcecode. (der glbegin-glend block ist aus einem tutorial kopiert, da ich mal Fehler bei unseren Zeichnungsroutinen ausschliessen will)

Besten Dank für Eure Hilfe

for(i = 0; i < model.numOfObjects; i++) {

t3DObject *pObject = &(model.pObject[i]);
pObject->displayList=glGenLists(1);
glNewList(pObject->displayList,GL_COMPILE);

if(pObject->bHasTexture) {
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glColor3ub(255, 255, 255);
glBindTexture(GL_TEXTURE_2D, g_Texture[pObject->materialIDs[0]]);

if (pObject->multitexture && configuration::getMultitexturing()) {
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glColor3ub(255, 255, 255);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);


glBindTexture(GL_TEXTURE_2D, g_Texture[pObject->materialIDs[1]]);

glMatrixMode(GL_TEXTURE);
// diese skalierung könnte man auch vorher berechnen
// aber ändert nichts an performance

glLoadIdentity();
glScalef((float)configuration::getMultitexturing_S cale(), (float)configuration::getMultitexturing_Scale(), 1);

glMatrixMode(GL_MODELVIEW);
}

} else {

glDisable(GL_TEXTURE_2D);
glColor3ub(255, 255, 255);
}

glBegin(GL_TRIANGLES);
for(int j = 0; j < pObject->numOfFaces; j++) {
for(int whichVertex = 0; whichVertex < 3; whichVertex++) {
int index = pObject->pFaces[j].vertIndex[whichVertex];

glNormal3f(pObject->pNormals[ index ].x, pObject->pNormals[ index ].y, pObject->pNormals[ index ].z);

if(pObject->bHasTexture) {
if(pObject->pTexVerts) {
glMultiTexCoord2fARB(GL_TEXTURE0_ARB,pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y);

if (pObject->multitexture && configuration::getMultitexturing()) {
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y);
}

}
} else {

if(model.pMaterials.size() && pObject->materialIDs[0] >= 0) {
BYTE *pColor = model.pMaterials[pObject->materialIDs[0]].color;

glColor3ub(pColor[0], pColor[1], pColor[2]);
}
}

glVertex3f(pObject->pVerts[ index ].x, pObject->pVerts[ index ].y, pObject->pVerts[ index ].z);
}
}

glEnd();

if(pObject->bHasTexture) {
if (pObject->multitexture && configuration::getMultitexturing()) {
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
}
glEndList();
}

Schon mal probiert statt der Display Lists das ganze einfach so auszuführen?

Das sollte zwar dann langsamer als mit Display Lists sein, aber wer weiß wie die Implementation der Display Lists in der ATI-Treiber-Version die ihr verwendet, ist (ich hab da bei Catalyst 3.8 schon mal ziemlich extreme Merkwürdigkeiten beobachten können).

Noch eine dumme Frage (bitte nicht als Beleidigung auffassen :D): generiert ihr die Display List eh nur einmal und ruft die dann auf, d.h. das Code-Snippet von euch ist nur von der Display List Initialisierung, und nicht aus der Render Loop?

Avenger
22-05-2004, 12:37
schon alle erdenklichen möglichkeiten ausprobiert:
mit displaylists, ohne, immediate mode, vertex arrays, ...
immer selbes problem
etwas interessantes ist mir aufgefallen:
wenn ich nur 1x texturkoordinaten übergeben (entweder an GL_TEXTURE1_ARB oder an GL_TEXTURE0_ARB) habe ich keinen performanceeinbruch. ich sehe halt entweder die detail textur oder die normale textur.

die displaylist wird nur 1xgeneriert und dann im render loop aufgerufen

lg

Chuck
22-05-2004, 13:35
letzter einfall:

auf die aktuellsten cataclyst treiber updaten falls du das noch nicht gemacht hast :)

Avenger
22-05-2004, 15:45
das habe ich auch schon gemacht:-)
ich habe jetzt aus einem tutorial 1zu1 den source code kopiert.
im tutorial (von www.gametutorials.com) habe ich ~80 fps.
nach dem einfügen in unser spiel, fällt die framerate wieder auf 20fps.
habe dann terrain texutur und terrain heightmap in das turorial eingefügt.
dort habe ich 80fps (d.h. gleiche anzahl vertices + gleiche texturen)
ich glaub bald pfeife ich auf multitexturinghttp://hades.gothic.at/iforum/images/smilies/biggrin.gif

Avenger
23-05-2004, 18:13
autsch!!!!
jetzt habe ich testweise mal fog eingefügt.
ich habe einen änhlichen performanceeinbruch wie beim multitexturing.
da muss irgendwas global faul sein.
hat jemand ideen?

lg

ChrisChiu
24-05-2004, 04:34
autsch!!!!
jetzt habe ich testweise mal fog eingefügt.
ich habe einen änhlichen performanceeinbruch wie beim multitexturing.
da muss irgendwas global faul sein.
hat jemand ideen?

lg

Du gibst hoffentlich eh nicht in jedem Frame etwas über printf() auf die Konsole aus oder ähnliches? (auch etwa "SetWindowText" zum Setzen des Fenstertitels unter Windows wäre z.B. langsam).

Avenger
24-05-2004, 16:29
nope tun wir nicht.
wenn es sowas wäre, könnte ich ja nicht einfach durch auskommentieren einer zeile (texturkoordinaten) wieder die vollen fps haben.
ist es event. denkbar, dass irgendeine art von speicher ausgeht und geswapt werden muss?

ChrisChiu
24-05-2004, 16:59
nope tun wir nicht.
wenn es sowas wäre, könnte ich ja nicht einfach durch auskommentieren einer zeile (texturkoordinaten) wieder die vollen fps haben.
ist es event. denkbar, dass irgendeine art von speicher ausgeht und geswapt werden muss?

Ja, ist denkbar. Kommt auf die OpenGL-Implementation (Treiber) an, aber laut Standard sollten Display Lists minimal zumindest so schnell wie Immediate Mode sein. In der Praxis kann es aber sein (z.B. bei vielen "kleinen" Display Lists), dass der Overhead für die Display Lists größer wird als der Nutzen.

Wieviele Display Lists verwendet euer Terrain?

Avenger
24-05-2004, 22:12
display lists habe ich jetzt mal ausgeschalten.
eine fehlerquelle weniger.
unser terrain hat derzeit 256*256 vertices. (lod oder culling noch nicht implementiert)
sind das vielleicht zu viele?
habe probiert, terrain 2x zu zeichnen:
2* draw methode aufgerufen: kaum veränderung der fps (graka cullt anscheinend)
2* draw methode aufgerufen mit 1x verschieben: fps fallen auf 27

lg