我正在使用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
任何帮助?
答案 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