麻烦将指针传递给OpenGL。上传的着色器已损坏

时间:2014-03-17 00:26:57

标签: opengl shader opengl-3 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报告上传着色器时没有错误,如果它接收到垃圾或错误的着色器代码,它应该是错误的。 这让我相信数据不一定是腐败的,而只是......空。

我认为问题是:

  1. 我没有正确传递数据
  2. OpenGL绑定存在问题
  3. 我倾向于第一个=)

1 个答案:

答案 0 :(得分:1)

似乎我需要一个额外的转换步骤,在文档示例中将字符串作为指针传递给我所不需要的。

旧代码是

glShaderSource(vs, 1, [vs_source], 0)

修复方法是添加转换调用。

glShaderSource(vs, 1, [convert(Ptr{Uint8}, vs_source)], 0)