1

So I have a few different objects in my opengl game. If I load a texture or color a vertex, all my other objects in the game are given that texture or their vertices are colored. So, for example. I have a bunch of cubes that I apply texture 'a' to. I then have a skybox that I apply texture 'b' to. If I then render both out, they both have texture 'b' for some reason. I call glPushMatrix() and glPopMatrix() when rendering the cubes, so why do they have the texture of the skybox? Here's some code:

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

My render method in my chunk class:

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

And then my skybox class:

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

} So really, why is it getting all screwed up?

2 Answers2

2

Pushing and popping the active matrix does only that - it stores or retrieves a matrix. It does not affect any other state, such as texture state or other attributes.

There was functionality to push and pop some rendering state in the old OpenGL API (see glPushAttrib()), but this has been removed from the more recent versions.

So you really would be advised do state management yourself, as that is what is expected in the current programming model (and with pretty much any other rendering API). You would also be advised to stop using the other deprecated functions you are relying on here, such as the fixed-function rendering pipeline in general.

JasonD
  • 16,464
  • 2
  • 29
  • 44
  • So is glPushAttrib the answeer to my question? –  Mar 25 '13 at 09:04
  • @opiop65 No, it isn't. It is an out-dated mechanism, which is not available in the newer OpenGL API. You should manage state yourself. – JasonD Mar 25 '13 at 09:20
0

OpenGL is a state machine, that means proper usage looks like that:

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

if you set a texture (when you load it) then all objects will be textures using it. The same goes for matrices, materials, etc. Of course when we are talking about Fixed Pipeline (OpenGL 1.5). In modern OpenGL (3.+) we have some more options.

glPushMatrix/glPopMatrix is used only for matrix stack it can save state for matrices bot does not influence textures, materials, etc.

fen
  • 9,835
  • 5
  • 34
  • 57
  • I understand that, but how do I solve it? Calling glPush and pop matrix does not work. I dont understand! –  Mar 25 '13 at 02:58
  • updated my answer, push/pop matrix does not influence textures, just set texture1 (use glBindTexture) before drawing first object, then set texture2 before drawing next object. – fen Mar 25 '13 at 10:37