2016-01-19 1 views
0

J'essaie de créer un shader de post-traitement en utilisant un framebuffer. Mais quand je tente d'échantillonner la texture dans les shaders, ça ne fait rien.LWJGL Impossible d'échantillonner la texture framebuffer dans le shader

Dès que je commente la ligne (dans le fragment shader)

vec4 textureColour = texture(screenTexture, textureCoords); 

sur tout fonctionne à nouveau

FrameBuffer.java

package postprocessing; 

import java.nio.ByteBuffer; 

import org.lwjgl.opengl.Display; 
import org.lwjgl.opengl.GL11; 
import org.lwjgl.opengl.GL14; 
import org.lwjgl.opengl.GL30; 
import org.lwjgl.opengl.GL32; 

public class FrameBuffer { 

protected static final int WIDTH = Display.getWidth(); 
private static final int HEIGHT = Display.getHeight(); 

private int framebuffer; 
private int texture; 
private int depthBuffer; 
private int depthTexture; 

public FrameBuffer() 
{ 
    initialise(); 
} 

public void cleanUp() 
{ 
    GL30.glDeleteFramebuffers(framebuffer); 
    GL11.glDeleteTextures(texture); 
    GL30.glDeleteRenderbuffers(depthBuffer); 
    GL11.glDeleteTextures(depthTexture); 
} 

public int getTexture() 
{ 
    return texture; 
} 

public int getDepthTexture() 
{ 
    return depthTexture; 
} 

private void initialise() 
{ 
    framebuffer = createFrameBuffer(); 
    texture = createTextureAttachment(WIDTH, HEIGHT); 
    depthBuffer = createDepthBufferAttachment(WIDTH, HEIGHT); 
    depthTexture = createDepthTextureAttachment(WIDTH, HEIGHT); 
    unbindCurrentFrameBuffer(); 
} 

public void bindFrameBuffer(){ 
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound 
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, framebuffer); 
    GL11.glViewport(0, 0, WIDTH, HEIGHT); 
} 

public void unbindCurrentFrameBuffer() {//call to switch to default frame buffer 
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0); 
    GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight()); 
} 

private int createFrameBuffer() { 
    int frameBuffer = GL30.glGenFramebuffers(); 
    //generate name for frame buffer 
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer); 
    //create the framebuffer 
    GL11.glDrawBuffer(GL30.GL_COLOR_ATTACHMENT0); 
    //indicate that we will always render to color attachment 0 
    return frameBuffer; 
} 

private int createTextureAttachment(int width, int height) { 
    int texture = GL11.glGenTextures(); 
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture); 
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height, 
      0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null); 
    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); 
    GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, 
      texture, 0); 
    return texture; 
} 

private int createDepthTextureAttachment(int width, int height){ 
    int texture = GL11.glGenTextures(); 
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture); 
    GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL14.GL_DEPTH_COMPONENT32, width, height, 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (ByteBuffer) null); 
    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); 
    GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, texture, 0); 
    return texture; 
} 

private int createDepthBufferAttachment(int width, int height) { 
    int depthBuffer = GL30.glGenRenderbuffers(); 
    GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer); 
    GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, width, 
      height); 
    GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, 
      GL30.GL_RENDERBUFFER, depthBuffer); 
    return depthBuffer; 
} 
} 

FrameBufferShader.java

package postprocessing; 

import shaders.ShaderProgram; 

public class FrameBufferShader extends ShaderProgram { 

private static final String VERTEX_FILE = "src/postprocessing/vertexShader.txt"; 
private static final String FRAGMENT_FILE = "src/postprocessing/fragmentShader.txt"; 

private int location_texture; 
private int location_depthMap; 

public FrameBufferShader() 
{ 
    super(VERTEX_FILE, FRAGMENT_FILE); 
} 

@Override 
protected void getAllUniformLocations() 
{ 
    bindAttributes(0, "position"); 
} 

@Override 
protected void bindAttributes() 
{ 
    location_texture = super.getUniformLocation("screenTexture"); 
    location_depthMap = super.getUniformLocation("depthMap"); 
} 

public void connectTextureUnits() 
{ 
    super.loadInt(location_texture, 0); 
    super.loadInt(location_depthMap, 1); 
} 
} 

FrameBufferRenderer.java

package postprocessing; 

import org.lwjgl.opengl.GL11; 
import org.lwjgl.opengl.GL13; 
import org.lwjgl.opengl.GL20; 
import org.lwjgl.opengl.GL30; 

import models.RawModel; 
import renderEngine.Loader; 

public class FrameBufferRenderer { 

private RawModel quad; 
private FrameBufferShader shader; 
private FrameBuffer fbo; 

public FrameBufferRenderer(Loader loader, FrameBufferShader shader, FrameBuffer fbo) 
{ 
    this.fbo = fbo; 
    this.shader = shader; 
    setUpVAO(loader); 
    shader.start(); 
    shader.connectTextureUnits(); 
    shader.stop(); 
} 

public void render() 
{ 
    prepareRender(); 
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, quad.getVertexCount()); 
    unbind(); 
} 

private void prepareRender() 
{ 
    shader.start(); 
    GL30.glBindVertexArray(quad.getVaoID()); 
    GL20.glEnableVertexAttribArray(0); 
    GL13.glActiveTexture(GL13.GL_TEXTURE0); 
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbo.getTexture()); 
    GL13.glActiveTexture(GL13.GL_TEXTURE1); 
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, fbo.getDepthTexture()); 

    GL11.glEnable(GL11.GL_BLEND); 
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 
} 

private void unbind() 
{ 
    GL11.glDisable(GL11.GL_BLEND); 
    GL20.glDisableVertexAttribArray(0); 
    GL30.glBindVertexArray(0); 
    shader.stop(); 
} 

private void setUpVAO(Loader loader) { 
    float[] vertices = { -1, -1, 1, -1, 1, 1, -1, 1 }; 
    quad = loader.loadtoVAO(vertices, 2); 
} 
} 

Vertex Shader

#version 400 

in vec2 position; 

void main() 
{ 
    gl_Position = vec4(position.x, position.y, 0.0, 1.0); 
} 

Fragment Shader

#version 400 

in vec2 textureCoords; 

out vec4 outColor; 

uniform sampler2D screenTexture; 
uniform sampler2D depthTexture; 

void main() 
{ 
    vec4 textureColour = texture(screenTexture, textureCoords); 

    outColor = vec4(1.0, 1.0, 1.0, 1.0); 
} 

Répondre

1

Vous ne pouvez pas goûter à la texture de la destination dans le shader.

Ce que vous pouvez faire est de créer une nouvelle texture et d'en faire la texture de destination pour l'étape précédente et de l'utiliser comme une texture normale dans l'étape en cours.

+0

Pourriez-vous donner un exemple? Je ne pense pas que je comprends tout à fait – WiNteR

+0

@AppleBunny: Qu'est-ce que vous ne comprenez pas? [Vous ne pouvez pas lire à partir de la texture à laquelle vous êtes en train d'écrire] (https://www.opengl.org/wiki/Memory_Model#Framebuffer_objects). Par conséquent, si vous voulez lire à partir d'une texture que vous avez écrite précédemment, vous devez * changer * le framebuffer que vous êtes en train de rendre. –

+0

Oooh bien, ça a du sens XD – WiNteR