0

我最近一直在学习 LWJGL,因为我使用 Java 已经有一段时间了,我了解到,由于 LWJGL 教程/参考资料并不多,我只是使用搜索 OpenGL 教程,因为我知道 LWJGL 是就像 OpenGL 的 Java 端口(我想你会这样描述)它们基本上是一样的,除了我总是需要稍微调整一下,而且我编写了这段代码(基本上都是我自己),当我运行时它,它只显示一个瓦片地图,但它应该总共显示 16 个瓦片!为什么是这样?

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();
}

}

4

2 回答 2

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();
于 2013-08-08T12:57:03.560 回答
0

尝试使用 glpushmatrix() 和 glpopmatrix(),目前您的 GL_QUADS 与最后绘制的一个相关,因此定位距离越高 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();

这将允许每个四边形回到世界空间坐标而不是最后绘制的四边形 - 我曾经遇到过同样的问题。
此外,加载标识应该只在每个新帧开始时完成,并尝试在循环之外加载两个纹理并在内部选择,为每个图块加载是对硬盘驱动器的真正浪费,请使用 RAM。

于 2013-08-02T05:53:18.090 回答