2012-03-15 1 views
1

Недавно я портировал свой собственный 2D-рендеринг на Android с помощью Mono для Android. Все прошло хорошо, за исключением того, что я не могу нарисовать текстуру вообще, все текстуры выглядят как пустой.Как правильно загрузить и нарисовать текстуру в OpenGLES с Mono для 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, но на моем реальном устройстве он по-прежнему показывает большой белый квадрат.

Что я здесь делаю неправильно?

+0

У вас есть шейдер? Похоже, вы запрашиваете контекст gles2.0, который, я считаю, не поддерживает какой-либо фиксированный конвейер. – Tim

+0

хорошо, шейдер работает отлично, скомпилирован хорошо, вершинный шейдер правильно преобразовал координаты в пространство экрана, и я могу контролировать выходной цвет через фрагментарный шейдер, только цвет = texture2D (SAMPLER0, TexCoord.st) равен (0,0 , 0,0). для примера кода выше, это то же самое, если я использую контекст GLES1_1 – liiir1985

+0

Я думаю, вам нужно начать поиск ошибок gl с помощью glGetError (или моно эквивалент). То, что у вас там, действительно не похоже на код gles2.0. glEnable (GL_TEXTURE_2D) является незаконным на opengles2.0, а glEnableClientState/glVertexPointer не являются реальными функциями либо в версии 2.0. Вам нужно использовать эквивалент шейдера, который является glEnableVertexAttribArray/glVertexAttribPointer. – Tim

ответ

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;