# OpenGL Blend Frage



## Helgon (16. Jan 2012)

Hey, ich hab grade gemerkt, dass die Methode wie ich sie verwende (aus nem Tutorial) 2 Texturen überblenden zu lassen bei eingeschaltetem depth test nicht funktioniert (ist ja auch logisch weils 2x die gleiche position ist). 

Gibts ne Elegantere Art das zu lösen als ich es tue, sodass der Depth test anbleiben kann? (außer die dreiecke an leicht andere Positionen zu verschieben)



```
//glEnable(GL_DEPTH_TEST);         				
		glEnable(GL_CULL_FACE);  						
		
		glViewport(0, 0, 800, 600);							
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(45, 800 / 600, 0.1f, 1000);

		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		
		glTranslatef(0, 0 , -6f);

		while(!Display.isCloseRequested()){
			

			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
			 

			  glLoadIdentity();
			  gluLookAt(0,2,8,
			            0,0,0,
			            0,1,0);
			  glPushMatrix();
			  
			  glEnable(GL_BLEND);
			  glBlendFunc(GL_SRC_ALPHA,GL_ONE);
			  glColor4f(1,1,1,0.5f);
			  
				t1.bind();				
				glBindTexture(GL_TEXTURE_2D, t1.getTextureID());
				glBegin(GL_TRIANGLES);
					glTexCoord3f(-1,-1, 0);	glVertex3f(-1,-1,0); 
					glTexCoord3f(1,-1, 0);	glVertex3f(1,-1,0);
					glTexCoord3f(0,1, 0);	glVertex3f(0,1,0);
				glEnd();
				
				t2.bind();				
				glBindTexture(GL_TEXTURE_2D, t2.getTextureID());
				glBegin(GL_TRIANGLES);
					glTexCoord3f(-1,-1, 0);	glVertex3f(-1,-1,0); 
					glTexCoord3f(1,-1, 0);	glVertex3f(1,-1,0);
					glTexCoord3f(0,1, 0);	glVertex3f(0,1,0);
				glEnd();
```

Grüße


----------



## Spacerat (16. Jan 2012)

1. Kleiner Nachtrag zu einem Anderen Thread...(werd' ich der Vollständigkeit halber dort auch noch posten.) www.joachimrohde.com - Artikel

2. Bei Lektion 8 (Blending) ist dort nachzulesen, warum sich Transparenz (Blending) und Tiefentest gegeneinander ausschliessen (leider nicht automatisch ).


----------



## Helgon (16. Jan 2012)

Hab glaub ich an die 30 OpenGL Tutorial Seiten (unteranderem auch die gefunden xD), aber OpenGL ist wirklich nicht so wie "mal eben ne neue Sprache lernen".. man muss sich doch recht konzentrieren und rumprobieren, damit man auch wirklich weis was da passiert.. - Dachte erst, einfach mal paar Seiten horten, aber das dauert wohl bis ich durch bin xD

Wie gesagt, GLDelphi ist sau gut (auch auf den anderen Thread bezogen) - bin grad da auch bei Blending Tutorial Lektion 7 ? DGL Wiki deswegen die Frage  Werd auch mal in deinen Link reinschauen und es mir durchlesen, danke


----------



## Guest2 (17. Jan 2012)

Moin,

warum willst Du denn auch 2 verschiedene Dreiecke auf dieselbe Position legen?

Klingt, als ob Du evtl. nach "Multitexture" suchst? 

Als Beispiel sieht das dann etwa so aus:
(Sorry, habe dazu gerade nur Code zur Hand, welchen Du nicht ausführen kannst. Sehe ihn als funktionierenden Pseudocode an und übersetze ihn in ein GL-Binding deiner Wahl. (Das geht mehr oder weniger 1:1))


```
public final class Multitexture<GLT extends GL21> extends GLCanvas<GLT> {

    private final List<TextureIO<GLT>> textures = new ArrayList<TextureIO<GLT>>();

    private GLT                        gl;


    public Multitexture() throws IOException {

        textures.add(new TextureIO<GLT>(getClass().getClassLoader().getResourceAsStream("1.png"), GLT.GL_TEXTURE0));
        textures.add(new TextureIO<GLT>(getClass().getClassLoader().getResourceAsStream("2.png"), GLT.GL_TEXTURE1));

    }


    @Override
    public void glInit(final GLT g) {

        gl = g;

        for (final TextureIO<GLT> texture : textures)
            texture.init(gl);

    }


    @Override
    public void glDisplay(final double deltaTime) {

        gl.glClear(GLT.GL_COLOR_BUFFER_BIT);
        gl.glLoadIdentity();


        textures.get(0).bind();

        gl.glTexEnvi(GLT.GL_TEXTURE_ENV, GLT.GL_TEXTURE_ENV_MODE, GLT.GL_DECAL);

        textures.get(1).bind();

        gl.glTexEnvi(GLT.GL_TEXTURE_ENV, GLT.GL_TEXTURE_ENV_MODE, GLT.GL_DECAL);


        gl.glBegin(GLT.GL_TRIANGLES);

        gl.glMultiTexCoord2f(textures.get(0).getUnit(), 0.0f, 0.0f);
        gl.glMultiTexCoord2f(textures.get(1).getUnit(), 0.0f, 0.0f);
        gl.glVertex3f(-1.0f, -1.0f, -0.5f);

        gl.glMultiTexCoord2f(textures.get(0).getUnit(), 1.0f, 0.0f);
        gl.glMultiTexCoord2f(textures.get(1).getUnit(), 1.0f, 0.0f);
        gl.glVertex3f(+1.0f, -1.0f, -0.5f);

        gl.glMultiTexCoord2f(textures.get(0).getUnit(), 0.5f, 1.0f);
        gl.glMultiTexCoord2f(textures.get(1).getUnit(), 0.5f, 1.0f);
        gl.glVertex3f(+0.0f, +1.0f, -0.5f);

        gl.glEnd();

        textures.get(0).unbind();
        textures.get(1).unbind();

    }


    @Override
    public void glReshape(final int x, final int y, final int width, final int height) {

        gl.glMatrixMode(GLT.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glMatrixMode(GLT.GL_MODELVIEW);
        gl.glLoadIdentity();

    }


    @Override
    public void glDispose() {

    }

}
```


```
public final class TextureIO<GLT extends GLActiveTexture & GLEnable & GLGenTextures & GLBindTexture & GLTexParameteri & GLTexImage2D & GLEnum11 & GLEnum12> {

    private final GLVoidBuffer texture;
    private final int          width;
    private final int          height;
    private final int          unit;

    private GLT                gl;
    private int                id;


    public TextureIO(final InputStream inputStream, final int unit) throws IOException {

        this.unit = unit;

        BufferedImage image = ImageIO.read(inputStream);

        width = image.getWidth();
        height = image.getHeight();

        final AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
        tx.translate(0, -height);

        final AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        image = op.filter(image, null);

        final int[] pixels = image.getRGB(0, 0, width, height, null, 0, width);
        texture = new GLVoidBuffer(pixels);

    }


    public void init(final GLT g) {

        gl = g;

        gl.glActiveTexture(unit);
        gl.glEnable(GLT.GL_TEXTURE_2D);

        final GLIntBuffer buffer = new GLIntBuffer(1);
        gl.glGenTextures(1, buffer);
        id = buffer.get(0);

        gl.glBindTexture(GLT.GL_TEXTURE_2D, id);
        gl.glTexParameteri(GLT.GL_TEXTURE_2D, GLT.GL_TEXTURE_MAG_FILTER, GLT.GL_LINEAR);
        gl.glTexParameteri(GLT.GL_TEXTURE_2D, GLT.GL_TEXTURE_MIN_FILTER, GLT.GL_LINEAR);

        gl.glTexImage2D(GLT.GL_TEXTURE_2D, 0, GLT.GL_RGBA8, width, height, 0, GLT.GL_BGRA, GLT.GL_UNSIGNED_INT_8_8_8_8_REV, texture);

        gl.glBindTexture(GLT.GL_TEXTURE_2D, 0);

    }


    public void bind() {

        gl.glActiveTexture(unit);
        gl.glBindTexture(GLT.GL_TEXTURE_2D, id);

    }


    public void unbind() {

        gl.glActiveTexture(unit);
        gl.glBindTexture(GLT.GL_TEXTURE_2D, 0);

    }


    public int getUnit() {

        return unit;

    }

}
```

Viele Grüße,
Fancy


----------



## Helgon (17. Jan 2012)

Hey danke für den ausführlichen Code. Ich hab mich damit und ein paar anderen Quellen noch mal hingesetzt und geguckt was ich noch machen kann. 

Dann hab ichs endlich geschafft, einziges Problem bleibt jedoch, dass 
	
	
	
	





```
glBlendFunc()
```
 keine Rolle zu spielen scheint.

Das Überblenden sieht immer gleich aus, egal was für Parameter ich da mitgebe. Ne Idee worans liegt? Grüße


```
glEnable(GL_CULL_FACE);  						
		glEnable(GL_TEXTURE_2D);
		glShadeModel(GL_SMOOTH);
		glClearColor(0, 0, 0, 0.5f);
		glClearDepth(1.0);		       
		glEnable(GL_DEPTH_TEST);	       
		glDepthFunc(GL_LEQUAL);	       
		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

		glViewport(0, 0, 800, 600);							
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(45, 800 / 600, 0.1f, 1000);

		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		
		t1.bind();
		t2.bind();
		  
		while(!Display.isCloseRequested()){
			
			glClearColor(0,0,0,0);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			
			glLoadIdentity();
			glTranslatef(0, 0 , -6f);
			
			//  Texturen vorbereiten
			ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE0_ARB);
			glEnable(GL_TEXTURE_2D);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);// Tex-Envroiment einstellen
			glBindTexture(GL_TEXTURE_2D, t1.getTextureID());
			
			ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);// Tex-Envroiment einstellen
			glEnable(GL_BLEND);
			glBlendFunc(GL_ONE, GL_SRC_COLOR);
			glBindTexture(GL_TEXTURE_2D, t2.getTextureID());
			  
			glBegin(GL_QUADS);
				
				ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE0_ARB, 0, 0);
				ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE1_ARB, 0, 0);
				glVertex3f(-1,-1,0);
				
				ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE0_ARB, 1, 0);
				ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE1_ARB, 1, 0);
				glVertex3f(1,-1,0);
				
				ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE0_ARB, 1, 1);
				ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE1_ARB, 1, 1);
				glVertex3f(1,1,0);
				
				ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE0_ARB, 0, 1);
				ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE1_ARB, 0, 1);
				glVertex3f(-1,1,0);
				
			glEnd();
					 
			
			Display.update();
			Display.sync(60);
		}
```


----------



## Guest2 (17. Jan 2012)

Wie die Farbwerte kombiniert werden, hängt bei der fixed function pipeline vom texture env mode ab. Gesetzt wird dieser über den 3. Parameter bei glTexEnvi (für jede Textur einzeln). Die "normalen" Werte (GL_MODULATE, GL_DECAL, GL_BLEND, GL_REPLACE) sind z.B. bei DGL erklärt. Weitere Kombinationsmöglichkeiten ergeben sich über GL_COMBINE, was z.B. ebenfalls bei DGL erklärt ist.

Nach Möglichkeit solltest Du die ARB-Versionen der Methoden meiden. Also statt [c]ARBMultitexture.glActiveTextureARB[/c] besser [c]GL13.glActiveTexture[/c].


Viele Grüße,
Fancy


----------



## Spacerat (17. Jan 2012)

Also wie gesagt... wenn GL_BLEND aktiv ist, muss GL_DEPTH_TEST disabled sein. Transparente Polygone muss man halt selber auf der orthogonalen Z-Achse sortieren und von hinten nach vorne zeichnen und zwar nachdem man mit dem Zeichnen aller undurchsichtigen Polygone fertig ist. Alles andere verfälscht das Endergebnis.


----------



## Helgon (17. Jan 2012)

@Spacerat: Das ist nicht das Problem weil 

```
glEnable(GL_DEPTH_TEST);	       
		glDepthFunc(GL_LEQUAL);
```
@Guest: Ich hab jetzt mal alle ARB durch GL13 ersetzt.

Ich hab mal versucht es IRGENDWIE! mit einander zu verblenden 


```
t1.bind();
			t2.bind();

			//  Texturen vorbereiten
			GL13.glActiveTexture(GL13.GL_TEXTURE0);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, t1.getTextureID());
			
			GL13.glActiveTexture(GL13.GL_TEXTURE1);
			glEnable(GL_TEXTURE_2D);
			glTexEnvi(GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL13.GL_INTERPOLATE);
			glEnable(GL_BLEND);
			glBindTexture(GL_TEXTURE_2D, t2.getTextureID());

			  
			glBegin(GL_QUADS);
				
				GL13.glMultiTexCoord2f(GL13.GL_TEXTURE0, 0, 1);
				GL13.glMultiTexCoord2f(GL13.GL_TEXTURE1, 0, 1);
				glVertex3f(-1,-1,0);
				
				GL13.glMultiTexCoord2f(GL13.GL_TEXTURE0, 1, 1);
				GL13.glMultiTexCoord2f(GL13.GL_TEXTURE1, 1, 1);
				glVertex3f(1,-1,0);
				
				GL13.glMultiTexCoord2f(GL13.GL_TEXTURE0, 1, 0);
				GL13.glMultiTexCoord2f(GL13.GL_TEXTURE1, 1, 0);
				glVertex3f(1,1,0);
				
				GL13.glMultiTexCoord2f(GL13.GL_TEXTURE0, 0, 0);
				GL13.glMultiTexCoord2f(GL13.GL_TEXTURE1, 0, 0);
				glVertex3f(-1,1,0);
				
			glEnd();
```

egal was ich da einsetze, hab einfach mal alles mögliche aus der Wiki und Source den ich aus Tutorials hab genommen, bei keinem verändert sich der Blendmodus.

Jedoch verändert sich dieser je nachdem wo ich t1 und t2 binde

Wo sollte man es denn richtiger weise machen?

Haste vllt gradn Beispiel, dass auch Funktioniert, weil wie gesagt, ich hab wie dumm rumprobiert mit dem glTexEnv aber nix bringt bei mir ne Veränderung :/

Grüße


----------



## Guest2 (17. Jan 2012)

Vielleicht noch zur Klarstellung, das, was mit [c]glEnable(GL BLEND)[/c] aktiviert wird, beschreibt, wie der Wert eines Pixels im Framebuffer durch ein neues Fragment beeinflusst wird. Das ist dann abhängig vom depth buffer. "Multitexture" bedeutet aber das auf einer Geometrie mehrere Texturen aufgelegt werden. Das wiederum ist dann unabhängig vom depth buffer und unabhängig vom [c]glEnable(GL BLEND)[/c].

Das Beispiel von oben 1:1 nach LWJGL übersetzt (und um GL_COMBINE statt GL_MODULATE ergänzt) ergibt:


```
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;

public class Multitexture {

    private final List<TextureIO> textures = new ArrayList<TextureIO>();


    public Multitexture() throws IOException {

        textures.add(new TextureIO(getClass().getClassLoader().getResourceAsStream("1.png"), GL13.GL_TEXTURE0));
        textures.add(new TextureIO(getClass().getClassLoader().getResourceAsStream("2.png"), GL13.GL_TEXTURE1));

    }


    public void init() throws LWJGLException {

        Display.setDisplayMode(new DisplayMode(500, 500));
        Display.create();

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        for (final TextureIO texture : textures)
            texture.init();

    }


    public void display() {

        while (!Display.isCloseRequested()) {

            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
            GL11.glLoadIdentity();


            textures.get(0).bind();
            GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);


            textures.get(1).bind();
            GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL13.GL_COMBINE);
            GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL11.GL_ADD);
            GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_RGB, GL11.GL_TEXTURE);
            GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE1_RGB, GL13.GL_PREVIOUS);


            GL11.glBegin(GL11.GL_TRIANGLES);

            GL13.glMultiTexCoord2f(textures.get(0).getUnit(), 0.0f, 0.0f);
            GL13.glMultiTexCoord2f(textures.get(1).getUnit(), 0.0f, 0.0f);
            GL11.glVertex3f(-1.0f, -1.0f, -0.5f);

            GL13.glMultiTexCoord2f(textures.get(0).getUnit(), 1.0f, 0.0f);
            GL13.glMultiTexCoord2f(textures.get(1).getUnit(), 1.0f, 0.0f);
            GL11.glVertex3f(+1.0f, -1.0f, -0.5f);

            GL13.glMultiTexCoord2f(textures.get(0).getUnit(), 0.5f, 1.0f);
            GL13.glMultiTexCoord2f(textures.get(1).getUnit(), 0.5f, 1.0f);
            GL11.glVertex3f(+0.0f, +1.0f, -0.5f);

            GL11.glEnd();


            textures.get(0).unbind();
            textures.get(1).unbind();


            Display.update();

        }

        Display.destroy();

    }


    public static void main(final String[] args) throws IOException, LWJGLException {

        final Multitexture multitexture = new Multitexture();
        multitexture.init();
        multitexture.display();

    }
}
```


```
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.IntBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;


public class TextureIO {

    private final IntBuffer texture;
    private final int       width;
    private final int       height;
    private final int       unit;

    private int             id;


    public TextureIO(final InputStream inputStream, final int unit) throws IOException {

        this.unit = unit;

        BufferedImage image = ImageIO.read(inputStream);

        width = image.getWidth();
        height = image.getHeight();

        final AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
        tx.translate(0, -height);

        final AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        image = op.filter(image, null);

        final int[] pixels = image.getRGB(0, 0, width, height, null, 0, width);
        texture = BufferUtils.createIntBuffer(pixels.length);
        texture.put(pixels);
        texture.rewind();

    }


    public void init() {

        GL13.glActiveTexture(unit);
        GL11.glEnable(GL11.GL_TEXTURE_2D);

        final IntBuffer buffer = BufferUtils.createIntBuffer(1);
        GL11.glGenTextures(buffer);
        id = buffer.get(0);

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);

        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, height, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, texture);

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

    }


    public void bind() {

        GL13.glActiveTexture(unit);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);

    }


    public void unbind() {

        GL13.glActiveTexture(unit);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

    }


    public int getUnit() {

        return unit;

    }


}
```

Viele Grüße,
Fancy


----------



## Spacerat (18. Jan 2012)

Helgon hat gesagt.:


> Das ist nicht das Problem weil
> 
> ```
> glEnable(GL_DEPTH_TEST);
> ...


Hmm... ignorier mich ruhig aber nicht die Fakten... :lol:

```
glDisable(GL_DEPTH_TEST); // !!!
glEnable(GL_BLEND); // !!!
```
Man kann es nicht oft genug sagen, auch wenn die Polygone eine Multitextur bekommen sollen. Blending wird zum zeichnen von Tranzparenz benutzt.
Nun gut... vllt. geht es ja gar nicht um Tranzparenz sondern darum, dass eine Multitextur anscheinend nicht richtig dargestellt wird, egal in welchem Modus man zeichnet.
Wie ich über Multitexturen informiert bin:
1.    Jede Textur hat genau einen Farbkanal (Color).
2.    Bei Multitexturen können wahlweise noch Bump, Light, Blend usw. als Kanal hinzugefügt werden.
3.1   Bump- und Light-Kanäle sind nur sichtbar, wenn Lightning aktiviert wurde
3.2.1 Der Blend-Kanal ist nur sichtbar, wenn Blending aktiviert wurde.
3.2.2 Tranzparenz zeichnet man am Ende der Szene mit abgeschaltetem Tiefenpuffer polygonweise von fern nach nah.
Und natürlich... Guest2 hat vollkommen recht. Texturen ist es vollkommen egal, wann und in welchem Modus sie erstellt oder verwendet werden. Ihre Capabilities (z.B. bei Multitexturen) werden aber halt erst in entsprechenden Modi sichtbar.


----------



## Helgon (18. Jan 2012)

Hey, erneut danke ich für die Antworten.

In nem anderen Forum hab ich die "klick machende Antwort" bekommen - Multitexturen sind nicht zum mit einander verblenden gedacht xD

Da hab ich wohl versucht mim Traktor zu fliegen. Klappt vllt wenn man sich von der Klippe stürzt, aber richtig funktionieren will es wohl doch nicht 

Hab mich dann umentschieden erstmal Nehe durchzuarbeiten, weil da einfach erstmal "Noob freundlicher" auf alles eingegangen wird. Bei der DGL wird mir einfach zu viel weggelassen und die Delphi Syntax... brauch ich was dazu sagen?  Da krieg ich Kopfschmerzen.


Aber auf jeden Fall Danke! Die nächsten Fragen werden wohl nicht lange auf sich warten lassen


----------



## JanHH (18. Jan 2012)

Bei komplexeren OpenGL-Fragen würd ich sonst eher im offiziellen OpenGL-Forum posten.. OpenGL.org Discussion and Help Forums - Forums powered by UBB.threads™

war da auch jahrelang aktiv (so 1999-2004 Nebenjob mit einer OpenGL-Engine)


----------



## Guest2 (18. Jan 2012)

Ob Multitexturen das richtige Mittel sind, hängt davon ab was Du exakt erreichen möchtest. Möchtest Du das was Dein erster Quelltext suggeriert und was in Deinem Link zum DGL Tutorial beschrieben wird, dann sind sie geeignet (die werden sogar am ende des Tutorial angesprochen). Möchtest Du was anderes erreichen, dann vielleicht auch nicht.

Viele Grüße,
Fancy


----------



## Helgon (18. Jan 2012)

Ich wollte eigentlich 3 Texturen vermischen.

Mal ne etwas andere Frage dann.

Wenn ich 2 Texturen habe.

Eine ist ne Blend Map (schwarz weiß) 
Das andere die Textur.

Wenn ich dann normal die Textur mit 
	
	
	
	





```
glBlendFunc(GL_ZERO,GL_SRC_COLOR);
```
 drüber lege, legt sich die Textur ja nur über die weißen stellen.

Wie krieg ichs hin eine andere Textur über die schwarzen zu legen? Mit irgend nem Blendmodus oder Multitexturing? 

Grüße

P.S.: Zur verständniss nochmal
So soll es am Ende aussehen. 
Vorher wäre das gras bspw weiß und wo die Stein textur liegt schwarz


----------



## Guest2 (18. Jan 2012)

Da das Ganze eine Fläche ist, werden dazu Multitexturen eingesetzt. Lediglich vor 1998 wurde dazu noch Blending verwendet. Heute wird Blending aber nur noch eingesetzt um durch eine Fläche hindurch auf eine andere (weiter hinten liegende) Oberfläche sehen zu können. Eigentlich ist das dann auch weniger Blending sondern meint vielmehr Transparency bzw. Translucency.

Bei der Anwendung von Multitexturen auf einer fixed function pipeline wird das Verhalten der einzelnen Texturen ausschließlich über glTexEnvi gesteuert.

Bei dem Bild in deinem Beispiel gibt es 2 Möglichkeiten:

1.: 3 verschiedene Texturen: 1x Stein, 1x Grass, 1x Blendmap (Alpha-Kanal)
2.: 2 verschiedene Texturen: 1x Stein, 1x Grass, Alpha wird aus der Stein- oder Grass- Textur gewählt.


Variante 1 sieht dann z.B. so aus:
(von blendmap.png wird nur der Alpha-Kanal genutzt, TextureIO wie oben)


```
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;

public class Multitexture {

    private final List<TextureIO> textures = new ArrayList<TextureIO>();


    public Multitexture() throws IOException {

        textures.add(new TextureIO(getClass().getClassLoader().getResourceAsStream("blendmap.png"), GL13.GL_TEXTURE0));
        textures.add(new TextureIO(getClass().getClassLoader().getResourceAsStream("rock.png"), GL13.GL_TEXTURE1));
        textures.add(new TextureIO(getClass().getClassLoader().getResourceAsStream("gras.png"), GL13.GL_TEXTURE2));

    }


    public void init() throws LWJGLException {

        Display.setDisplayMode(new DisplayMode(500, 500));
        Display.create();

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        for (final TextureIO texture : textures)
            texture.init();

        textures.get(0).bind();
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE);

        textures.get(1).bind();
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL13.GL_COMBINE);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL11.GL_REPLACE);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_RGB, GL11.GL_TEXTURE);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_ALPHA, GL11.GL_REPLACE);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_ALPHA, GL13.GL_PREVIOUS);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_ALPHA, GL11.GL_SRC_ALPHA);

        textures.get(2).bind();
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL13.GL_COMBINE);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_COMBINE_RGB, GL13.GL_INTERPOLATE);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE0_RGB, GL13.GL_PREVIOUS);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE1_RGB, GL11.GL_TEXTURE);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND1_RGB, GL11.GL_SRC_COLOR);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_SOURCE2_RGB, GL13.GL_PREVIOUS);
        GL11.glTexEnvi(GL11.GL_TEXTURE_ENV, GL13.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);

    }


    public void display() {

        while (!Display.isCloseRequested()) {

            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
            GL11.glLoadIdentity();

            textures.get(0).bind();
            textures.get(1).bind();
            textures.get(2).bind();


            GL11.glBegin(GL11.GL_TRIANGLES);

            GL13.glMultiTexCoord2f(textures.get(0).getUnit(), 0.0f, 0.0f);
            GL13.glMultiTexCoord2f(textures.get(1).getUnit(), 0.0f, 0.0f);
            GL13.glMultiTexCoord2f(textures.get(2).getUnit(), 0.0f, 0.0f);
            GL11.glVertex3f(-1.0f, -1.0f, -0.5f);

            GL13.glMultiTexCoord2f(textures.get(0).getUnit(), 1.0f, 0.0f);
            GL13.glMultiTexCoord2f(textures.get(1).getUnit(), 1.0f, 0.0f);
            GL13.glMultiTexCoord2f(textures.get(2).getUnit(), 1.0f, 0.0f);
            GL11.glVertex3f(+1.0f, -1.0f, -0.5f);

            GL13.glMultiTexCoord2f(textures.get(0).getUnit(), 0.5f, 1.0f);
            GL13.glMultiTexCoord2f(textures.get(1).getUnit(), 0.5f, 1.0f);
            GL13.glMultiTexCoord2f(textures.get(2).getUnit(), 0.5f, 1.0f);
            GL11.glVertex3f(+0.0f, +1.0f, -0.5f);

            GL11.glEnd();


            textures.get(0).unbind();
            textures.get(1).unbind();
            textures.get(2).unbind();


            Display.update();

        }

        Display.destroy();

    }


    public static void main(final String[] args) throws IOException, LWJGLException {

        final Multitexture multitexture = new Multitexture();
        multitexture.init();
        multitexture.display();

    }
}
```

(als Shader wäre das übrigens ein übersichtlicher 1-Zeiler, hat schon seinen Grund, warum der ganze Schmu depricatet ist.)

Viele Grüße,
Fancy


----------



## Helgon (18. Jan 2012)

Ah, danke für die Infos!

Hast mir echt geholfen, vielen Dank OpenGL-Guru


----------



## Spacerat (18. Jan 2012)

Guest2 hat gesagt.:


> Eigentlich ist das dann auch weniger Blending sondern meint vielmehr Transparency bzw. Translucency.


Nee nee, des ist schon Blending... Allerdings ausschliesslich Alpha-Blending (Transparency bzw. Translucency :lol und nichts anderes. Soweit ich mich erinner, gab es GL_BLEND schon anno 1995 bei Mesa 3D (realisierung einer OpenGL-Schnittstelle für diverse Platformen unter anderem auch AmigaOS). Warum es blos GL_BLEND statt GL_ALPHA_BLENDING hies, lässt sich wohl nur damit erklären, weil man andere Blendings bzw. Mappings (für damalige Verhältnisse fallen mir da auf Anhieb nur noch Bumpmaps ein) eigentlich gar nicht brauchte, da sie nur auf Licht reagierten und deswegen im Tiefenpuffer gleich mitbeachtet werden konnten. Transparenz war etwas ganz anderes und konnte von Anfang an nicht im Tiefenpuffer realisiert werden, weil dort ohne Rücksichtnahme auf einen vorhandenen Alpha-Kanal gezeichnet wurde (bzw. immer noch wird?).
"Multitexturing" gab's übrigens auch schon vor den Riva TNTs, jedoch nur "softwareemuliert". Dazu wurden halt (wie es heute durch die Hardware geschieht) die einzelnen Pixel von zwei oder drei Texturen miteinander per Algorithmus verknüpft, bevor sie an den Texturpuffer der GraKa übergeben wurden.


----------



## Guest2 (19. Jan 2012)

Spacerat hat gesagt.:


> Nee nee, des ist schon Blending... Allerdings ausschliesslich Alpha-Blending (Transparency bzw. Translucency :lol und nichts anderes.



Ich bezog mich damit auf dem hier:



			
				http://www.opengl.org/resources/faq/technical/transparency.htm hat gesagt.:
			
		

> 15.010 What is the difference between transparent, translucent, and blended primitives?
> 
> A transparent physical material shows objects behind it as unobscured and doesn't reflect light off its surface. Clear glass is a nearly transparent material. Although glass allows most light to pass through unobscured, in reality it also reflects some light. A perfectly transparent material is completely invisible.
> 
> ...






Spacerat hat gesagt.:


> Soweit ich mich erinner, gab es GL_BLEND schon anno 1995 bei Mesa 3D (realisierung einer OpenGL-Schnittstelle für diverse Platformen unter anderem auch AmigaOS). Warum es blos GL_BLEND statt GL_ALPHA_BLENDING hies, lässt sich wohl nur damit erklären, weil man andere Blendings bzw. Mappings (für damalige Verhältnisse fallen mir da auf Anhieb nur noch Bumpmaps ein) eigentlich gar nicht brauchte[..]



Mesa 3D nutzt die OpenGL API. In OpenGL ist glBlendFunc ab Version 1.1 enthalten, welche im Januar 1997 veröffentlicht wurde. Seit Anfang an gibt es auch z.B. GL_ONE welches für additives blending genutzt wird, bei dem kein Alpha-Wert berücksichtigt wird.

Viele Grüße,
Fancy


----------



## Spacerat (19. Jan 2012)

Guest2 hat gesagt.:


> Ich bezog mich damit auf dem hier:...


Okay... nichts davon widerlegt meine Aussage.





Guest2 hat gesagt.:


> Mesa 3D nutzt die OpenGL API.


Tja... Schnittstellen tun halt so... wäre ja Schlimm, wenn OpenGL-Schnittstellen die DirectX-API nutzen würden.





Guest2 hat gesagt.:


> In OpenGL ist glBlendFunc ab Version 1.1 enthalten, welche im Januar 1997 veröffentlicht wurde. Seit Anfang an gibt es auch z.B. GL_ONE welches für additives blending genutzt wird, bei dem kein Alpha-Wert berücksichtigt wird.


Das wäre dann wohl die Erklärung dafür, warum Transparency-Maps anfangs nur Monochrome sein brauchten bzw. durften.[/QUOTE]


----------

