2013-08-02 22 views
0

我最近一直在学习LWJGL,因为我已经使用了Java一段时间了,并且我已经了解到,由于没有很多LWJGL教程/参考资料,我只是使用搜索OpenGL教程,因为我知道LWJGL就像一个OpenGL的Java端口(我认为这就是你如何描述的),它们基本上是完全一样的,除了我总是需要调整一下,而且我做了这个代码(基本上全由我自己),当我运行它时,它只显示一个瓷砖地图,但它应该显示16个瓷砖!为什么是这样?OpenGL(LWJGL)TileMap只显示一个图块

package testandothertutorials; 

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

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 

import org.lwjgl.LWJGLException; 
import org.lwjgl.input.Mouse; 
import org.lwjgl.opengl.Display; 
import org.lwjgl.opengl.DisplayMode; 
import org.newdawn.slick.opengl.Texture; 
import org.newdawn.slick.opengl.TextureLoader; 

public class TileMapTest { 

int tilemap[][] = { 
     { 0, 1, 1, 0 }, 
     { 0, 1, 1, 0 }, 
     { 0, 1, 1, 0 }, 
     { 1, 0, 0, 1 } 
}; 
int TILE_SIZE = 32; 
int WORLD_SIZE = 4; 

Texture stone_texture, dirt_texture; 

public TileMapTest() { 
    try { 
     Display.setDisplayMode(new DisplayMode(640, 480)); 
     Display.setTitle("Game"); 
     Display.create(); 
    } catch(LWJGLException e) { 

    } 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(0, 640, 480, 0, 1, -1); 
    glMatrixMode(GL_MODELVIEW); 
    glEnable(GL_TEXTURE_2D); 

    //Load the stone and dirt textures before the render loop 
    try { 
     stone_texture = TextureLoader.getTexture("PNG", new FileInputStream(new File("C://Users//Gannon//Desktop//Java//workspace//Test Game//res//stone.png"))); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    try { 
     dirt_texture = TextureLoader.getTexture("PNG", new FileInputStream(new File("C://Users//Gannon//Desktop//Java//workspace//Test Game//res//dirt.png"))); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    while(!Display.isCloseRequested()) { 

     glClear(GL_COLOR_BUFFER_BIT); 

     drawTiles(); 

     Display.update(); 
     Display.sync(60); 
    } 

    Display.destroy(); 
} 

public void drawTiles() { 
    for(int x = 0; x < WORLD_SIZE; x++) { 
     for(int y = 0; y < WORLD_SIZE; y++) { 
      if(tilemap[x][y] == 0) { //If the selected tile in the tilemap equals 0, set it to the stone texture to draw 
       stone_texture.bind(); 
      } else if(tilemap[x][y] == 1) { //If the selected tile equals 1, set it to the dirt texture to draw 
       dirt_texture.bind(); 
      } 

      glPushMatrix(); 
      glTranslatef(x, y, 0); 
      glBegin(GL_QUADS); 
       glTexCoord2f(0, 0); 
       glVertex2f(0, 0); 
       glTexCoord2f(1, 0); 
       glVertex2f(32, 0); 
       glTexCoord2f(1, 1); 
       glVertex2f(32, 32); 
       glTexCoord2f(0, 1); 
       glVertex2f(0, 32); 
      glEnd(); 
      glPopMatrix(); 
     } 
    } 
} 

public static void main(String args[]) { 
    new TileMapTest(); 
} 

}

回答

0

使用glpushmatrix()和glpopmatrix()尝试,目前你的GL_QUADS是reletive最后一个绘制等定位得到相距甚远高于x和y做:

glPushMatrix(); 
glTranslatef(x, y, 0); 
glBegin(GL_QUADS); 
    glTexCoord2f(0, 0); 
    glVertex2f(0, 0); 
    glTexCoord2f(1, 0); 
    glVertex2f(32, 0); 
    glTexCoord2f(1, 1); 
    glVertex2f(32, 32); 
    glTexCoord2f(0, 1); 
    glVertex2f(0, 32); 
glEnd(); 
glPopMatrix(); 

这将允许每个四边形回到世界空间坐标而不是最后绘制的四边形 - 我曾经有同样的问题。
另外,加载标识只能在每个新框架的开始时完成,并尝试在循环外部加载两个纹理并在内部进行选择,每个tile的加载对硬盘驱动器是一种真正的浪费,要使用RAM。

+0

我实现了你的建议,但它仍然无效。更新了上面的代码。 – n1ghtk1n9

+0

您是否曾尝试在'while(!Display.isCloseRequested())'循环中添加glloadidentity()作为第一个命令? (像我说的每个循环的开始? –

0

你的问题发生,因为你没有翻译足够的瓷砖,所以你最终渲染所有的瓷砖在彼此之上!

当前你在做glTranslatef(x, y, 0);并记住你的瓷砖有32像素的宽度和高度,但是你翻译的范围只有0到4(因为你只渲染16个瓷砖),你需要改变你的翻译。

这是你应该如何翻译。

glTranslatef(x * TILE_SIZE, y * TILE_SIZE, 0); 

所以在渲染部分,它看起来像这样。

glPushMatrix(); 
glTranslatef(x * TILE_SIZE, y * TILE_SIZE, 0); 
glBegin(GL_QUADS); 
    glTexCoord2f(0, 0); 
    glVertex2f(0, 0); 
    glTexCoord2f(1, 0); 
    glVertex2f(32, 0); 
    glTexCoord2f(1, 1); 
    glVertex2f(32, 32); 
    glTexCoord2f(0, 1); 
    glVertex2f(0, 32); 
glEnd(); 
glPopMatrix();