我正在学习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非常简单。
如果你想要更多代码告诉我。抱歉我的英语:(。
答案 0 :(得分:0)
您可以做的是使用不同的渲染技术,渲染器类中的许多方法都使用所谓的立即模式渲染。尝试学习如何使用顶点缓冲对象(VBO)或显示列表。它们更快,并且会大幅增加游戏的平均FPS。 :)