如何使用Mono for Android在OpenGLES中正确加载和绘制纹理

时间:2012-03-15 19:30:29

标签: android opengl-es xamarin.android

我最近使用Mono for Android将我自己的2D渲染引擎移植到Android 一切顺利,但我根本无法绘制纹理,所有纹理看起来都是空的。

所以我开始了一个新的干净项目来测试它,我根据java的示例代码编写了它,我发现我也无法绘制纹理。 这是我用于测试的代码:

class GLView1 : AndroidGameView
{
    public GLView1(Context context)
        : base(context)
    {
        this.GLContextVersion = OpenTK.Graphics.GLContextVersion.Gles1_1;
    }

    // This gets called when the drawing surface is ready
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        // Run the render loop
        Run();
    }

    bool initialized = false;
    int[] textureID = new int[1];
    // This gets called on each frame render
    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);
        if (!initialized)
        {
            initialized = true;
            GL.Enable(All.Texture2D);
            GL.GenTextures(1, textureID);
            GL.ShadeModel(All.Smooth);
            GL.BindTexture(All.Texture2D, textureID[0]);

            Bitmap bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.Icon);
            Android.Opengl.GLUtils.TexImage2D(Android.Opengl.GLES10.GlTexture2d, 0, Android.Opengl.GLES10.GlRgba, bitmap, 0);
            bitmap.Recycle();

            GL.TexParameter(All.Texture2D, All.TextureMinFilter, (int)All.Nearest);
            GL.TexParameter(All.Texture2D, All.TextureMagFilter, (int)All.Linear);
        }
        GL.ClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        GL.Clear((uint)All.ColorBufferBit);

        GL.BindTexture(All.Texture2D, textureID[0]);

        GL.EnableClientState(All.VertexArray);
        GL.EnableClientState(All.TextureCoordArray);
        GL.FrontFace(All.Cw);

        GL.VertexPointer(2, All.Float, 0, square_vertices);
        GL.TexCoordPointer(2, All.Float, 0, uv);

        GL.DrawArrays(All.TriangleStrip, 0, 4);

        SwapBuffers();
    }

    float[] uv ={
                    0,1,
                    0,0,
                    1,1,
                    1,0,
               };

    float[] square_vertices = {
        -0.5f, -0.5f,
        0.5f, -0.5f,
        -0.5f, 0.5f, 
        0.5f, 0.5f,
    };

    byte[] square_colors = {
        255, 255,   0, 255,
        0,   255, 255, 255,
        0,     0,    0,  0,
        255,   0,  255, 255,
    };
}

我在Android设备上看到的只是一个大的白色方块。

PS:我用Android模拟器再次测试它,看起来这个代码在Android模拟器中工作,但在我的真实设备上它仍然显示一个大的白色方块。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

BitmapFactory.decodeResource()可能存在问题。我遇到了同样的问题,但是当我使用openRawResource()将资源作为流打开然后使用BitmapFactory.decodeStream()来加载位图时,纹理突然出现。

进一步研究BitmapFactory.decodeResource(),它似乎可以根据目标设备的像素密度进行缩放。请参阅:http://blog.poweredbytoast.com/loading-opengl-textures-in-android

这将导致所有整齐的2个大小的纹理尺寸变得有趣,以至于硬件加速无法识别(模拟器不关心非2次幂的大小)。因此,请使用上面链接中的代码,为方便起见,将其复制到此处:

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inScaled = false;