我是朱莉娅的新手,我正在尝试运行一个最小的OpenGL程序,我使用Julia的OpenGL和GLFW库来移植我的一些Python。
我遇到的问题是OpenGL告诉我,我的着色器已损坏。 着色器应该完全有效,我在Python代码中使用它,尽管在Python中更复杂。
不幸的是,我没有可以参考的着色器驱动的OpenGL示例,GLUT repo和SDL上提供的示例仅使用较旧的固定功能渲染,并且不使用我能看到的任何着色器。
代码如下:
push!(Sys.DL_LOAD_PATH, "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/")
global OpenGLver="3.2"
using OpenGL
import GLFW
#
# Window Setup
#
GLFW.Init()
GLFW.OpenWindowHint(GLFW.OPENGL_VERSION_MAJOR, 3)
GLFW.OpenWindowHint(GLFW.OPENGL_VERSION_MINOR, 2)
GLFW.OpenWindowHint(GLFW.OPENGL_FORWARD_COMPAT, TRUE)
GLFW.OpenWindowHint(GLFW.OPENGL_PROFILE, GLFW.OPENGL_CORE_PROFILE)
width, height = 1024, 768
GLFW.OpenWindow(
width, height,
8, 8, 8,
8, 24, 0,
GLFW.WINDOW
)
result = Cint[0]
#
# Mesh
#
glGenVertexArrays(1, result)
vao = result[1]
glBindVertexArray(vao)
vertices = Float32[
-1., 1.,-1.,
-1.,-1.,-1.,
1., 1.,-1.,
-1.,-1.,-1.,
1.,-1.,-1.,
1., 1.,-1.,
]
glGenBuffers(1, result)
vbo = result[1]
glBindBuffer(ARRAY_BUFFER, vbo)
glBufferData(ARRAY_BUFFER, sizeof(vertices), vertices, STATIC_DRAW)
#
# Shader
#
vs_source = """
#version 150
// input
in vec3 in_position;
void main(void)
{
gl_Position = vec4(in_position, 1.0);
}
"""
fs_source = """
#version 150
// output
out vec4 out_frag_color;
void main(void)
{
out_frag_color = vec4(1.0, 0.0, 0.0, 1.0);
}
"""
println("VERTEX SHADER")
vs = glCreateShader(VERTEX_SHADER)
println("error:",glGetError())
if 0 == vs
println("Failed to create vertex shader")
exit(1)
end
#glShaderSource(vs, 1, [vs_source], [length(vs_source)])
glShaderSource(vs, 1, [vs_source], 0)
println("length:",length(vs_source))
println("error:",glGetError())
glCompileShader(vs)
println("error:",glGetError())
println("original")
println(vs_source)
println("returned")
glGetShaderiv(vs, SHADER_SOURCE_LENGTH, result)
println("size:", result[1])
s = Array(Uint8, result[1])
glGetShaderSource(vs, result[1], result, s)
println(s)
s = bytestring(convert(Ptr{Uint8}, s))
println(s)
glGetShaderiv(vs, COMPILE_STATUS, result)
if FALSE == result[1]
println("Vertex shader failed to compile")
glGetShaderiv(vs, INFO_LOG_LENGTH, result)
s = Array(Uint8, result[1])
glGetShaderInfoLog(vs, result[1], result, s)
println("log:",bytestring(convert(Ptr{Uint8}, s)))
exit(1)
end
println("FRAGMENT SHADER")
fs = glCreateShader(FRAGMENT_SHADER)
println("error:",glGetError())
if 0 == fs
println("Failed to create fragment shader")
exit(1)
end
#glShaderSource(fs, 1, [fs_source], [length(fs_source)])
glShaderSource(fs, 1, [fs_source], 0)
println("length:",length(fs_source))
println("error:",glGetError())
glCompileShader(fs)
println("error:",glGetError())
println("original")
println(fs_source)
println("returned")
glGetShaderiv(fs, SHADER_SOURCE_LENGTH, result)
println("size:", result[1])
s = Array(Uint8, result[1])
glGetShaderSource(fs, result[1], result, s)
println(s)
s = bytestring(convert(Ptr{Uint8}, s))
println(s)
glGetShaderiv(fs, COMPILE_STATUS, result)
if FALSE == result[1]
println("Fragment shader failed to compile")
glGetShaderiv(fs, INFO_LOG_LENGTH, result)
s = Array(Uint8, result[1])
glGetShaderInfoLog(fs, result[1], result, s)
println("log:",bytestring(convert(Ptr{Uint8}, s)))
exit(1)
end
println("SHADER PROGRAM")
p = glCreateProgram()
println("error:",glGetError())
glAttachShader(p, vs)
println("error:",glGetError())
glAttachShader(p, fs)
println("error:",glGetError())
s = Array(Int8, 2)
glGetAttachedShaders(p, length(s), result, s)
println("attached:",[vs, fs])
println("length:",result[1])
println("actual:",s)
glLinkProgram(p)
println("error:",glGetError())
glGetProgramiv(p, LINK_STATUS, result)
if FALSE == result[1]
println("Shader program failed to link")
glGetProgramiv(p, INFO_LOG_LENGTH, result)
s = Array(Uint8, result[1])
glGetProgramInfoLog(p, result[1], result, s)
println("log:",bytestring(convert(Ptr{Uint8}, s)))
exit(1)
end
glUseProgram(p)
in_position = glGetAttribLocation(p, "in_position")
println(in_position)
glEnableVertexAttribArray(in_position)
glVertexAttribPointer(in_position, 3, FLOAT, FALSE, sizeof(vertices)/2, 0)
#
# Render
#
glDisable(CULL_FACE)
glClearColor(0.2, 0.2, 0.2, 1.0)
glViewport(0, 0, width, height)
while GLFW.GetWindowParam(GLFW.OPENED) && !GLFW.GetKey(GLFW.KEY_ESC)
glClear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT)
glDrawArrays(TRIANGLES, 0, length(vertices))
GLFW.SwapBuffers()
end
GLFW.CloseWindow()
GLFW.Terminate()
输出如下:
julia test.jl
VERTEX SHADER
error:0
length:164
error:0
error:0
original
#version 150
// input
in vec3 in_position;
void main(void)
{
// apply projection and model view matrix to vertex
gl_Position = vec4(in_position, 1.0);
}
returned
size:2
10
0
FRAGMENT SHADER
error:0
length:118
error:0
error:0
original
#version 150
// output
out vec4 out_frag_color;
void main(void)
{
out_frag_color = vec4(1.0, 0.0, 0.0, 1.0);
}
returned
size:2
10
0
SHADER PROGRAM
error:0
error:0
error:0
attached:1
2
length:2
actual:1
0
error:0
Shader program failed to link
log:ERROR: Compiled vertex shader was corrupt.
ERROR: Compiled fragment shader was corrupt.
OpenGL.jl源位于:https://github.com/rennis250/OpenGL.jl/blob/master/src/gl32/gl32.jl
glShaderSource具有以下签名:
@getCFun "libGL" glShaderSource glShaderSource(shader::GLuint, count::GLsizei, string_::Ptr{Uint8}, length::Ptr{GLint})::Void
export glShaderSource
正如您所看到的,我收到的大部分数据都不正确。 glAttachedShaders返回0,1而不是1,2。 glGetShader返回着色器大小为2 glShaderSource返回一个空字符串。
它也令人沮丧,因为OpenGL报告上传着色器时没有错误,如果它接收到垃圾或错误的着色器代码,它应该是错误的。 这让我相信数据不一定是腐败的,而只是......空。
我认为问题是:
我倾向于第一个=)
答案 0 :(得分:1)
似乎我需要一个额外的转换步骤,在文档示例中将字符串作为指针传递给我所不需要的。
旧代码是
glShaderSource(vs, 1, [vs_source], 0)
修复方法是添加转换调用。
glShaderSource(vs, 1, [convert(Ptr{Uint8}, vs_source)], 0)