lib: intro of the glesv2 module
[nit.git] / lib / glesv2.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # OpenGL graphics rendering library for embedded systems, version 2.0.
18 #
19 # Most services of this module are a direct wrapper of the underlying
20 # C library. If a method or class is not documented in Nit, refer to
21 # the official documentation by the Khronos Group at:
22 # http://www.khronos.org/opengles/sdk/docs/man/
23 module glesv2 is pkgconfig("glesv2")
24
25 in "C Header" `{
26 #include <GLES2/gl2.h>
27 `}
28
29 # Opengl ES program to which we attach shaders
30 extern class GLProgram `{GLuint`}
31 new `{ return glCreateProgram(); `}
32
33 fun is_ok: Bool `{ return glIsProgram(recv); `}
34
35 fun attach_shader(shader: GLShader) `{ glAttachShader(recv, shader); `}
36
37 fun bind_attrib_location(index: Int, name: String) import String.to_cstring `{
38 GLchar *c_name = String_to_cstring(name);
39 glBindAttribLocation(recv, index, c_name);
40 `}
41
42 fun attrib_location(name: String): Int import String.to_cstring `{
43 GLchar *c_name = String_to_cstring(name);
44 return glGetAttribLocation(recv, c_name);
45 `}
46
47 fun query(pname: Int): Int `{
48 int val;
49 glGetProgramiv(recv, pname, &val);
50 return val;
51 `}
52
53 fun link `{ glLinkProgram(recv); `}
54 fun is_linked: Bool do return query("8B82".to_hex) != 0
55
56 fun use `{ glUseProgram(recv); `}
57
58 fun delete `{ glDeleteProgram(recv); `}
59 fun is_deleted: Bool do return query("8B80".to_hex) != 0
60
61 fun validate `{ glValidateProgram(recv); `}
62 fun is_validated: Bool do return query("8B83".to_hex) != 0
63
64 fun info_log: String import NativeString.to_s `{
65 int size;
66 glGetProgramiv(recv, GL_INFO_LOG_LENGTH, &size);
67 GLchar *msg = malloc(size);
68 glGetProgramInfoLog(recv, size, NULL, msg);
69 return NativeString_to_s(msg);
70 `}
71 end
72
73 # Abstract OpenGL ES shader object, implemented by `GLFragmentShader` and `GLVertexShader`
74 extern class GLShader `{GLuint`}
75 fun source=(code: String) import String.to_cstring, String.length `{
76 GLchar *c_code = String_to_cstring(code);
77 glShaderSource(recv, 1, (const GLchar * const*)&c_code, NULL);
78 `}
79 fun source: nullable String import NativeString.to_s `{
80 int size;
81 glGetShaderiv(recv, GL_SHADER_SOURCE_LENGTH, &size);
82 if (size == 0) return NULL;
83 GLchar *code = malloc(size);
84 glGetShaderSource(recv, size, NULL, code);
85 return NativeString_to_s(code);
86 `}
87
88 protected fun query(pname: Int): Int `{
89 int val;
90 glGetShaderiv(recv, pname, &val);
91 return val;
92 `}
93
94 fun compile `{ glCompileShader(recv); `}
95 fun is_compiled: Bool do return query("8B81".to_hex) != 0
96
97 fun delete `{ glDeleteShader(recv); `}
98 fun is_deleted: Bool do return query("8B80".to_hex) != 0
99
100 fun is_ok: Bool `{ return glIsShader(recv); `}
101
102 fun info_log: String import NativeString.to_s `{
103 int size;
104 glGetShaderiv(recv, GL_INFO_LOG_LENGTH, &size);
105 GLchar *msg = malloc(size);
106 glGetShaderInfoLog(recv, size, NULL, msg);
107 return NativeString_to_s(msg);
108 `}
109
110 end
111
112 extern class GLFragmentShader
113 super GLShader
114
115 new `{ return glCreateShader(GL_FRAGMENT_SHADER); `}
116 end
117
118 extern class GLVertexShader
119 super GLShader
120
121 new `{ return glCreateShader(GL_VERTEX_SHADER); `}
122 end
123
124 # An array of `Float` associated to a program variable
125 class VertexArray
126 var index: Int
127 var count: Int
128 protected var glfloat_array: GLfloatArray
129
130 init(index, count: Int, array: Array[Float])
131 do
132 self.index = index
133 self.count = count
134 self.glfloat_array = new GLfloatArray(array)
135 end
136
137 fun attrib_pointer do attrib_pointer_intern(index, count, glfloat_array)
138 private fun attrib_pointer_intern(index, count: Int, array: GLfloatArray) `{
139 glVertexAttribPointer(index, count, GL_FLOAT, GL_FALSE, 0, array);
140 `}
141
142 fun enable do enable_intern(index)
143 private fun enable_intern(index: Int) `{ glEnableVertexAttribArray(index); `}
144
145 fun draw_arrays_triangles do draw_arrays_triangles_intern(index, count)
146 private fun draw_arrays_triangles_intern(index, count: Int) `{
147 glDrawArrays(GL_TRIANGLES, index, count);
148 `}
149 end
150
151 # Low level array of `Float`
152 extern class GLfloatArray `{GLfloat *`}
153 new (array: Array[Float]) import Array[Float].length, Array[Float].[] `{
154 int i;
155 int len = Array_of_Float_length(array);
156 GLfloat *vertex_array = malloc(sizeof(GLfloat)*len);
157 for (i = 0; i < len; i ++) vertex_array[i] = Array_of_Float__index(array, i);
158 return vertex_array;
159 `}
160 end
161
162 extern class GLError `{ GLenum `}
163 fun is_ok: Bool do return is_no_error
164 fun is_no_error: Bool `{ return recv == GL_NO_ERROR; `}
165 fun is_invalid_enum: Bool `{ return recv == GL_INVALID_ENUM; `}
166 fun is_invalid_value: Bool `{ return recv == GL_INVALID_VALUE; `}
167 fun is_invalid_operation: Bool `{ return recv == GL_INVALID_OPERATION; `}
168 fun is_invalid_framebuffer_operation: Bool `{ return recv == GL_INVALID_FRAMEBUFFER_OPERATION; `}
169 fun is_out_of_memory: Bool `{ return recv == GL_OUT_OF_MEMORY; `}
170
171 redef fun to_s
172 do
173 if is_no_error then return "No error"
174 if is_invalid_enum then return "Invalid enum"
175 if is_invalid_value then return "Invalid value"
176 if is_invalid_operation then return "Invalid operation"
177 if is_invalid_framebuffer_operation then return "invalid framebuffer operation"
178 if is_out_of_memory then return "Out of memory"
179 return "Truely unknown error"
180 end
181 end
182
183 protected fun gl_clear_color(r, g, b, a: Float) `{ glClearColor(r, g, b, a); `}
184 protected fun gl_viewport(x, y, width, height: Int) `{ glViewport(x, y, width, height); `}
185 protected fun gl_vertex_attrib_pointer_int(index, length: Int, normalize: Bool, stride: Int, vertex: Array[Int]) import Array[Int].length, Array[Int].intern_items `{
186 int* c_vertex = Array_of_Int_intern_items(vertex);
187 glVertexAttribPointer(index, length, GL_INT, normalize, stride, c_vertex);
188 `}
189 protected fun gl_vertex_attrib_pointer_float(index, length: Int, normalize: Bool, stride: Int, vertex: Array[Float]) import Array[Float].length, Array[Float].intern_items `{
190 int* c_vertex = Array_of_Float_intern_items(vertex);
191 glVertexAttribPointer(index, length, GL_FLOAT, normalize, stride, c_vertex);
192 `}
193
194 # Direct call to `glClear`, call with a combinaison of `gl_clear_color_buffer`,
195 # `gl_stencil_buffer_bit` and `gl_color_buffer_bit`.
196 private fun gl_clear(flag: Int) `{ glClear(flag); `}
197
198 protected fun gl_depth_buffer_bit: Int do return once "0100".to_hex
199 protected fun gl_stencil_buffer_bit: Int do return once "0400".to_hex
200 protected fun gl_color_buffer_bit: Int do return once "4000".to_hex
201
202 protected fun gl_clear_color_buffer do gl_clear(gl_color_buffer_bit)
203 protected fun gl_clear_depth_buffer do gl_clear(gl_depth_buffer_bit)
204 protected fun gl_clear_stencil_buffer do gl_clear(gl_stencil_buffer_bit)
205
206 protected fun gl_error: GLError `{ return glGetError(); `}
207 protected fun assert_no_gl_error
208 do
209 var error = gl_error
210 if not error.is_ok then
211 print "GL error: {error}"
212 abort
213 end
214 end
215
216 private fun gl_get_bool(key: Int): Bool `{
217 GLboolean val;
218 glGetBooleanv(GL_SHADER_COMPILER, &val);
219 return val == GL_TRUE;
220 `}
221 private fun gl_get_float(key: Int): Float `{
222 GLfloat val;
223 glGetFloatv(key, &val);
224 return val;
225 `}
226 private fun gl_get_int(key: Int): Int `{
227 GLint val;
228 glGetIntegerv(key, &val);
229 return val;
230 `}
231
232 fun gl_shader_compiler: Bool do return gl_get_bool("8DFA".to_hex)