OpenGL相机位置与渲染图像不匹配

3
我正在尝试使用LWJGL创建一个小的基于体素的项目。该项目的一部分是在玩家移动时加载围绕其周围的小块景观。这个加载部分工作得还好,但是我遇到了一个问题,当我沿着 +X 轴行走时,同样距离沿 -X 轴行走的景观块会被加载。Z 轴也会发生同样的情况。
好奇心驱使我尝试颠倒块的 X 和 Z 轴渲染方向,看起来解决了这个问题。然而,我还决定将轴渲染为线,并验证是否正确绘制了所有内容。我生成了下面的图片:
(似乎无法嵌入图像,所以链接:http://i.imgur.com/y5hO1Im.png
在这张图片中,红色、蓝色和绿色线条沿着负轴绘制,而紫色、黄色和青色线条沿着正轴绘制。真正奇怪的是,图像显示摄像机处于 +X 和 +Z 范围内,但在内部,摄像机的位置矢量却处于 -X 和 -Z 范围内。如果相机在 +X 上渲染,但实际上其内部位置在 -X 处,那么将加载 -X 块。
所以我不确定到底出了什么问题。我确定有一些小设置或正/负不正确的地方正在错过,但我似乎找不到任何东西。所以我的问题是:相机是否正确地呈现了内部位置?如果是这样,我需要颠倒所有渲染的内容吗?如果不是,是否有明显可见的相机问题导致渲染出错?
以下是相关代码的片段,尽量避免使用代码块使帖子溢出:
Camera.java
public class Camera {

    // Camera position
    private Vector3f position = new Vector3f(x, y, z);

    // Camera view properties
    private float pitch = 1f, yaw = 0.0f, roll = 0.0f;

    // Mouse sensitivity
    private float mouseSensitivity = 0.25f;

    // Used to change the yaw of the camera
    public void yaw(float amount) {
        this.yaw += (amount * this.mouseSensitivity);
    }

    // Used to change the pitch of the camera
    public void pitch(float amount) {
        this.pitch += (amount * this.mouseSensitivity);
    }

    // Used to change the roll of the camera
    public void roll(float amount) {
        this.roll += amount;
    }

    // Moves the camera forward relative to its current rotation (yaw)
    public void walkForward(float distance) {
        position.x -= distance * (float)Math.sin(Math.toRadians(yaw));
        position.z += distance * (float)Math.cos(Math.toRadians(yaw));
    }

    // Moves the camera backward relative to its current rotation (yaw)
    public void walkBackwards(float distance) {
        position.x += distance * (float)Math.sin(Math.toRadians(yaw));
        position.z -= distance * (float)Math.cos(Math.toRadians(yaw));
    }

    // Strafes the camera left relative to its current rotation (yaw)
    public void strafeLeft(float distance) {
        position.x -= distance * (float)Math.sin(Math.toRadians(yaw-90));
        position.z += distance* (float)Math.cos(Math.toRadians(yaw-90));
    }

    // Strafes the camera right relative to its current rotation (yaw)
    public void strafeRight(float distance) {
        position.x -= distance * (float)Math.sin(Math.toRadians(yaw+90));
        position.z += distance * (float)Math.cos(Math.toRadians(yaw+90));
    }

    // Translates and rotates the matrix so that it looks through the camera
    public void lookThrough() {
        GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
        GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
        GL11.glTranslatef(position.x, position.y, position.z);
    }
}

Main.java 渲染代码

private void render() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glLoadIdentity();

        // Set the view matrix to the player's view
        this.player.lookThrough();

        // Render the visible chunks
        this.chunkManager.render();

        // Draw axis
        GL11.glBegin(GL11.GL_LINES);

            // X Axis
            GL11.glColor3f(1, 0, 0);
            GL11.glVertex3f(-100, 0, 0);
            GL11.glVertex3f(0, 0, 0);

            GL11.glColor3f(1, 1, 0);
            GL11.glVertex3f(0, 0, 0);
            GL11.glVertex3f(100, 0, 0);

            // Y Axis
            GL11.glColor3f(0, 1, 0);
            GL11.glVertex3f(0, -100, 0);
            GL11.glVertex3f(0, 0, 0);

            GL11.glColor3f(0, 1, 1);
            GL11.glVertex3f(0, 0, 0);
            GL11.glVertex3f(0, 100, 0);

            // Z Axis
            GL11.glColor3f(0, 0, 1);
            GL11.glVertex3f(0, 0, -100);
            GL11.glVertex3f(0, 0, 0);

            GL11.glColor3f(1, 0, 1);
            GL11.glVertex3f(0, 0, 0);
            GL11.glVertex3f(0, 0, 100);
        GL11.glEnd();

        // Render the origin
        this.origin.render();
    }

chunkManager.render() 只是遍历所有已加载的块并调用它们的 .render() 方法,然后创建一个巨大的实心立方体在块的原点处进行渲染。

如果需要,可以提供更多代码。

1个回答

1
替换

标签。

GL11.glTranslatef(position.x, position.y, position.z);

使用

GL11.glTranslatef(-position.x, -position.y, -position.z);

想一想,你希望将世界翻译成与相机位置相反的位置,使得0,0,0处于相机位置。


是的,没错。回顾OpenGL流水线,translate是用来移动世界的,而不是相机本身,所以它必须是负位置。这是我犯的愚蠢疏忽,谢谢提醒! - user3089564

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接