2013-12-10 35 views
1

我正在製作一個基本的LWJGL遊戲,爲這個週末的Ludum Dare做準備。LWJGL和Slick2D:瘋狂滯後! (0.7 FPS)

我幾乎沒有任何代碼,但只要我在我的網格中實現了紋理,我一直在變得糟糕的FPS!

下面是我的一些代碼:

Screen類(用於渲染遊戲)(向下滾動到drawGrid()法)

package game; 

import game.blocks.Block; 
import game.entities.EntityLiving; 
import game.entities.Human; 
import game.world.Grid; 

import org.lwjgl.LWJGLException; 
import org.lwjgl.opengl.Display; 
import org.lwjgl.opengl.DisplayMode; 
import org.lwjgl.opengl.GL11; 
import org.newdawn.slick.opengl.Texture; 

public class Screen { 

//Screen Constructor 
public Screen() { 
    try { 
     Display.setDisplayMode(new DisplayMode(Game.WIDTH*2,Game.HEIGHT*2)); 
     Display.create(); 
     init(); 
     while(!Display.isCloseRequested()) { 
      render(); 
     } 
     Display.destroy(); 
    } catch (LWJGLException e) { 
     e.printStackTrace(); 
     System.exit(0); 
    } 
} 

//OpenGl Initialization 
public void init() { 
    GL11.glMatrixMode(GL11.GL_PROJECTION); 
    GL11.glLoadIdentity(); 
    GL11.glOrtho(0, Game.WIDTH, Game.HEIGHT, 0, 1, -1); 
    GL11.glMatrixMode(GL11.GL_MODELVIEW); 
    GL11.glEnable(GL11.GL_TEXTURE_2D); 
} 

public void render() { 
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); 
    Display.sync(60); 
    Grid grid = new Grid(); 
    drawGrid(grid); 
    drawEntity(new Human(64,64)); 
    Display.update(); 
    System.out.println("render"); 
} 

public void drawEntity(EntityLiving e) { 
    Texture tex = e.getTexture(); 
    tex.bind(); 
    GL11.glColor4f(1, 1, 1, 1); 
    GL11.glBegin(GL11.GL_QUADS); 
    GL11.glTexCoord2f(0,0); 
    GL11.glVertex2f(e.getX(),e.getY()); 
    GL11.glTexCoord2f(1,0); 
    GL11.glVertex2f(e.getX()+e.getWidth(),e.getY()); 
    GL11.glTexCoord2f(1,1); 
    GL11.glVertex2f(e.getX()+e.getWidth(),e.getY()+e.getHeight()); 
    GL11.glTexCoord2f(0,1); 
    GL11.glVertex2f(e.getX(),e.getY()+e.getHeight()); 
    GL11.glEnd(); 
} 

public void drawGrid(Grid grid) { 
    Block[][] level = grid.getGrid(); 
    for(int i = 0; i < Grid.WIDTH; i++) { 
     for(int j = 0; j < Grid.HEIGHT; j++) { 
      Texture tex = level[i][j].getTexture(); 
      tex.bind(); 
      GL11.glBegin(GL11.GL_QUADS); 
      GL11.glTexCoord2f(0,0); 
      GL11.glVertex2f(i*16,j*16); 
      GL11.glTexCoord2f(1,0); 
      GL11.glVertex2f(i*16+16,j*16); 
      GL11.glTexCoord2f(1,1); 
      GL11.glVertex2f(i*16+16,j*16+16); 
      GL11.glTexCoord2f(0,1); 
      GL11.glVertex2f(i*16,j*16+16); 
      GL11.glEnd(); 
     } 
    } 
} 

} 

網格類

package game.world; 

import game.Game; 
import game.blocks.Block; 
import game.blocks.Grass; 

public class Grid { 

public static final int HEIGHT=Game.HEIGHT/16; 
public static final int WIDTH=Game.WIDTH/16; 
public Block[][] grid; 

public Grid() { 
    grid = new Block[WIDTH][HEIGHT]; 
    for(int i = 0; i < WIDTH; i++) { 
     for(int j = 0; j < HEIGHT; j++) { 
      grid[i][j] = new Grass(); 
     } 
    } 
} 

public Block[][] getGrid() { 
    return grid; 
} 
} 

Block類

package game.blocks; 

import java.io.IOException; 

import org.lwjgl.opengl.GL11; 
import org.newdawn.slick.opengl.Texture; 
import org.newdawn.slick.opengl.TextureLoader; 
import org.newdawn.slick.util.ResourceLoader; 

public class Block { 
public Texture tex; 
public Block(String texname) { 
    try { 
     tex = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/images/blocks/" + texname + ".png"), GL11.GL_NEAREST); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     System.exit(0); 
    } 
} 
public Texture getTexture() { 
    return tex; 
} 
} 

讓我知道我是否應該再包括代碼。謝謝。

回答

2

從這些頂點座標開始我猜你正在製作基於拼圖的遊戲,而Grass是一種塊。 這些是主要的事情,我可以看到,會減慢渲染:

  1. 在內存中創建許多紋理(每塊)
  2. 過於頻繁地更改紋理(每塊)
  3. 沒有緩衝的策略緩存網(全球在這種情況下)

我強烈建議你拼接所有的塊紋理連成一個精靈表,然後使用glTexCoord2f中較大的一個定義特定的紋理的位置。這將使您在渲染世界時幾乎不會改變紋理。但是,目前您正在爲每個塊加載所述紋理;我建議你做一些紋理管理器(也許它可以管理子紋理),這將允許你只需加載紋理一次,然後在每個塊中定義渲染器的子紋理位置。總而言之,這將大大降低已用內存​​總是不錯的,並且會大大改善幀速率。

根據您生成的網格的大小,您在頂點繪製每個幀(在這種情況下應該是WIDTH X HEIGHT X 4),傳遞給OpenGL需要更長的時間,而且如果此網格永遠不會變化,在重新創建它的每一幀時,有很多方法可以將它緩衝到圖形內存中,例如顯示列表(我個人認爲是最容易實現的)或頂點緩衝區對象,它們甚至更快,但需要更深入的知識。

+0

1&2:我還沒有意識到這些未免太麻煩了!我想這是有道理的,因爲我調用每個render()的紋理......這是很多紋理。我一定會使用spritesheet。我想我起初太害怕了,但我想現在或永遠都不會。 3:我已經閱讀了有關緩衝策略,並忘記實施一個。你知道是否有鏈接到你描述的紋理管理器? 總而言之,非常棒的迴應!非常感謝您的幫助。 – joeyiny

+0

我不認爲在線任何地方都有紋理管理器,就像你現在或永遠所說的那樣。如果這是您正在尋找的內容,您會介意加註和/或接受嗎?這就是答案系統在這裏工作的方式。 –

+0

對不起,我嘗試upvoting,但我不能,因爲我沒有足夠的聲譽。 – joeyiny

-1

try/catch語句& & while循環太多負荷