安卓OpenGL ES和2D

97

这里是我的请求。我不会OpenGL,也不想学它,我想直接学习OpenGL ES,因为我正在开发Android应用。然而,我希望学习OpenGL ES以便开发我的2D游戏。我选择它是为了性能目的(因为基本的SurfaceView绘图对于实时游戏来说效率不高)。

我的问题是:从哪里开始?

我花了一个多月的时间浏览谷歌并阅读/尝试一些我在任何地方找到的教程/示例,但老实说,这并没有帮助太多,原因有两个:

  1. 几乎所有我找到的文章/教程都与3D相关(我只想学习如何进行2D精灵绘制)
  2. 没有起点,因为所有文章都针对特定的事物,比如:“如何绘制三角形(带顶点)”,“如何创建网格”等等。

我也尝试过阅读一些源代码(例如:复制岛),但代码太复杂,包含了很多不必要的东西;结果是:我迷失在100个具有奇怪类名和其他东西的.java文件之间。

我猜没有像我要找的那样的课程,但如果有人能给我一些指导和一些链接(仅限于OpenGL ES 2D Sprites渲染!没有3D),我会非常高兴的。


34
“而且我不愿意学习它” 这不是一个很好的在这里提问的方式。 - Falmarri
64
请阅读我的完整问题,你只提取了其中一个敏感部分,留下了最重要的补充内容:“我不知道OpenGL,也不想学习它,我想直接学习OpenGL ES,因为我是针对Android开发的。”如果我只打算在嵌入式设备上使用OpenGL ES,学习OpenGL有什么意义呢?谢谢。 - CoolStraw
5
鉴于OpenGL ES大多是OpenGL的子集,因此我不明白为什么要说你不打算学习OpenGL,因为根据定义,你必须学习它。 - dash-tom-bang
2
顺便提一句 - Replica Island 是寻找的绝佳场所。你可以从那开始,先对其进行更改。去掉那些不需要的部分,类数就从100变成99、98、97... - dash-tom-bang
5个回答

85

我曾经也遇到过类似的情况。
开始学习OpenGL时,你可以先看一些非常基础的GLSurfaceView样例/演示。

首先,设置你的应用程序活动,并设置基本画布。

查看复制岛源代码文件GameRenderer.java,了解如何使用适当的GL标志设置画布以进行2D(精灵)渲染。你真的应该看看同一作者的SpriteMethodTest:http://code.google.com/p/apps-for-android/source/browse/trunk/SpriteMethodTest

请参见我发布自己代码的这个问题:Using OpenGL to replace Canvas - Android

在设置好画布后,你可以调用以下类似的函数: gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

然后你就可以渲染一个精灵了。 首先,你需要将精灵加载到纹理中:http://qdevarena.blogspot.com/2009/02/how-to-load-texture-in-android-opengl.html

然而,这是真正帮助我的加载精灵的教程: http://tkcodesharing.blogspot.com/2008/05/working-with-textures-in-androids.html

这是我做的,我有一个名为Texture.java的类:

public class Texture
{
    /*Begin public declarations*/
    public float x = 0;
    public float y = 0;
    public float z = 0;
    public float width = 0;
    public float height = 0;
    /*Begin Private Declarations*/
    private GL10 gl;
    public int[] texture;    //holds the texture in integer form
    private int texture_name;
    private int[] mCropWorkspace;
    private final BitmapFactory.Options sBitmapOptions;


/*Begin Methods*/
public Texture( GL10 gl_obj )
{
    gl = gl_obj;
    texture = new int[1];
    mCropWorkspace = new int[4];
    sBitmapOptions = new BitmapFactory.Options();
    sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
    //Log.d(TAG, "Initializing Texture Object");
}    
public int get_texture_name( )
{
    return texture_name;
}

/*Loads the resource to memory*/
public boolean Load( Bitmap bitmap ) //rename this to glLoad and don't have it as an initializer parameter
{
    /*many thanks to sprite method test if this works*/
    if ( gl == null )
    {
        Log.e(TAG, "Failed to load resource.  Context/GL is NULL");
        return false;
    }
    int error;

    int textureName = -1;
    gl.glGenTextures(1, texture, 0);
    textureName = texture[0];

    //Log.d(TAG, "Generated texture: " + textureName);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
    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);

    mCropWorkspace[0] = 0;
    mCropWorkspace[1] = bitmap.getHeight();
    mCropWorkspace[2] = bitmap.getWidth();
    mCropWorkspace[3] = -bitmap.getHeight();

    ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D, 
            GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCropWorkspace, 0);

    error = gl.glGetError();
    if (error != GL10.GL_NO_ERROR)
    { 
        Log.e(TAG, "GL Texture Load Error: " + error);

    }
    //Log.d(TAG, "Loaded texture: " + textureName);
    return true;
 }
}

然后在我的onDrawFrame()方法中,我只需执行以下操作:
Texture texture = ...
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture.texture[0]);
((GL11Ext) gl).glDrawTexfOES((float)(draw_x + 0.5), (float)(draw_y + 0.5), 0, tile_width, tile_height);

这将帮助您在openGL画布上绘制2D精灵。我注意到没有一个简单明了的教程。希望将来我会在我的开发博客上发布一篇: http://developingthedream.blogspot.com/

7
兄弟非常感谢!我从未收到过这样的指引,这正是我正在寻找的!我会关注你的博客,希望你能在将来提供给我们一些很棒的教程 :) 再次感谢你。 - CoolStraw
1
和OP处于同样的情况,像他一样感谢你的回答。祝你的游戏/博客好运。再次感谢。 - unR
1
谢谢@Miguel Morales,我已经厌倦了寻找GL的2D绘图。正如CoolStraw所说,有太多教程包含了许多不必要的东西。这个答案清晰明了,简单易懂。 - Evren Ozturk
@Miguel Morales 经过多次尝试,我无法绘制任何东西,我的纹理显示为黑色。我提出了一个问题http://stackoverflow.com/questions/9624260/gl10-2d-texture-shows-up-fully-black/9624770#9624770 你能看一下吗? - Evren Ozturk

12

8
严格来说,您仍然使用Z,这样您就可以让硬件为您进行排序。重大变化是(很可能)2D应用程序将使用正交视图而不是透视视图。 - dash-tom-bang
非常感谢您的回答,您的陈述向我展示了我对Opengl和Opengl ES定义的错误。 - CoolStraw

3
我会毫不犹豫地查看Chris Pruett在Google IO演讲中的Android内容-为Android编写实时游戏redux。同时,也要下载PDF文件,因为这对很多方面都有帮助。Chris在为移动设备创建游戏方面拥有非常丰富的经验。但是如果你真的只关注2D图形,那么就从Canvas开始http://developer.android.com/guide/topics/graphics/index.html#drawing-with-canvas。另一个选项取决于技能水平,就是将Flash+AdobeAIR转换为Android。我自己喜欢并且深爱着编程,并且随着你进一步开发,你会发现为什么了。OpenGL:请查看Nehe Productions。还有一些你可能想在手机上安装的应用程序,它们是免费的:OpenGL演示,min3d框架,RedBook示例。

1

0

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