在OpenGL中将纹理应用于方形的问题

时间:2009-01-24 18:51:48

标签: c# .net windows-mobile opengl-es

我无法将纹理映射到openGLES中的正方形。我试图在屏幕上显示一个jpg图像,为了让我这样做,我绘制了一个我想要的图形,然后将图像映射到。然而,我得到的所有输出都是白色方块。我不知道我做错了什么。而这个问题阻碍了我继续推进我的项目。我正在使用Managed OpenGL ES wrapper用于Windows Mobile。 我验证了纹理正确加载,但我无法将其应用于我的对象。我上传了显示我的问题here的示例项目。您需要VS2008和Windows Mobile 6 SDK才能运行它。我还发布了在这里渲染和纹理对象的Form的代码。任何建议都会非常感激,因为我一直坚持这个问题,我无法弄清楚我做错了什么。

    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);
    }
}

4 个答案:

答案 0 :(得分:2)

您需要启用纹理:

glEnable( GL_TEXTURE_2D );
在渲染正方形之前

答案 1 :(得分:1)

如果您使用OpenGL | ES,请查看是否支持glDrawTexImage-Extension(嗯 - 应该,它是核心扩展并且是必需的,但您永远不会知道......)

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

答案 2 :(得分:1)

如果使用UIImage,CGImage和CGContext从PNG或JPG文件加载纹理,在创建纹理之前将GL_TEXTURE_MIN_FILTER设置为GL_LINEAR或GL_NEAREST非常重要,因为如果不这样做,除了最后一个纹理之外的所有纹理都是如此bound将设置为空白。

答案 3 :(得分:0)

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

编辑: Upps,对不起,我的图像的左上角是黑色的,这就是为什么我没有看到任何东西。将图像更改为具有不同的颜色,现在我可以看到渲染的部分图像。它没有属性映射,但我可以想出那部分。 非常感谢你们的帮助!!!