【问题标题】:OpenGL function refusing to render triangleOpenGL函数拒绝渲染三角形
【发布时间】:2012-07-02 13:59:45
【问题描述】:

这可能与我的转变有关,但现在我无法弄清楚这一点,这让我发疯。我已经包装了绘制代码,以便我可以轻松定义新的三角形。但是,当我把它放到一个函数中时,它只是显示一个灰屏。功能代码如下:

 public void Draw(float[] mViewMatrix, float[] mModelMatrix, float[] mProjectionMatrix, int mPositionHandle,  int mColorHandle, int mMVPMatrixHandle)
{

    long time = SystemClock.uptimeMillis() % 10000L;
    float angleInDegrees = (360.0f / 10000.0f) * ((int) time);      

    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);     

    aBuffer = ByteBuffer.allocateDirect(verts.length * mBytesPerFloat)
    .order(ByteOrder.nativeOrder()).asFloatBuffer();



    //aBuffer.position(mPositionOffset);
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
            mStrideBytes, aBuffer);        

    GLES20.glEnableVertexAttribArray(mPositionHandle);        

    // Pass in the color information
    aBuffer.position(mColorOffset);
    GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false,
            mStrideBytes, aBuffer);        

    GLES20.glEnableVertexAttribArray(mColorHandle);

    // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
    // (which currently contains model * view).
    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

    // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
    // (which now contains model * view * projection).
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); 
}

正在运行的代码是:

        public void onDrawFrame(GL10 glUnused) 
{
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);                    



    // Do a complete rotation every 10 seconds.
    long time = SystemClock.uptimeMillis() % 10000L;
    float angleInDegrees = (360.0f / 10000.0f) * ((int) time);

    // Draw the triangle facing straight on.
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);        
    drawTriangle(mTriangle1Vertices);

    // Draw one translated a bit down and rotated to be flat on the ground.
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 0.0f, -1.0f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, 90.0f, 1.0f, 0.0f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);        
    drawTriangle(mTriangle2Vertices);

    // Draw one translated a bit to the right and rotated to be facing to the left.
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 1.0f, 0.0f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, 90.0f, 0.0f, 1.0f, 0.0f);
    Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
    drawTriangle(mTriangle3Vertices);
    */

    /*
    for (int x = 0; x < staticHolder.objectList.size(); x++)
    {
        staticHolder.objectList.get(x).Draw(mViewMatrix, mModelMatrix, mProjectionMatrix, mPositionHandle, mColorHandle, mMVPMatrixHandle);
    }
    */
}   

/**
 * Draws a triangle from the given vertex data.
 * 
 * @param aTriangleBuffer The buffer containing the vertex data.
 */
private void drawTriangle(final FloatBuffer aTriangleBuffer)
{       
    // Pass in the position information
    aTriangleBuffer.position(mPositionOffset);
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
            mStrideBytes, aTriangleBuffer);        

    GLES20.glEnableVertexAttribArray(mPositionHandle);        

    // Pass in the color information
    aTriangleBuffer.position(mColorOffset);
    GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false,
            mStrideBytes, aTriangleBuffer);        

    GLES20.glEnableVertexAttribArray(mColorHandle);

    // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
    // (which currently contains model * view).
    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

    // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
    // (which now contains model * view * projection).
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);                               
}

我传入相同的变量,这里使用的最终变量初始化相同。封装函数中还有一些其他工作。知道为什么它拒绝在函数中渲染吗?

以下代码加载列表中的对象:

  final float[] triangle1VerticesData = {
            // X, Y, Z, 
            // R, G, B, A
            -0.5f, -0.25f, 0.0f, 
            1.0f, 0.0f, 0.0f, 1.0f,

            0.5f, -0.25f, 0.0f,
            0.0f, 0.0f, 1.0f, 1.0f,

            0.0f, 0.559016994f, 0.0f, 
            0.0f, 1.0f, 0.0f, 1.0f};

    final float[] triangle2VerticesData = {
            // X, Y, Z, 
            // R, G, B, A
            -0.5f, -0.25f, 0.0f, 
            1.0f, 1.0f, 0.0f, 1.0f,

            0.5f, -0.25f, 0.0f, 
            0.0f, 1.0f, 1.0f, 1.0f,

            0.0f, 0.559016994f, 0.0f, 
            1.0f, 0.0f, 1.0f, 1.0f};

    // This triangle is white, gray, and black.
    final float[] triangle3VerticesData = {
            // X, Y, Z, 
            // R, G, B, A
            -0.5f, -0.25f, 0.0f, 
            1.0f, 1.0f, 1.0f, 1.0f,

            0.5f, -0.25f, 0.0f, 
            0.5f, 0.5f, 0.5f, 1.0f,

            0.0f, 0.559016994f, 0.0f, 
            0.0f, 0.0f, 0.0f, 1.0f};

    staticHolder.objectList.add(new Triangle(triangle1VerticesData));
    staticHolder.objectList.add(new Triangle(triangle2VerticesData));
    staticHolder.objectList.add(new Triangle(triangle3VerticesData));

接收类是:

    public class Triangle extends shape 
    {

     public Triangle(float[] data)
     {
          verts = data;
     }

     }

【问题讨论】:

  • 你为什么把aBuffer.position(mPositionOffset);注释掉了?这是必要的代码行。
  • 我必须把它注释掉,因为我正忙着让它工作
  • 如果取消注释后它仍然不起作用,那么麻烦制造者代码位于其他地方(可能在表面或 GL 对象的初始化中)。
  • 为什么第一种方法行得通而不是第二种?
  • 问题可能出在传递给staticHolder.objectList 的缓冲区中。我相信您已经注意到,绘制代码本身是工作代码的完美克隆(aBuffer 的名称除外)。您是否验证过 Draw 是否被调用?

标签: java android opengl-es


【解决方案1】:

在以下代码之后:

aBuffer = ByteBuffer.allocateDirect(verts.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();

您必须将顶点放入缓冲区(否则,它是空白的!):

aBuffer.put(verts);

这不是在代码中起作用的原因是因为这三组顶点的缓冲区是预先分配的,然后顶点被放入其中(在初始化时)。它们每次都只是简单地传递给方法,因此不必再次输入put()

关于这一点,您需要避免在 Draw 方法中进行分配,因为它每帧调用多次,可能会导致渲染缓慢。分配一次aBuffer,每次都放入新的顶点。

【讨论】:

  • 太棒了!非常感谢!我对任何 GL 都非常陌生(在大学里有一门关于 C++ 的 openGL 课程,它教的绝对没有任何可挽救的东西)。我一直在寻找解决方案几个小时!我欠你一个!
  • 没问题!我也一直在学习 GL……2.0 太痛苦了,不是吗?祝你旅途愉快! :)
  • 嗯,出于某种原因,大学/高中对教我任何数学知识几乎没有兴趣,所以几何编程就像一片茂密的森林。你有什么资源可以让我快速学习吗?我发现大多数 openGL 教程都是由“哦,你应该已经知道了,笨蛋!”所写的。善良的人,让他们的教程完全没用
  • 我不知道我会在那个部门提供多少帮助;我很快就掌握了几何学(没有线性代数……幸运的是,这主要用于 3D)。我想说你最好的资源要么是书籍(在图书馆、亚马逊或 Google Play 中查看),要么是非 Android OpenGL 2.0 教程。 This 与数学无关,但很有帮助,至少对我来说是这样。
猜你喜欢
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 2020-04-05
  • 2017-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多