2013-10-27 26 views
0

我已經對渲染代碼進行了幾次優化,但仍然沒有渲染,並且所有可見的都是黑色窗口。它之前已經工作(使用OpenGL immedieate模式渲染,但我似乎已經打破了系統。不使用lwjgl和頂點緩衝區進行渲染的紋理

Texture.java

import static org.lwjgl.opengl.ARBBufferObject.*; 
import static org.lwjgl.opengl.ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB; 
import static org.lwjgl.opengl.GL11.*; 

import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.nio.ByteBuffer; 
import java.nio.FloatBuffer; 
import java.nio.IntBuffer; 

import javax.imageio.ImageIO; 

import org.lwjgl.BufferUtils; 
import org.lwjgl.util.ReadableColor; 

public class Texture { 

    public static Texture font1; 

    public static Texture smallButton1; 
    public static Texture smallButton1Hover; 

    public static Texture background1; 

    public static Texture title1; 

    public static Texture smallTextBox1; 
    public static Texture largeTextBox1; 

    final String file; 
    boolean loaded = false; 
    private ByteBuffer buffer; 
    public final int width, height; 

    public static void loadTextures() { 
     font1 = new Texture("/fonts/font1.png"); 

     background1 = new Texture("/textures/background1.png"); 

     title1 = new Texture("/textures/title1.png"); 

     smallButton1 = new Texture("/textures/smallButton1.png"); 
     smallButton1Hover = new Texture("/textures/smallButton1Hover.png"); 

     smallTextBox1 = new Texture("/textures/smallTextBox1.png"); 
     largeTextBox1 = new Texture("/textures/largeTextBox1.png"); 
    } 

    public Texture(String path) { 
     BufferedImage image = null; 
     try { 
      image = ImageIO.read(TacAttack.class.getResourceAsStream(path)); 
      int BYTES_PER_PIXEL = 4; 
      int[] pixels = new int[image.getWidth() * image.getHeight()]; 
      image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); 

      buffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * BYTES_PER_PIXEL); //4bytes for RGBA 
      for (int y = 0; y < image.getHeight(); y++) { 
       for (int x = 0; x < image.getWidth(); x++) { 
        int pixel = pixels[y * image.getWidth() + x]; 
        buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component 
        buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component 
        buffer.put((byte) (pixel & 0xFF)); // Blue component 
        buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component 
       } 
      } 
      buffer.flip(); 

      loaded = true; 

      System.out.println("Loaded texture: \"" + path + "\""); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      ErrorHandler.fatalError(ErrorType.IOError, "Couldn't load texture: " + path); 
     } 

     this.file = path; 

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

    public ByteBuffer getBuffer() { 
     if (!loaded) { 
      ErrorHandler.fatalError(ErrorType.textureError, "Buffer requested before texture loaded."); 
      return null; 
     } else { 
      return buffer; 
     } 
    } 

    private void use(int texID, ReadableColor color) { 
     glEnable(GL_TEXTURE_2D); 
     glColor4b(color.getRedByte(), color.getGreenByte(), color.getBlueByte(), color.getAlphaByte()); 
     glBindTexture(GL_TEXTURE_2D, texID); 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    } 

    private void endUse() { 
     glDisable(GL_BLEND); 
     glDisable(GL_TEXTURE_2D); 
    } 

    public void render(int texID, IntBuffer vBuffer, FloatBuffer tBuffer, boolean changed, int vHandle, int tHandle, ReadableColor color) { 
     if (!loaded) { 
      return; 
     } 

     System.out.println(""); 
     System.out.println(">>"); 
     System.out.println("apparently rendered at: x" + vBuffer.get(0) + ", y" + vBuffer.get(1) + ", w" + (vBuffer.get(4) - vBuffer.get(0)) + ", h" + (vBuffer.get(5) - vBuffer.get(1)) + " with vHandle - " + vHandle + ", " + file); 
     System.out.println("apparent texturecoords: x" + tBuffer.get(0) + ", y" + tBuffer.get(1) + ", w" + (tBuffer.get(4) - tBuffer.get(0)) + ", h" + (tBuffer.get(5) - tBuffer.get(1)) + " with tHandle - " + tHandle); 

     use(texID, color); 

     glEnableClientState(GL_VERTEX_ARRAY); 
     glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

     glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle); 
     if (changed) { 
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, vBuffer, GL_STATIC_DRAW_ARB); 
      System.out.println("yeah"); 
     } 
     glVertexPointer(2, GL_INT, 2 * 4, 0L); 

     glBindBufferARB(GL_ARRAY_BUFFER_ARB, tHandle); 
     if (changed) { 
      glBufferDataARB(GL_ARRAY_BUFFER_ARB, tBuffer, GL_STATIC_DRAW_ARB); 
      System.out.println("yeah2"); 
     } 
     glTexCoordPointer(2, GL_FLOAT, 2 * 4, 0L); 

     glDrawArrays(GL_QUADS, 0, 4); 

     glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 

     glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
     glDisableClientState(GL_VERTEX_ARRAY); 

     endUse(); 
    } 

} 

TextureObject.java

import static org.lwjgl.opengl.ARBBufferObject.glGenBuffersARB; 
import static org.lwjgl.opengl.GL11.*; 

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

import org.lwjgl.BufferUtils; 
import org.lwjgl.opengl.GL12; 
import org.lwjgl.util.Color; 
import org.lwjgl.util.ReadableColor; 

public class TextureObject { 

    private final Texture texture; 

    public final int width, height; 

    private final int texID; 
    private IntBuffer vBuffer; 
    private FloatBuffer tBuffer; 

    private boolean changed = true; 

    private IntBuffer ib = BufferUtils.createIntBuffer(2); 
    private final int vHandle; 
    private final int tHandle; 

    public TextureObject(Texture texture) { 
     this.texture = texture; 
     this.width = texture.width; 
     this.height = texture.height; 

     texID = glGenTextures(); 
     glBindTexture(GL_TEXTURE_2D, texID); 

     //Setup wrap mode 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL12.GL_CLAMP_TO_EDGE); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL12.GL_CLAMP_TO_EDGE); 

     //Setup texture scaling filtering 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

     //Send tex data to OpenGL 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.getBuffer()); 

     vBuffer = BufferUtils.createIntBuffer(8); 
     tBuffer = BufferUtils.createFloatBuffer(8); 
     vBuffer.put(0).put(0).put(0).put(0).put(0).put(0).put(0).put(0); 
     tBuffer.put(0).put(0).put(0).put(0).put(0).put(0).put(0).put(0); 

     glGenBuffersARB(ib); 
     vHandle = ib.get(0); 
     tHandle = ib.get(1); 
    } 

    public void render(int sx, int sy, int swidth, int sheight) { 
     updateBuffers(sx, sy, swidth, sheight, 0, 0, 1, 1); 
     texture.render(texID, vBuffer, tBuffer, changed, vHandle, tHandle, Color.WHITE); 
    } 

    public void render(int sx, int sy, int swidth, int sheight, ReadableColor color) { 
     updateBuffers(sx, sy, swidth, sheight, 0, 0, 1, 1); 
     texture.render(texID, vBuffer, tBuffer, changed, vHandle, tHandle, color); 
    } 

    public void render(int sx, int sy, int swidth, int sheight, float tx, float ty, float twidth, float theight) { 
     updateBuffers(sx, sy, swidth, sheight, tx, ty, twidth, theight); 
     texture.render(texID, vBuffer, tBuffer, changed, vHandle, tHandle, Color.WHITE); 
    } 

    public void render(int sx, int sy, int swidth, int sheight, float tx, float ty, float twidth, float theight, ReadableColor color) { 
     updateBuffers(sx, sy, swidth, sheight, tx, ty, twidth, theight); 
     texture.render(texID, vBuffer, tBuffer, changed, vHandle, tHandle, color); 
    } 

    private void updateBuffers(int sx, int sy, int swidth, int sheight, float tx, float ty, float twidth, float theight) { 
     IntBuffer tempVertexBuffer = BufferUtils.createIntBuffer(8); 
     FloatBuffer tempTextureCoordsBuffer = BufferUtils.createFloatBuffer(8); 

     tempVertexBuffer.clear(); 
     tempTextureCoordsBuffer.clear(); 

     tempVertexBuffer.put(sx).put(sy); 
     tempVertexBuffer.put(sx + swidth).put(sy); 
     tempVertexBuffer.put(sx + swidth).put(sy + sheight); 
     tempVertexBuffer.put(sx).put(sy + sheight); 

     float ttx = tx/(float) texture.width; 
     float tty = ty/(float) texture.height; 
     tempTextureCoordsBuffer.put(ttx).put(tty); 
     tempTextureCoordsBuffer.put(ttx + twidth).put(tty); 
     tempTextureCoordsBuffer.put(ttx + twidth).put(tty + theight); 
     tempTextureCoordsBuffer.put(ttx).put(tty + theight); 

     for (int i = 0; i < 8; i++) { 
      if (vBuffer.get(i) != tempVertexBuffer.get(i)) { 
       vBuffer.clear(); 
       tempVertexBuffer.flip(); 
       vBuffer.put(tempVertexBuffer); 
       vBuffer.flip(); 
       changed = true; 
       break; 
      } else { 
       changed = false; 
      } 
     } 
     for (int i = 0; i < 8; i++) { 
      if (tBuffer.get(i) != tempTextureCoordsBuffer.get(i)) { 
       tBuffer.clear(); 
       tempTextureCoordsBuffer.flip(); 
       tBuffer.put(tempTextureCoordsBuffer); 
       tBuffer.flip(); 
       changed = true; 
       break; 
      } else { 
       changed = false; 
      } 
     } 
    } 
} 

所有紋理通過調用呈現「TextureObject.render(args)」和從「Texture.render(args)」輸出的控制檯都是正確的。

我沒有錯誤,但沒有任何渲染,所以我懷疑te xture本身莫名其妙地變成了一堆零。

也許這條線從TextueObject.java?

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.getBuffer()); 

或與此相關? :)

buffer.flip(); 

一直沒能算出這個數天...

+0

你有沒有紋理的渲染四?或者你可以從字面上看不到任何東西,甚至沒有看到任何東西。 (你可以在glDrawArrays之前調用即時模式着色來測試) –

回答

1

好了,時間大量花在這個玩弄後,我應該知道的問題couldn」 t與緩衝區在一起。

問題原來是從Texture.java這一行:

glColor4b(color.getRedByte(), color.getGreenByte(), color.getBlueByte(), color.getAlphaByte()); 

這顯然顏色設置爲黑色。

然而,這工作時,我嘗試了(感謝「正面全裸」幫助我發現這一點):

glColor4f((float) color.getRed()/255f, (float) color.getGreen()/255f, (float) color.getBlue()/255f, (float) color.getAlpha()/255f); 

它好像一個ReadableColor返回的字節是不是那種字節那lwjgl需要...

但是,它現在有效!

+0

Err,不需要這樣做。實際上最近有一個[類似的問題](http://stackoverflow.com/questions/19577444/difference-between-glcolor3b-and-glcolor3ub)。它使用***簽名的***字節歸結爲'glColor4b(...)'。它有一系列** - 128 ** - ** 127 **。如果嘗試使用無符號顏色,如果將其傳遞給帶符號的顏色函數並且將變爲負值,則一半的顏色空間將溢出。負面顏色在許多上下文中都沒有用,並且當存儲在framebuffer中時,它將簡單地替換爲0;) - 簡而言之,使用'glColor4ub(...)'。 –