C# - OpenGl.Net着色器无法编译而没有错误

时间:2018-05-15 03:23:09

标签: c# opengl

我正在使用C#和OpenGL.Net制作一个显示三角形的简单程序,但由于某种原因,程序运行并使屏幕空白。它表示顶点和片段着色器都无法编译,但没有错误列表。

以下是代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
using System.Text;

using SFML;
using SFML.Graphics;
using SFML.Window;
using OpenGL;

using System.Media;
using System.IO;

namespace SFML_Test
{
    static class Program
    {
        static void Main()
        {
            // Create the main window
            ContextSettings settings = new ContextSettings
            {
                DepthBits = 24,
                StencilBits = 8,
                AntialiasingLevel = 2 // optional
            };
            RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML Works!");
            window.Closed += new EventHandler(OnClose);

            Color windowColor = new Color(0, 0, 0);
            // Setup
            uint vao = Gl.GenVertexArray();
            Gl.BindVertexArray(vao);

            float[] trianglePoints = 
                { -0.5F, -0.5F,
                0.5F, -0.5F,
                0F, 0.5F};
            uint vbo = Gl.GenBuffer();
            Gl.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            Gl.BufferData(BufferTarget.ArrayBuffer, (uint)(4*trianglePoints.Length), trianglePoints, BufferUsage.StaticDraw);
            SetupVertexShader();

            Gl.EnableVertexAttribArray(0);
            Gl.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            Gl.VertexAttribPointer(0, 3, VertexAttribType.Float, false, 0, (IntPtr)0);
            Gl.DrawArrays(OpenGL.PrimitiveType.Triangles, 0, 3);
            // Start the game loop
            while (window.IsOpen())
            {
                window.DispatchEvents();
                window.Clear(windowColor);
                Gl.DrawElements(OpenGL.PrimitiveType.Triangles, 3, DrawElementsType.UnsignedInt, 0);

                Thread.Sleep((1/30) * 1000);
                window.Display();
            }
        }
        static void SetupVertexShader()
        {
            uint vertexShader = Gl.CreateShader(ShaderType.VertexShader);
            string[] shaderString = File.ReadAllLines(@".\Shaders\vertex.shader");
            Gl.ShaderSource(vertexShader, shaderString);
            Gl.CompileShader(vertexShader);
            int success;
            Gl.GetShader(vertexShader, ShaderParameterName.CompileStatus, out success);
            if (success != 0)
            {
                Console.WriteLine("Vertex Creation Success.");
            }
            else
            {
                Console.WriteLine("Vertex creation fail.");
                Gl.GetShader(vertexShader, ShaderParameterName.InfoLogLength, out int logLength);
                int logMaxLength = 1024;
                StringBuilder infoLog = new StringBuilder(logMaxLength);
                Gl.GetShaderInfoLog(vertexShader, 1024, out int infoLogLength, infoLog);
                Console.WriteLine("Errors: \n{0}", infoLog.ToString());
            }
            uint fragmentShader = Gl.CreateShader(ShaderType.FragmentShader);
            Gl.ShaderSource(fragmentShader, File.ReadAllLines(@".\Shaders\fragment.shader"));
            Gl.CompileShader(fragmentShader);
            Gl.GetShader(fragmentShader, ShaderParameterName.CompileStatus, out success);
            if (success != 0)
            {
                Console.WriteLine("Fragment Creation Success.");
            }
            else
            {
                Console.WriteLine("Fragment creation fail.");
                Gl.GetShader(fragmentShader, ShaderParameterName.InfoLogLength, out int logLength);
                int logMaxLength = 1024;
                StringBuilder infoLog = new StringBuilder(logMaxLength);
                Gl.GetShaderInfoLog(vertexShader, 1024, out int infoLogLength, infoLog);
                Console.WriteLine("Errors: \n{0}", infoLog);
            }
            uint shaderProgram = Gl.CreateProgram();
            Gl.AttachShader(shaderProgram, vertexShader);
            Gl.AttachShader(shaderProgram, fragmentShader);
            Gl.BindFragDataLocation(shaderProgram, 0, "outColor");
            Gl.LinkProgram(shaderProgram);
            Gl.UseProgram(shaderProgram);
        }
        static void OnClose(object sender, EventArgs e)
        {
            // Close window
            RenderWindow window = (RenderWindow)sender;
            window.Close();
        }
    }
}

这是vertex.shader:

#version 150 core

in vec2 position;

void main()
{
    gl_Position = vec4(position, 0.0, 1.0);
}

这里是fragment.shader:

#version 150 core
out vec4 outColor;
void main()
{
    outColor = vec4(1.0, 1.0, 1.0, 1.0);
}

修改 正如Luca所建议的那样(谢谢)我在所有内容之前添加了Gl.Initialize() 其他。我还从预处理器指令中删除了core,现在着色器使用此错误进行编译:

WARNING: 2:1: invalid profile specified
ERROR: 2:1: '' : syntax error: #version
ERROR: 2:1: '' : syntax error: unexpected tokens following preprocessor 
directive - expected a newline

任何帮助?

1 个答案:

答案 0 :(得分:1)

您的着色器以#version 150 core开头,与OpenGL 3.2 Core Profile版本匹配。
要正确使用它,你必须设置适当的背景。

我不懂SMFL。调查它的sources我可以猜到你的问题,你缺乏这个背景设置。你应该这样做:

    // Create the main window
    ContextSettings settings = new ContextSettings
    {
        DepthBits = 24,
        StencilBits = 8,
        AntialiasingLevel = 2, // optional
        MajorVersion = 3, // OpenGL version
        MinorVersion = 2, // OpenGL version
        AttributeFlags = ContextSettings.Attribute.Core
    };
    RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML Works!", settings);
    window.setActive(true); //set the context as current

另一种方法是让SFML请求兼容性配置文件,这与核心配置文件相反。然后启动你的着色器,而不是"核心",就像 #version 150