2012-03-15 36 views
1

我最近使用Mono for Android将我自己的2D渲染引擎移植到Android 除了我根本无法绘制纹理,所有纹理看起来都像空。如何使用Mono for Android在OpenGLES中正确加载和绘制纹理

所以我开始了一个新的干净的项目来测试它,并且我根据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模拟器中工作,但在我的真实设备上它仍然显示一个大的白色方块。

我在这里做错了什么?

+0

你有着色器?看起来你正在请求一个gles2.0上下文,我相信它不支持任何固定的管道。 – Tim 2012-03-15 19:34:27

+0

好吧,着色器工作正常,编译良好,顶点着色器正确地将坐标转换为屏幕空间,并且我可以通过片段着色器控制输出颜色,只是颜色= texture2D(SAMPLER0,TexCoord.st)相等(0,0 ,0,0)。对于上面的示例代码,如果我使用GLES1_1上下文是相同的 – liiir1985 2012-03-15 19:37:57

+0

我认为你需要用glGetError(或单声道等价物)开始寻找gl错误。你有什么真的不像gles2.0代码。 glEnable(GL_TEXTURE_2D)在opengles2.0上是非法的,glEnableClientState/glVertexPointer在2.0中不是真正的函数。您需要使用等效的着色器,即glEnableVertexAttribArray/glVertexAttribPointer。 – Tim 2012-03-15 19:42:11

回答

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;