【问题标题】:Render image for 2D game use in OpenGL ES for android在 OpenGL ES for android 中用于 2D 游戏的渲染图像
【发布时间】:2011-03-23 18:59:30
【问题描述】:

编辑:解决了!我犯了一个愚蠢的错误,我有一个我忘记了应该使用的 textureID 的 textureId。

好的,我完全知道这是一个反复出现的问题,并且有很多教程和开源代码。但是我在这里已经尽了最大努力,但我的屏幕仍然是空白的(使用 glClearColor() 设置的任何颜色)。

所以,我将不胜感激一些指针,指出我做错了什么,或者更好的是,一些可以呈现资源图像的工作代码。

我将在实现 Renderer 的类的 onDrawFrame 中展示我目前的成果(通过一些巧妙的复制粘贴)。我已经删除了一些方法之间的跳转,并且将按照执行顺序简单地粘贴它。

请随意忽略我当前的代码,如果有人可以给我一段工作代码,我很乐意重新开始。

设置:

    bitmap = BitmapFactory.decodeResource(panel.getResources(), 
            R.drawable.test); 
    addGameComponent(new MeleeAttackComponent());

    // Mapping coordinates for the vertices
    float textureCoordinates[] = { 0.0f, 2.0f, //
            2.0f, 2.0f, //
            0.0f, 0.0f, //
            2.0f, 0.0f, //
    };

    short[] indices = new short[] { 0, 1, 2, 1, 3, 2 };

    float[] vertices = new float[] { -0.5f, -0.5f, 0.0f,
                                      0.5f, -0.5f, 0.0f,
                                     -0.5f,  0.5f, 0.0f,
                                      0.5f, 0.5f, 0.0f };

    setIndices(indices);
    setVertices(vertices);
    setTextureCoordinates(textureCoordinates);

protected void setVertices(float[] vertices) {
    // a float is 4 bytes, therefore we multiply the number if
    // vertices with 4.
    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    mVerticesBuffer = vbb.asFloatBuffer();
    mVerticesBuffer.put(vertices);
    mVerticesBuffer.position(0);
}


protected void setIndices(short[] indices) {
    // short is 2 bytes, therefore we multiply the number if
    // vertices with 2.
    ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
    ibb.order(ByteOrder.nativeOrder());
    mIndicesBuffer = ibb.asShortBuffer();
    mIndicesBuffer.put(indices);
    mIndicesBuffer.position(0);
    mNumOfIndices = indices.length;
}


protected void setTextureCoordinates(float[] textureCoords) { 

    // float is 4 bytes, therefore we multiply the number of
    // vertices with 4.
    ByteBuffer byteBuf = ByteBuffer
            .allocateDirect(textureCoords.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    mTextureBuffer = byteBuf.asFloatBuffer();
    mTextureBuffer.put(textureCoords);
    mTextureBuffer.position(0);
}

//onDrawFrame(GL10 gl)

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    gl.glLoadIdentity();
    gl.glTranslatef(0, 0, -4);

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    // Specifies the location and data format of an array of vertex
    // coordinates to use when rendering.
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVerticesBuffer);

    if(shoudlLoadTexture){
        loadGLTextures(gl);
        shoudlLoadTexture = false;
    }

    if (mTextureId != -1 && mTextureBuffer != null) {
        gl.glEnable(GL10.GL_TEXTURE_2D);
        // Enable the texture state
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // Point to our buffers
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);
    }

    gl.glTranslatef(posX, posY, 0);
    // Point out the where the color buffer is.
    gl.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
            GL10.GL_UNSIGNED_SHORT, mIndicesBuffer);
    // Disable the vertices buffer.
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

    if (mTextureId != -1 && mTextureBuffer != null) {
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }


 private void loadGLTextures(GL10 gl) {

    int[] textures = new int[1];
    gl.glGenTextures(1, textures, 0);
    mTextureID = textures[0];

    gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
    gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);

    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

}

它不会崩溃,没有例外,只是一个有颜色的空白屏幕。我已经在那里打印了一些东西,所以我很确定它已经全部执行了。

我知道只粘贴代码并不是最佳选择,但目前,我只想能够做我能够用画布做的事情:)

非常感谢

【问题讨论】:

  • 直接问题:您是否在未显示的地方初始化模型视图和项目堆栈?
  • 可能是这样,因为我不确定你会怎么做,我想我展示了大部分代码。它确实运行并给了我背景颜色,所以我做对了。你能详细说明你的意思吗? (对不起,我缺乏理解,这是一个可怕的未知领域:S)
  • 我需要发布一个答案以获得足够的空间,即使它不一定是答案。

标签: java android opengl-es


【解决方案1】:

如果您获得了背景颜色,则表示您的窗口设置正确。 OpenGL 连接到屏幕的那个区域。

但是,OpenGL 剪辑到近端和远端剪辑平面,确保对象不会与相机交叉或相交(这在数学和逻辑上都没有意义)并且不会出现太远的对象.所以如果你没有正确设置模型视图和投影,很可能你的所有几何图形都被剪裁了。

Modelview 用于从世界映射到眼睛空间。从眼睛空间到屏幕空间的投影图。所以一个典型的应用是使用前者来定位场景中的物体,并相对于相机定位场景,然后后者处理相机是否透视,多少世界单位组成多少屏幕单位等。

如果您查看示例like this one,尤其是onSurfaceChanged,您会看到一个透视投影示例,其中相机固定在原点。

因为相机位于 (0, 0, 0),所以将几何图形留在 z = 0 上,就像您的代码一样,会导致它被剪裁。在该示例代码中,他们将近裁剪平面设置为 z = 0.1,因此在您现有的代码中您可以更改:

gl.glTranslatef(posX, posY, 0);

收件人:

gl.glTranslatef(posX, posY, -1.0);

将几何图形向后推到足够远以显示在屏幕上。

【讨论】:

  • 谢谢,但它没有改变任何东西:S 你可以看到在顶部,我设置了 glTranslatef(0,0,-4),据我了解教程,应该已经成功了
  • 您的代码仍然没有显示您设置模型视图和投影的位置。我真的认为这就是你绊倒的地方,如果没有看到这些东西,很难提供更具体的建议。
猜你喜欢
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多