我在我的项目中使用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;
}test.frag
#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>发布于 2015-05-17 16:13:02
我知道这个问题很老,但是,我在谷歌上搜索一种使用gl.GetShaderInfoLog的方法时,我先到了这里,然后到了SharpGL的源代码Shader.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在编译错误方面走在了正确的轨道上。现在,您真的有编译错误吗?我不知道,但要回答这个问题,正确检查编译错误是至关重要的。
发布于 2012-11-22 19:46:17
不确定sharpGL是否进行错误检查,但如果不是,您可能需要在某个地方测试一些glGetError。
我不太清楚您的问题可能是什么,但我想指出的是,我不认为检查infolog的长度是测试一个操作是否成功的充分方法。
若要测试着色器编译/链接中的错误,应将glGetShaderiv/glGetProgramiv与目标GL_COMPILE_STATUS或GL_LINK_STATUS一起使用。此布尔值的结果确定编译/链接是否成功。
大多数情况下,使用infolog长度可能是正确的,但它不能保证。我在一些平台上看到了一些错误,其中链接可能失败,并且没有错误日志,我也知道编译/链接成功并仍然打印消息是可能的。
https://stackoverflow.com/questions/13515794
复制相似问题