我在将位图绘制到 GLControl 中时遇到问题

问题描述 投票:0回答:0

我正在使用来自 NuGet 的最新 OpenTK 4.7.7 库和来自 GitHub 的最新 GLControl 库。我有一个 .NET 7 Windows 窗体项目,其中有一个 GLControl 对象。我的主要目标是将位图图像绘制到其中,类似于 System.Drawing.Graphics 将图像绘制到面板等控件中的方式。我仍然是 OpenGL 图形渲染的初学者,所以我不确定自己做错了什么。 GLControl 对象创建得很好,但实际上绘制图像不起作用。我还确认控件正在工作,因为我可以更改其背景颜色。我确实在窗帘区域进行了一些检查以查看错误发生的位置,并且我在代码中标记了这些区域。

GLControl 库的 GitHub 链接:https://github.com/opentk/GLControl

这是我用来管理控件的包装类:

//OpenTK libs
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.WinForms;

using DrwImage = System.Drawing.Image;
using GLControl = OpenTK.WinForms.GLControl;

//Namespace here

public class OpenGLRenderer
    {
        public GLControl _MainGLControl;
        public OpenGLRenderer(Form contextFrom, Size size, Point location, Color backGroundColour ) 
        {
            _MainGLControl = new()
            {
                Parent = contextFrom,
                Location = location,
                Size = size,
                BackColor = backGroundColour
            };
            _MainGLControl.Paint += OnPaint;
            contextFrom.Load += (sender, e) =>
            {
                MakeControlCurrent();
            };
        }
        public OpenGLRenderer(GLControl gLControl) 
        {
            _MainGLControl= gLControl;
        }
        private void MakeControlCurrent()
        {
            _MainGLControl.MakeCurrent();
            GL.Enable(EnableCap.Texture2D);//This line gives error (InvalidEnum)
            MessageBox.Show("Enable: " + GL.GetError().ToString());
            GL.ClearColor(_MainGLControl.BackColor);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.Viewport(0, 0, _MainGLControl.Width, _MainGLControl.Height);
        }

        public void DrawImage(DrwImage image, float x, float y)
        {
            //MakeControlCurrent();
            int textureid = ImageToTexture(image);

            GL.ClearColor(Color.Brown);//Test colour
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            GL.BindTexture(TextureTarget.Texture2D, textureid);

            GL.Begin(PrimitiveType.Quads);//This line gives GL error(InvalidOperation) 
            MessageBox.Show("Begin: " + GL.GetError().ToString());

            GL.TexCoord2(0f, 0f);
            GL.Vertex2(x, y);

            GL.TexCoord2(1f, 0f);
            GL.Vertex2(x + image.Width, y);

            GL.TexCoord2(1f, 1f);
            GL.Vertex2(x + image.Width, y + image.Height);

            GL.TexCoord2(0f, 1f);
            GL.Vertex2(x, y + image.Height);

            GL.End();//This line gives GL error(InvalidOperation)
            MessageBox.Show("End: " + GL.GetError().ToString());

            _MainGLControl.SwapBuffers();

            GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.DeleteTexture(textureid);
        }
        private void OnPaint(object? sender, PaintEventArgs e)
        {
            //GL.ClearColor(Color.Black);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            _MainGLControl.SwapBuffers();
        }
        private int ImageToTexture(DrwImage image)
        {
            Bitmap bmp = new Bitmap(image);

            GL.GenTextures(1, out int textureID);

            GL.BindTexture(TextureTarget.Texture2D, textureID);
            BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
                OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.Byte, data.Scan0);
            bmp.UnlockBits(data);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);

            return textureID;
        }

我尝试了什么: 我试着查看其他做类似事情的网站和视频,看看我搞砸了什么。

我的期望: 我希望图像至少以某种形式出现在 GLControl 对象中。

实际发生了什么: GLControl 没有绘制请求的图像。

c# winforms opentk
© www.soinside.com 2019 - 2024. All rights reserved.