# Post Processing mit FBO



## javaPanther (4. Dez 2011)

Hallo liebe Leute,
nach sehr guten Erfahrungen beim letzen Besuch hier nun eine nuee Frage. Um Post-Processing Effekte zu realisieren würde ich gerne die Inhalte meiner Szenerie in eine Textur speichern um diese dann z.B. mit einem Radialblur zu überziehen.

Ein FBO Example habe ich bereits soweit angepasst, leider ohne das eine Textur dauerhaft gezeichnet wird. Die Textur wird geladen und einmalig kurz zu Beginn gerendert, aber sehr kurze Zeit später (ich nehme an im 2. Frame) wird sie nicht mehr (nur die Clearcolor) dargestellt.

Hier mein kleines Beispiel:

```
import java.io.IOException;

import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14;
import org.lwjgl.util.glu.GLU;

import com.trivial.graphics.Texture;
import com.trivial.graphics.TextureLoader;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.EXTFramebufferObject.*;
 
public class FBOExample {
 	
	int colorTextureID;
	int framebufferID;
	int depthRenderBufferID;
	private Texture hand;
 
	public void start() {
		init();
 
		initGL(); // init OpenGL
 
		while (!Display.isCloseRequested()) {
 
			renderGL();
 
			Display.update();
			Display.sync(60); // cap fps to 60fps
		}
 
		Display.destroy();
	}
 
	public void initGL() {
		
		GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);                       // Black Background
        GL11.glClearDepth(1.0f); // Depth Buffer Setup
		GL11.glBlendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
		GL11.glEnable( GL11.GL_BLEND );
        GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping

        GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
        GL11.glLoadIdentity(); // Reset The Projection Matrix

        // Calculate The Aspect Ratio Of The Window
        GLU.gluPerspective(45.0f, width / height, 0.1f, 100.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
		
        
        try {
			hand =new TextureLoader().getTexture("Target.png");
		} catch (IOException e) {
			e.printStackTrace();
		}
        
        
		framebufferID = glGenFramebuffersEXT();											// create a new framebuffer
		colorTextureID = glGenTextures();												// and a new texture used as a color buffer
		depthRenderBufferID = glGenRenderbuffersEXT();									// And finally a new depthbuffer
	
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID); 						// switch to the new framebuffer
	
		// initialize color texture
		glBindTexture(GL_TEXTURE_2D, colorTextureID);									// Bind the colorbuffer texture
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);				// make it linear filterd
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0,GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);	// Create the texture data
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, colorTextureID, 0); // attach it to the framebuffer
	
		// initialize depth renderbuffer
		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthRenderBufferID);				// bind the depth renderbuffer
		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL14.GL_DEPTH_COMPONENT24, width, height);	// get the data space for it
		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, depthRenderBufferID); // bind it to the renderbuffer
	
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);									// Swithch back to normal framebuffer rendering			
	}
 
	public void renderGL() {
		
		glBindTexture(GL_TEXTURE_2D, 0);								// unlink textures because if we dont it all is gonna fail
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID);		// switch to rendering on our FBO

		glClearColor (1.0f, 0.0f, 0.0f, 0.5f);
		glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear Screen And Depth Buffer on the fbo to red
		glLoadIdentity ();												// Reset The Modelview Matrix
		glTranslatef (0.0f, 0.0f, -4.0f);								// Translate 6 Units Into The Screen and then rotate
												// set color to yellow
		hand.bind();
		drawBox();														// draw the box

		glEnable(GL_TEXTURE_2D);										// enable texturing
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);					// switch to rendering on the framebuffer

		glClearColor (0.0f, 1.0f, 0.0f, 0.5f);
		glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear Screen And Depth Buffer on the framebuffer to black

		glBindTexture(GL_TEXTURE_2D, colorTextureID);					// bind our FBO texture

		glLoadIdentity ();												// Reset The Modelview Matrix
		glTranslatef (0.0f, 0.0f, -4.0f);												// set the color to white
		drawBox();														// draw the box

		glDisable(GL_TEXTURE_2D);
		glFlush ();
	}
	
	public void drawBox() { 
		glBegin(GL_QUADS);
			// Front Face
			glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	// Bottom Left Of The Texture and Quad
			glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	// Bottom Right Of The Texture and Quad
			glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	// Top Right Of The Texture and Quad
			glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	// Top Left Of The Texture and Quad
		glEnd();
	}
	
	public static int width = 800;
    public static int height = 600;
    static boolean fullscreen = false;
	public static void init(){
		try {
        	Display.setFullscreen(fullscreen);
			// get modes
			DisplayMode[] dm = org.lwjgl.util.Display.getAvailableDisplayModes(
					width, height, -1, -1, -1, -1, 60, 60);

			org.lwjgl.util.Display.setDisplayMode(dm, new String[] {
					"width=" + width,
					"height=" + height,
					"freq=" + 60,
					"bpp=" + org.lwjgl.opengl.Display.getDisplayMode().getBitsPerPixel() });
			
	        Display.create();
	        
	        DisplayMode[] modes = Display.getAvailableDisplayModes();
	        for (int i=0;i<modes.length;i++) {
		        DisplayMode current = modes[i];
	        }
	        
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Unable to enter fullscreen, continuing in windowed mode");
		}
	}
 
	public static void main(String[] argv) {
		FBOExample fboExample = new FBOExample();
		fboExample.start();
	}
}
```

Wenn gewünscht könnte ich auch noch die Klassen für Textur und TexturLoader nachschicken um das Beispiel zu einem KSKB zu machen ^^

Beste Grüße und Dank im Voraus!


----------



## Guest2 (5. Dez 2011)

Moin,

vielleicht hilft Dir das hier schon weiter. Dort wird auch ein RadialBlur über ein FBO realisiert. Das ist zwar jogl und auch schon etwas älter, brachte aber zumindest mal die erwarteten Ergebnisse.

Ansonsten poste mal den Rest für ein KSKB.

Gruß,
Fancy


----------



## javaPanther (5. Dez 2011)

Danke für das Beispiel. Ich habe es jetzt soweit angepasst wie ich konnte (auf lwjgl übersetzt), leider mit ein paar Fehlern, die ich so nicht ausmerzen konnte. Hier das Übersetzte Beispiel:


```
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.EXTFramebufferObject;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;


public class FBOTest{

    private static final int     sunGlowTextureSize = 128;
    private static final float[] sunPosition        = { 0.0f, 0.0f, 0.0f };

    private int                  fboHandle          = 0;
    private int                  rboHandle          = 0;
    private int                  glowHandle         = 0;

    private double[]             modelview          = null;
    private double[]             projection         = null;
    private int[]                viewport           = null;

    public void initGL() {
        // setup ogl basics
        GL11.glClearDepth(1.0f);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

        final int[] fboHandleBuffer = new int[1];
        GL11.glGenFramebuffersEXT(fboHandleBuffer);
        fboHandle = fboHandleBuffer[0];

        final int[] rboHandleBuffer = new int[1];
        GL11.glGenRenderbuffersEXT(rboHandleBuffer);
        rboHandle = rboHandleBuffer[0];

        final int[] glowHandleBuffer = new int[1];
        GL11.glGenTextures(IntBuffer.wrap(glowHandleBuffer));
        glowHandle = glowHandleBuffer[0];

        EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, fboHandle);
        EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, rboHandle);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, glowHandle);

        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_LUMINANCE, sunGlowTextureSize, sunGlowTextureSize, 0, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, null);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);

        EXTFramebufferObject.glRenderbufferStorageEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, GL11.GL_DEPTH_COMPONENT, sunGlowTextureSize, sunGlowTextureSize);
        EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT, rboHandle);
        EXTFramebufferObject.glFramebufferTexture2DEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT, GL11.GL_TEXTURE_2D, glowHandle, 0);

        if (EXTFramebufferObject.glCheckFramebufferStatusEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT) != EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT) {
            System.out.println("Error: GL11.GL_FRAMEBUFFER_EXT");
            System.exit(1);
        }

        EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, 0);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
        EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);

        // save GL_VIEWPORT for gluProject
        viewport = new int[4];
        GL11.glViewport(0, 0, sunGlowTextureSize, sunGlowTextureSize);
        GL11.glGetIntegerv(GL11.GL_VIEWPORT, viewport, 0);
    }

    
    private void setupCamera() {

        final double time = System.currentTimeMillis();

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();
        GLU.gluLookAt(0.0f, 0.0f, 20.0f, 6 * (float) Math.sin(time / 700), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
    }

    
    private void renderGlowToTexture() {

    	EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, fboHandle);
        GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT);
        GL11.glViewport(0, 0, sunGlowTextureSize, sunGlowTextureSize);

        setupCamera();

        // save current GL_MODELVIEW_MATRIX for gluProject
        modelview = new double[16];
        GL11.glGetDoublev(GL11.GL_MODELVIEW_MATRIX, modelview, 0);

        // draw the "sun"
        GL11.glTranslatef(sunPosition[0], sunPosition[1], sunPosition[2]);
        GLU.gluSphere(GLU.gluNewQuadric(), 1, 20, 20);

        GL11.glPopAttrib();
        EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, 0);
    }

    
    private void renderGlowToScreen() {

        // corona parameter
        float spost = 0.0f;
        float alpha = 0.2f;
        
        final int times = 25;
        final float inc = 1.0f / times;
        final float alphainc = alpha / times;

        // calculate current sun position
        final double[] sunPosBuffer = new double[4];
        GLU.gluProject(sunPosition[0], sunPosition[1], sunPosition[2], modelview, 0, projection, 0, viewport, 0, sunPosBuffer, 0);

        final float currentSunPosX = (float) (sunPosBuffer[0] / sunGlowTextureSize);
        final float currentSunPosY = (float) (sunPosBuffer[1] / sunGlowTextureSize);

        // draw the glow texture to screen
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glPushMatrix();
        GL11.glLoadIdentity();
        GL11.glFrustum(-1.0f, 1.0f, -1, 1, 0.0f, 1.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glPushMatrix();
        GL11.glLoadIdentity();

        GL11.glDisable(GL11.GL_DEPTH_TEST);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
        GL11.glEnable(GL11.GL_BLEND);

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, glowHandle);
        GL11.glBegin(GL11.GL_QUADS);

        for (int i = 0; i < times; i++) {

            GL11.glColor4f(1.0f, 1.0f, 1.0f, alpha);
            
            GL11.glTexCoord2f(spost * currentSunPosX, spost * currentSunPosY);
            GL11.glVertex3f(-1.0f, -1.0f, 0.0f);
            
            GL11.glTexCoord2f(1 - ((1 - currentSunPosX) * spost), spost * currentSunPosY);
            GL11.glVertex3f(1.0f, -1.0f, 0.0f);
            
            GL11.glTexCoord2f(1 - ((1 - currentSunPosX) * spost), 1 - ((1 - currentSunPosY) * spost));
            GL11.glVertex3f(1.0f, 1.0f, 0.0f);
            
            GL11.glTexCoord2f(spost * currentSunPosX, 1 - ((1 - currentSunPosY) * spost));
            GL11.glVertex3f(-1.0f, 1.0f, 0.0f);

            spost += inc;
            alpha = alpha - alphainc;
        }

        GL11.glEnd();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

        GL11.glDisable(GL11.GL_BLEND);
        GL11.glEnable(GL11.GL_DEPTH_TEST);

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glPopMatrix();
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glPopMatrix();
    }
    
    public static void main(String[] args) {
    	FBOTest fboExample = new FBOTest();
		fboExample.start();
    }
    
    public static int width = 800;
    public static int height = 600;
    static boolean fullscreen = false;
	public static void init(){
		try {
        	Display.setFullscreen(fullscreen);
			// get modes
			DisplayMode[] dm = org.lwjgl.util.Display.getAvailableDisplayModes(
					width, height, -1, -1, -1, -1, 60, 60);

			org.lwjgl.util.Display.setDisplayMode(dm, new String[] {
					"width=" + width,
					"height=" + height,
					"freq=" + 60,
					"bpp=" + org.lwjgl.opengl.Display.getDisplayMode().getBitsPerPixel() });
			
	        Display.create();
	        
	        DisplayMode[] modes = Display.getAvailableDisplayModes();
	        for (int i=0;i<modes.length;i++) {
		        DisplayMode current = modes[i];
	        }
	        
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Unable to enter fullscreen, continuing in windowed mode");
		}
	}
	
	public void start() {
		init();
 
		initGL(); // init OpenGL
 
		while (!Display.isCloseRequested()) {
 
			renderGlowToTexture();
			renderGlowToScreen();
 
			Display.update();
			Display.sync(60); // cap fps to 60fps
		}
 
		Display.destroy();
	}
}
```

Falls Jemand allerdings doch noch ein KSKB meines ersten Beispiels wünscht:


```
package com.trivial.graphics;

import org.lwjgl.opengl.GL11;

public class Texture {
	
    private int target; 
    public int textureID;
    public int height, width;
    private int texWidth;
    private int texHeight;
    public float widthRatio, heightRatio;
    
    public Texture(int target,int textureID) {
        this.target = target;
        this.textureID = textureID;
    }
    
    public void bind() {
      GL11.glBindTexture(target, textureID); 
    }
    
    public void setHeight(int height) {
        this.height = height;
        setHeight();
    }
    
    public void setWidth(int width) {
        this.width = width;
        setWidth();
    }
    
    public void setTextureHeight(int texHeight) {
        this.texHeight = texHeight;
        setHeight();
    }
    
    public void setTextureWidth(int texWidth) {
        this.texWidth = texWidth;
        setWidth();
    }
    
    private void setHeight() {
        if (texHeight != 0) {
            heightRatio = ((float) height)/texHeight;
        }
    }
    
    private void setWidth() {
        if (texWidth != 0) {
            widthRatio = ((float) width)/texWidth;
        }
    }
}
```

und 


```
package com.trivial.graphics;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Hashtable;

import javax.imageio.ImageIO;

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

public class TextureLoader {
    private HashMap<String, Texture> textures = new HashMap<String, Texture>();
    private ColorModel glAlphaColorModel;
    private ColorModel glColorModel;
    
    
    public TextureLoader() {
        glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {8,8,8,8}, true, false, ComponentColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
                                            
        glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {8,8,8,0}, false, false, ComponentColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
    }
    
    private int createTextureID() 
    { 
       IntBuffer tmp = createIntBuffer(1); 
       GL11.glGenTextures(tmp); 
       return tmp.get(0);
    } 
    
    public Texture getTexture(String resourceName) throws IOException {
        Texture tex = textures.get(resourceName);
        
        if (tex != null) {
            return tex;
        }
        
        tex = getTexture(resourceName, GL11.GL_TEXTURE_2D,  GL11.GL_RGBA, GL11.GL_LINEAR, GL11.GL_LINEAR);
        
        textures.put(resourceName,tex);
        
        return tex;
    }
    
    public Texture getTexture(String resourceName, int target, int dstPixelFormat, int minFilter, int magFilter) throws IOException 
    { 
        int srcPixelFormat = 0;
        
        int textureID = createTextureID(); 
        Texture texture = new Texture(target,textureID); 
        
        // bind this texture 
        GL11.glBindTexture(target, textureID); 
 
        BufferedImage bufferedImage = loadImage(resourceName); 
        texture.setWidth(bufferedImage.getWidth());
        texture.setHeight(bufferedImage.getHeight());
        
        if (bufferedImage.getColorModel().hasAlpha()) {
            srcPixelFormat = GL11.GL_RGBA;
        } else {
            srcPixelFormat = GL11.GL_RGB;
        }

        // convert that image into a byte buffer of texture data 
        ByteBuffer textureBuffer = convertImageData(bufferedImage,texture); 
        
        if (target == GL11.GL_TEXTURE_2D) 
        { 
            GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, minFilter); 
            GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, magFilter); 
            GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT );
            GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT );
        } 
 
        // produce a texture from the byte buffer
        GL11.glTexImage2D(target, 
                      0, 
                      dstPixelFormat, 
                      get2Fold(bufferedImage.getWidth()), 
                      get2Fold(bufferedImage.getHeight()), 
                      0, 
                      srcPixelFormat, 
                      GL11.GL_UNSIGNED_BYTE, 
                      textureBuffer ); 
        
        return texture; 
    } 
    
    private int get2Fold(int fold) {
        int ret = 2;
        while (ret < fold) {
            ret *= 2;
        }
        return ret;
    } 
    
    private ByteBuffer convertImageData(BufferedImage bufferedImage,Texture texture) { 
        ByteBuffer imageBuffer = null; 
        WritableRaster raster;
        BufferedImage texImage;
        
        int texWidth = 2;
        int texHeight = 2;
        
        // find the closest power of 2 for the width and height
        // of the produced texture
        while (texWidth < bufferedImage.getWidth()) {
            texWidth *= 2;
        }
        while (texHeight < bufferedImage.getHeight()) {
            texHeight *= 2;
        }
        
        texture.setTextureHeight(texHeight);
        texture.setTextureWidth(texWidth);
        
        // create a raster that can be used by OpenGL as a source
        // for a texture
        if (bufferedImage.getColorModel().hasAlpha()) {
            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,texWidth,texHeight,4,null);
            texImage = new BufferedImage(glAlphaColorModel,raster,false,new Hashtable<String, Texture>());
        } else {
            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,texWidth,texHeight,3,null);
            texImage = new BufferedImage(glColorModel,raster,false,new Hashtable<String, Texture>());
        }
            
        // copy the source image into the produced image
        Graphics g = texImage.getGraphics();
        g.setColor(new Color(0f,0f,0f,0f));
        g.fillRect(0,0,texWidth,texHeight);
        g.drawImage(bufferedImage,0,0,null);
        
        // build a byte buffer from the temporary image 
        // that be used by OpenGL to produce a texture.
        byte[] data = ((DataBufferByte) texImage.getRaster().getDataBuffer()).getData(); 

        imageBuffer = ByteBuffer.allocateDirect(data.length); 
        imageBuffer.order(ByteOrder.nativeOrder()); 
        imageBuffer.put(data, 0, data.length); 
        imageBuffer.flip();
        
        return imageBuffer; 
    } 
    
    private BufferedImage loadImage(String ref) throws IOException 
    { 
        URL url = TextureLoader.class.getClassLoader().getResource(ref);
        
        if (url == null) {
            throw new IOException("Cannot find: "+ref);
        }
        
        BufferedImage bufferedImage = ImageIO.read(new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(ref))); 
 
        return bufferedImage;
    }
    
    protected IntBuffer createIntBuffer(int size) {
      ByteBuffer temp = ByteBuffer.allocateDirect(4 * size);
      temp.order(ByteOrder.nativeOrder());

      return temp.asIntBuffer();
    }    
}
```

Ich hoffe, dass dies soweit hilfreich ist


----------



## Guest2 (6. Dez 2011)

Ja, mit den GL-Profilen kann das in lwjgl schon mal nerven. Hier ist das Beispiel aus dem anderen Thread (was Du oben gepostet hast) um die restlichen Fehler korrigiert:


```
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.glu.GLU;


public class FBOTest {

    private static final int     width              = 1024;
    private static final int     height             = 786;

    private static final int     sunGlowTextureSize = 128;
    private static final float[] sunPosition        = { 0.0f, 0.0f, 0.0f };

    private int                  fboHandle          = 0;
    private int                  rboHandle          = 0;
    private int                  glowHandle         = 0;

    private FloatBuffer          modelview          = null;
    private FloatBuffer          projection         = null;
    private IntBuffer            viewport           = null;


    public FBOTest() {

        // setup ogl basics
        GL11.glClearDepth(1.0f);
        GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
        GL11.glShadeModel(GL11.GL_SMOOTH);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        GL11.glDepthFunc(GL11.GL_LEQUAL);
        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

        // setup fbo stuff
        fboHandle = GL30.glGenFramebuffers();
        rboHandle = GL30.glGenRenderbuffers();
        glowHandle = GL11.glGenTextures();

        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fboHandle);
        GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, rboHandle);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, glowHandle);

        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_LUMINANCE, sunGlowTextureSize, sunGlowTextureSize, 0, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);

        GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, sunGlowTextureSize, sunGlowTextureSize);
        GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, rboHandle);
        GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, glowHandle, 0);

        if (GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) != GL30.GL_FRAMEBUFFER_COMPLETE) {

            System.out.println("Error: GL30.GL_FRAMEBUFFER");
            System.exit(1);

        }

        GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, 0);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);

        // save GL_VIEWPORT for gluProject
        viewport = BufferUtils.createIntBuffer(16);
        GL11.glViewport(0, 0, sunGlowTextureSize, sunGlowTextureSize);
        GL11.glGetInteger(GL11.GL_VIEWPORT, viewport);

        // set projection and modelview
        GL11.glViewport(0, 0, width, height);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GLU.gluPerspective(45.0f, (float) width / (float) height, 1.0f, 50.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        // save current GL_PROJECTION_MATRIX for gluProject
        projection = BufferUtils.createFloatBuffer(16);
        GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projection);

    }


    private void setupCamera() {

        final double time = System.currentTimeMillis();

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();
        GLU.gluLookAt(0.0f, 0.0f, 20.0f, 6 * (float) Math.sin(time / 700), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

    }


    private void renderGlowToTexture() {

        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fboHandle);
        GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT);
        GL11.glViewport(0, 0, sunGlowTextureSize, sunGlowTextureSize);

        setupCamera();

        // save current GL_MODELVIEW_MATRIX for gluProject
        modelview = BufferUtils.createFloatBuffer(16);
        GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelview);

        // draw the "sun"
        GL11.glTranslatef(sunPosition[0], sunPosition[1], sunPosition[2]);
        GL11.glBegin(GL11.GL_TRIANGLES);
        GL11.glVertex3f(+0f, 1f, 0);
        GL11.glVertex3f(-1f, -1f, 0);
        GL11.glVertex3f(+1f, -1f, 0);
        GL11.glEnd();

        GL11.glPopAttrib();
        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);

    }


    private void renderGlowToScreen() {

        // corona parameter
        float spost = 0.0f;
        float alpha = 0.2f;

        final int times = 25;
        final float inc = 1.0f / times;
        final float alphainc = alpha / times;

        // calculate current sun position
        final FloatBuffer sunPosBuffer = BufferUtils.createFloatBuffer(16);
        GLU.gluProject(sunPosition[0], sunPosition[1], sunPosition[2], modelview, projection, viewport, sunPosBuffer);

        final float currentSunPosX = (sunPosBuffer.get(0) / sunGlowTextureSize);
        final float currentSunPosY = (sunPosBuffer.get(1) / sunGlowTextureSize);

        // draw the glow texture to screen
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glPushMatrix();
        GL11.glLoadIdentity();
        GL11.glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 50.0f);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glPushMatrix();
        GL11.glLoadIdentity();

        GL11.glDisable(GL11.GL_DEPTH_TEST);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
        GL11.glEnable(GL11.GL_BLEND);

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, glowHandle);
        GL11.glBegin(GL11.GL_QUADS);

        for (int i = 0; i < times; i++) {

            GL11.glColor4f(1.0f, 1.0f, 1.0f, alpha);

            GL11.glTexCoord2f(spost * currentSunPosX, spost * currentSunPosY);
            GL11.glVertex3f(-1.0f, -1.0f, -1.0f);

            GL11.glTexCoord2f(1 - ((1 - currentSunPosX) * spost), spost * currentSunPosY);
            GL11.glVertex3f(1.0f, -1.0f, -1.0f);

            GL11.glTexCoord2f(1 - ((1 - currentSunPosX) * spost), 1 - ((1 - currentSunPosY) * spost));
            GL11.glVertex3f(1.0f, 1.0f, -1.0f);

            GL11.glTexCoord2f(spost * currentSunPosX, 1 - ((1 - currentSunPosY) * spost));
            GL11.glVertex3f(-1.0f, 1.0f, -1.0f);

            spost += inc;
            alpha = alpha - alphainc;
        }

        GL11.glEnd();
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

        GL11.glDisable(GL11.GL_BLEND);
        GL11.glEnable(GL11.GL_DEPTH_TEST);

        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glPopMatrix();
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glPopMatrix();
    }


    public static void main(final String[] args) {

        try {

            final PixelFormat pf = new PixelFormat().withSamples(4);
            Display.setDisplayMode(new DisplayMode(width, height));
            Display.setVSyncEnabled(true);
            Display.create(pf);

        } catch (final LWJGLException e) {

            e.printStackTrace();
            System.exit(0);

        }

        final FBOTest test = new FBOTest();

        while (!Display.isCloseRequested()) {

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

            test.renderGlowToTexture();
            test.renderGlowToScreen();

            Display.update();
            Display.sync(60);
        }

        Display.destroy();

    }


}
```

Wenn Dir das nicht reicht, um den Fehler in Deinem Beispiel zu finden, werf ich da morgen auch nochmal einen Blick drauf.

Gruß,
Fancy


----------



## javaPanther (7. Dez 2011)

Danke für die Mühe und die neue Variante. Leider habe ich auch bei diesem Beispiel das Problem, dass ich die Texturen nicht auf die Objekte dargestellt bekomme. Zudem sehe ich, dass hier GL30 eingesetzt wird. Mein Ziel ist es max bis GL2x zu gehen. Vielleicht findest du ja heraus, was bei meinem Beispiel schief lief


----------



## Guest2 (7. Dez 2011)

Wenn Du bei GL2 bleiben willst, muss die Grafikkarte für einen FBO aber GL_EXT_framebuffer_object unterstützen. Und ich glaube nicht, dass es noch allzu viele Karten gibt, die diese Extension unterstützen aber kein GL3 können.

Auf die schnelle Dein FBOExample zurechtgedengelt (Texture und TextureLoader habe ich mir nicht weiter angesehen):


```
import static org.lwjgl.opengl.EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.GL_FRAMEBUFFER_COMPLETE_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.GL_FRAMEBUFFER_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.GL_RENDERBUFFER_EXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glBindFramebufferEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glBindRenderbufferEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glCheckFramebufferStatusEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glFramebufferRenderbufferEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glFramebufferTexture2DEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glGenFramebuffersEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glGenRenderbuffersEXT;
import static org.lwjgl.opengl.EXTFramebufferObject.glRenderbufferStorageEXT;
import static org.lwjgl.opengl.GL11.GL_BLEND;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_NICEST;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_PERSPECTIVE_CORRECTION_HINT;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.GL_RGBA;
import static org.lwjgl.opengl.GL11.GL_RGBA8;
import static org.lwjgl.opengl.GL11.GL_SMOOTH;
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glBlendFunc;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glClearDepth;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glGenTextures;
import static org.lwjgl.opengl.GL11.glHint;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;
import static org.lwjgl.opengl.GL11.glShadeModel;
import static org.lwjgl.opengl.GL11.glTexCoord2f;
import static org.lwjgl.opengl.GL11.glTexImage2D;
import static org.lwjgl.opengl.GL11.glTexParameteri;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.opengl.GL11.glVertex3f;
import static org.lwjgl.opengl.GL11.glViewport;
import static org.lwjgl.opengl.GL14.GL_DEPTH_COMPONENT24;

import java.io.IOException;
import java.nio.ByteBuffer;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.glu.GLU;

import com.trivial.graphics.Texture;
import com.trivial.graphics.TextureLoader;

public class FBOExample {

    private static final int width  = 1024;
    private static final int height = 786;

    private final int        fboHandle;
    private final int        rboHandle;
    private final int        fboTextureHandle;

    private Texture          texture;


    public FBOExample() {

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClearDepth(1.0f);

        glEnable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);

        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glShadeModel(GL_SMOOTH);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

        glViewport(0, 0, width, height);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        GLU.gluPerspective(45.0f, ((float) width / (float) height), 0.1f, 100.0f);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();


        try {

            texture = new TextureLoader().getTexture("Target.png");

        } catch (final IOException e) {

            e.printStackTrace();

        }


        fboHandle = glGenFramebuffersEXT();
        rboHandle = glGenRenderbuffersEXT();
        fboTextureHandle = glGenTextures();

        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboHandle);
        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboHandle);
        glBindTexture(GL_TEXTURE_2D, fboTextureHandle);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer) null);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboHandle);
        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboTextureHandle, 0);

        if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT) {

            System.out.println("Error: GL_FRAMEBUFFER_EXT");
            System.exit(1);

        }

        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
        glBindTexture(GL_TEXTURE_2D, 0);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

    }


    public void renderToFBO() {

        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboHandle);

        glClearColor(1.0f, 0.0f, 0.0f, 0.5f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glLoadIdentity();
        glTranslatef(0.0f, 0.0f, -4.0f);

        texture.bind();
        drawBox();

        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

    }


    public void renderToScreen() {

        glClearColor(0.0f, 1.0f, 0.0f, 0.5f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glLoadIdentity();
        glTranslatef(0.0f, 0.0f, -4.0f);

        glBindTexture(GL_TEXTURE_2D, fboTextureHandle);
        drawBox();
        glBindTexture(GL_TEXTURE_2D, 0);

    }


    public void drawBox() {

        glBegin(GL_QUADS);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-1.0f, -1.0f, 1.0f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(1.0f, -1.0f, 1.0f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(1.0f, 1.0f, 1.0f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, 1.0f);
        glEnd();

    }


    public static void main(final String[] args) {

        try {

            final PixelFormat pf = new PixelFormat().withSamples(4);
            Display.setDisplayMode(new DisplayMode(width, height));
            Display.setVSyncEnabled(true);
            Display.create(pf);

        } catch (final LWJGLException e) {

            e.printStackTrace();
            System.exit(0);

        }

        final FBOExample test = new FBOExample();

        while (!Display.isCloseRequested()) {

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glLoadIdentity();

            test.renderToFBO();
            test.renderToScreen();

            Display.update();
            Display.sync(60);
        }

        Display.destroy();

    }
}
```

Gruß,
Fancy


----------



## javaPanther (7. Dez 2011)

Oh ja klasse endlich Texturen generieren und Post-Processing anwenden ^^ Vielen Dank für diese Unterstützung!


----------

