使用OpenGL替代Canvas - Android

8

我试图用更快的OpenGL-ES表面取代已有的基于Canvas的渲染系统,但是似乎无法让OpenGL渲染器以2D场景的方式呈现,而不是透视视图。

我的当前渲染器代码如下:

     @Override
     public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrthof(0.0f, width, 0.0f, height, 0.0f, 1.0f);

        gl.glShadeModel(GL10.GL_FLAT);
        gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
        gl.glEnable(GL10.GL_TEXTURE_2D);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

        gl.glClearColor(0.5f, 0.5f, 0.5f, 1);
        gl.glShadeModel(GL10.GL_FLAT);
        gl.glDisable(GL10.GL_DEPTH_TEST);
        gl.glEnable(GL10.GL_TEXTURE_2D);

        gl.glDisable(GL10.GL_DITHER);
        gl.glDisable(GL10.GL_LIGHTING);

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    
    }

我该如何设置渲染器,使得翻译转换与屏幕上的像素匹配?(例如将其向右移动5个像素)


为什么不直接将GL实例传递给Canvas构造函数呢?http://developer.android.com/reference/android/graphics/Canvas.html - James Black
这样做是否能在绘制位图时保留openGL的速度优势,而不是基本的Canvas? - Kleptine
不要使用Canvas。尽管有文档记录,但它并不起作用。此外,根据IRC中的讨论,Canvas的开发者已经将其从未来版本的API中删除了。 - Moncader
他们真的要弃用它吗?那肯定会使我的应用程序退出竞选。 :/ - Kleptine
1个回答

9
请注意,在openGL中,Y坐标是倒置的。其他都一样。
至于正确的标志,我建议您查看开源Android游戏复制岛:http://code.google.com/p/replicaisland/
以下是我在自己的代码中使用的内容:
public void onSurfaceChanged(GL10 gl, int width, int height) 
{
    mViewWidth = width;
    mViewHeight = height;

    gl.glViewport(0, 0, mViewWidth,  mViewHeight);
    gl.glLoadIdentity();
    GLU.gluOrtho2D(gl, 0, mViewWidth, mViewHeight, 0);
}

public void onSurfaceCreated(GL10 gl, EGLConfig config) 
{
    gl.glClearColor(0.5f, 0.5f, 0.5f, 1);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
    gl.glShadeModel(GL10.GL_FLAT);
    gl.glDisable(GL10.GL_DEPTH_TEST);
    gl.glEnable(GL10.GL_BLEND);
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA); 

    gl.glViewport(0, 0, mViewWidth,  mViewHeight);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glEnable(GL10.GL_BLEND);
    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
    gl.glShadeModel(GL10.GL_FLAT);
    gl.glEnable(GL10.GL_TEXTURE_2D);

    GLU.gluOrtho2D(gl, 0, mViewWidth, mViewHeight, 0);
}

其中mViewWidthmViewHeight是显示器的尺寸。


我有代码,但是由于优化和基于瓦片的系统的缘故,它非常臃肿,以至于很难找到我需要渲染几个纹理到屏幕上的简单代码。 - Kleptine
我曾经遇到过类似的问题,并没有问题找到了复制岛作者设置gl画布的部分。它在名为GameRenderer.java的文件中。我已编辑原始响应以包含我使用的设置代码。 - Miguel Morales
好的,谢谢。虽然我的整体代码结构还没有完全过渡成功。有没有办法存储非2的幂大小的纹理?如果没有,使用openGL也不值得麻烦(我已经推动了Android的内存限制)。 - Kleptine
对于非2进制的部分我不是很确定。虽然我没有使用过,但我相信它在OpenGL ES 2.0中得到了支持,只有Android 2.0支持。或许还有其他的技巧可以让它们起作用,也许你可以发布一个新的问题。祝好运。 - Miguel Morales

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接