SharpGL WPF 不使用 gl.DrawArrays() 和 gl.VertexPointer() 绘图

Posted

技术标签:

【中文标题】SharpGL WPF 不使用 gl.DrawArrays() 和 gl.VertexPointer() 绘图【英文标题】:SharpGL WPF Not drawing with gl.DrawArrays() and gl.VertexPointer() 【发布时间】:2022-01-15 14:11:54 【问题描述】:

我正在尝试使用 SharpGL 在使用 gl.VertexPointer() 和 gl.DrawArrays() 的 WPF 应用程序中进行渲染。但我不能让它渲染一个正方形。背景清除为绿色,我可以在 WPF 面板的左下方看到 FPS 绘图。为正方形添加代码时,FPS 文本也消失了,我只有一个空白屏幕。

我正在做与我在 C++ 项目中所做的完全相同的事情,它工作得很好。我不知道我错过了什么或做错了什么。

XAML

<Window x:Class="NodePlusPlus.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NodePlusPlus"
        xmlns:gl="clr-namespace:SharpGL.WPF;assembly=SharpGL.WPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="900" Width="1600" Background="#FF202020">
    <Grid x:Name="MainGrid">
        
        <gl:OpenGLControl x:Name="glPanel" DrawFPS="True" />

    </Grid>
</Window>

C#

        public MainWindow()
        
            InitializeComponent();

            glPanel.OpenGLInitialized += glPanel_OpenGLInitialized;
            glPanel.OpenGLDraw += glPanel_OpenGLDraw;
            glPanel.Resized += glPanel_Resized;
        

        private void glPanel_Resized(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
        
            OpenGL gl = args.OpenGL;
            gl.Ortho2D(0, Width, 0, Height);
        

        private void glPanel_OpenGLInitialized(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
        
            OpenGL gl = args.OpenGL;

            gl.Hint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_FASTEST);
            gl.ShadeModel(OpenGL.GL_SMOOTH);
            gl.Enable(OpenGL.GL_CULL_FACE);
            gl.Enable(OpenGL.GL_TEXTURE_2D);
            gl.Enable(OpenGL.GL_BLEND);
            gl.Enable(OpenGL.GL_DEPTH_TEST);
            gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);
            gl.EnableClientState(OpenGL.GL_VERTEX_ARRAY);
            gl.EnableClientState(OpenGL.GL_TEXTURE_COORD_ARRAY);
            gl.ClearColor(0.0f, 1.0f, 0.0f, 0.1f);
        

        private void glPanel_OpenGLDraw(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
        
            OpenGL gl = args.OpenGL;

            // Clear the color and depth buffers
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            gl.LoadIdentity();
            
            // Build a rectangle
            float Width     = 100.0f;
            float Height    = 100.0f;
            float[] vertices = new float[18];
            vertices[0]  = 0;       vertices[1] = 0;        vertices[2] = 0.0f;
            vertices[3]  = 0;       vertices[4] = Height;   vertices[5] = 0.0f;
            vertices[6]  = Width;   vertices[7] = Height;   vertices[8] = 0.0f;

            vertices[9]  = 0;       vertices[10] = 0;       vertices[11] = 0.0f;
            vertices[12] = Width;   vertices[13] = Height;  vertices[14] = 0.0f;
            vertices[15] = Width;   vertices[16] = 0;       vertices[17] = 0.0f;


            // If I remove this whole Begin()-End() section, it will render the Open GL FPS.  With this draw code here, it does not render the FPS.
            gl.Begin(OpenGL.GL_TRIANGLES);

            gl.Translate(0.0f, 0.0f, 0.0f);
            gl.Color(0.0f, 0.0f, 0.0f, 1.0f);
            gl.VertexPointer(3, 0, vertices);
            gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, 6);

            gl.End();

            gl.Flush();
        

使用绘图代码...

没有绘制代码​​...

【问题讨论】:

在 glBegin 和 glEnd 之间不能调用 glTranslate 和 glDrawArrays。请检查 OpenGL 错误 (glGetError)。 感谢glGetError() 的提醒。我删除了 Begin()/End() 调用(没有意识到我不需要它们)并且 FPS 开始绘制。但是,现在它在gl.DrawArrays() 上崩溃了。我目前正在解决这个问题。 @szMuzzyA 你没有指定纹理坐标。所以你必须删除gl.EnableClientState(OpenGL.GL_TEXTURE_COORD_ARRAY); 好电话!这修复了崩溃。还是没画。我打电话给gl.CullFace(OpenGL.GL_FRONT),我的黑色纹理出现了。这对我来说不是。我的三角形是顺时针排列的。但这回答了帖子。 @szMuzzyA 默认缠绕顺序是逆时针。见Face Culling 【参考方案1】:

正如@BDL 所述,glBegin()glEnd() 在这种情况下不使用。

正如@Rabbid76 所说,glEnableClientState(OpenGL.GL_TEXTURE_COORD_ARRAY) 应该被删除,因为我没有使用纹理坐标。

感谢大家的帮助!

在特定示例中还需要删除 gl.Enable(OpenGL.GL_CULL_FACE) 来绘制我的正方形。正如@Rabbid76 提到的,默认的缠绕顺序是逆时针的。我的顶点是顺时针缠绕的。

最终结果

        private void glPanel_OpenGLInitialized(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
        
            OpenGL gl = args.OpenGL;

            gl.Hint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_FASTEST);
            gl.ShadeModel(OpenGL.GL_SMOOTH);
            gl.Enable(OpenGL.GL_TEXTURE_2D);
            gl.Enable(OpenGL.GL_BLEND);
            gl.Enable(OpenGL.GL_DEPTH_TEST);
            gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);
            gl.EnableClientState(OpenGL.GL_VERTEX_ARRAY);
            gl.ClearColor(0.0f, 1.0f, 0.0f, 0.1f);
        

        private void glPanel_OpenGLDraw(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
        
            OpenGL gl = args.OpenGL;

            // Clear the color and depth buffers
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            gl.LoadIdentity();
            
            // Build a rectangle
            float Width     = 100.0f;
            float Height    = 100.0f;
            float[] vertices = new float[18];
            vertices[0]  = 0;       vertices[1] = 0;        vertices[2] = 0.0f;
            vertices[3]  = 0;       vertices[4] = Height;   vertices[5] = 0.0f;
            vertices[6]  = Width;   vertices[7] = Height;   vertices[8] = 0.0f;

            vertices[9]  = 0;       vertices[10] = 0;       vertices[11] = 0.0f;
            vertices[12] = Width;   vertices[13] = Height;  vertices[14] = 0.0f;
            vertices[15] = Width;   vertices[16] = 0;       vertices[17] = 0.0f;

            gl.Translate(0.0f, 0.0f, 0.0f);
            gl.Color(0.0f, 0.0f, 0.0f, 1.0f);
            gl.VertexPointer(3, 0, vertices);
            gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, 6);

            gl.Flush();
        

【讨论】:

以上是关于SharpGL WPF 不使用 gl.DrawArrays() 和 gl.VertexPointer() 绘图的主要内容,如果未能解决你的问题,请参考以下文章

SharpGL的功能应用--图形绘制

是否可以通过 D3DImage 和 ANGLE 将 OpenGL ES 代码与 WPF 应用程序一起使用?

SharpGL之Viewport

SharpGL之透视投影和摄像机

[go + SDL + OpenGL + MacOS示例=在DrawArrays()之后我得到了INVALID_OPERATION

怎样在wpf下固定控件位置随界面的变化保持不动