Java LWJGL游戏

时间:2014-05-23 19:55:31

标签: java lwjgl

我正在学习LWJGL,我正在写一个简单的游戏。但如果我渲染Level 200x200,我有10-15 fps。我添加了一个renderLimiter,有了它,我有40-60 fps的Vsync。我怎样才能加快渲染速度?这是一个代码(不是100%):

Game.class:

package main;

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

import java.applet.Applet;
import java.awt.Canvas;

import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.vector.Vector3f;

import Graphics.Render;
import Levels.level1;
import player.Player;

public class Game {

    DisplayMode dispMode = new DisplayMode(gameX, gameY);

    public static int gameX = 800;
    public static int gameY = 600;

    public static final float RenderDistance = 20.0f;
    public static final boolean Vsync = true;
    public static final boolean isApplet = false;

    private static Player player;

    int frames = 0;

    private level1 lvl1;

    public Game(){
        init();

    }
    public void init(){
        if(!isApplet) {
        try {
            initApplication();
            Render.init();
        } catch (LWJGLException e) {
            e.printStackTrace();
        }
        }

        player = new Player(45.0f, (float)dispMode.getWidth() / (float)dispMode.getHeight(), 0.5f, 300.0f);

        lvl1 = new level1();

        System.out.println("OpenGL version : "+ GL11.glGetString(GL11.GL_VERSION));

        gameLoop();
    }
    public void start(){

    }
    public void stop(){

    }
    public void destroy(){

    }
    public void initApplication() throws LWJGLException{
        Display.setDisplayMode(dispMode);

        Display.setVSyncEnabled(Vsync);
        Display.setFullscreen(true);
        Display.create();

        initGl();
    }   
    public void initGl(){
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();

        GLU.gluPerspective(45.0f, (float)dispMode.getWidth() / (float)dispMode.getHeight(), 2f, RenderDistance*2-10);

        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        GL11.glEnable(GL11.GL_DEPTH_TEST);

        GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);

        GL11.glShadeModel(GL11.GL_SMOOTH); 
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        GL11.glDisable(GL11.GL_BLEND);
    }
    public void cleanUp(){
        Display.destroy();
    }
    public void gameLoop(){

        double unprocessedSeconds = 0;
        long previousTime = System.nanoTime();
        double secondsPerTick = 1 / 60.0;
        int tickCount = 0;
        boolean ticked = false;

        while(!Display.isCloseRequested()){
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glLoadIdentity();

            long currentTime = System.nanoTime();
            long passedTime = currentTime - previousTime;

            previousTime = currentTime;
            unprocessedSeconds += passedTime / 1000000000.0;

            while(unprocessedSeconds > secondsPerTick){
                tick();
                unprocessedSeconds -= secondsPerTick;
                ticked = true;
                tickCount++;
                if(tickCount % 60 == 0){
                    System.out.println("FPS: "+frames);
                    System.out.println("----------");
                    System.out.println("PlayerX: "+player.getX());
                    System.out.println("PlayerY: "+player.getY());
                    System.out.println("PlayerZ: "+player.getZ());
                    previousTime += 1000;
                    frames = 0;
                }
            }
            if(ticked){
                tick();
                frames++;
            }       
            render();
            Mouse.setGrabbed(true);

            if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
                cleanUp();
            }
            Display.update();
            Display.sync(100);
        }
        cleanUp();
    }
    public void tick(){
        player.tick(lvl1);
    }
    public static boolean inRenderRange(int x, int y, int z){
        if(x - RenderDistance > player.getX()/2 || y - RenderDistance > player.getY()/2 || z - RenderDistance > player.getZ()/2){
            return false;
        }else{
            if(x + RenderDistance < player.getX()/2 || y + RenderDistance < player.getY()/2 || z + RenderDistance < player.getZ()/2){
                return false;
            }else{
                return true;
            }
        }
    }
    public void render(){   
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();

        player.tick(lvl1);

        lvl1.render();
        /*for(int i = 0; i < 20; i++){
            for(int j = 0; j < 20; j++){
                //Render.drawCube(i*2, 1, j*2, 0, Textures.floor);
                new Wall(new Vector3f(i*2, 0, j*2));
            }
        }*/
        Render.drawSphere(1, 1, 1, 3);
        Render.drawCube(player.getX(), player.getY(), player.getZ()-5, 30);

        /*for(int i = 0; i <200; i++){
            for(int j = 0; j < 200; j++){
                Render.drawCube(i, 0, j, new Vector3f(.5f, .3f, 0f));
            }
        }*/
    }
    public static void main(String[] args){
        new Game();
    }
}

Render.class:

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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Random;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.Sphere;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;

public class Render {

    private static FloatBuffer vertices = BufferUtils.createFloatBuffer(3 * 4 * 6);

    public Render(){
    }
    public static void init(){
        vertices.put(new float[] {
                -1.0f, -1.0f, 1.0f,
                1.0f, -1.0f, 1.0f,
                1.0f, 1.0f, 1.0f,
                -1.0f, 1.0f, 1.0f,

                -1.0f, -1.0f, -1.0f,
                -1.0f, 1.0f, -1.0f,
                1.0f, 1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,

                -1.0f, 1.0f, -1.0f,
                -1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, -1.0f,

                -1.0f, -1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,
                1.0f, -1.0f, 1.0f,
                -1.0f, -1.0f, 1.0f,

                1.0f, -1.0f, -1.0f,
                1.0f, 1.0f, -1.0f,
                1.0f, 1.0f, 1.0f,
                1.0f, -1.0f, 1.0f,

                -1.0f, -1.0f, -1.0f,
                -1.0f, -1.0f, 1.0f,
                -1.0f, 1.0f, 1.0f,
                -1.0f, 1.0f, -1.0f}); 
    }
    public static void drawTile(float x, float y, float z, float angle, float r, float g, float b){
        glPushMatrix();{
            glTranslatef(x, y, z);
            glRotatef(angle, 8, 1, 0);
            glBegin(GL_QUADS);{
                glColor3f(r, g, b);
                glVertex3f(-1,1,-1);
                glVertex3f(1,1,-1);
                glVertex3f(1,1,1);
                glVertex3f(-1,1,1);
            }glEnd();
        }glPopMatrix();
    }
    public static void drawTile(float x, float y, float z, float angle, Texture texture){
        texture.bind();

        glPushMatrix();{
            glTranslatef(x, y, z);
            glRotatef(angle, 8, 1, 0);
            glBegin(GL_QUADS);{
                glTexCoord2f(0,0); glVertex3f(-1,1,-1);
                glTexCoord2f(0,1); glVertex3f(1,1,-1);
                glTexCoord2f(1,1); glVertex3f(1,1,1);
                glTexCoord2f(1,0); glVertex3f(-1,1,1);
                texture.release();
            }glEnd();
        }glPopMatrix();
    }
    public static void drawTile(float x, float y, float z, float angle){
        glPushMatrix();{
            glTranslatef(x, y, z);
            glRotatef(angle, 8, 1, 0);
            glBegin(GL_QUADS);{
                glVertex3f(-1,1,-1);
                glVertex3f(1,1,-1);
                glVertex3f(1,1,1);
                glVertex3f(-1,1,1);
            }glEnd();
        }glPopMatrix();
    }
    public static void drawLine(float x, float y, float z, float xx, float yy, float zz){
        glPushMatrix();{
            glBegin(GL_LINE);{
                glVertex3f(x,y,z);
                glVertex3f(xx,yy,zz);
            }glEnd();
        }glPopMatrix();
    }
    public static void drawCube(float x, float y, float z, float angle, Texture texture){
        texture.bind();

        glPushMatrix();{
        glTranslatef(x,y,z);
        glRotatef(angle,8,1,0);
        glBegin(GL_QUADS);{

        //FrontFace
        glTexCoord2f(0,0); glVertex3f(-1,-1,1);
        glTexCoord2f(0,1); glVertex3f(1,-1,1);
        glTexCoord2f(1,1); glVertex3f(1,1,1);
        glTexCoord2f(1,0); glVertex3f(-1,1,1);

        //BackFace
        glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
        glTexCoord2f(0,1); glVertex3f(-1,1,-1);
        glTexCoord2f(1,1); glVertex3f(1,1,-1);
        glTexCoord2f(1,0); glVertex3f(1,-1,-1);

        //BottomFace
        glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
        glTexCoord2f(0,1); glVertex3f(-1,-1,1);
        glTexCoord2f(1,1); glVertex3f(-1,1,1);
        glTexCoord2f(1,0); glVertex3f(-1,1,-1);

        //TopFace
        glTexCoord2f(0,0); glVertex3f(1,-1,-1);
        glTexCoord2f(0,1); glVertex3f(1,-1,1);
        glTexCoord2f(1,1); glVertex3f(1,1,1);
        glTexCoord2f(1,0); glVertex3f(1,1,-1);

        //LeftFace
        glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
        glTexCoord2f(0,1); glVertex3f(1,-1,-1);
        glTexCoord2f(1,1); glVertex3f(1,-1,1);
        glTexCoord2f(1,0); glVertex3f(-1,-1,1);

        //Right Face
        glTexCoord2f(0,0); glVertex3f(-1,1,-1);
        glTexCoord2f(0,1); glVertex3f(1,1,-1);
        glTexCoord2f(1,1); glVertex3f(1,1,1);
        glTexCoord2f(1,0); glVertex3f(-1,1,1);


        texture.release();
        }glEnd();
        }glPopMatrix();
    }

    public static void drawCube(float x, float y, float z, Vector3f color){
         glTranslatef(x, y, z);

         glColor3f(color.x, color.y, color.z);

         glEnableClientState(GL11.GL_VERTEX_ARRAY);
         vertices.rewind();
         glVertexPointer(3, 0, vertices);

         glPushMatrix();{
             glDrawArrays(GL11.GL_QUADS, 0, 24);
         }glPopMatrix();

         glDisableClientState(GL11.GL_VERTEX_ARRAY);
         glColor3f(1,1,1);
    }
    public static void drawTriangle(float x, float y, float z){
        FloatBuffer cBuffer = BufferUtils.createFloatBuffer(9);
        cBuffer.put(1).put(0).put(0);
        cBuffer.put(0).put(1).put(0);
        cBuffer.put(0).put(0).put(1);
        cBuffer.flip();

      FloatBuffer vBuffer = BufferUtils.createFloatBuffer(9);
      vBuffer.put(-0.5f).put(-0.5f).put(0.0f);
      vBuffer.put(+0.5f).put(-0.5f).put(0.0f);
      vBuffer.put(+0.5f).put(+0.5f).put(0.0f);
      vBuffer.flip();

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);

      glColorPointer(3, /* stride */3 << 2, cBuffer);
      glVertexPointer(3, /* stride */3 << 2, vBuffer);
      glPushMatrix();
      glTranslatef(x, y, z);
      glDrawArrays(GL_TRIANGLES, 0, /* elements */3);
      glPopMatrix();
      glDisableClientState(GL_COLOR_ARRAY);
      glDisableClientState(GL_VERTEX_ARRAY); 
    }
    public static void drawCube(float x, float y, float z, float size,float angle, Texture texture){
        texture.bind();

        float scale = size / 8f;

        glPushMatrix();{
        glTranslatef(x,y,z);
        glRotatef(angle,8,1,0);
        glScalef(scale, scale, scale);
        glBegin(GL_QUADS);{
        //FrontFace
        glTexCoord2f(0,0); glVertex3f(-1,-1,1);
        glTexCoord2f(0,1); glVertex3f(1,-1,1);
        glTexCoord2f(1,1); glVertex3f(1,1,1);
        glTexCoord2f(1,0); glVertex3f(-1,1,1);

        //BackFace
        glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
        glTexCoord2f(0,1); glVertex3f(-1,1,-1);
        glTexCoord2f(1,1); glVertex3f(1,1,-1);
        glTexCoord2f(1,0); glVertex3f(1,-1,-1);

        //BottomFace
        glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
        glTexCoord2f(0,1); glVertex3f(-1,-1,1);
        glTexCoord2f(1,1); glVertex3f(-1,1,1);
        glTexCoord2f(1,0); glVertex3f(-1,1,-1);

        //TopFace
        glTexCoord2f(0,0); glVertex3f(1,-1,-1);
        glTexCoord2f(0,1); glVertex3f(1,-1,1);
        glTexCoord2f(1,1); glVertex3f(1,1,1);
        glTexCoord2f(1,0); glVertex3f(1,1,-1);

        //LeftFace
        glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
        glTexCoord2f(0,1); glVertex3f(1,-1,-1);
        glTexCoord2f(1,1); glVertex3f(1,-1,1);
        glTexCoord2f(1,0); glVertex3f(-1,-1,1);

        //Right Face
        glTexCoord2f(0,0); glVertex3f(-1,1,-1);
        glTexCoord2f(0,1); glVertex3f(1,1,-1);
        glTexCoord2f(1,1); glVertex3f(1,1,1);
        glTexCoord2f(1,0); glVertex3f(-1,1,1);


        texture.release();
        }glEnd();
        }glPopMatrix();
    }
    public static void drawCube(float x, float y, float z, float angle){

        glPushMatrix();{

            glTranslatef(x, y, z);
            glRotatef(angle,8,1,0);

            glBegin(GL_QUADS);{

                glColor3f(1f,0f,0f);
                glVertex3f(-1,-1,1);
                glVertex3f(-1,1,1);
                glVertex3f(1,1,1);
                glVertex3f(1,-1,1);

                glColor3f(0f,1f,0f);
                glVertex3f(-1,-1,-1);
                glVertex3f(-1,1,-1);
                glVertex3f(1,1,-1);
                glVertex3f(1,-1,-1);

                glColor3f(0f,0f,1f);
                glVertex3f(-1,-1,-1);
                glVertex3f(-1,-1,1);
                glVertex3f(-1,1,1);
                glVertex3f(-1,1,-1);

                glColor3f(0.5f,1f,0f);
                glVertex3f(1,-1,-1);
                glVertex3f(1,-1,1);
                glVertex3f(1,1,1);
                glVertex3f(1,1,-1);

                glColor3f(0f,0.5f,1f);
                glVertex3f(-1,-1,-1);
                glVertex3f(1,-1,-1);
                glVertex3f(1,-1,1);
                glVertex3f(-1,-1,1);

                glColor3f(1f,0.5f,1f);
                glVertex3f(-1,1,-1);
                glVertex3f(1,1,-1);
                glVertex3f(1,1,1);
                glVertex3f(-1,1,1);

                glColor3f(1f, 1f, 1f);
            }
            glEnd();
        }glPopMatrix();
    }
    public static void drawSphere(float x, float y, float z, float size){
        glPushMatrix();{
            glTranslatef(x, y, z);
            Sphere s = new Sphere();
            s.draw(size, 16, 16);
        }glPopMatrix();
    }

Object.class:

    import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;

public abstract class Object {
    public Vector3f cords;

    Texture texture;

    String name;

    public Object(float x, float y, float z){
        cords = new Vector3f(x, y, z);
        setUp();
        render();
    }
    public Object(Vector3f cords){
        this.cords = cords;
        render();
    }
    public Object(float x, float y, float z, Texture texture){
        this.texture = texture;
        render();
    }
    public Object(Vector3f cords, Texture texture){
        this.cords = cords;
        this.texture = texture;
        render();
    }
    public Vector3f getCoordinates(){
        return cords;
    }
    public Texture getTexture(){
        if(texture != null){
            return texture;
        }else{
            return null;
        }
    }
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    public void setTexture(Texture texture){
        this.texture = texture;
    }
    public void setCoords(Vector3f cords){
        this.cords = cords;
    }
    public float getX(){
        return cords.x;
    }
    public float getY(){
        return cords.y;
    }
    public float getZ(){
        return cords.z;
    }
    public abstract void render();
    public abstract void setUp();

}

Floor.class:

    import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;

import Graphics.Render;
import Graphics.Textures;
import main.Object;

public class Floor extends Object{

    public Floor(Vector3f cords) {
        super(cords);
        setTexture(Textures.floor);
        setName("FLOOR");
    }
    public void render(){
        //Render.drawTile(cords.x, cords.y - 0.01f, cords.z, 0, Textures.floor);
        Render.drawCube(cords.x, cords.y, cords.z, 0, Textures.floor);
    }
    public void setUp() {
    }
}   

Wall.class非常简单。

如果你想要更多代码告诉我。抱歉我的英语:(。

1 个答案:

答案 0 :(得分:0)

您可以做的是使用不同的渲染技术,渲染器类中的许多方法都使用所谓的立即模式渲染。尝试学习如何使用顶点缓冲对象(VBO)或显示列表。它们更快,并且会大幅增加游戏的平均FPS。 :)