LWJGL和Slick2D:疯狂滞后! (0.7 FPS)

时间:2013-12-10 19:04:13

标签: java lwjgl lag frame-rate slick2d

本周末,我正在制作基本的LWJGL游戏,为Ludum Dare做准备。

我几乎没有任何代码,但只要我在网格中实现纹理,我就会变得非常糟糕的FPS!

这是我的一些代码:

屏幕类(用于渲染游戏)(向下滚动到 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;
}
}

阻止类

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 个答案:

答案 0 :(得分:2)

从那些顶点坐标开始,我猜你正在制作一个基于平铺的游戏,而Grass是一种Block。 这些是我能看到的会减慢渲染速度的主要内容:

  1. 在内存中创建多个纹理(每个块一个)
  2. 经常更改纹理(每个块)
  3. 缓存网格没有缓冲策略(本例中为世界)
  4. 我强烈建议将所有块纹理拼接成一个精灵表,然后使用glTexCoord2f在较大的纹理中定义特定纹理的位置。这将允许您在渲染世界时几乎从不更改纹理。但是目前你正在为每个块加载所述纹理;我建议你做一些纹理管理器(也许它也可以管理子纹理),这将允许你只需加载纹理一次然后在每个块中可以定义渲染器的子纹理位置。 总而言之,这将大大减少使用的内存,这总是很好,并且会大大提高帧速率。

    根据所得到的网格在顶点中绘制每个帧的大小(在本例中为WIDTH X HEIGHT X 4),将需要更长时间才能传递给OpenGL,如果此网格永远不会在那里更改没有必要在每一帧重新创建它,为此有很多方法可以将它缓冲到图形内存中,例如显示列表(我个人认为最容易实现)或顶点缓冲对象更快但是需要更深入的知识。

答案 1 :(得分:-1)

尝试/抓住声明&amp;&amp;虽然循环负载太多