-
Notifications
You must be signed in to change notification settings - Fork 5
/
gltools.jl
118 lines (100 loc) · 4.28 KB
/
gltools.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
function glGenOne(glGenFn)
id::Ptr{GLuint} = GLuint[0]
glGenFn(1, id)
glCheckError("generating a buffer, array, or texture")
unsafe_load(id)
end
glGenBuffer() = glGenOne(glGenBuffers)
glGenVertexArray() = glGenOne(glGenVertexArrays)
glGenTexture() = glGenOne(glGenTextures)
function getInfoLog(obj::GLuint)
# Return the info log for obj, whether it be a shader or a program.
isShader = glIsShader(obj)
getiv = isShader == GL_TRUE ? glGetShaderiv : glGetProgramiv
getInfo = isShader == GL_TRUE ? glGetShaderInfoLog : glGetProgramInfoLog
# Get the maximum possible length for the descriptive error message
int::Ptr{GLint} = GLint[0]
getiv(obj, GL_INFO_LOG_LENGTH, int)
maxlength = unsafe_load(int)
# TODO: Create a macro that turns the following into the above:
# maxlength = @glPointer getiv(obj, GL_INFO_LOG_LENGTH, GLint)
# Return the text of the message if there is any
if maxlength > 0
buffer = zeros(GLchar, maxlength)
sizei::Ptr{GLsizei} = GLsizei[0]
getInfo(obj, maxlength, sizei, buffer)
length = unsafe_load(sizei)
bytestring(pointer(buffer), length)
else
""
end
end
function validateShader(shader)
success::Ptr{GLint} = GLint[0]
glGetShaderiv(shader, GL_COMPILE_STATUS, success)
unsafe_load(success) == GL_TRUE
end
function glErrorMessage()
# Return a string representing the current OpenGL error flag, or the empty string if there's no error.
err = glGetError()
err == GL_NO_ERROR ? "" :
err == GL_INVALID_ENUM ? "GL_INVALID_ENUM: An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag." :
err == GL_INVALID_VALUE ? "GL_INVALID_VALUE: A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag." :
err == GL_INVALID_OPERATION ? "GL_INVALID_OPERATION: The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag." :
err == GL_INVALID_FRAMEBUFFER_OPERATION ? "GL_INVALID_FRAMEBUFFER_OPERATION: The framebuffer object is not complete. The offending command is ignored and has no other side effect than to set the error flag." :
err == GL_OUT_OF_MEMORY ? "GL_OUT_OF_MEMORY: There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded." : "Unknown OpenGL error with error code $err."
end
function glCheckError(actionName="")
message = glErrorMessage()
if length(message) > 0
if length(actionName) > 0
error("Error ", actionName, ": ", message)
else
error("Error: ", message)
end
end
end
function createShader(source, typ)
# Create the shader
shader = glCreateShader(typ)::GLuint
if shader == 0
error("Error creating shader: ", glErrorMessage())
end
# Compile the shader
glShaderSource(shader, 1, convert(Ptr{Uint8}, pointer([convert(Ptr{GLchar}, pointer(source))])), C_NULL)
glCompileShader(shader)
# Check for errors
!validateShader(shader) && error("Shader creation error: ", getInfoLog(shader))
shader
end
function createShaderProgram(f, vertexShader, fragmentShader)
# Create, link then return a shader program for the given shaders.
# Create the shader program
prog = glCreateProgram()
if prog == 0
error("Error creating shader program: ", glErrorMessage())
end
# Attach the vertex shader
glAttachShader(prog, vertexShader)
glCheckError("attaching vertex shader")
# Attach the fragment shader
glAttachShader(prog, fragmentShader)
glCheckError("attaching fragment shader")
f(prog)
# Finally, link the program and check for errors.
glLinkProgram(prog)
status::Ptr{GLint} = GLint[0]
glGetProgramiv(prog, GL_LINK_STATUS, status)
if unsafe_load(status) == GL_FALSE then
glDeleteProgram(prog)
error("Error linking shader: ", glGetInfoLog(prog))
end
prog
end
createShaderProgram(vertexShader, fragmentShader) = createShaderProgram(prog->0, vertexShader, fragmentShader)
function printGLInfo()
println("GLSL version: ", bytestring(glGetString(GL_SHADING_LANGUAGE_VERSION)))
println("OpenGL version: ", bytestring(glGetString(GL_VERSION)))
println("OpenGL vendor: ", bytestring(glGetString(GL_VENDOR)))
println("OpenGL renderer: ", bytestring(glGetString(GL_RENDERER)))
end