2009-01-24 53 views
0

我被困在无法将纹理映射到openGLES中的正方形中。我试图在屏幕上显示一个jpg图像,为了让我做到这一点,我画了一个正方形,然后将图像映射到上面。然而,我得到的所有输出都是白色方块。我不知道我做错了什么。而这个问题阻止了我继续我的项目。我为Windows Mobile使用Managed OpenGL ES wrapper。 我证实纹理加载正确,但我无法将其应用于我的对象。我上传了示例项目,显示我的问题here。你需要VS2008和Windows Mobile 6 SDK才能运行它。我还发布了在这里呈现和贴图对象的表单的代码。任何建议都将非常感激,因为我一直在这个问题上停留了一段时间,我无法弄清楚我做错了什么。在OpenGL中将纹理应用到正方形时出现的问题

public partial class Form1 : Form 
{ 
    [DllImport("coredll")] 
    extern static IntPtr GetDC(IntPtr hwnd); 

    EGLDisplay myDisplay; 
    EGLSurface mySurface; 
    EGLContext myContext; 

    public Form1() 
    { 
     InitializeComponent(); 
     myDisplay = egl.GetDisplay(new EGLNativeDisplayType(this)); 

     int major, minor; 
     egl.Initialize(myDisplay, out major, out minor); 

     EGLConfig[] configs = new EGLConfig[10]; 
     int[] attribList = new int[] 
     { 
      egl.EGL_RED_SIZE, 5, 
      egl.EGL_GREEN_SIZE, 6, 
      egl.EGL_BLUE_SIZE, 5, 
      egl.EGL_DEPTH_SIZE, 16 , 
      egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT, 
      egl.EGL_STENCIL_SIZE, egl.EGL_DONT_CARE, 
      egl.EGL_NONE, egl.EGL_NONE 
     }; 

     int numConfig; 
     if (!egl.ChooseConfig(myDisplay, attribList, configs, configs.Length, out numConfig) || numConfig < 1) 
      throw new InvalidOperationException("Unable to choose config."); 

     EGLConfig config = configs[0]; 
     mySurface = egl.CreateWindowSurface(myDisplay, config, Handle, null); 
     myContext = egl.CreateContext(myDisplay, config, EGLContext.None, null); 

     egl.MakeCurrent(myDisplay, mySurface, mySurface, myContext); 
     gl.ClearColor(0, 0, 0, 0); 
     InitGL(); 
    } 

    void InitGL() 
    { 
     gl.ShadeModel(gl.GL_SMOOTH); 
     gl.ClearColor(0.0f, 0.0f, 0.0f, 0.5f); 
     gl.BlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA); 
     gl.Hint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST); 
    } 

    public unsafe void DrawGLScene() 
    { 
     gl.MatrixMode(gl.GL_PROJECTION); 
     gl.LoadIdentity(); 
     gl.Orthof(0, ClientSize.Width, ClientSize.Height, 0, 0, 1); 
     gl.Disable(gl.GL_DEPTH_TEST); 

     gl.MatrixMode(gl.GL_MODELVIEW); 
     gl.LoadIdentity(); 

     Texture myImage; 
     Bitmap Image = new Bitmap(@"\Storage Card\Texture.jpg"); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      Image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); 
      myImage = Texture.LoadStream(ms, false); 
     } 

     float[] rectangle = new float[] { 
       0, 0, 
       myImage.Width, 0, 
       0, myImage.Height, 
       myImage.Width, myImage.Height 
      }; 

     float[] texturePosition = new float[] { 
       0, 0, 
       myImage.Width, 0, 
       0, myImage.Height, 
       myImage.Width, myImage.Height 
      }; 

     //Bind texture 
     gl.BindTexture(gl.GL_TEXTURE_2D, myImage.Name); 
     gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR); 
     gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR); 
     gl.EnableClientState(gl.GL_TEXTURE_COORD_ARRAY); 
     gl.EnableClientState(gl.GL_VERTEX_ARRAY); 

     //draw square and texture it. 
     fixed (float* rectanglePointer = &rectangle[0], positionPointer = &texturePosition[0]) 
     { 
      gl.TexCoordPointer(2, gl.GL_FLOAT, 0, (IntPtr)positionPointer); 
      gl.VertexPointer(2, gl.GL_FLOAT, 0, (IntPtr)rectanglePointer); 
      gl.DrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4); 
     } 

     gl.DisableClientState(gl.GL_TEXTURE_COORD_ARRAY); 
     gl.DisableClientState(gl.GL_VERTEX_ARRAY); 

    } 

    protected override void OnPaintBackground(PaintEventArgs e) 
    { 

    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     gl.Clear(gl.GL_COLOR_BUFFER_BIT); 

     DrawGLScene(); 
     egl.SwapBuffers(myDisplay, mySurface); 
     gl.Clear(gl.GL_COLOR_BUFFER_BIT); 
    } 

    protected override void OnClosing(CancelEventArgs e) 
    { 
     if (!egl.DestroySurface(myDisplay, mySurface)) 
      throw new Exception("Error while destroying surface."); 
     if (!egl.DestroyContext(myDisplay, myContext)) 
      throw new Exception("Error while destroying context."); 
     if (!egl.Terminate(myDisplay)) 
      throw new Exception("Error while terminating display."); 
     base.OnClosing(e); 
    } 
} 

回答

2

您需要启用纹理:呈现方形前

glEnable(GL_TEXTURE_2D); 

0

感谢您的帮助!然而你的建议并没有解决这个问题。现在广场是黑色而不是白色,但仍然没有纹理。我试过在每个可能的位置添加gl.Enable(gl.GL_TEXTURE_2D),但结果仍然是黑色方块。

编辑: 乌普斯,对不起,我的形象的左上角是黑色的,这就是为什么我什么都没看到。更改图像具有不同的颜色,现在我可以看到部分图像呈现。它没有被映射,但我可以把这部分弄清楚。 非常感谢帮助!

1

如果您使用OpenGL合作| ES也看看是否支持glDrawTexImage拓(好 - 它应该,这是一个核心,延伸和必需的,但你永远不知道...)

它赢得了直接帮助你解决问题(例如,你也必须启用纹理化),但是glDrawTexImage比多边形渲染更有效率。而且它需要更少的代码来编写。

+0

不幸的是它在我使用的包装中不受支持。它可能在OpenGLES的Windows Mobile实现中得到支持,但不在包装中。虽然不错,但... – 2009-01-24 21:07:01

1

如果您使用UIImage,CGImage和CGContext从PNG或JPG文件加载纹理,则在创建纹理之前将GL_TEXTURE_MIN_FILTER设置为GL_LINEAR或GL_NEAREST非常重要,因为如果您不这样做,则所有纹理最后的界限将被设置为空白。