【问题标题】:Android OpenGL - glTranslatef is retained after glPopMatrixAndroid OpenGL - glTranslatef 在 glPopMatrix 之后保留
【发布时间】:2012-04-01 10:50:37
【问题描述】:

对于我的游戏中的精灵,我通过循环遍历每个精灵、调用 glPushMatrix、转换到位置、绘制四边形并调用 glPopMatrix 来绘制它们。

我希望这没问题,但我得到了一些奇怪的行为,屏幕上的其他一些对象(似乎)随机翻译了一些量。我认为精灵位置的变换以某种方式影响了其他绘图,但是在调用 glPopMatrix 后怎么会发生这种情况?

我正在绘制精灵和点,出于某种原因,当我只绘制点时,没有任何东西得到这种随机翻译。当我开始绘制精灵时,它会发生,任何人都可以帮助找出导致它的原因吗?

这是我的精灵绘制例程:

gl.glPushMatrix();

//set the drawing position
gl.glTranslatef((float)positionDelta.getX(), (float)positionDelta.getY(), z);
gl.glRotatef((float) (180*angle/Math.PI), 0, 0, 1);

//draw 
getSprite().draw(gl);

//reset the drawing position
gl.glPopMatrix();

以及四边形的绘图功能:

public void draw(GL10 gl) {
  gl.glEnable(GL10.GL_TEXTURE_2D);

  //Bind our only previously generated texture in this case
  gl.glBindTexture(GL10.GL_TEXTURE_2D, texture.getGLID());

  //Point to our buffers
  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

  //Set the face rotation
  gl.glFrontFace(GL10.GL_CCW);

  //Enable the vertex and texture state
  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

  //Set The Color To Blue
  gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);   

  //Draw the vertices as triangles, based on the Index Buffer information
  gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);      


  //Disable the client state before leaving
  gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
  gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

这里是一些似乎总是被翻译的东西的图纸,一个简单的点:

gl.glDisable(GL10.GL_TEXTURE_2D);

//Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

//Set the face rotation
gl.glFrontFace(GL10.GL_CCW);

//Enable the vertex and texture state
//gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

gl.glPushMatrix();

//set the drawing position
gl.glTranslatef((float)positionDelta.getX(), (float)positionDelta.getY(), z);

gl.glPointSize(size);

gl.glColor4f(red, green, blue, alpha);

//Draw the vertices as triangles, based on the Index Buffer information
gl.glDrawElements(GL10.GL_POINTS, indexBuffer.capacity(), GL10.GL_UNSIGNED_BYTE, indexBuffer);

//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

//reset the drawing position
gl.glPopMatrix();

(对于下面的 cmets)OnSurfaceChange:

     @Override
  public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    //GLU.gluPerspective(gl, 60.0f, (float)width / (float)height, 0.1f, 100.0f);
    GLU.gluOrtho2D(gl, -width, width , -height, height);

    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();

    //font loading stuff
    texFont = new TexFont(context, gl);
    try {
      getTexFont().LoadFont("Fonts/Palatino Linotype.bff", gl);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

以下是 OpenGL 调用的一部分:

04-01 13:46:08.535: VERBOSE/GLSurfaceView(20649): glPushMatrix();
04-01 13:46:08.535: VERBOSE/GLSurfaceView(20649): glTranslatef(15.63553, 119.22188, 0.0);
04-01 13:46:08.540: VERBOSE/GLSurfaceView(20649): glRotatef(61.17992, 0.0, 0.0, 1.0);
04-01 13:46:08.540: VERBOSE/GLSurfaceView(20649): glEnable(GL_TEXTURE_2D);
04-01 13:46:08.540: VERBOSE/GLSurfaceView(20649): glBindTexture(GL_TEXTURE_2D, 1);
04-01 13:46:08.540: VERBOSE/GLSurfaceView(20649): glEnableClientState(GL_VERTEX_ARRAY);
04-01 13:46:08.540: VERBOSE/GLSurfaceView(20649): glEnableClientState(GL_TEXTURE_COORD_ARRAY);
04-01 13:46:08.545: VERBOSE/GLSurfaceView(20649): glFrontFace(2305);
04-01 13:46:08.545: VERBOSE/GLSurfaceView(20649): glVertexPointer(3, GL_FLOAT, 0, java.nio.FloatToByteBufferAdapter, status: capacity=12 position=0 limit=12);
04-01 13:46:08.545: VERBOSE/GLSurfaceView(20649): glTexCoordPointer(2, GL_FLOAT, 0, java.nio.FloatToByteBufferAdapter, status: capacity=8 position=0 limit=8);
04-01 13:46:08.565: VERBOSE/GLSurfaceView(20649): glColor4f(0.5, 0.5, 1.0, 1.0);
04-01 13:46:08.580: VERBOSE/GLSurfaceView(20649): glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE
04-01 13:46:08.580: VERBOSE/GLSurfaceView(20649):  [0 : 0] = v:{-40.0, -40.0, 0.0} t:{0.0, 0.0}
04-01 13:46:08.580: VERBOSE/GLSurfaceView(20649):  [1 : 1] = v:{40.0, -40.0, 0.0} t:{0.0, 1.0}
04-01 13:46:08.580: VERBOSE/GLSurfaceView(20649):  [2 : 3] = v:{40.0, 40.0, 0.0} t:{1.0, 1.0}
04-01 13:46:08.580: VERBOSE/GLSurfaceView(20649):  [3 : 0] = v:{-40.0, -40.0, 0.0} t:{0.0, 0.0}
04-01 13:46:08.580: VERBOSE/GLSurfaceView(20649):  [4 : 3] = v:{40.0, 40.0, 0.0} t:{1.0, 1.0}
04-01 13:46:08.580: VERBOSE/GLSurfaceView(20649):  [5 : 2] = v:{-40.0, 40.0, 0.0} t:{1.0, 0.0}
04-01 13:46:08.580: VERBOSE/GLSurfaceView(20649): );
04-01 13:46:08.590: VERBOSE/GLSurfaceView(20649): glDisableClientState(GL_VERTEX_ARRAY);
04-01 13:46:08.590: VERBOSE/GLSurfaceView(20649): glDisableClientState(GL_TEXTURE_COORD_ARRAY);
04-01 13:46:08.590: VERBOSE/GLSurfaceView(20649): glPopMatrix();
04-01 13:46:08.590: VERBOSE/GLSurfaceView(20649): glDisable(GL_TEXTURE_2D);
04-01 13:46:08.590: VERBOSE/GLSurfaceView(20649): glEnableClientState(GL_VERTEX_ARRAY);
04-01 13:46:08.590: VERBOSE/GLSurfaceView(20649): glFrontFace(2305);
04-01 13:46:08.590: VERBOSE/GLSurfaceView(20649): glPushMatrix();
04-01 13:46:08.595: VERBOSE/GLSurfaceView(20649): glTranslatef(-14.2896805, 191.06998, 0.0);
04-01 13:46:08.595: VERBOSE/GLSurfaceView(20649): glPointSize(5.0);
04-01 13:46:08.595: VERBOSE/GLSurfaceView(20649): glColor4f(1.0, 0.0, 0.0, 0.5);
04-01 13:46:08.600: VERBOSE/GLSurfaceView(20649): glDrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE
04-01 13:46:08.600: VERBOSE/GLSurfaceView(20649):  [0 : 0] = v:{-40.0, -40.0, 0.0}
04-01 13:46:08.600: VERBOSE/GLSurfaceView(20649): );
04-01 13:46:08.600: VERBOSE/GLSurfaceView(20649): glDisableClientState(GL_VERTEX_ARRAY);
04-01 13:46:08.600: VERBOSE/GLSurfaceView(20649): glPopMatrix();

它绘制了一些点,然后是一个精灵,然后又是一些点。一切看起来都很好,除了我注意到点的顶点是-40、-40。我不认为这恰好与四边形的第一个顶点相同是巧合!这似乎是问题所在,而不是矩阵。

编辑找到了!

gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

缺少点,这意味着他们使用了最后一个绘制对象的第一个顶点,如果它是一个精灵,那就是-40,-40!谢谢!

【问题讨论】:

  • 在任何地方都没有呼叫glMatrixMode - 你确定这是正确的吗?
  • 在 onSurfaceChanged 期间我调用 gl.glMatrixMode(GL10.GL_PROJECTION) gl.glLoadIdentity() 然后 gl.glMatrixMode(GL10.GL_MODELVIEW) gl.glLoadIdentity()
  • 不能把代码放在这里,添加 onSurfaceChange 到问题的结尾。是不是放错地方了?
  • 看起来没问题,只要这是完成切换的唯一位置。由于您使用的是 GL10,请通过 [setDebugFlags][1] 设置 DEBUG_LOG_GL_CALLS。这包装了 GL10 实例并使调用出现在 LogCat 中(脚注:我希望包括 push/pop 调用,这不适用于 GLES20)。在日志流中添加一些日志调用自己作为标记。 [1]:developer.android.com/reference/android/opengl/…
  • 抱歉,我无法更正最后一个链接;不知何故,MarkDown 不喜欢在链接的末尾加上右括号

标签: android opengl-es rendering translate


【解决方案1】:

看起来没问题,只要这是完成切换的唯一位置。由于您使用的是 GL10,请通过 setDebugFlags 设置 DEBUG_LOG_GL_CALLS。这包装了 GL10 实例并使调用出现在 LogCat 中(脚注:我希望包括 push/pop 调用,这不适用于 GLES20)。在日志流中添加一些日志调用作为标记。

【讨论】:

    猜你喜欢
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多