egen material push/pop? (C++/OpenGL)

Permalänk
Medlem

egen material push/pop? (C++/OpenGL)

Hej hej!

Jag håller på att skriva en egen push/pop material och behöver lite hjälp. Så här ser min nuvarande kod ut:

void MaterialNode::PushMaterial(){ Material *m=new Material(); glGetMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,m->ambient ); glGetMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,m->diffuse ); glGetMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,m->specular ); glGetMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,&m->shininess ); //textureid=? //shaderid=? backup.push_back(m); }

Och som ni ser vet jag inte hur man kan spara undan texturid samt shaderid, det som sparas kommer alltså från föregående nod, men dom vet inte av varandra så jag antar att man får hämta värden på detta sätt.

Noden tillhör ett träd i scengrafstil ifall det är relevant. Noden kan vara en förälder till en annan typ av nod och kan ev ha flera barn av olika nodtyper. Push & Pop är nödvändigt för att material skall återställas till det rätta så att inte fel objekt råkar få föregående material osv...

Om ni har några lösningar eller idéer, printa gärna ner dom Jag testade med glPushAttrib(GL_ALL_ATTRIB_BITS) men den var alldeles för slö, antar jag nu manuellt måste spara undan det jag vill.

mvh Dalton Sleeper

stavfel
Permalänk
Medlem

Finns det nån anlening att hantera en stack av material? Personligen skulle jag nog bara göra glSetMaterial med mitt aktiva material varje gång jag ritar, om det skiljer sig från det föregående materialet.

Dessutom: använd en riktig stack för materialet om du verkligen måste göra så där. new:a inte runtime om du bryr dig om prestanda. Det kanske inte ser så illa ut för dig, men om koden växer och du gör så där överallt kommer det bli kaos

Ett annat sätt att göra det är att implementera egna stateobjekt. Alltså en struct som innehåller information om material, blendmodes och liknande. Din renderare tar sedan in ett och ett sådant (eller en lista) och sätter bara de states som ändrats för varje renderbatch.

Visa signatur

void@qnet
teeworlds, stålverk80, evil schemer, c, c++
Languages shape the way we think, or don't.

Permalänk
Medlem

okey, ska försöka rita lite:
M=Material
T=Transformation
G=Geometri

Antag preorder som traverseringsalgoritm.

M | T / \ M G / \ G T \ G

Skulle det inte vara användbart med push/pop här? Skulle nog bli lite omständigt att leta uppåt i trät för att kolla senaste material som tillhör rätt delträd. Mina tankar perkar på en stack som alla materialnoder kan komma åt, som pushar & poppar då man passerar dom, dock har jag ingen aning om hur det skulle bli med new som du nämnde, eller om man kan ha en statisk allokerad för varje nod som backup, sen pekare i en stack, då kan man lätt kolla tillbaka på föregående material. Allt snurrar i skallen just nu :S

Permalänk
Medlem

Generellt sett ska du ALDRIG anropa glGet* eller push/pop attrib. Mycket bättre att hålla en egen attribstack med just de settings du är intresserad av. Om du nu verkligen behöver ett så pass dynamiskt träd du har där så behöver du en materialstack ja, men implementera den som en array/vector av Material* där du pushar pekaren till din materialnod, du kan sedan enkelt sätta det gamla materialet när du pop:ar. Om du är ute efter prestandan bör du dock försöka minimera state changes rent generellt. Det är rätt enkelt att alltid sätta alla parametrar hela tiden, och drivrutinerna kan hjälpa dig i viss mån att se vad som verkligen ändrats, men de kan aldrig göra den viktigaste optimeringen, vilket är att sortera om renderpatchar så att statechanges minimeras. Detta därför att API:t garanterar batchordningen.

Visa signatur

void@qnet
teeworlds, stålverk80, evil schemer, c, c++
Languages shape the way we think, or don't.

Permalänk
Medlem

Okey ska diskutera detta med min handledare så får vi se vad som händer.
Självklart vill vi ha det så snabbt & effektivt som möjligt, dock behålla flexibiliteten.