2012-10-07 4 views
-1

텍스처로 렌더링 할 수 있어야하고 그 텍스처를 전체 화면 쿼드로 그릴 수 있어야합니다. 노골적으로 LWJGL 자습서를 복사하면 나는 질감 및 이동 쿼드을 할 수 있었다, 그러나 나는 텍스처를 렌더링 할 수 없습니다 : 여기 lwjgl 및 텍스처로 렌더링

import java.io.BufferedReader; 
import java.io.FileInputStream; 
import java.io.FileReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.nio.ByteBuffer; 
import java.nio.FloatBuffer; 
import java.nio.IntBuffer; 

import org.lwjgl.BufferUtils; 
import org.lwjgl.LWJGLException; 
import org.lwjgl.input.Keyboard; 
import org.lwjgl.opengl.ContextAttribs; 
import org.lwjgl.opengl.Display; 
import org.lwjgl.opengl.DisplayMode; 
import org.lwjgl.opengl.GL11; 
import org.lwjgl.opengl.GL12; 
import org.lwjgl.opengl.GL13; 
import org.lwjgl.opengl.GL15; 
import org.lwjgl.opengl.GL20; 
import org.lwjgl.opengl.GL30; 
import org.lwjgl.opengl.GL32; 
import org.lwjgl.opengl.PixelFormat; 
import org.lwjgl.util.glu.GLU; 
import org.lwjgl.util.vector.Matrix4f; 
import org.lwjgl.util.vector.Vector3f; 


import de.matthiasmann.twl.utils.PNGDecoder; 
import de.matthiasmann.twl.utils.PNGDecoder.Format; 

public class TheQuadExampleMovingFBO { 
    // Entry point for the application 
    public static void main(String[] args) { 
     new TheQuadExampleMovingFBO(); 
    } 

    // Setup variables 
    private final String WINDOW_TITLE = "The Quad: Moving"; 
    private final int WIDTH = 320; 
    private final int HEIGHT = 240; 
    private final double PI = 3.14159265358979323846; 
    // Frame Buffer variables 
    private int fboID = 0; 
    private int colID = 0; 
    private int depID = 0; 
    private IntBuffer drawBuffs; 
    // Quad variables 
    private int vaoId = 0; 
    private int vboId = 0; 
    private int vboiId = 0; 
    private int indicesCount = 0; 
    private VertexData[] vertices = null; 
    private ByteBuffer verticesByteBuffer = null; 
    // Shader variables 
    private int vsId = 0; 
    private int fsId = 0; 
    private int pId = 0; 
    // Texture variables 
    private int[] texIds = new int[] {0, 0}; 
    private int textureSelector = 0; 
    // Moving variables 
    private int projectionMatrixLocation = 0; 
    private int viewMatrixLocation = 0; 
    private int modelMatrixLocation = 0; 
    private Matrix4f projectionMatrix = null; 
    private Matrix4f viewMatrix = null; 
    private Matrix4f modelMatrix = null; 
    private Vector3f modelPos = null; 
    private Vector3f modelAngle = null; 
    private Vector3f modelScale = null; 
    private Vector3f cameraPos = null; 
    private FloatBuffer matrix44Buffer = null; 

    public TheQuadExampleMovingFBO() { 
     // Initialize OpenGL (Display) 
     this.setupOpenGL(); 

     this.setupQuad(); 
     this.setupShaders(); 
     this.setupTextures(); 
     this.setupMatrices(); 

     while (!Display.isCloseRequested()) { 
      // Do a single loop (logic/render) 
      this.loopCycle(); 

      // Force a maximum FPS of about 60 
      Display.sync(60); 
      // Let the CPU synchronize with the GPU if GPU is tagging behind 
      Display.update(); 
     } 

     // Destroy OpenGL (Display) 
     this.destroyOpenGL(); 
    } 

    private void setupMatrices() { 
     // Setup projection matrix 
     projectionMatrix = new Matrix4f(); 
     float fieldOfView = 60f; 
     float aspectRatio = (float)WIDTH/(float)HEIGHT; 
     float near_plane = 0.1f; 
     float far_plane = 100f; 

     float y_scale = this.coTangent(this.degreesToRadians(fieldOfView/2f)); 
     float x_scale = y_scale/aspectRatio; 
     float frustum_length = far_plane - near_plane; 

     projectionMatrix.m00 = x_scale; 
     projectionMatrix.m11 = y_scale; 
     projectionMatrix.m22 = -((far_plane + near_plane)/frustum_length); 
     projectionMatrix.m23 = -1; 
     projectionMatrix.m32 = -((2 * near_plane * far_plane)/frustum_length); 

     // Setup view matrix 
     viewMatrix = new Matrix4f(); 

     // Setup model matrix 
     modelMatrix = new Matrix4f(); 

     // Create a FloatBuffer with the proper size to store our matrices later 
     matrix44Buffer = BufferUtils.createFloatBuffer(16); 
    } 

    private void setupTextures() { 
     texIds[0] = this.loadPNGTexture("assets/images/stGrid1.png", GL13.GL_TEXTURE0); 
     texIds[1] = this.loadPNGTexture("assets/images/stGrid2.png", GL13.GL_TEXTURE0); 

     this.exitOnGLError("setupTexture"); 
    } 

    private void setupOpenGL() { 
     // Setup an OpenGL context with API version 3.2 
     try { 
      PixelFormat pixelFormat = new PixelFormat(); 
      ContextAttribs contextAtrributes = new ContextAttribs(3, 2); 
      contextAtrributes.withForwardCompatible(true); 
      contextAtrributes.withProfileCore(true); 

      Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT)); 
      Display.setTitle(WINDOW_TITLE); 
      Display.create(pixelFormat, contextAtrributes); 

      GL11.glViewport(0, 0, WIDTH, HEIGHT); 
     } catch (LWJGLException e) { 
      e.printStackTrace(); 
      System.exit(-1); 
     } 

     // Setup an XNA like background color 
     GL11.glClearColor(0.4f, 0.6f, 0.9f, 0f); 

     // Map the internal OpenGL coordinate system to the entire screen 
     GL11.glViewport(0, 0, WIDTH, HEIGHT); 
     System.out.println(GL11.glGetString(GL11.GL_VERSION)); 
     this.exitOnGLError("setupOpenGL"); 
    } 

    private void setupQuad() { 
     // We'll define our quad using 4 vertices of the custom 'TexturedVertex' class 
     VertexData v0 = new VertexData(); 
     v0.setXYZ(-0.5f, 0.5f, 0); v0.setRGB(1, 0, 0); v0.setST(0, 0); 
     VertexData v1 = new VertexData(); 
     v1.setXYZ(-0.5f, -0.5f, 0); v1.setRGB(0, 1, 0); v1.setST(0, 1); 
     VertexData v2 = new VertexData(); 
     v2.setXYZ(0.5f, -0.5f, 0); v2.setRGB(0, 0, 1); v2.setST(1, 1); 
     VertexData v3 = new VertexData(); 
     v3.setXYZ(0.5f, 0.5f, 0); v3.setRGB(1, 1, 1); v3.setST(1, 0); 

     vertices = new VertexData[] {v0, v1, v2, v3}; 

     // Put each 'Vertex' in one FloatBuffer 
     verticesByteBuffer = BufferUtils.createByteBuffer(vertices.length * 
       VertexData.stride);    
     FloatBuffer verticesFloatBuffer = verticesByteBuffer.asFloatBuffer(); 
     for (int i = 0; i < vertices.length; i++) { 
      // Add position, color and texture floats to the buffer 
      verticesFloatBuffer.put(vertices[i].getElements()); 
     } 
     verticesFloatBuffer.flip(); 


     // OpenGL expects to draw vertices in counter clockwise order by default 
     byte[] indices = { 
       0, 1, 2, 
       2, 3, 0 
     }; 
     indicesCount = indices.length; 
     ByteBuffer indicesBuffer = BufferUtils.createByteBuffer(indicesCount); 
     indicesBuffer.put(indices); 
     indicesBuffer.flip(); 

     // Create a new Vertex Array Object in memory and select it (bind) 
     vaoId = GL30.glGenVertexArrays(); 
     GL30.glBindVertexArray(vaoId); 

     // Create a new Vertex Buffer Object in memory and select it (bind) 
     vboId = GL15.glGenBuffers(); 
     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId); 
     GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesFloatBuffer, GL15.GL_STREAM_DRAW); 

     // Put the position coordinates in attribute list 0 
     GL20.glVertexAttribPointer(0, VertexData.positionElementCount, GL11.GL_FLOAT, 
       false, VertexData.stride, VertexData.positionByteOffset); 
     // Put the color components in attribute list 1 
     GL20.glVertexAttribPointer(1, VertexData.colorElementCount, GL11.GL_FLOAT, 
       false, VertexData.stride, VertexData.colorByteOffset); 
     // Put the texture coordinates in attribute list 2 
     GL20.glVertexAttribPointer(2, VertexData.textureElementCount, GL11.GL_FLOAT, 
       false, VertexData.stride, VertexData.textureByteOffset); 

     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 

     // Deselect (bind to 0) the VAO 
     GL30.glBindVertexArray(0); 

     // Create a new VBO for the indices and select it (bind) - INDICES 
     vboiId = GL15.glGenBuffers(); 
     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId); 
     GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, 
       GL15.GL_STATIC_DRAW); 
     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 

     // Set the default quad rotation, scale and position values 
     modelPos = new Vector3f(0, 0, 0); 
     modelAngle = new Vector3f(0, 0, 0); 
     modelScale = new Vector3f(1, 1, 1); 
     cameraPos = new Vector3f(0, 0, 0); 

     ////////// THIS IS WHERE I ADDED CODE FOR THE FRAMEBUFFER STUFF ////////////// 

     //render to texture attempt 
     fboID = GL30.glGenFramebuffers(); 
     GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fboID); 
     colID = GL11.glGenTextures(); 
     GL11.glBindTexture(GL11.GL_TEXTURE_2D, colID); 
     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_NEAREST); 
     GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); 
     GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); 
     GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); 
     depID = GL30.glGenRenderbuffers(); 
     GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depID); 
     GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, WIDTH, HEIGHT); 
     GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, depID); 
     GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, colID, 0); 
     drawBuffs = BufferUtils.createIntBuffer(1); 
     drawBuffs.put(0, GL30.GL_COLOR_ATTACHMENT0); 
     GL20.glDrawBuffers(drawBuffs); 
     if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) != GL30.GL_FRAMEBUFFER_COMPLETE){ 
      System.out.println("Framebuffer not complete!"); 
     }else{ System.out.println("Framebuffer is complete!");} 


     //////// END OF NEW CODE HERE, LOOK IN RENDER CYCLE FOR MORE NEW CODE /////////// 

     this.exitOnGLError("setupQuad"); 
    } 

    private void setupShaders() {  
     // Load the vertex shader 
     vsId = this.loadShader("assets/shaders/moving/vertex.glsl", 
       GL20.GL_VERTEX_SHADER); 
     // Load the fragment shader 
     fsId = this.loadShader("assets/shaders/moving/fragment.glsl", 
       GL20.GL_FRAGMENT_SHADER); 

     // Create a new shader program that links both shaders 
     pId = GL20.glCreateProgram(); 
     GL20.glAttachShader(pId, vsId); 
     GL20.glAttachShader(pId, fsId); 
     GL20.glLinkProgram(pId); 

     // Position information will be attribute 0 
     GL20.glBindAttribLocation(pId, 0, "in_Position"); 
     // Color information will be attribute 1 
     GL20.glBindAttribLocation(pId, 1, "in_Color"); 
     // Textute information will be attribute 2 
     GL20.glBindAttribLocation(pId, 2, "in_TextureCoord"); 

     // Get matrices uniform locations 
     projectionMatrixLocation = GL20.glGetUniformLocation(pId, "projectionMatrix"); 
     viewMatrixLocation = GL20.glGetUniformLocation(pId, "viewMatrix"); 
     modelMatrixLocation = GL20.glGetUniformLocation(pId, "modelMatrix"); 

     GL20.glValidateProgram(pId); 

     this.exitOnGLError("setupShaders"); 
    } 

    private void logicCycle() { 
     //-- Input processing 
     float rotationDelta = 15f; 
     float scaleDelta = 0.1f; 
     float posDelta = 0.1f; 
     Vector3f scaleAddResolution = new Vector3f(scaleDelta, scaleDelta, scaleDelta); 
     Vector3f scaleMinusResolution = new Vector3f(-scaleDelta, -scaleDelta, 
       -scaleDelta); 

     while(Keyboard.next()) {    
      // Only listen to events where the key was pressed (down event) 
      if (!Keyboard.getEventKeyState()) continue; 

      // Switch textures depending on the key released 
      switch (Keyboard.getEventKey()) { 
      case Keyboard.KEY_1: 
       textureSelector = 0; 
       break; 
      case Keyboard.KEY_2: 
       textureSelector = 1; 
       break; 
      } 

      // Change model scale, rotation and translation values 
      switch (Keyboard.getEventKey()) { 
      // Move 
      case Keyboard.KEY_UP: 
       modelPos.y += posDelta; 
       break; 
      case Keyboard.KEY_DOWN: 
       modelPos.y -= posDelta; 
       break; 
      // Scale 
      case Keyboard.KEY_P: 
       Vector3f.add(modelScale, scaleAddResolution, modelScale); 
       break; 
      case Keyboard.KEY_M: 
       Vector3f.add(modelScale, scaleMinusResolution, modelScale); 
       break; 
      // Rotation 
      case Keyboard.KEY_LEFT: 
       modelAngle.z += rotationDelta; 
       break; 
      case Keyboard.KEY_RIGHT: 
       modelAngle.z -= rotationDelta; 
       break; 
      } 
     } 

     //-- Update matrices 
     // Reset view and model matrices 
     viewMatrix = new Matrix4f(); 
     modelMatrix = new Matrix4f(); 

     // Translate camera 
     Matrix4f.translate(cameraPos, viewMatrix, viewMatrix); 

     // Scale, translate and rotate model 
     Matrix4f.scale(modelScale, modelMatrix, modelMatrix); 
     Matrix4f.translate(modelPos, modelMatrix, modelMatrix); 
     Matrix4f.rotate(this.degreesToRadians(modelAngle.z), new Vector3f(0, 0, 1), 
       modelMatrix, modelMatrix); 
     Matrix4f.rotate(this.degreesToRadians(modelAngle.y), new Vector3f(0, 1, 0), 
       modelMatrix, modelMatrix); 
     Matrix4f.rotate(this.degreesToRadians(modelAngle.x), new Vector3f(1, 0, 0), 
       modelMatrix, modelMatrix); 

     // Upload matrices to the uniform variables 
     GL20.glUseProgram(pId); 

     projectionMatrix.store(matrix44Buffer); matrix44Buffer.flip(); 
     GL20.glUniformMatrix4(projectionMatrixLocation, false, matrix44Buffer); 
     viewMatrix.store(matrix44Buffer); matrix44Buffer.flip(); 
     GL20.glUniformMatrix4(viewMatrixLocation, false, matrix44Buffer); 
     modelMatrix.store(matrix44Buffer); matrix44Buffer.flip(); 
     GL20.glUniformMatrix4(modelMatrixLocation, false, matrix44Buffer); 

     GL20.glUseProgram(0); 

     this.exitOnGLError("logicCycle"); 
    } 

    private void renderCycle() { 
     ////////// THESE LINES ARE NEW, ADDED TO RENDER TO THE FRAME BUFFER ///////// 
     GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fboID); 
     GL11.glViewport(0, 0, WIDTH, HEIGHT); 
     ///////// THIS IS THE ORIGINAL RENDER CYCLE CODE, I WANT THIS TO GO TO THE FBO /////// 
     GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); 

     GL20.glUseProgram(pId); 

     // Bind the texture 
     GL13.glActiveTexture(GL13.GL_TEXTURE0); 
     GL11.glBindTexture(GL11.GL_TEXTURE_2D, texIds[textureSelector]); 

     // Bind to the VAO that has all the information about the vertices 
     GL30.glBindVertexArray(vaoId); 
     GL20.glEnableVertexAttribArray(0); 
     GL20.glEnableVertexAttribArray(1); 
     GL20.glEnableVertexAttribArray(2); 

     // Bind to the index VBO that has all the information about the order of the vertices 
     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId); 

     // Draw the vertices 
     GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_BYTE, 0); 

     // Put everything back to default (deselect) 
     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 
     GL20.glDisableVertexAttribArray(0); 
     GL20.glDisableVertexAttribArray(1); 
     GL20.glDisableVertexAttribArray(2); 
     GL30.glBindVertexArray(0); 

     GL20.glUseProgram(0); 


     //////// NEW CODE, I WANT TO DRAW A FULL SCREEN QUAD WITH THE TEXTURE FROM THE FBO /////// 
     // draw the texture from the FBO 
     GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0); 
     GL11.glViewport(0, 0, WIDTH, HEIGHT); 
     GL11.glBegin(GL11.GL_QUADS); 
      GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f(0.0f, 0.0f, 0.0f); 
      GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f((float)WIDTH, 0.0f, 0.0f); 
      GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f((float)WIDTH, (float)HEIGHT, 0.0f); 
      GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f(0.0f, (float)HEIGHT, 0.0f); 
     GL11.glEnd(); 
     ///////// END OF NEW CODE /////////// 
     this.exitOnGLError("renderCycle"); 
    } 

    private void loopCycle() { 
     // Update logic 
     this.logicCycle(); 
     // Update rendered frame 
     this.renderCycle(); 

     this.exitOnGLError("loopCycle"); 
    } 

    private void destroyOpenGL() { 
     // Delete the texture 
     GL11.glDeleteTextures(texIds[0]); 
     GL11.glDeleteTextures(texIds[1]); 

     // Delete the shaders 
     GL20.glUseProgram(0); 
     GL20.glDetachShader(pId, vsId); 
     GL20.glDetachShader(pId, fsId); 

     GL20.glDeleteShader(vsId); 
     GL20.glDeleteShader(fsId); 
     GL20.glDeleteProgram(pId); 

     // Select the VAO 
     GL30.glBindVertexArray(vaoId); 

     // Disable the VBO index from the VAO attributes list 
     GL20.glDisableVertexAttribArray(0); 
     GL20.glDisableVertexAttribArray(1); 

     // Delete the vertex VBO 
     GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); 
     GL15.glDeleteBuffers(vboId); 

     // Delete the index VBO 
     GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 
     GL15.glDeleteBuffers(vboiId); 

     // Delete the VAO 
     GL30.glBindVertexArray(0); 
     GL30.glDeleteVertexArrays(vaoId); 

     this.exitOnGLError("destroyOpenGL"); 

     Display.destroy(); 
    } 

    private int loadShader(String filename, int type) { 
     StringBuilder shaderSource = new StringBuilder(); 
     int shaderID = 0; 

     try { 
      BufferedReader reader = new BufferedReader(new FileReader(filename)); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       shaderSource.append(line).append("\n"); 
      } 
      reader.close(); 
     } catch (IOException e) { 
      System.err.println("Could not read file."); 
      e.printStackTrace(); 
      System.exit(-1); 
     } 

     shaderID = GL20.glCreateShader(type); 
     GL20.glShaderSource(shaderID, shaderSource); 
     GL20.glCompileShader(shaderID); 

     if (GL20.glGetShader(shaderID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) { 
      System.err.println("Could not compile shader."); 
      System.exit(-1); 
     } 

     this.exitOnGLError("loadShader"); 

     return shaderID; 
    } 

    private int loadPNGTexture(String filename, int textureUnit) { 
     ByteBuffer buf = null; 
     int tWidth = 0; 
     int tHeight = 0; 

     try { 
      // Open the PNG file as an InputStream 
      InputStream in = new FileInputStream(filename); 
      // Link the PNG decoder to this stream 
      PNGDecoder decoder = new PNGDecoder(in); 

      // Get the width and height of the texture 
      tWidth = decoder.getWidth(); 
      tHeight = decoder.getHeight(); 


      // Decode the PNG file in a ByteBuffer 
      buf = ByteBuffer.allocateDirect(
        4 * decoder.getWidth() * decoder.getHeight()); 
      decoder.decode(buf, decoder.getWidth() * 4, Format.RGBA); 
      buf.flip(); 

      in.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      System.exit(-1); 
     } 

     // Create a new texture object in memory and bind it 
     int texId = GL11.glGenTextures(); 
     GL13.glActiveTexture(textureUnit); 
     GL11.glBindTexture(GL11.GL_TEXTURE_2D, texId); 

     // All RGB bytes are aligned to each other and each component is 1 byte 
     GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1); 

     // Upload the texture data and generate mip maps (for scaling) 
     GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, tWidth, tHeight, 0, 
       GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buf); 
     GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D); 

     // Setup the ST coordinate system 
     GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); 
     GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); 

     // Setup what to do when the texture has to be scaled 
     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_MIPMAP_LINEAR); 

     this.exitOnGLError("loadPNGTexture"); 

     return texId; 
    } 

    private float coTangent(float angle) { 
     return (float)(1f/Math.tan(angle)); 
    } 

    private float degreesToRadians(float degrees) { 
     return degrees * (float)(PI/180d); 
    } 

    private void exitOnGLError(String errorMessage) { 
     int errorValue = GL11.glGetError(); 

     if (errorValue != GL11.GL_NO_ERROR) { 
      String errorString = GLU.gluErrorString(errorValue); 
      System.err.println("ERROR - " + errorMessage + ": " + errorString); 

      if (Display.isCreated()) Display.destroy(); 
      System.exit(-1); 
     } 
    } 
} 

나는 질감으로 렌더링을위한 라인을 추가 한 코드의 부분입니다 : I는 프레임 버퍼 STUFF //////////////

//render to texture attempt 
    fboID = GL30.glGenFramebuffers(); 
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fboID); 
    colID = GL11.glGenTextures(); 
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, colID); 
    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_NEAREST); 
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); 
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); 
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); 
    depID = GL30.glGenRenderbuffers(); 
    GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depID); 
    GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, WIDTH, HEIGHT); 
    GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, depID); 
    GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, colID, 0); 
    drawBuffs = BufferUtils.createIntBuffer(1); 
    drawBuffs.put(0, GL30.GL_COLOR_ATTACHMENT0); 
    GL20.glDrawBuffers(drawBuffs); 
    if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) != GL30.GL_FRAMEBUFFER_COMPLETE){ 
     System.out.println("Framebuffer not complete!"); 
    }else{ System.out.println("Framebuffer is complete!");} 


    //////// END OF NEW CODE HERE, LOOK IN RENDER CYCLE FOR MORE NEW CODE /////////// 
위한 코드 추가 WHERE

가 FBO에게 ////////// 설정이다

이고 렌더링 코드는 다음과 같습니다. //////////이 줄들은 새로 추가되었으며, 렌더러에 추가되었습니다. 프레임 버퍼 ///////// GL30.glBindFramebuffer (GL30.GL_FRAMEBUFFER, fboID); GL11.gl 뷰포트 (0, 0, WIDTH, HEIGHT); ///////// 이것은 원래의 렌더 코드입니다. FBO로 가려면이 코드를 사용하십시오 /////// GL11.glClear (GL11.GL_COLOR_BUFFER_BIT);

GL20.glUseProgram(pId); 

    // Bind the texture 
    GL13.glActiveTexture(GL13.GL_TEXTURE0); 
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texIds[textureSelector]); 

    // Bind to the VAO that has all the information about the vertices 
    GL30.glBindVertexArray(vaoId); 
    GL20.glEnableVertexAttribArray(0); 
    GL20.glEnableVertexAttribArray(1); 
    GL20.glEnableVertexAttribArray(2); 

    // Bind to the index VBO that has all the information about the order of the vertices 
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId); 

    // Draw the vertices 
    GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_BYTE, 0); 

    // Put everything back to default (deselect) 
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 
    GL20.glDisableVertexAttribArray(0); 
    GL20.glDisableVertexAttribArray(1); 
    GL20.glDisableVertexAttribArray(2); 
    GL30.glBindVertexArray(0); 

    GL20.glUseProgram(0); 


    //////// NEW CODE, I WANT TO DRAW A FULL SCREEN QUAD WITH THE TEXTURE FROM THE FBO /////// 
    // draw the texture from the FBO 
    GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0); 
    GL11.glViewport(0, 0, WIDTH, HEIGHT); 
    GL11.glBegin(GL11.GL_QUADS); 
     GL11.glTexCoord2f(0.0f, 0.0f); GL11.glVertex3f(0.0f, 0.0f, 0.0f); 
     GL11.glTexCoord2f(1.0f, 0.0f); GL11.glVertex3f((float)WIDTH, 0.0f, 0.0f); 
     GL11.glTexCoord2f(1.0f, 1.0f); GL11.glVertex3f((float)WIDTH, (float)HEIGHT, 0.0f); 
     GL11.glTexCoord2f(0.0f, 1.0f); GL11.glVertex3f(0.0f, (float)HEIGHT, 0.0f); 
    GL11.glEnd(); 
    ///////// END OF NEW CODE /////////// 

이 코드를 실행하면 그때 내 렌더링주기에서 잘못된 작업에 대한 OpenGL은 오류가 발생하며 충돌이 약 1 초 동안 검은 사각형, 콘솔 프레임 버퍼가 완료되었음을 알려줍니다 얻을 . 나는이 문제가 내 풀 스크린 쿼드 코드 어딘가에 있다고 생각하지만, 제대로하는 방법을 모른다. 렌더링 할 스크린을위한 새로운 쉐이더 프로그램을 생성해야합니까? glBegin (GL_QUADS)을 삭제하고 버텍스 버퍼를 사용해야합니까?

답변

2

드로잉을 위해 FBO를 바인딩하기 전에 colID 텍스처를 바인딩 해제해야합니다 (그렇지 않으면 동시에 읽을 수 있고 동시에 쓸 수 있습니다).

+0

괜찮습니다.이 줄을 추가했습니다. GL11.glBindTexture (GL11.GL_TEXTURE_2D, 0); 렌더링주기에서 FBO를 바인딩하기 직전입니다. 또한 화면에 그리기 전에 colID를 다시 바인딩하는 행을 추가했습니다. 나는 여전히 검은 창이 나타나고 잘못된 조작 오류가 발생한다. – user137

+1

@ user137 : 오류를 정확히 테스트하려면 어떻게해야합니까? 오류가 누적되면서 OpenGL의 오류보고는 사용하기가 약간 까다 롭습니다. 어떤 시점에서 glGetError를 호출하면 오래 전에 오류가보고 될 수 있습니다. 참고로이 FBO는 C : https://github.com/datenwolf/codesamples/blob/master/samples/OpenGL/minimalfbo/minimalfbo.c에서 저에게 쓰여진 텍스처 예제로 렌더됩니다. – datenwolf

관련 문제