--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# OpenGL graphics rendering library for embedded systems, version 2.0.
+#
+# Most services of this module are a direct wrapper of the underlying
+# C library. If a method or class is not documented in Nit, refer to
+# the official documentation by the Khronos Group at:
+# http://www.khronos.org/opengles/sdk/docs/man/
+module glesv2 is pkgconfig("glesv2")
+
+in "C Header" `{
+ #include <GLES2/gl2.h>
+`}
+
+# Opengl ES program to which we attach shaders
+extern class GLProgram `{GLuint`}
+ new `{ return glCreateProgram(); `}
+
+ fun is_ok: Bool `{ return glIsProgram(recv); `}
+
+ fun attach_shader(shader: GLShader) `{ glAttachShader(recv, shader); `}
+
+ fun bind_attrib_location(index: Int, name: String) import String.to_cstring `{
+ GLchar *c_name = String_to_cstring(name);
+ glBindAttribLocation(recv, index, c_name);
+ `}
+
+ fun attrib_location(name: String): Int import String.to_cstring `{
+ GLchar *c_name = String_to_cstring(name);
+ return glGetAttribLocation(recv, c_name);
+ `}
+
+ fun query(pname: Int): Int `{
+ int val;
+ glGetProgramiv(recv, pname, &val);
+ return val;
+ `}
+
+ fun link `{ glLinkProgram(recv); `}
+ fun is_linked: Bool do return query("8B82".to_hex) != 0
+
+ fun use `{ glUseProgram(recv); `}
+
+ fun delete `{ glDeleteProgram(recv); `}
+ fun is_deleted: Bool do return query("8B80".to_hex) != 0
+
+ fun validate `{ glValidateProgram(recv); `}
+ fun is_validated: Bool do return query("8B83".to_hex) != 0
+
+ fun info_log: String import NativeString.to_s `{
+ int size;
+ glGetProgramiv(recv, GL_INFO_LOG_LENGTH, &size);
+ GLchar *msg = malloc(size);
+ glGetProgramInfoLog(recv, size, NULL, msg);
+ return NativeString_to_s(msg);
+ `}
+end
+
+# Abstract OpenGL ES shader object, implemented by `GLFragmentShader` and `GLVertexShader`
+extern class GLShader `{GLuint`}
+ fun source=(code: String) import String.to_cstring, String.length `{
+ GLchar *c_code = String_to_cstring(code);
+ glShaderSource(recv, 1, (const GLchar * const*)&c_code, NULL);
+ `}
+ fun source: nullable String import NativeString.to_s `{
+ int size;
+ glGetShaderiv(recv, GL_SHADER_SOURCE_LENGTH, &size);
+ if (size == 0) return NULL;
+ GLchar *code = malloc(size);
+ glGetShaderSource(recv, size, NULL, code);
+ return NativeString_to_s(code);
+ `}
+
+ protected fun query(pname: Int): Int `{
+ int val;
+ glGetShaderiv(recv, pname, &val);
+ return val;
+ `}
+
+ fun compile `{ glCompileShader(recv); `}
+ fun is_compiled: Bool do return query("8B81".to_hex) != 0
+
+ fun delete `{ glDeleteShader(recv); `}
+ fun is_deleted: Bool do return query("8B80".to_hex) != 0
+
+ fun is_ok: Bool `{ return glIsShader(recv); `}
+
+ fun info_log: String import NativeString.to_s `{
+ int size;
+ glGetShaderiv(recv, GL_INFO_LOG_LENGTH, &size);
+ GLchar *msg = malloc(size);
+ glGetShaderInfoLog(recv, size, NULL, msg);
+ return NativeString_to_s(msg);
+ `}
+
+end
+
+extern class GLFragmentShader
+ super GLShader
+
+ new `{ return glCreateShader(GL_FRAGMENT_SHADER); `}
+end
+
+extern class GLVertexShader
+ super GLShader
+
+ new `{ return glCreateShader(GL_VERTEX_SHADER); `}
+end
+
+# An array of `Float` associated to a program variable
+class VertexArray
+ var index: Int
+ var count: Int
+ protected var glfloat_array: GLfloatArray
+
+ init(index, count: Int, array: Array[Float])
+ do
+ self.index = index
+ self.count = count
+ self.glfloat_array = new GLfloatArray(array)
+ end
+
+ fun attrib_pointer do attrib_pointer_intern(index, count, glfloat_array)
+ private fun attrib_pointer_intern(index, count: Int, array: GLfloatArray) `{
+ glVertexAttribPointer(index, count, GL_FLOAT, GL_FALSE, 0, array);
+ `}
+
+ fun enable do enable_intern(index)
+ private fun enable_intern(index: Int) `{ glEnableVertexAttribArray(index); `}
+
+ fun draw_arrays_triangles do draw_arrays_triangles_intern(index, count)
+ private fun draw_arrays_triangles_intern(index, count: Int) `{
+ glDrawArrays(GL_TRIANGLES, index, count);
+ `}
+end
+
+# Low level array of `Float`
+extern class GLfloatArray `{GLfloat *`}
+ new (array: Array[Float]) import Array[Float].length, Array[Float].[] `{
+ int i;
+ int len = Array_of_Float_length(array);
+ GLfloat *vertex_array = malloc(sizeof(GLfloat)*len);
+ for (i = 0; i < len; i ++) vertex_array[i] = Array_of_Float__index(array, i);
+ return vertex_array;
+ `}
+end
+
+extern class GLError `{ GLenum `}
+ fun is_ok: Bool do return is_no_error
+ fun is_no_error: Bool `{ return recv == GL_NO_ERROR; `}
+ fun is_invalid_enum: Bool `{ return recv == GL_INVALID_ENUM; `}
+ fun is_invalid_value: Bool `{ return recv == GL_INVALID_VALUE; `}
+ fun is_invalid_operation: Bool `{ return recv == GL_INVALID_OPERATION; `}
+ fun is_invalid_framebuffer_operation: Bool `{ return recv == GL_INVALID_FRAMEBUFFER_OPERATION; `}
+ fun is_out_of_memory: Bool `{ return recv == GL_OUT_OF_MEMORY; `}
+
+ redef fun to_s
+ do
+ if is_no_error then return "No error"
+ if is_invalid_enum then return "Invalid enum"
+ if is_invalid_value then return "Invalid value"
+ if is_invalid_operation then return "Invalid operation"
+ if is_invalid_framebuffer_operation then return "invalid framebuffer operation"
+ if is_out_of_memory then return "Out of memory"
+ return "Truely unknown error"
+ end
+end
+
+protected fun gl_clear_color(r, g, b, a: Float) `{ glClearColor(r, g, b, a); `}
+protected fun gl_viewport(x, y, width, height: Int) `{ glViewport(x, y, width, height); `}
+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 `{
+ int* c_vertex = Array_of_Int_intern_items(vertex);
+ glVertexAttribPointer(index, length, GL_INT, normalize, stride, c_vertex);
+`}
+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 `{
+ int* c_vertex = Array_of_Float_intern_items(vertex);
+ glVertexAttribPointer(index, length, GL_FLOAT, normalize, stride, c_vertex);
+`}
+
+# Direct call to `glClear`, call with a combinaison of `gl_clear_color_buffer`,
+# `gl_stencil_buffer_bit` and `gl_color_buffer_bit`.
+private fun gl_clear(flag: Int) `{ glClear(flag); `}
+
+protected fun gl_depth_buffer_bit: Int do return once "0100".to_hex
+protected fun gl_stencil_buffer_bit: Int do return once "0400".to_hex
+protected fun gl_color_buffer_bit: Int do return once "4000".to_hex
+
+protected fun gl_clear_color_buffer do gl_clear(gl_color_buffer_bit)
+protected fun gl_clear_depth_buffer do gl_clear(gl_depth_buffer_bit)
+protected fun gl_clear_stencil_buffer do gl_clear(gl_stencil_buffer_bit)
+
+protected fun gl_error: GLError `{ return glGetError(); `}
+protected fun assert_no_gl_error
+do
+ var error = gl_error
+ if not error.is_ok then
+ print "GL error: {error}"
+ abort
+ end
+end
+
+private fun gl_get_bool(key: Int): Bool `{
+ GLboolean val;
+ glGetBooleanv(GL_SHADER_COMPILER, &val);
+ return val == GL_TRUE;
+`}
+private fun gl_get_float(key: Int): Float `{
+ GLfloat val;
+ glGetFloatv(key, &val);
+ return val;
+`}
+private fun gl_get_int(key: Int): Int `{
+ GLint val;
+ glGetIntegerv(key, &val);
+ return val;
+`}
+
+fun gl_shader_compiler: Bool do return gl_get_bool("8DFA".to_hex)