2013-08-02 52 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();