所以我的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();
}
} 真的,为什么它会搞砸了?
答案 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
仅用于矩阵堆栈,它可以保存状态,因为矩阵不会影响纹理,材料等。