如何将平面设置为与相机具有相同的旋转?

时间:2015-01-04 12:05:13

标签: java opengl lwjgl

我想要一张树的广告牌,以便始终面对镜头。

enter image description here

目前,我只是使用glRotatef()并将树的偏航旋转到相机的偏航:

glRotatef(camera.yaw(), 0f, 1f, 0f);

然而,遗憾的是,这不起作用。

<Insert GIF here (will add when it uploads)>

当它向左转时,树似乎正在向右转弯。

我已经尝试过反转旋转,但这不起作用。

 glRotatef(-camera.yaw(), 0f, 1f, 0f);
OR
 glRotatef(camera.yaw(), 0f, -1f, 0f);

我总是可以选择做一个交叉的广告牌(就像我在我的草地上做的那样),但是扩大它看起来很可怕。我宁愿只把它作为最后的手段使用。

enter image description here

我也可以使用3D模型作为替代方案,但是我发现它更难,而且它在显卡上也更加密集。

enter image description here

我已经尝试过寻找here来获得答案了,但这不仅令人困惑,而且也适用于闪存,甚至似乎都没有接近告诉如何为其他人做这件事。语言。

如果需要(无论出于何种原因),我的整个渲染代码是:

public void render(){
    Main.TerrainDemo.shader.start();
    glPushMatrix();
    glDisable(GL_LIGHTING);
    glTranslatef(location.x * TerrainDemo.scale, location.y, location.z * TerrainDemo.scale); //Scale is the size of the map: More players online = bigger map.
    TexturedModel texturedModel = TerrainDemo.textModel;
    RawModel model = texturedModel.getRawModel();
    glDisable(GL_CULL_FACE);
    GL30.glBindVertexArray(model.getVaoID());
    GL20.glEnableVertexAttribArray(0);
    GL20.glEnableVertexAttribArray(1);
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, TerrainDemo.textModel.getTexture().getID());
    glScalef(size.x, size.y, size.z);
    glColor4f(0, 0, 0, 0.5f); //0,0,0, because of the shaders.
    glRotatef(Main.TerrainDemo.camera.yaw(), 0f, 1f, 0f);
    glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);

    GL20.glDisableVertexAttribArray(0);
    GL20.glDisableVertexAttribArray(1);
    GL30.glBindVertexArray(0);
    glEnable(GL_LIGHTING);
    glPopMatrix();
    Main.TerrainDemo.shader.stop();
}

camera.yaw()

 /** @return the yaw of the camera in degrees */
public float yaw() {
    return yaw;
}

偏航介于360和-360之间。

 /** Processes mouse input and converts it in to camera movement. */
public void processMouse() {
    float mouseDX = Mouse.getDX() * 0.16f;
    float mouseDY = Mouse.getDY() * 0.16f;

    if (yaw + mouseDX >= 360) {
        yaw = yaw + mouseDX - 360;
    } else if (yaw + mouseDX < 0) {
        yaw = 360 - yaw + mouseDX;
    } else {
        yaw += mouseDX/50;
    }
    //Removed code relevant to pitch, since it is not relevant to this question.
}

更新: 我尝试了很多组合,但是camera.yaw()似乎与树正在做什么无关? 无论我时代或分裂或似乎与它做什么,它似乎总是错误的!

1 个答案:

答案 0 :(得分:4)

你想要的是一个轴对齐的广告牌。首先将中心轴放在局部坐标中,我们称之为 a 。其次你需要轴从视角到一些点沿着轴(树的底部会很好),我们称之为 v 。鉴于这两个矢量,你想形成一个“三脚架”,其中一条腿与中心轴和观察方向共面。

这可以通过使用Gram-Schmidt process将矢量 v a 正交化,产生 v'来完成。三脚架的第三段是 a v'之间的cross product,产生 r = a × v'。轴对齐广告牌的边缘平行于 a r ;但这只是另一种说法,广告牌被旋转到( a r )平面,这正是旋转矩阵所描述的。假设未转换的广告牌几何图形在XY平面中, a 与Y平行,则旋转矩阵将为

[ r a ,(0,0,1)]

或稍微复杂一点的写作方式

| r.x , a.x , 0 |
| r.y , a.y , 0 |
| r.z , a.z , 1 |

要形成完整的4×4同质转换矩阵,请将其扩展为

| r.x , a.x , 0 , t.x |
| r.y , a.y , 0 , t.y |
| r.z , a.z , 1 , t.z |
|  0  ,  0  , 0 ,  1  |

t 是翻译。


请注意,如果关于矩阵和向量操作的任何内容对您来说还没有意义,那么您必须立即停止使用OpenGL执行的任何操作,并首先了解这些必要的基本技能。你需要它们。