OpenGL blending Probleme



  • Hallo,

    ich möchte mit folgenden beiden Texturen:

    http://www.pictureupload.de/pictures/290807114926_1.jpg
    http://www.pictureupload.de/pictures/290807115008_2.jpg

    folgenden Effekt erzielen, wie er hier mit einer Ziegelwand und einer Grastextur erreicht wird. Also ein weiches "übergehen" von einer Textur zur Anderen.

    http://www.pictureupload.de/pictures/290807115502_ziel.jpg.jpg

    Allerdings erhalte ich eine totale Durchsichtigkeit, die von einer Seite zur anderen abnimmt ( Aber es werden die beiden Texturen schon übereinander geblendet, denn man sieht eine Mischung aus beiden Texturen)
    Damit man es besser sieht vor einem Berge Hintergrund

    http://www.pictureupload.de/pictures/290807121619_Beispiel.jpg

    Ich mache es mit folgndem Code

    void test_blending()
    	{
    			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  //Blending Funktion
    
    			glDisable(GL_LIGHTING);								//Licht ausschalten
    			glEnable(GL_BLEND);									//Blending aktivieren
    
    			glActiveTextureARB(GL_TEXTURE0_ARB);				//Textureinheit 0 aktivieren
    			glBindTexture(GL_TEXTURE_2D,land.get_Textur(0)->get_texture());  //Textur 0 laden
    			glEnable(GL_TEXTURE_2D);							//2D Texturierung aktivieren
    
    			glActiveTextureARB(GL_TEXTURE1_ARB);				//Textureinheit 1 aktivieren
    			glBindTexture(GL_TEXTURE_2D,land.get_Textur(1)->get_texture());		//Textur 1 laden
    			glEnable(GL_TEXTURE_2D);							//2D Texturierung aktivieren
    
    			glBegin(GL_QUADS);									//Das 4-Eck zeichnen
    
    			glColor4f(1.0f,1.0f,1.0f,1.0f);
    			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);	//Koordinaten für die nullte Textureinheit
    			glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);	//Koordinaten für die erste Textureinheit
    			glVertex3d(10,10,10);
    
    			glColor4f(1.0f,1.0f,1.0f,1.0f);
    			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f);
    			glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f);
    			glVertex3d(10,10,20);
    
    			glColor4f(1.0f,1.0f,1.0f,0.0f);
    			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f);
    			glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f);
    			glVertex3d(20,10,20);
    
    			glColor4f(1.0f,1.0f,1.0f,0.0f);
    			glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f);
    			glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f);
    			glVertex3d(20,10,10);
    
    			glEnd();
    
    			glDisable(GL_TEXTURE_2D);								//Zeichnen der 1. Textureinheit abschalten
    
    			glDisable(GL_BLEND);									//Blending ausschalten
    			glEnable(GL_LIGHTING);									//Licht wieder anmachen
    
    			glActiveTextureARB(GL_TEXTURE0_ARB);					//Textureinhait null wieder aktivieren
    	}
    

    Was mache ich falsch?



  • Warum schaltest du Alpha-Blending ein?
    Wenn du das mit Multi-Texturing lösen willst, ist das Unfug, und das ist auch der Grund, warum dein Rechteck transparent erscheint.

    Ohne Multi-Texturing würde ich es wie folgt machen:
    Zuerst das Rechteck mit Grastextur rendern, ohne Alpha-Blending (volle Opazität).
    Dann renderst du die Mauertextur mit Alpha-Blending drüber und setzt da, wo die Mauer voll sichtbar sein soll, den Alphawert der Vertizes auf 100% und da, wo nur das Gras sichtbar sein soll, auf 0%.

    Das geht sicher auch mit Multi-Texturing (dann bräuchtest du nur einen Durchgang), aber damit kenne ich mich bzgl. OpenGL nicht aus.



  • Also ohne multitexturing weiß ich wie das geht:

    Rock.SetTexture;
      glBegin(gl_Quads);
        glColor4f(1,1,1,1);
        glTexCoord2f(0,0);
        glVertex3f(-1,-1,0);
    
        glColor4f(1,1,1,0);
        glTexCoord2f(1,0);
        glVertex3f(1,-1,0);
        glTexCoord2f(1,1);
        glvertex3f(1,1,0);
    
        glColor4f(1,1,1,1);
        glTexCoord2f(0,1);
        glvertex3f(-1,1,0);
      glEnd;
    
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA,GL_DST_ALPHA);
    
      gras.SetTexture;
      glBegin(gl_Quads);
        glColor4f(1,1,1,0);
        glTexCoord2f(0,0);
        glVertex3f(-1,-1,0);
    
        glColor4f(1,1,1,1);
        glTexCoord2f(1,0);
        glVertex3f(1,-1,0);
        glTexCoord2f(1,1);
        glvertex3f(1,1,0);
    
        glColor4f(1,1,1,0);
        glTexCoord2f(0,1);
        glvertex3f(-1,1,0);
      glEnd;
    

    Aber wie geht das mit multitexturing, so das es schneller geht?



  • Ich denke, Du mußt noch (mit glTexEnv?) einstellen, wie die Texturen ineinander geblendet werden.



  • Hallo,

    ich habe mit glTexEnvi(...); experimentiert:

    z.B:

    glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); 
    			glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
    

    Da es aber sooo viele Möglichkeiten gibt habe ich die richtige nicht gefunden.

    Die eigentliche Frage ist ja, wie man bei der 0. Textureinheit das Blending auschaltet. (So das es bei der 1. Textureinheit aktiv bleibt)

    Hat Jemand dazu eine Idee (oder weiß wie es geht )?



  • In Direct3D geht es, indem du bei der 2. Textur den Operator D3DTOP_BLENDDIFFUSEALPHA verwendest. Jetzt musst du nur noch das OpenGL-Äquivalent dazu finden 😉



  • Vieleicht hilft dir diese Seite etwas weiter: http://wiki.delphigl.com/index.php/Tutorial_Lektion_7



  • Hallo, etwas hilft diese Seite, doch genau das Entschgeidende fehlt:

    Wie funktioniert das ganze nun für uns? OpenGL verwendet als Standard die Unit 0. Binden wir eine Textur oder definieren das Blending so beziehen sich alle diese Angaben immer auf die momentan selektierte Textur-Unit. Alles was wir machen müssen ist, die gewünschte auszuwählen:

    glActiveTextureARB(GL_TEXTURE0_ARB);Ich denke der Parameter erklärt sich praktisch von selbst! GL_TEXTURE1_ARB wäre entsprechend die zweite Textur-Unit. Nun setzen wir alle Einstellungen für diese Unit:

    glEnable(GL_TEXTURE_2D);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    wall.SetTexture;Zunächst teilen wir der Unit mit, dass sie bei der 2D-texturierung zur Verfügung stehen soll. Anschließend setzen wir die Textur-Envroiment auf die "Standard-Einstellung". Wenn mich jetzt jemand fragt, wofür die Parameter gut sind, dann zitiere ich das RedBook "es muss so sein" 😉 Wichtig ist eigentlich nur, dass hinten GL_MODULATE steht, damit die Textur ordnungsgemäß, so wie wir sie sehen auf das Quad wandern.

    glActiveTextureARB(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glEnable(gl_BLEND);
    glBlendFunc(GL_ONE,GL_ONE);
    light.SetTexture;Wir wechseln danach zur zweiten Textur-Unit und machen ähnliche Einstellungen, aktivieren zusätzlich jedoch Blending für diese Funktion. Diesmal etwas sehr simples.

    Denn genau für das Problem haben se den Code nicht hingeschrieben:

    Wir wechseln danach zur zweiten Textur-Unit und machen ähnliche Einstellungen, aktivieren zusätzlich jedoch Blending für diese Funktion.

    Wie kann man das Blending nur für die 2. Textur Unit aktivieren?

    Denn wenn ich glEnable(GL_BLEND); schreibe wenn Textur Unit 1 aktiv wirkt sich das trotzdem auch auf Texturunit 0 aus, denn auch hierbei ist das Ergebnis insgesamt transparent

    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    			glActiveTextureARB(GL_TEXTURE1_ARB);               
                glEnable(GL_TEXTURE_2D);
    			glEnable(GL_BLEND);                                             //Hier
     			glBindTexture(GL_TEXTURE_2D,land.get_Textur(0)->get_texture());
    	        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    
                glActiveTextureARB(GL_TEXTURE0_ARB);               
                glEnable(GL_TEXTURE_2D);                           
       			glBindTexture(GL_TEXTURE_2D,land.get_Textur(1)->get_texture()); 
    			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    
                glBegin(GL_QUADS);                                    
    
                glColor4f(1.0f,1.0f,1.0f,1.0f); 
                glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,1.0f);    
                glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,1.0f);    
                glVertex3d(10,10,10); 
    
                glColor4f(1.0f,1.0f,1.0f,1.0f); 
                glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,1.0f); 
                glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,1.0f); 
                glVertex3d(10,10,20); 
    
                glColor4f(1.0f,1.0f,1.0f,0.0f); 
                glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0f,0.0f); 
                glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0f,0.0f); 
                glVertex3d(20,10,20); 
    
                glColor4f(1.0f,1.0f,1.0f,0.0f); 
                glMultiTexCoord2fARB(GL_TEXTURE0_ARB,1.0f,0.0f); 
                glMultiTexCoord2fARB(GL_TEXTURE1_ARB,1.0f,0.0f); 
                glVertex3d(20,10,10); 
    
                glEnd(); 
    
    			glActiveTextureARB(GL_TEXTURE1_ARB); 
    
                glDisable(GL_TEXTURE_2D);                                
                glDisable(GL_BLEND);                                    
                glActiveTextureARB(GL_TEXTURE0_ARB);
    

    Weiß Jemand wie der Code aussieht, der mit diesem Satz erähnt ist, dort aber leider nicht steht?




Anmelden zum Antworten