SharpGL:简单的着色和vbo不起作用



我正在为我的项目使用 SharpGL,这将涉及使用 glsl 版本 4.2。

在过去的几天里,我尝试了一些例子,但没有一个有效。为 OpenTK 编写的类似代码对我有用,所以我不知道我做错了什么,但在 SharpGL 中,如果我使用着色器和 VBO 屏幕,则不会吸引任何内容。要么我失去了理智,要么 SharpGL 本身无法正常工作,我对此表示怀疑。

我宁愿使用SharpGL作为其WPF控件。我附上了一个非常简单的示例代码。我将不胜感激有关此事的任何帮助。请注意,在 OpenTK 中,只需稍作更改即可使用相同的代码。

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Runtime.InteropServices;
using System.IO;
using SharpGL;
using SharpGL.SceneGraph;
namespace SharpGLTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        OpenGL gl;
        uint theProgram, positionBufferObject;
        string strVertexShader = "test.vert";
        string strFragmentShader = "test.frag";
        public MainWindow()
        {
            InitializeComponent();
        }
        private void OpenGLControl_OpenGLInitialized(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            gl = args.OpenGL;
            InitializeVertexBuffer();
            InitializeProgram();
        }
        private uint CreateProgram(List<uint> shaderList)
        {
            uint program = gl.CreateProgram();
            foreach (uint shader in shaderList)
                gl.AttachShader(program, shader);
            gl.LinkProgram(program);
            ProgramErrorInfo(program);
            foreach (uint shader in shaderList)
                gl.DetachShader(program, shader);
            return program;
        }
        private uint CreateShader(uint eShaderType, string strShaderFile)
        {
            uint shader = gl.CreateShader(eShaderType);
            string[] strFileData = { File.ReadAllText(strShaderFile) };
            gl.ShaderSource(shader, strFileData);
            gl.CompileShader(shader);
            ShaderErrorInfo(shader);
            return shader;
        }
        private void InitializeProgram()
        {
            List<uint> shaderList = new List<uint>();
            shaderList.Add(CreateShader(OpenGL.GL_VERTEX_SHADER, strVertexShader));
            shaderList.Add(CreateShader(OpenGL.GL_FRAGMENT_SHADER, strFragmentShader));
            theProgram = CreateProgram(shaderList);
            foreach (uint shader in shaderList)
                gl.DeleteShader(shader);
        }
        private void InitializeVertexBuffer()
        {
            float[] vertexPositions = {
                0.75f, 0.75f, 0.0f, 1.0f,
                0.75f, -0.75f, 0.0f, 1.0f,
                -0.75f, -0.75f, 0.0f, 1.0f,
            };
            GCHandle handle = GCHandle.Alloc(vertexPositions, GCHandleType.Pinned);
            IntPtr vertexPtr = handle.AddrOfPinnedObject();
            var size = Marshal.SizeOf(typeof(float)) * vertexPositions.Length;
            uint[] pbo = new uint[1];
            gl.GenBuffers(1, pbo);
            positionBufferObject = pbo[0];
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, positionBufferObject);
            gl.BufferData(OpenGL.GL_ARRAY_BUFFER, size, vertexPtr, OpenGL.GL_STATIC_DRAW);
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, 0);
            handle.Free();
        }
        private void OpenGLControl_OpenGLDraw(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT);
            gl.UseProgram(theProgram);
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, positionBufferObject);
            gl.EnableVertexAttribArray(0);
            gl.VertexAttribPointer(0, 4, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero);
            gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, 3);
            gl.DisableVertexAttribArray(0);
            gl.UseProgram(0);
            gl.Flush();
        }
        private void OpenGLControl_Resized(object sender, OpenGLEventArgs args)
        {
            gl.Viewport(0, 0, gl.RenderContextProvider.Width, gl.RenderContextProvider.Height);
        }
        private bool ShaderErrorInfo(uint shaderId)
        {
            StringBuilder builder = new StringBuilder(2048);
            gl.GetShaderInfoLog(shaderId, 2048, IntPtr.Zero, builder);
            string res = builder.ToString();
            if (!res.Equals(""))
            {
                System.Console.WriteLine(res);
                return false;
            }
            return true;
        }
        private bool ProgramErrorInfo(uint programId)
        {
            StringBuilder builder = new StringBuilder(2048);
            gl.GetProgramInfoLog(programId, 2048, IntPtr.Zero, builder);
            string res = builder.ToString();
            if (!res.Equals(""))
            {
                System.Console.WriteLine(res);
                return false;
            }
            return true;
        }
    }
}

test.vert

#version 330
layout(location = 0) in vec4 position;
void main()
{
    gl_Position = position;
}

测试碎片

#version 330
out vec4 outputColor;
void main()
{
   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}

MainWindow.xaml

<Window x:Class="SharpGLTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:sharpGL="clr-namespace:SharpGL.WPF;assembly=SharpGL.WPF">
    <Grid>
        <sharpGL:OpenGLControl x:Name="OpenGLControl"
            OpenGLInitialized="OpenGLControl_OpenGLInitialized"
            OpenGLDraw="OpenGLControl_OpenGLDraw" 
            RenderContextType="FBO"
            Resized="OpenGLControl_Resized"
                               />
    </Grid>
</Window>
我知道

这个问题相当古老,但是,我正在谷歌搜索一种使用 gl 的方法。GetShaderInfoLog,当我第一次来到这里,然后是SharpGL源代码的着色器.cs。

在SharpGl中,确实没有glGetShaderiv/glGetProgramiv。然而,这不是为我们提供编译状态的信息日志,它是这样获得的(摘自 Shader.cs):

public bool GetCompileStatus(OpenGL gl)
    {
        int[] parameters = new int[] { 0 };
        gl.GetShader(shaderObject, OpenGL.GL_COMPILE_STATUS, parameters);
        return parameters[0] == OpenGL.GL_TRUE;
    }

就我而言,这向我展示了一个错误,而您的方式并没有引起任何事情。

最后,Tim 在编译错误方面走上了正确的轨道。现在,你真的有编译错误吗?我不知道,但要回答这个问题,正确检查编译错误至关重要。

不确定sharpGL是否进行错误检查,但如果不是,您可能应该在某个地方测试一些glGetError。

我不完全确定您的问题可能是什么,但我想指出,我认为检查信息日志的长度不足以测试操作是否成功。

要测试着色器编译/链接中的错误,您应该将glGetShaderiv/glGetProgramiv与目标GL_COMPILE_STATUSGL_LINK_STATUS一起使用。此布尔值的结果确定编译/链接是否成功。

在大多数情况下,使用信息日志长度可能是正确的,但不能保证。我在某些平台上看到过链接可能失败并且没有错误日志的错误,我也知道编译/链接有可能成功并仍然打印消息。

相关内容

  • 没有找到相关文章

最新更新