【发布时间】:2014-03-17 00:26:57
【问题描述】:
我是 Julia 的新手,正在尝试运行一个最小的 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 没有报告上传着色器的错误,如果它接收到垃圾或错误的着色器代码,它应该这样做。 这让我相信数据不一定是损坏的,而只是......空的。
我认为问题是:
- 我没有正确传递数据
- OpenGL 绑定存在问题
我倾向于第一个 =)
【问题讨论】:
标签: opengl shader opengl-3 julia