推动和弹出矩阵

时间:2013-03-24 18:57:37

标签: java opengl lwjgl

所以我的opengl游戏中有一些不同的对象。如果我为一个顶点加载一个纹理或颜色,那么游戏中的所有其他对象都会被赋予纹理或它们的顶点是彩色的。所以,例如。我有一堆立方体,我将纹理'a'应用到。然后我有一个天空盒,我应用纹理'b'。如果我然后将它们全部渲染出去,它们都会因某​​种原因而具有纹理“b”。我在渲染多维数据集时调用glPushMatrix()glPopMatrix(),那为什么它们具有天空盒的纹理?这是一些代码:

public void render() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glLoadIdentity();

    glRotatef(input.xrot, 1.0f, 0, 0);
    glRotatef(input.yrot, 0, 1.0f, 0);

    glTranslatef(-input.xpos, -input.ypos - 19, -input.zpos - 5);

    box.render();
    chunk.render();
    BitMapFont.drawString("X: " + (int)-input.xpos + " Y: " + (int)-input.ypos + " Z: " + (int)-input.zpos, 10, 0);
}

我的chunk类中的render方法:

public void render() {
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboV);
    glVertexPointer(vertSize, GL_FLOAT, 0, 0L);

    GL15.glBindBuffer(GL15.GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, vboT);
    glTexCoordPointer(3, GL_FLOAT, 0, 0L);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    glPushMatrix();
    glDrawArrays(GL_QUADS, 0, vertSize * vertAmount * faceAmount * currentBlockCount);
    glPopMatrix();

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

然后是我的天空盒类:

public class SkyBox {

Texture tex;

int x, z, y, offSet;

public void bindTex() {
    tex.bind();
}

public SkyBox(int x, int z, int y) {
    this.x = x;
    this.z = z;
    this.y = y;
    this.offSet = 128;
    try {
        tex = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/Blocks/air.png")));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void render() {

    glBegin(GL_QUADS);

    glTexCoord2f(0, 0);
    glVertex3f(x, z, y);
    glTexCoord2f(1, 0);
    glVertex3f(x + offSet, z, y);
    glTexCoord2f(1, 1);
    glVertex3f(x + offSet, z, y + offSet);
    glTexCoord2f(0, 1);
    glVertex3f(x, z, y + offSet);

    glTexCoord2f(1, 0);
    glVertex3f(x, z, y + offSet);
    glTexCoord2f(1, 0);
    glVertex3f(x + offSet, z, y + offSet);
    glTexCoord2f(1, 1);
    glVertex3f(x + offSet, z + offSet, y + offSet);
    glTexCoord2f(0, 1);
    glVertex3f(x, z + offSet, y + offSet);

    glTexCoord2f(0, 0);
    glVertex3f(x + offSet, z, y);
    glTexCoord2f(0, 1);
    glVertex3f(x + offSet, z + offSet, y);
    glTexCoord2f(1, 1);
    glVertex3f(x + offSet, z + offSet, y + offSet);
    glTexCoord2f(0, 1);
    glVertex3f(x + offSet, z, y + offSet);

    glTexCoord2f(0, 0);
    glVertex3f(x, z + offSet, y);
    glTexCoord2f(1, 0);
    glVertex3f(x, z, y);
    glTexCoord2f(1, 1);
    glVertex3f(x, z, y + offSet);
    glTexCoord2f(0, 1);
    glVertex3f(x, z + offSet, y + offSet);

    glTexCoord2f(0, 0);
    glVertex3f(x, z + offSet, y + offSet);
    glTexCoord2f(1, 0);
    glVertex3f(x + offSet, z + offSet, y + offSet);
    glTexCoord2f(1, 1);
    glVertex3f(x + offSet, z + offSet, y);
    glTexCoord2f(0, 1);
    glVertex3f(x, z + offSet, y);

    glTexCoord2f(0, 0);
    glVertex3f(x, z + offSet, y);
    glTexCoord2f(1, 0);
    glVertex3f(x + offSet, z + offSet, y);
    glTexCoord2f(1, 1);
    glVertex3f(x + offSet, z, y);
    glTexCoord2f(0, 1);
    glVertex3f(x, z, y);

    glEnd();
}

} 真的,为什么它会搞砸了?

2 个答案:

答案 0 :(得分:2)

推送和弹出活动矩阵只会 - 它存储或检索矩阵。它不会影响任何其他状态,例如纹理状态或其他属性。

在旧的OpenGL API中有推送和弹出一些呈现状态的功能(请参阅glPushAttrib()),但这已从更新版本中删除。

所以你真的会被建议做自己的状态管理,因为这是当前编程模型(以及几乎任何其他渲染API)所期望的。您还会被建议停止使用您在此处依赖的其他已弃用的函数,例如一般的固定函数渲染管道。

答案 1 :(得分:0)

OpenGL是一个状态机,这意味着正确的用法如下:

render() {
    setTexture(textId_1)
    glPushMatrix();
        // set transformations related to this object
        drawObject_1()
    glPopMatrix();

    setTexture(textId_2)
    glPushMatrix();
        // set transformations related to this object
        drawObject_2()
    glPopMatrix();
}

如果你设置一个纹理(当你加载它时),那么所有对象都将是使用它的纹理。 对于矩阵,材料等也是如此。当然,当我们谈论固定管道(OpenGL 1.5)时。在现代OpenGL(3. +)中,我们有更多选择。

glPushMatrix/glPopMatrix仅用于矩阵堆栈,它可以保存状态,因为矩阵不会影响纹理,材料等。