├── ndll └── Linux64 │ └── ogl.ndll ├── samples ├── cube_texture.png ├── Makefile ├── Sample1.hx ├── Sample.hx ├── Sample2.hx ├── Sample3.hx ├── Sample5.hx ├── Sample4.hx └── Sample6.hx ├── include ├── gl.h └── utils.h ├── src ├── main.cpp └── gl.cpp ├── Makefile ├── haxelib.json ├── ogl ├── NativeBinding.hx ├── DebugDraw.hx ├── GLArray.hx ├── GLM.hx └── Macros.hx ├── Build.xml └── README.md /ndll/Linux64/ogl.ndll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deltaluca/hx-ogl/HEAD/ndll/Linux64/ogl.ndll -------------------------------------------------------------------------------- /samples/cube_texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deltaluca/hx-ogl/HEAD/samples/cube_texture.png -------------------------------------------------------------------------------- /include/gl.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "utils.h" 3 | #include 4 | 5 | extern "C" void gl_allocateKinds(); 6 | -------------------------------------------------------------------------------- /samples/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | haxe -neko Sample.n -main Sample -lib glfw3 -lib ogl -lib format 3 | neko Sample.n 4 | 5 | cpp: 6 | haxe -cpp bin -main Sample -lib glfw3 -lib ogl -lib format -D HXCPP_M64 7 | ./bin/Sample 8 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #define IMPLEMENT_API 2 | #define NEKO_COMPATIBLE 3 | #include 4 | 5 | #include "gl.h" 6 | 7 | extern "C" void hx_ogl_entry() { 8 | gl_allocateKinds(); 9 | } 10 | DEFINE_ENTRY_POINT(hx_ogl_entry); 11 | 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: haxelib 2 | haxe -x Testgl -lib ogl -D dump=pretty 3 | # cd bin && neko Main.n 4 | 5 | .PHONY: lib 6 | lib: 7 | haxelib run hxcpp Build.xml -DHXCPP_M64 8 | 9 | main: haxelib 10 | haxe -main Main.hx -cpp bin -D HXCPP_M64 -lib ogl -lib glfw3 -lib goodies -debug 11 | 12 | .PHONY: haxelib 13 | haxelib: lib 14 | rm -f ogl.zip 15 | zip -r ogl src ogl include ndll Build.xml haxelib.json samples -x \*samples/bin\* 16 | haxelib local ogl.zip 17 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ogl", 3 | "url": "https://github.com/deltaluca/hx-ogl", 4 | "license": "MIT", 5 | "tags": ["cpp","neko"], 6 | "description": "Bindings to OpenGL 3,x, partial GLM emulation.", 7 | "version": "0.2.0", 8 | "releasenote": "Added a DebugDraw utility for line/triangle debug drawings.", 9 | "contributors": ["deltaluca"], 10 | "dependencies": { 11 | "hxcpp": "", 12 | "goodies": "" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ogl/NativeBinding.hx: -------------------------------------------------------------------------------- 1 | package ogl; 2 | 3 | class NativeBinding { 4 | @:allow(ogl) 5 | var nativeObject:Dynamic; 6 | 7 | @:allow(ogl) 8 | function new(x:Dynamic) { 9 | nativeObject = x; 10 | } 11 | 12 | @:allow(ogl) 13 | inline static function generic(x:Null):Null { 14 | return if (x == null) null else new NativeBinding(x); 15 | } 16 | 17 | @:allow(ogl) 18 | static inline function native(object:Null):Null { 19 | return if (object == null) null else object.nativeObject; 20 | } 21 | 22 | @:allow(ogl) 23 | static inline function mapNative(objects:Null>>):Null>> { 24 | if (objects == null) return null; 25 | else { 26 | var ret = []; 27 | for (o in objects) ret.push(native(o)); 28 | return ret; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/Sample1.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import Sample; 4 | import ogl.GL; 5 | import ogl.GLM; 6 | import ogl.GLArray; 7 | 8 | class Sample1 { 9 | public function new() {} 10 | 11 | var vBuffer:GLuint; 12 | 13 | public function init() { 14 | var vData:GLfloatArray = [ 15 | [-1,-1,0], 16 | [ 1,-1,0], 17 | [ 0, 1,0], 18 | ]; 19 | vBuffer = GL.genBuffers(1)[0]; 20 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 21 | GL.bufferData(GL.ARRAY_BUFFER, vData, GL.STATIC_DRAW); 22 | 23 | return "The First Triangle"; 24 | } 25 | 26 | public function cleanup() { 27 | GL.deleteBuffers([vBuffer]); 28 | } 29 | 30 | public function render() { 31 | GL.clear(GL.COLOR_BUFFER_BIT); 32 | 33 | GL.enableVertexAttribArray(0); 34 | 35 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 36 | GL.vertexAttribPointer(0, 3, GL.FLOAT, false, 0, 0); 37 | 38 | GL.drawArrays(GL.TRIANGLES, 0, 3); 39 | 40 | GL.disableVertexAttribArray(0); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Build.xml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /samples/Sample.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import ogl.GL; 4 | import ogl.GLM; 5 | import ogl.GLArray; 6 | 7 | import glfw3.GLFW; 8 | 9 | typedef SampleNo = { 10 | public function init():String; 11 | public function cleanup():Void; 12 | public function render():Void; 13 | } 14 | 15 | class Sample { 16 | static var window:Window; 17 | 18 | static var samples:Array; 19 | static var curSample:SampleNo; 20 | 21 | static function loadSample(id:Int) { 22 | if (id < 0 || id >= samples.length) return; 23 | if (curSample != null) 24 | curSample.cleanup(); 25 | curSample = samples[id]; 26 | var title = curSample.init(); 27 | GLFW.setWindowTitle(window, 'Sample ${id+1}/${samples.length} : $title'); 28 | } 29 | 30 | static function main() { 31 | GLFW.setErrorCallback(function (i,e) throw(e)); 32 | GLFW.init(); 33 | GLFW.windowHint(GLFW.RESIZABLE, 0); 34 | window = GLFW.createWindow(800, 600, ""); 35 | GLFW.makeContextCurrent(window); 36 | GL.init(); 37 | 38 | samples = [ 39 | new Sample1(), 40 | new Sample2(), 41 | new Sample3(), 42 | new Sample4(), 43 | new Sample5(), 44 | new Sample6(), 45 | ]; 46 | loadSample(0); 47 | 48 | GLFW.setKeyCallback(window, function (_, key:Int, _, state:Int, _) { 49 | if (state == GLFW.PRESS) 50 | loadSample(key - GLFW.ONE); 51 | }); 52 | 53 | while (!GLFW.windowShouldClose(window)) { 54 | GLFW.pollEvents(); 55 | curSample.render(); 56 | GLFW.swapBuffers(window); 57 | } 58 | 59 | GLFW.destroyWindow(window); 60 | GLFW.terminate(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /samples/Sample2.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import Sample; 4 | import ogl.GL; 5 | import ogl.GLM; 6 | import ogl.GLArray; 7 | 8 | class Sample2 { 9 | public function new() {} 10 | 11 | var vBuffer:GLuint; 12 | var program:GLuint; 13 | 14 | public function init() { 15 | var vData:GLfloatArray = [ 16 | [-1,-1,0], 17 | [ 1,-1,0], 18 | [ 0, 1,0], 19 | ]; 20 | vBuffer = GL.genBuffers(1)[0]; 21 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 22 | GL.bufferData(GL.ARRAY_BUFFER, vData, GL.STATIC_DRAW); 23 | 24 | var vShader = GL.createShader(GL.VERTEX_SHADER); 25 | var fShader = GL.createShader(GL.FRAGMENT_SHADER); 26 | program = GL.createProgram(); 27 | 28 | GL.shaderSource(vShader, " 29 | #version 130 30 | in vec3 vPosition; 31 | void main() { 32 | gl_Position.xyz = vPosition; 33 | gl_Position.w = 1; 34 | } 35 | "); 36 | GL.shaderSource(fShader, " 37 | #version 130 38 | out vec3 colour; 39 | void main() { 40 | colour = vec3(1,0,0); 41 | } 42 | "); 43 | 44 | GL.compileShader(vShader); 45 | GL.compileShader(fShader); 46 | 47 | GL.attachShader(program, vShader); 48 | GL.attachShader(program, fShader); 49 | 50 | GL.bindAttribLocation(program, 0, "vPosition"); 51 | GL.linkProgram(program); 52 | 53 | GL.deleteShader(vShader); 54 | GL.deleteShader(fShader); 55 | 56 | return "The First Triangle, Coloured with Shaders"; 57 | } 58 | 59 | public function cleanup() { 60 | GL.deleteBuffers([vBuffer]); 61 | GL.deleteProgram(program); 62 | GL.useProgram(0); // back to fixed-function 63 | } 64 | 65 | public function render() { 66 | GL.clear(GL.COLOR_BUFFER_BIT); 67 | 68 | GL.useProgram(program); 69 | GL.enableVertexAttribArray(0); 70 | 71 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 72 | GL.vertexAttribPointer(0, 3, GL.FLOAT, false, 0, 0); 73 | 74 | GL.drawArrays(GL.TRIANGLES, 0, 3); 75 | 76 | GL.disableVertexAttribArray(0); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /samples/Sample3.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import Sample; 4 | import ogl.GL; 5 | import ogl.GLM; 6 | import ogl.GLArray; 7 | 8 | class Sample3 { 9 | public function new() {} 10 | 11 | var vBuffer:GLuint; 12 | var program:GLuint; 13 | var uMatrix:GLuint; 14 | 15 | public function init() { 16 | var vData:GLfloatArray = [ 17 | [-1,-1,0], 18 | [ 1,-1,0], 19 | [ 0, 1,0], 20 | ]; 21 | vBuffer = GL.genBuffers(1)[0]; 22 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 23 | GL.bufferData(GL.ARRAY_BUFFER, vData, GL.STATIC_DRAW); 24 | 25 | var vShader = GL.createShader(GL.VERTEX_SHADER); 26 | var fShader = GL.createShader(GL.FRAGMENT_SHADER); 27 | program = GL.createProgram(); 28 | 29 | GL.shaderSource(vShader, " 30 | #version 130 31 | in vec3 vPosition; 32 | uniform mat4 MVP; 33 | void main() { 34 | vec4 v = vec4(vPosition, 1); 35 | gl_Position = MVP * v; 36 | } 37 | "); 38 | GL.shaderSource(fShader, " 39 | #version 130 40 | out vec3 colour; 41 | void main() { 42 | colour = vec3(1,0,0); 43 | } 44 | "); 45 | 46 | GL.compileShader(vShader); 47 | GL.compileShader(fShader); 48 | 49 | GL.attachShader(program, vShader); 50 | GL.attachShader(program, fShader); 51 | 52 | GL.bindAttribLocation(program, 0, "vPosition"); 53 | GL.linkProgram(program); 54 | 55 | GL.deleteShader(vShader); 56 | GL.deleteShader(fShader); 57 | 58 | uMatrix = GL.getUniformLocation(program, "MVP"); 59 | 60 | return "The First Triangle, Transformed by Matrices"; 61 | } 62 | 63 | public function cleanup() { 64 | GL.deleteBuffers([vBuffer]); 65 | GL.deleteProgram(program); 66 | GL.useProgram(0); // back to fixed-function 67 | } 68 | 69 | public function render() { 70 | GL.clear(GL.COLOR_BUFFER_BIT); 71 | 72 | GL.useProgram(program); 73 | GL.enableVertexAttribArray(0); 74 | 75 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 76 | GL.vertexAttribPointer(0, 3, GL.FLOAT, false, 0, 0); 77 | 78 | var projection = Mat4.perspective(45, 4/3, 0.1, 100); 79 | var view = Mat4.lookAt([4,3,3], [0,0,0], [0,1,0]); 80 | var model = Mat4.identity(); 81 | var MVP = projection * view * model; 82 | GL.uniformMatrix4fv(uMatrix, false, MVP); 83 | 84 | GL.drawArrays(GL.TRIANGLES, 0, 3); 85 | 86 | GL.disableVertexAttribArray(0); 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /include/utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef UTILS_H 3 | #define UTILS_H 4 | #include 5 | #include 6 | 7 | 8 | 9 | typedef const char* string; 10 | 11 | 12 | 13 | // Parameterised allocs 14 | template 15 | static value alloc(T x) { neko_error(); } 16 | template <> 17 | inline value alloc(int x) { return alloc_int(x); } 18 | template <> 19 | inline value alloc(float x) { return alloc_float(x); } 20 | template <> 21 | inline value alloc(double x) { return alloc_float(x); } 22 | template <> 23 | inline value alloc(bool x) { return alloc_bool(x); } 24 | template <> 25 | inline value alloc(string x) { return alloc_string(x); } 26 | 27 | inline value alloc_double(float x) { return alloc(x); } 28 | inline value alloc_double(double x) { return alloc(x); } 29 | 30 | 31 | 32 | // Parameterised val_gets 33 | template 34 | T val_get(value x) { neko_error(); } 35 | template <> 36 | inline int val_get(value x) { 37 | if (val_is_int (x)) return val_int(x); 38 | if (val_is_float(x)) return (int)val_float(x); 39 | if (val_is_bool (x)) return (int)val_bool(x); 40 | neko_error(); 41 | return -1; 42 | } 43 | template <> 44 | inline double val_get(value x) { 45 | if (val_is_int (x)) return (double)val_int(x); 46 | if (val_is_float(x)) return val_float(x); 47 | if (val_is_bool (x)) return (double)val_bool(x); 48 | neko_error(); 49 | return -1; 50 | } 51 | template <> 52 | inline float val_get(value x) { 53 | double r = val_get(x); 54 | return r; 55 | } 56 | template <> 57 | inline string val_get(value x) { return val_get_string(x); } 58 | template <> 59 | inline bool val_get(value x) { return val_get_bool(x); } 60 | 61 | inline string safe_val_string(value x) { 62 | return val_is_null(x) ? NULL : val_get(x); 63 | } 64 | 65 | // Typical finalisation 66 | template 67 | void finaliser(value v) { 68 | T* ptr = (T*)val_data(v); 69 | delete ptr; 70 | } 71 | 72 | 73 | // Defining GL_# integer consts. 74 | #define PCONST(P, R, N) \ 75 | value hx_##P##_##N() { return alloc_int(R##_##N); } \ 76 | DEFINE_PRIM(hx_##P##_##N, 0) 77 | 78 | 79 | #define PGETPROP(P, N, M, I) \ 80 | value hx_##P##_##N##_get_##M(value v) { \ 81 | val_check_kind(v, k_##N); \ 82 | P::N* ptr = (P::N*)val_data(v); \ 83 | return alloc(ptr->M); \ 84 | } \ 85 | DEFINE_PRIM(hx_##P##_##N##_get_##M, 1) 86 | #define PSETPROP(P, N, M, I) \ 87 | value hx_##P##_##N##_set_##M(value v, value M) { \ 88 | val_check_kind(v, k_##N); \ 89 | P::N* ptr = (P::N*)val_data(v); \ 90 | return alloc(ptr->M = val_get(M)); \ 91 | } \ 92 | DEFINE_PRIM(hx_##P##_##N##_set_##M, 2) 93 | #define PPROP(P, N, M, I) \ 94 | PGETPROP(P, N, M, I); \ 95 | PSETPROP(P, N, M, I) 96 | 97 | 98 | // GLFW single version callbacks 99 | #define GLFWCALLBACK(N, G, P) \ 100 | void hx_glfw_##N(value cbfun) { \ 101 | if (hx_##N != NULL) { \ 102 | delete hx_##N; \ 103 | hx_##N = NULL; \ 104 | } \ 105 | if (val_is_null(cbfun)) \ 106 | glfw##G(NULL); \ 107 | else { \ 108 | val_check_function(cbfun, P); \ 109 | hx_##N = new AutoGCRoot(cbfun); \ 110 | glfw##G(bound_##N); \ 111 | } \ 112 | } \ 113 | DEFINE_PRIM(hx_glfw_##N, 1) 114 | 115 | #include 116 | 117 | // GLFW multiple version callbacks 118 | #define GLFWMULTIDECLARE(N) \ 119 | std::map hx_##N##_cbs 120 | #define GLFWMULTIFUNC(N, w) \ 121 | hx_##N##_cbs[w]->get() 122 | #define GLFWMULTIDEFINE(N, G) \ 123 | void hx_glfw_##N(value v, value cbfun) { \ 124 | GLFWwindow* w = (GLFWwindow*)val_data(v); \ 125 | if (hx_##N##_cbs.find(w) != hx_##N##_cbs.end()) { \ 126 | delete hx_##N##_cbs[w]; \ 127 | hx_##N##_cbs[w] = NULL; \ 128 | } \ 129 | if (val_is_null(cbfun)) { \ 130 | glfw##G(w, NULL); \ 131 | } \ 132 | else { \ 133 | hx_##N##_cbs[w] = new AutoGCRoot(cbfun); \ 134 | glfw##G(w, bound_##N); \ 135 | } \ 136 | } \ 137 | DEFINE_PRIM(hx_glfw_##N, 2) 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /samples/Sample5.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import Sample; 4 | import ogl.GL; 5 | import ogl.GLM; 6 | import ogl.GLArray; 7 | import sys.io.File; 8 | 9 | class Sample5 { 10 | public function new() {} 11 | 12 | var vBuffer:GLuint; 13 | var uvBuffer:GLuint; 14 | var texture:GLuint; 15 | var program:GLuint; 16 | var uMatrix:GLuint; 17 | 18 | public function init() { 19 | var vData:GLfloatArray = [ 20 | [-1, 1, 1],[-1, 1,-1],[-1,-1, 1], [-1, 1,-1],[-1,-1,-1],[-1,-1, 1], 21 | [-1, 1,-1],[ 1, 1,-1],[-1,-1,-1], [ 1, 1,-1],[ 1,-1,-1],[-1,-1,-1], 22 | [ 1, 1, 1],[ 1,-1, 1],[ 1, 1,-1], [ 1, 1,-1],[ 1,-1, 1],[ 1,-1,-1], 23 | [-1,-1, 1],[ 1, 1, 1],[-1, 1, 1], [-1,-1, 1],[ 1,-1, 1],[ 1, 1, 1], 24 | [-1, 1, 1],[ 1, 1,-1],[-1, 1,-1], [-1, 1, 1],[ 1, 1, 1],[ 1, 1,-1], 25 | [-1,-1,-1],[ 1,-1, 1],[-1,-1, 1], [-1,-1,-1],[ 1,-1,-1],[ 1,-1, 1], 26 | ]; 27 | vBuffer = GL.genBuffers(1)[0]; 28 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 29 | GL.bufferData(GL.ARRAY_BUFFER, vData, GL.STATIC_DRAW); 30 | 31 | var t = 1/3; var T = 2/3; 32 | var q = 1/4; var h = 1/2; var m = 3/4; 33 | var uvData:GLfloatArray = [ 34 | [q,t],[0,t],[q,T], [0,t],[0,T],[q,T], 35 | [1,t],[m,t],[1,T], [m,t],[m,T],[1,T], 36 | [h,t],[h,T],[m,t], [m,t],[h,T],[m,T], 37 | [q,T],[h,t],[q,t], [q,T],[h,T],[h,t], 38 | [q,t],[h,0],[q,0], [q,t],[h,t],[h,0], 39 | [q,1],[h,T],[q,T], [q,1],[h,1],[h,T], 40 | ]; 41 | uvBuffer = GL.genBuffers(1)[0]; 42 | GL.bindBuffer(GL.ARRAY_BUFFER, uvBuffer); 43 | GL.bufferData(GL.ARRAY_BUFFER, uvData, GL.STATIC_DRAW); 44 | 45 | var vShader = GL.createShader(GL.VERTEX_SHADER); 46 | var fShader = GL.createShader(GL.FRAGMENT_SHADER); 47 | program = GL.createProgram(); 48 | 49 | GL.shaderSource(vShader, " 50 | #version 130 51 | in vec3 vPosition; 52 | in vec2 vUV; 53 | uniform mat4 MVP; 54 | out vec2 fUV; 55 | void main() { 56 | vec4 v = vec4(vPosition, 1); 57 | gl_Position = MVP * v; 58 | fUV = vUV; 59 | } 60 | "); 61 | GL.shaderSource(fShader, " 62 | #version 130 63 | in vec2 fUV; 64 | uniform sampler2D tex; 65 | out vec3 colour; 66 | void main() { 67 | colour = texture(tex, fUV).rgb; 68 | } 69 | "); 70 | 71 | GL.compileShader(vShader); 72 | GL.compileShader(fShader); 73 | 74 | GL.attachShader(program, vShader); 75 | GL.attachShader(program, fShader); 76 | 77 | GL.bindAttribLocation(program, 0, "vPosition"); 78 | GL.bindAttribLocation(program, 1, "vUV"); 79 | GL.linkProgram(program); 80 | 81 | GL.deleteShader(vShader); 82 | GL.deleteShader(fShader); 83 | 84 | uMatrix = GL.getUniformLocation(program, "MVP"); 85 | 86 | GL.enable(GL.DEPTH_TEST); 87 | 88 | var file = File.read("cube_texture.png", true); 89 | var pngData = (new format.png.Reader(file)).read(); 90 | var data = format.png.Tools.extract32(pngData).getData(); 91 | var textureData:GLubyteArray = data; 92 | var pngHeader = format.png.Tools.getHeader(pngData); 93 | 94 | texture = GL.genTextures(1)[0]; 95 | GL.bindTexture(GL.TEXTURE_2D, texture); 96 | GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGB, pngHeader.width, pngHeader.height, 0, GL.BGRA, textureData); 97 | GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR); 98 | GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR_MIPMAP_LINEAR); 99 | GL.generateMipmap(GL.TEXTURE_2D); 100 | 101 | // reset animation. 102 | glfw3.GLFW.setTime(0); 103 | 104 | return "A Textured Cube"; 105 | } 106 | 107 | public function cleanup() { 108 | GL.deleteBuffers([vBuffer, uvBuffer]); 109 | GL.deleteProgram(program); 110 | GL.useProgram(0); // back to fixed-function 111 | GL.disable(GL.DEPTH_TEST); 112 | GL.deleteTextures([texture]); 113 | } 114 | 115 | public function render() { 116 | GL.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT); 117 | 118 | GL.useProgram(program); 119 | GL.enableVertexAttribArray(0); 120 | GL.enableVertexAttribArray(1); 121 | 122 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 123 | GL.vertexAttribPointer(0, 3, GL.FLOAT, false, 0, 0); 124 | GL.bindBuffer(GL.ARRAY_BUFFER, uvBuffer); 125 | GL.vertexAttribPointer(1, 2, GL.FLOAT, false, 0, 0); 126 | 127 | var projection = Mat4.perspective(45, 4/3, 0.1, 100); 128 | var view = Mat4.lookAt([4,3,3], [0,0,0], [0,1,0]); 129 | var t = glfw3.GLFW.getTime()/4; 130 | var s = Math.sin(t*3)*0.5+1; 131 | var model = Mat4.rotateX(t*-1)*Mat4.rotateY(t*3)*Mat4.rotateZ(t*-2)*Mat4.scale(s,s,s); 132 | var MVP = projection * view * model; 133 | GL.uniformMatrix4fv(uMatrix, false, MVP); 134 | 135 | GL.drawArrays(GL.TRIANGLES, 0, 12*3); 136 | 137 | GL.disableVertexAttribArray(0); 138 | GL.disableVertexAttribArray(1); 139 | } 140 | } 141 | 142 | -------------------------------------------------------------------------------- /samples/Sample4.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import Sample; 4 | import ogl.GL; 5 | import ogl.GLM; 6 | import ogl.GLArray; 7 | 8 | class Sample4 { 9 | public function new() {} 10 | 11 | var vBuffer:GLuint; 12 | var cBuffer:GLuint; 13 | var program:GLuint; 14 | var uMatrix:GLuint; 15 | 16 | public function init() { 17 | var vData:GLfloatArray = [ 18 | [-1, 1, 1],[-1, 1,-1],[-1,-1, 1], [-1, 1,-1],[-1,-1,-1],[-1,-1, 1], 19 | [-1, 1,-1],[ 1, 1,-1],[-1,-1,-1], [ 1, 1,-1],[ 1,-1,-1],[-1,-1,-1], 20 | [ 1, 1, 1],[ 1,-1, 1],[ 1, 1,-1], [ 1, 1,-1],[ 1,-1, 1],[ 1,-1,-1], 21 | [-1,-1, 1],[ 1, 1, 1],[-1, 1, 1], [-1,-1, 1],[ 1,-1, 1],[ 1, 1, 1], 22 | [-1, 1, 1],[ 1, 1,-1],[-1, 1,-1], [-1, 1, 1],[ 1, 1, 1],[ 1, 1,-1], 23 | [-1,-1,-1],[ 1,-1, 1],[-1,-1, 1], [-1,-1,-1],[ 1,-1,-1],[ 1,-1, 1], 24 | ]; 25 | vBuffer = GL.genBuffers(1)[0]; 26 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 27 | GL.bufferData(GL.ARRAY_BUFFER, vData, GL.STATIC_DRAW); 28 | 29 | var cData:GLfloatArray = [ 30 | [0.583, 0.771, 0.014], 31 | [0.609, 0.115, 0.436], 32 | [0.327, 0.483, 0.844], 33 | [0.822, 0.569, 0.201], 34 | [0.435, 0.602, 0.223], 35 | [0.310, 0.747, 0.185], 36 | [0.597, 0.770, 0.761], 37 | [0.559, 0.436, 0.730], 38 | [0.359, 0.583, 0.152], 39 | [0.483, 0.596, 0.789], 40 | [0.559, 0.861, 0.639], 41 | [0.195, 0.548, 0.859], 42 | [0.014, 0.184, 0.576], 43 | [0.771, 0.328, 0.970], 44 | [0.406, 0.615, 0.116], 45 | [0.676, 0.977, 0.133], 46 | [0.971, 0.572, 0.833], 47 | [0.140, 0.616, 0.489], 48 | [0.997, 0.513, 0.064], 49 | [0.945, 0.719, 0.592], 50 | [0.543, 0.021, 0.978], 51 | [0.279, 0.317, 0.505], 52 | [0.167, 0.620, 0.077], 53 | [0.347, 0.857, 0.137], 54 | [0.055, 0.953, 0.042], 55 | [0.714, 0.505, 0.345], 56 | [0.783, 0.290, 0.734], 57 | [0.722, 0.645, 0.174], 58 | [0.302, 0.455, 0.848], 59 | [0.225, 0.587, 0.040], 60 | [0.517, 0.713, 0.338], 61 | [0.053, 0.959, 0.120], 62 | [0.393, 0.621, 0.362], 63 | [0.673, 0.211, 0.457], 64 | [0.820, 0.883, 0.371], 65 | [0.982, 0.099, 0.879], 66 | ]; 67 | cBuffer = GL.genBuffers(1)[0]; 68 | GL.bindBuffer(GL.ARRAY_BUFFER, cBuffer); 69 | GL.bufferData(GL.ARRAY_BUFFER, cData, GL.STATIC_DRAW); 70 | 71 | var vShader = GL.createShader(GL.VERTEX_SHADER); 72 | var fShader = GL.createShader(GL.FRAGMENT_SHADER); 73 | program = GL.createProgram(); 74 | 75 | GL.shaderSource(vShader, " 76 | #version 130 77 | in vec3 vPosition; 78 | in vec3 vColour; 79 | uniform mat4 MVP; 80 | out vec3 fColour; 81 | void main() { 82 | vec4 v = vec4(vPosition, 1); 83 | gl_Position = MVP * v; 84 | fColour = vColour; 85 | } 86 | "); 87 | GL.shaderSource(fShader, " 88 | #version 130 89 | in vec3 fColour; 90 | out vec3 colour; 91 | void main() { 92 | colour = fColour; 93 | } 94 | "); 95 | 96 | GL.compileShader(vShader); 97 | GL.compileShader(fShader); 98 | 99 | GL.attachShader(program, vShader); 100 | GL.attachShader(program, fShader); 101 | 102 | GL.bindAttribLocation(program, 0, "vPosition"); 103 | GL.bindAttribLocation(program, 1, "vColour"); 104 | GL.linkProgram(program); 105 | 106 | GL.deleteShader(vShader); 107 | GL.deleteShader(fShader); 108 | 109 | uMatrix = GL.getUniformLocation(program, "MVP"); 110 | 111 | GL.enable(GL.DEPTH_TEST); 112 | 113 | // reset animation. 114 | glfw3.GLFW.setTime(0); 115 | 116 | return "A Coloured Cube"; 117 | } 118 | 119 | public function cleanup() { 120 | GL.deleteBuffers([vBuffer, cBuffer]); 121 | GL.deleteProgram(program); 122 | GL.useProgram(0); // back to fixed-function 123 | GL.disable(GL.DEPTH_TEST); 124 | } 125 | 126 | public function render() { 127 | GL.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT); 128 | 129 | GL.useProgram(program); 130 | GL.enableVertexAttribArray(0); 131 | GL.enableVertexAttribArray(1); 132 | 133 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 134 | GL.vertexAttribPointer(0, 3, GL.FLOAT, false, 0, 0); 135 | GL.bindBuffer(GL.ARRAY_BUFFER, cBuffer); 136 | GL.vertexAttribPointer(1, 3, GL.FLOAT, false, 0, 0); 137 | 138 | var projection = Mat4.perspective(45, 4/3, 0.1, 100); 139 | var view = Mat4.lookAt([4,3,3], [0,0,0], [0,1,0]); 140 | var t = glfw3.GLFW.getTime()/4; 141 | var model = Mat4.rotateX(t*-3)*Mat4.rotateY(t*1)*Mat4.rotateZ(t*2); 142 | var MVP = projection * view * model; 143 | GL.uniformMatrix4fv(uMatrix, false, MVP); 144 | 145 | GL.drawArrays(GL.TRIANGLES, 0, 12*3); 146 | 147 | GL.disableVertexAttribArray(0); 148 | GL.disableVertexAttribArray(1); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /ogl/DebugDraw.hx: -------------------------------------------------------------------------------- 1 | package ogl; 2 | 3 | import ogl.GLM; 4 | import ogl.GL; 5 | import ogl.GLArray; 6 | 7 | class DebugDraw { 8 | 9 | static inline var VERTEX_SIZE = 7; // xyz rgba 10 | 11 | var lineMode:Bool = true; // true when drawing lines, false when drawing triangles. 12 | var vertexData:GLfloatArray; 13 | var numVertices:Int = 0; 14 | 15 | var vertexArray:GLuint; 16 | var vertexBuffer:GLuint; 17 | var program:GLuint; 18 | var projUniform:GLuint; 19 | 20 | public function new(textured=false) { 21 | vertexData = GL.allocBuffer(GL.FLOAT, VERTEX_SIZE*6); // 6 = lcf(line=2 verts, tri=3 verts) 22 | vertexArray = GL.genVertexArrays(1)[0]; 23 | GL.bindVertexArray(vertexArray); 24 | 25 | vertexBuffer = GL.genBuffers(1)[0]; 26 | GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); 27 | GL.bufferData(GL.ARRAY_BUFFER, vertexData, GL.STREAM_DRAW); 28 | 29 | var vertexShader = GL.createShader(GL.VERTEX_SHADER); 30 | var fragmentShader = GL.createShader(GL.FRAGMENT_SHADER); 31 | if (textured) { 32 | GL.shaderSource(vertexShader, " 33 | #version 130 34 | in vec3 vPos; 35 | in vec4 vColour; 36 | uniform mat4 proj; 37 | out vec4 uv_a; 38 | void main() { 39 | gl_Position = proj * vec4(vPos, 1); 40 | uv_a = vColour; 41 | } 42 | "); 43 | GL.shaderSource(fragmentShader, " 44 | #version 130 45 | in vec4 uv_a; 46 | out vec4 outColour; 47 | uniform sampler2D tex; 48 | void main() { 49 | outColour = vec4(texture(tex, uv_a.xy).rgb,uv_a.a); 50 | } 51 | "); 52 | } 53 | else { 54 | GL.shaderSource(vertexShader, " 55 | #version 130 56 | in vec3 vPos; 57 | in vec4 vColour; 58 | uniform mat4 proj; 59 | out vec4 colour; 60 | void main() { 61 | gl_Position = proj * vec4(vPos, 1); 62 | colour = vColour; 63 | } 64 | "); 65 | GL.shaderSource(fragmentShader, " 66 | #version 130 67 | in vec4 colour; 68 | out vec4 outColour; 69 | void main() { 70 | outColour = colour; 71 | } 72 | "); 73 | } 74 | GL.compileShader(vertexShader); 75 | GL.compileShader(fragmentShader); 76 | 77 | program = GL.createProgram(); 78 | GL.attachShader(program, vertexShader); 79 | GL.attachShader(program, fragmentShader); 80 | GL.bindAttribLocation(program, 0, "vPos"); 81 | GL.bindAttribLocation(program, 1, "vColour"); 82 | GL.linkProgram(program); 83 | 84 | GL.deleteShader(vertexShader); 85 | GL.deleteShader(fragmentShader); 86 | 87 | projUniform = GL.getUniformLocation(program, "proj"); 88 | } 89 | 90 | public function destroy() { 91 | GL.deleteProgram(program); 92 | GL.deleteVertexArrays([vertexArray]); 93 | GL.deleteBuffers([vertexBuffer]); 94 | } 95 | 96 | inline function vertex(vindex:Int, off:Int, p:Vec3, c:Vec4, dup=false) { 97 | vindex += off*VERTEX_SIZE; 98 | vertexData.subDataVec(p, vindex); 99 | vertexData.subDataVec(c, vindex+3); 100 | if (dup) { 101 | vertexData.subDataVec(p, vindex+VERTEX_SIZE); 102 | vertexData.subDataVec(c, vindex+VERTEX_SIZE+3); 103 | } 104 | } 105 | 106 | public inline function swapLines() { 107 | if (!lineMode) flush(); 108 | lineMode = true; 109 | } 110 | public inline function swapFills() { 111 | if (lineMode) flush(); 112 | lineMode = false; 113 | } 114 | 115 | public inline function pushVertex(p:Vec3, c:Vec4) { 116 | var vindex = reserve(1); 117 | vertex(vindex, 0, p, c); 118 | } 119 | public inline function pushData(xs:Array) { 120 | var vindex = reserve(Std.int(xs.length/VERTEX_SIZE)); 121 | vertexData.subData(xs, vindex); 122 | } 123 | 124 | public inline function drawLine(p0:Vec3, p1:Vec3, c:Vec4) { 125 | swapLines(); 126 | pushData([p0.x,p0.y,p0.z, c.r,c.g,c.b,c.a, 127 | p1.x,p1.y,p1.z, c.r,c.g,c.b,c.a]); 128 | } 129 | 130 | public function drawDashedLine(p0:Vec3, p1:Vec3, c:Vec4, solidLength:Float, gapLength:Float) { 131 | var dt = Vec3.distance(p0, p1); 132 | var del = Vec3.normalise(p1 - p0); 133 | var d = 0.0; 134 | var p = p0; 135 | while (d < dt) { 136 | var dp = d + solidLength; 137 | if (dp > dt) dp = dt; 138 | drawLine(p0 + del*d, p0 + del*dp, c); 139 | d = dp; 140 | if (d >= dt) break; 141 | var dp = d + gapLength; 142 | if (dp > dt) dp = dt; 143 | d = dp; 144 | if (d >= dt) break; 145 | } 146 | } 147 | 148 | inline function reserve(numVerts:Int) { 149 | var current = numVertices * VERTEX_SIZE; 150 | var newsize = current + (numVerts * VERTEX_SIZE); 151 | if (newsize > vertexData.count) { 152 | var size = vertexData.count; 153 | do size *= 2 while (size < newsize); 154 | vertexData.resize(size); 155 | GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); 156 | GL.bufferData(GL.ARRAY_BUFFER, vertexData, GL.STREAM_DRAW); 157 | } 158 | numVertices += numVerts; 159 | return current; 160 | } 161 | 162 | public function clear() { 163 | numVertices = 0; 164 | return this; 165 | } 166 | 167 | public function begin(texture:GLuint=-1) { 168 | GL.useProgram(program); 169 | GL.enableVertexAttribArray(0); 170 | GL.enableVertexAttribArray(1); 171 | if (texture != -1) GL.bindTexture(GL.TEXTURE_2D, texture); 172 | 173 | GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); 174 | GL.vertexAttribPointer(0, 3, GL.FLOAT, false, VERTEX_SIZE*4, 0); 175 | GL.vertexAttribPointer(1, 4, GL.FLOAT, false, VERTEX_SIZE*4, 3*4); 176 | return this; 177 | } 178 | 179 | public function setTransform(mat:Mat4,dontClear=false) { 180 | flush(dontClear); 181 | GL.uniformMatrix4fv(projUniform, false, mat); 182 | return this; 183 | } 184 | 185 | public function flush(dontClear=false) { 186 | if (numVertices == 0) return this; 187 | 188 | GL.bufferSubData(GL.ARRAY_BUFFER, 0, GLfloatArray.view(vertexData, 0, numVertices*VERTEX_SIZE)); 189 | GL.drawArrays(lineMode ? GL.LINES : GL.TRIANGLES, 0, numVertices); 190 | 191 | if (!dontClear) 192 | clear(); 193 | return this; 194 | } 195 | 196 | public function end(dontClear=false) { 197 | flush(dontClear); 198 | GL.disableVertexAttribArray(0); 199 | GL.disableVertexAttribArray(1); 200 | return this; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /samples/Sample6.hx: -------------------------------------------------------------------------------- 1 | package; 2 | 3 | import Sample; 4 | import ogl.GL; 5 | import ogl.GLM; 6 | import ogl.GLArray; 7 | import sys.io.File; 8 | 9 | class Sample6 { 10 | public function new() {} 11 | 12 | var vBuffer:GLuint; 13 | var uvBuffer:GLuint; 14 | var nBuffer:GLuint; 15 | var texture:GLuint; 16 | var program:GLuint; 17 | 18 | var uMVP:GLuint; 19 | var uMVit:GLuint; 20 | var uM:GLuint; 21 | var ulpos:GLuint; 22 | 23 | public function init() { 24 | var vData:GLfloatArray = [ 25 | [-1, 1, 1],[-1, 1,-1],[-1,-1, 1], [-1, 1,-1],[-1,-1,-1],[-1,-1, 1], 26 | [-1, 1,-1],[ 1, 1,-1],[-1,-1,-1], [ 1, 1,-1],[ 1,-1,-1],[-1,-1,-1], 27 | [ 1, 1, 1],[ 1,-1, 1],[ 1, 1,-1], [ 1, 1,-1],[ 1,-1, 1],[ 1,-1,-1], 28 | [-1,-1, 1],[ 1, 1, 1],[-1, 1, 1], [-1,-1, 1],[ 1,-1, 1],[ 1, 1, 1], 29 | [-1, 1, 1],[ 1, 1,-1],[-1, 1,-1], [-1, 1, 1],[ 1, 1, 1],[ 1, 1,-1], 30 | [-1,-1,-1],[ 1,-1, 1],[-1,-1, 1], [-1,-1,-1],[ 1,-1,-1],[ 1,-1, 1], 31 | ]; 32 | vBuffer = GL.genBuffers(1)[0]; 33 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 34 | GL.bufferData(GL.ARRAY_BUFFER, vData, GL.STATIC_DRAW); 35 | 36 | var t = 1/3; var T = 2/3; 37 | var q = 1/4; var h = 1/2; var m = 3/4; 38 | var uvData:GLfloatArray = [ 39 | [q,t],[0,t],[q,T], [0,t],[0,T],[q,T], 40 | [1,t],[m,t],[1,T], [m,t],[m,T],[1,T], 41 | [h,t],[h,T],[m,t], [m,t],[h,T],[m,T], 42 | [q,T],[h,t],[q,t], [q,T],[h,T],[h,t], 43 | [q,t],[h,0],[q,0], [q,t],[h,t],[h,0], 44 | [q,1],[h,T],[q,T], [q,1],[h,1],[h,T], 45 | ]; 46 | uvBuffer = GL.genBuffers(1)[0]; 47 | GL.bindBuffer(GL.ARRAY_BUFFER, uvBuffer); 48 | GL.bufferData(GL.ARRAY_BUFFER, uvData, GL.STATIC_DRAW); 49 | 50 | var n0 = [-1,0,0]; var n1 = [0,0,-1]; var n2 = [1, 0,0]; 51 | var n3 = [ 0,0,1]; var n4 = [0,1, 0]; var n5 = [0,-1,0]; 52 | var nData:GLfloatArray = [ 53 | n0,n0,n0, n0,n0,n0, 54 | n1,n1,n1, n1,n1,n1, 55 | n2,n2,n2, n2,n2,n2, 56 | n3,n3,n3, n3,n3,n3, 57 | n4,n4,n4, n4,n4,n4, 58 | n5,n5,n5, n5,n5,n5, 59 | ]; 60 | nBuffer = GL.genBuffers(1)[0]; 61 | GL.bindBuffer(GL.ARRAY_BUFFER, nBuffer); 62 | GL.bufferData(GL.ARRAY_BUFFER, nData, GL.STATIC_DRAW); 63 | 64 | var vShader = GL.createShader(GL.VERTEX_SHADER); 65 | var fShader = GL.createShader(GL.FRAGMENT_SHADER); 66 | program = GL.createProgram(); 67 | 68 | GL.shaderSource(vShader, " 69 | #version 130 70 | in vec3 vPosition; 71 | in vec2 vUV; 72 | in vec3 vNormal; 73 | uniform mat4 MVP; 74 | uniform mat4 MVit; 75 | uniform mat4 M; 76 | out vec2 fUV; 77 | out vec3 fnormal; 78 | out vec3 fpos; 79 | void main() { 80 | vec4 v = vec4(vPosition, 1); 81 | gl_Position = MVP * v; 82 | fUV = vUV; 83 | fnormal = normalize((MVit * vec4(vNormal,0)).xyz); 84 | fpos = (M * v).xyz; 85 | } 86 | "); 87 | GL.shaderSource(fShader, " 88 | #version 130 89 | in vec2 fUV; 90 | in vec3 fnormal; 91 | in vec3 fpos; 92 | uniform vec3 lpos; 93 | uniform sampler2D tex; 94 | out vec3 colour; 95 | void main() { 96 | vec3 l = lpos - fpos; 97 | float dist = length(l); 98 | l = normalize(l); 99 | float cosTheta = clamp(dot(fnormal, l), 0, 1); 100 | colour = texture(tex, fUV).rgb * (cosTheta * 4 / (dist * dist) + 0.1); 101 | } 102 | "); 103 | 104 | GL.compileShader(vShader); 105 | GL.compileShader(fShader); 106 | 107 | GL.attachShader(program, vShader); 108 | GL.attachShader(program, fShader); 109 | 110 | GL.bindAttribLocation(program, 0, "vPosition"); 111 | GL.bindAttribLocation(program, 1, "vUV"); 112 | GL.bindAttribLocation(program, 2, "vNormal"); 113 | GL.linkProgram(program); 114 | 115 | GL.deleteShader(vShader); 116 | GL.deleteShader(fShader); 117 | 118 | uMVP = GL.getUniformLocation(program, "MVP"); 119 | uMVit = GL.getUniformLocation(program, "MVit"); 120 | uM = GL.getUniformLocation(program, "M"); 121 | ulpos = GL.getUniformLocation(program, "lpos"); 122 | 123 | GL.enable(GL.DEPTH_TEST); 124 | 125 | var file = File.read("cube_texture.png", true); 126 | var pngData = (new format.png.Reader(file)).read(); 127 | var textureData:GLubyteArray = format.png.Tools.extract32(pngData).getData(); 128 | var pngHeader = format.png.Tools.getHeader(pngData); 129 | 130 | texture = GL.genTextures(1)[0]; 131 | GL.bindTexture(GL.TEXTURE_2D, texture); 132 | GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGB, pngHeader.width, pngHeader.height, 0, GL.BGRA, textureData); 133 | GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR); 134 | GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR_MIPMAP_LINEAR); 135 | GL.generateMipmap(GL.TEXTURE_2D); 136 | 137 | // reset animation. 138 | glfw3.GLFW.setTime(0); 139 | 140 | return "A Shaded Cube"; 141 | } 142 | 143 | public function cleanup() { 144 | GL.deleteBuffers([vBuffer, uvBuffer, nBuffer]); 145 | GL.deleteProgram(program); 146 | GL.useProgram(0); // back to fixed-function 147 | GL.disable(GL.DEPTH_TEST); 148 | GL.deleteTextures([texture]); 149 | } 150 | 151 | public function render() { 152 | GL.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT); 153 | 154 | GL.useProgram(program); 155 | GL.enableVertexAttribArray(0); 156 | GL.enableVertexAttribArray(1); 157 | GL.enableVertexAttribArray(2); 158 | 159 | GL.bindBuffer(GL.ARRAY_BUFFER, vBuffer); 160 | GL.vertexAttribPointer(0, 3, GL.FLOAT, false, 0, 0); 161 | GL.bindBuffer(GL.ARRAY_BUFFER, uvBuffer); 162 | GL.vertexAttribPointer(1, 2, GL.FLOAT, false, 0, 0); 163 | GL.bindBuffer(GL.ARRAY_BUFFER, nBuffer); 164 | GL.vertexAttribPointer(2, 3, GL.FLOAT, false, 0, 0); 165 | 166 | var projection = Mat4.perspective(45, 4/3, 0.1, 100); 167 | var view = Mat4.lookAt([4,3,3], [0,0,0], [0,1,0]); 168 | 169 | var t = glfw3.GLFW.getTime()/4; 170 | var s = Math.sin(t*3)*0.5+1; 171 | var model = Mat4.rotateX(t*-1)*Mat4.rotateY(t*3)*Mat4.rotateZ(t*-2)*Mat4.scale(s,s,s); 172 | 173 | GL.uniformMatrix4fv(uMVP, false, projection * view * model); 174 | GL.uniformMatrix4fv(uMVit, false, (view * model).inverse().transpose()); 175 | GL.uniformMatrix4fv(uM, false, model); 176 | 177 | var s = Math.sin(t*2)*0.5+3; 178 | var model = Mat4.rotateX(t*2)*Mat4.rotateY(t*-1)*Mat4.rotateZ(t*3)*Mat4.scale(s,s,s); 179 | GL.uniform3fv(ulpos, GLfloatArray.view(model, 0, 3)); 180 | 181 | GL.drawArrays(GL.TRIANGLES, 0, 12*3); 182 | 183 | GL.disableVertexAttribArray(0); 184 | GL.disableVertexAttribArray(1); 185 | GL.disableVertexAttribArray(2); 186 | } 187 | } 188 | 189 | 190 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Haxe-c++ bindings for OpenGL 3.3+ 2 | 3 | This is incredibly early alpha I suppose, I am not at this time intending myself to fully 4 | support the entirety of the API, and the API that is supported will not have been 5 | thoroughly tested if at all. 6 | 7 | Anyone wishing to use OpenGL 3,x in hxcpp/neko should consider testing and submitting pull requests :) 8 | 9 | #### Table of Contents 10 | - [API Changes to OpenGL](#API Changes to OpenGL) 11 | - [GLArray](#GLArray) WebGL style typed arrays for GL data. 12 | - [GLM](#GLM) Vector/Matrix types emulating subset of GLSL types (As per GLM library) 13 | - [DebugDraw](#DebugDraw) Utility for line/triangle drawing for debug purposes. 14 | 15 | 16 | #### API Changes to OpenGL. 17 | 18 | Major change, is that unless -D ogl-dont-check-errors is set, every GL call will call glGetError to look for errors 19 | and if found, will be thrown in Haxe. This is also true of things like glCompileShader, glLinkProgram which will check 20 | for success and throw with the error message given otherwise. 21 | 22 | Most of the API is unchanged, the most common change is replacing instances of an 'out' pointer argument with a return value. 23 | 24 | eg: 25 | ``` 26 | // C 27 | GLuint textures[10]; 28 | GLint data; 29 | glGenTextures(10, textures); 30 | glGetBufferParameteriv(target, value, &data); 31 | 32 | // Haxe 33 | var textures = GL.genTextures(10); 34 | var data = GL.getBufferParameteriv(target, value); 35 | ``` 36 | 37 | Most other changes regard uses of GLvoid* data buffers and arrays of GLbyte/GLshort/GLfloat, these are replaced by uses of GLArray in hx-ogl which roughly mimics WebGL TypedArrays 38 | 39 | ``` 40 | // C 41 | // GLvoid* data 42 | // size/offset in bytes 43 | glBufferData(target, size, data, usage); 44 | glBufferSubData(target, offset, size, data); 45 | glTexImage1D(target, level, internalFormat, width, border, format, type, data); 46 | 47 | // Haxe 48 | // data : GLArray 49 | // size is determined by the array, and offset is in 'element' counts. 50 | // i.e. if data type is GL_FLOAT, then a Haxe offset of 1xGL_FLOAT is a C offset of 4 bytes 51 | GL.bufferData(target, data, usage); 52 | GL.bufferSubData(target, offset, data); 53 | // GL data type is given by the array 54 | GL.texImage1D(target, level, internalFormat, width, border, format, data); 55 | ``` 56 | 57 | 58 | #### GLArray 59 | 60 | GLArray is the underlying type of the (abstract) typed arrays: 61 | * GLubyteArray 62 | * GLbyteArray 63 | * GLushortArray 64 | * GLshortArray 65 | * GLuintArray -- normally, functions will work with Array instead 66 | * GLintArray -- normally, functions will work with Array instead 67 | * GLfloatArray 68 | * GLdoubleArray -- normally, functions will work with Array instead 69 | 70 | All of these share the same interface: 71 | ``` 72 | // produce typed array using given data as storage 73 | function new(raw:haxe.io.BytesData) 74 | 75 | // for implict casting of BytesData to a typed array 76 | @:from static function fromRaw(raw:BytesData):GL#Array 77 | 78 | // for implict casting of an Array of values to typed array 79 | // Supports nested arrays that will be flattened so that 80 | // [[1,2],[3,4,5],6,7] is treat equally to [1,2,3,4,5,6,7] 81 | // similar to GLSL vector constructors. 82 | @:from static function fromArr(arr:Array):GL#Array 83 | 84 | // create typed array with space for 'count' elements 85 | static function alloc(count:Int):GL#Array 86 | 87 | // create a view onto an existing array 88 | // starting at 'byteOffset' in the BytesData 89 | // looking at 'count' elements 90 | static function view(arr:GLArray, byteOffset:Int, count:Int):GL#Array 91 | 92 | // size of a data element in this array 93 | public var size(get,never):Int; 94 | 95 | // access to raw BytesData associated with typed array 96 | // a view on a particular array will have the same raw value as the original 97 | public var raw(get,never):BytesData; 98 | 99 | // number of elements viewed by array 100 | public var count(get,never):BytesData 101 | 102 | // access element at index 'i' 103 | // set element at index 'i' 104 | @:arrayAccess public function get(i:Int):# ; 105 | @:arrayAccess public function set(i:Int, val:#):#; 106 | 107 | // resize the raw data storage for this array 108 | // this can be called on views, and resizes the underlying data store. 109 | // data will be copied. 110 | public function resize(count:Int):Void; 111 | ``` 112 | 113 | Example: 114 | ``` 115 | var vertex_data:GLfloatArray = [ 116 | [-1,1,1],[-1,1,1-1],[-1,-1,1], 117 | [-1,1,-1],[1,1,-1],[-1,-1,-1] 118 | ]; 119 | var vertex_buffer = GL.genBuffers(1)[0]; 120 | GL.bindBuffer(GL.ARRAY_BUFFER, vertex_buffer); 121 | GL.bufferData(GL.ARRAY_BUFFER, vertex_data, GL.DYNAMIC_DRAW); 122 | 123 | // update first 3 vertices from vertex_data 124 | GL.bufferSubData(GL.ARRAY_BUFFER, 0, GLfloatArray.view(vertex_data, 0, 3)); 125 | // update second 3 vertices from vertex_data 126 | GL.bufferSubData(GL.ARRAY_BUFFER, 3, GLfloatArray.view(vertex_data, 3*vertex_data.size, 3)); 127 | ``` 128 | 129 | 130 | #### GLM 131 | 132 | Inspired by the GLM library, emulating GLSL vector/matrix types and behaviours in C, there are some equivalent types in hx-ogl 133 | for float vector types, and float matrix types based on GLfloatArray 134 | ``` 135 | var cameraPos:Vec3 = [100,40,20]; 136 | var model = Mat4.rotateX(Math.PI); 137 | var view = Mat4.lookAt(cameraPos, [0,0,0]); 138 | var proj = Mat4.perspective(45, 4/3, 0.1, 1000); 139 | GL.uniformMatrix4fv(matrixID, false, proj * view * model); 140 | ``` 141 | 142 | 143 | #### DebugDraw 144 | 145 | Utility for drawing lines/triangles with OGL. 146 | ``` 147 | // Construct new DebugDraw instance. 148 | // If 'textured' is true, then fragment colours are chosen from a 1D texture using the 149 | // 'red' component of a vertex colour, with vertex 'alpha' used, and 'green'/'blue' ignored. 150 | function new(textured:Bool=false) 151 | 152 | // Release GL buffers/arrays/programs 153 | function destroy():Void 154 | 155 | // Draw a solid line 156 | function drawLine(p0:Vec3, p1:Vec3, colour:Vec4):Void; 157 | 158 | // Draw a dashed line 159 | function drawDashedLine(p0:Vec3, p1:Vec3, colour:Vec4, solidLength:Float, gapLength:Float):Void; 160 | 161 | // Begin drawing, must be called before setting transform 162 | function begin(texture:GLuint=-1):Void; 163 | 164 | // Flush any currently buffered calls to GPU 165 | function flush():Void; 166 | 167 | // End drawing, any buffered calls will be flushed. 168 | function end():Void; 169 | 170 | // Clear any currently buffered calls 171 | function clear():Void; 172 | 173 | // Set transform for next batch of calls, any currently buffered calls will be flushed. 174 | function setTransform(mat:Mat4):Void; 175 | ``` 176 | 177 | The following are for manual drawing of geometry: 178 | ``` 179 | // Swap to line rendering mode, any currently buffered triangle geom. will be flushed. 180 | function swapLines():Void; 181 | 182 | // Swap to triangle rendering mode, any currently buffered line geom. will be flushed. 183 | function swapFills():Void; 184 | 185 | // Push a single vertex into geom. buffer. 186 | function pushVertex(p:Vec3, colour:Vec4):Void; 187 | 188 | // Push a sequence of vertex data into geom. buffer. 189 | // [p, c, p, c, p, c, ...] 190 | function pushData(xs:Array):Void; 191 | ``` 192 | -------------------------------------------------------------------------------- /ogl/GLArray.hx: -------------------------------------------------------------------------------- 1 | package ogl; 2 | 3 | import ogl.GL; 4 | import haxe.io.BytesData; 5 | 6 | import #if neko neko #else cpp #end.Lib; 7 | class ByteUtils { 8 | public static inline function length(b:GLbuffer) { 9 | return Lib.load("ogl", "hx_gl_vector_len", 1)(b); 10 | } 11 | } 12 | 13 | abstract GLubyteArray(GLArray) to GLArray { 14 | inline public function new(raw:GLbuffer) this = new GLArray(raw, 1, GL.UNSIGNED_BYTE); 15 | @:from public static inline function fromData(b:BytesData):GLubyteArray return new GLubyteArray(GL.dataBuffer(b, GL.UNSIGNED_BYTE)); 16 | @:from public static inline function fromArr(arr:Array):GLubyteArray return new GLubyteArray(GL.buffer(arr, GL.UNSIGNED_BYTE)); 17 | @:from public static inline function fromRaw(raw:GLbuffer) return new GLubyteArray(raw); 18 | public static inline function alloc(count:Int):GLubyteArray return GL.allocBuffer(GL.UNSIGNED_BYTE, count); 19 | public static inline function view(arr:GLArray, byteOffset:Int, count:Int) { 20 | var ret = new GLubyteArray(arr.vector); 21 | arr = ret; arr.view(byteOffset, count); 22 | return ret; 23 | } 24 | 25 | public var size(get, never):Int; 26 | inline function get_size() return 1; 27 | public var raw(get, never):GLbuffer; 28 | inline function get_raw() return this.vector; 29 | public var count(get, never):Int; 30 | inline function get_count() return this.count; 31 | 32 | @:arrayAccess public inline function get(i:Int):GLubyte { 33 | var byte = Lib.load("ogl", "hx_gl_vector_get_byte", 3)(this.vector, this.byteOffset, i); 34 | return (byte < 0) ? (byte & 0xff) | 0x80 : byte; 35 | } 36 | @:arrayAccess public inline function set(i:Int, x:GLubyte):GLubyte 37 | return Lib.load("ogl", "hx_gl_vector_set_byte", 4)(this.vector, this.byteOffset, i, x&0xff); 38 | 39 | inline public function resize(count:Int) GL.load("arrvector_resize", 2)(this.vector, count*this.size); 40 | } 41 | 42 | abstract GLbyteArray(GLArray) to GLArray { 43 | inline public function new(raw:GLbuffer) this = new GLArray(raw, 1, GL.BYTE); 44 | @:from public static inline function fromData(b:BytesData):GLbyteArray return new GLbyteArray(GL.dataBuffer(b, GL.BYTE)); 45 | @:from public static inline function fromArr(arr:Array):GLbyteArray return new GLbyteArray(GL.buffer(arr, GL.BYTE)); 46 | @:from public static inline function fromRaw(raw:GLbuffer) return new GLbyteArray(raw); 47 | public static inline function alloc(count:Int):GLbyteArray return GL.allocBuffer(GL.BYTE, count); 48 | public static inline function view(arr:GLArray, byteOffset:Int, count:Int) { 49 | var ret = new GLbyteArray(arr.vector); 50 | arr = ret; arr.view(byteOffset, count); 51 | return ret; 52 | } 53 | 54 | public var size(get, never):Int; 55 | inline function get_size() return 1; 56 | public var raw(get, never):GLbuffer; 57 | inline function get_raw() return this.vector; 58 | public var count(get, never):Int; 59 | inline function get_count() return this.count; 60 | 61 | @:arrayAccess public inline function get(i:Int):GLbyte { 62 | var byte = Lib.load("ogl", "hx_gl_vector_get_byte", 3)(this.vector, this.byteOffset, i); 63 | return (byte < 0) ? (byte & 0xff) | 0x80 : byte; 64 | } 65 | @:arrayAccess public inline function set(i:Int, x:GLbyte):GLbyte 66 | return Lib.load("ogl", "hx_gl_vector_set_byte", 4)(this.vector, this.byteOffset, i, x&0xff); 67 | 68 | inline public function resize(count:Int) GL.load("arrvector_resize", 2)(this.vector, count*this.size); 69 | } 70 | 71 | abstract GLushortArray(GLArray) to GLArray { 72 | inline public function new(raw:GLbuffer) this = new GLArray(raw, 2, GL.UNSIGNED_SHORT); 73 | @:from public static inline function fromData(b:BytesData):GLushortArray return new GLushortArray(GL.dataBuffer(b, GL.UNSIGNED_SHORT)); 74 | @:from public static inline function fromArr(arr:Array):GLushortArray return new GLushortArray(GL.buffer(arr, GL.UNSIGNED_SHORT)); 75 | @:from public static inline function fromRaw(raw:GLbuffer) return new GLushortArray(raw); 76 | public static inline function alloc(count:Int):GLushortArray return GL.allocBuffer(GL.UNSIGNED_SHORT, count); 77 | public static inline function view(arr:GLArray, byteOffset:Int, count:Int) { 78 | var ret = new GLushortArray(arr.vector); 79 | arr = ret; arr.view(byteOffset, count); 80 | return ret; 81 | } 82 | 83 | public var size(get, never):Int; 84 | inline function get_size() return 2; 85 | public var raw(get, never):GLbuffer; 86 | inline function get_raw() return this.vector; 87 | public var count(get, never):Int; 88 | inline function get_count() return this.count; 89 | 90 | @:arrayAccess public inline function get(i:Int):GLushort 91 | return Lib.load("ogl", "hx_gl_vector_get_short", 3)(this.vector, this.byteOffset, i); 92 | @:arrayAccess public inline function set(i:Int, x:GLushort):GLushort 93 | return Lib.load("ogl", "hx_gl_vector_set_short", 4)(this.vector, this.byteOffset, i, x); 94 | 95 | inline public function resize(count:Int) GL.load("arrvector_resize", 2)(this.vector, count*this.size); 96 | } 97 | 98 | abstract GLshortArray(GLArray) to GLArray { 99 | inline public function new(raw:GLbuffer) this = new GLArray(raw, 2, GL.SHORT); 100 | @:from public static inline function fromData(b:BytesData):GLshortArray return new GLshortArray(GL.dataBuffer(b, GL.SHORT)); 101 | @:from public static inline function fromArr(arr:Array):GLshortArray return new GLshortArray(GL.buffer(arr, GL.SHORT)); 102 | @:from public static inline function fromRaw(raw:GLbuffer) return new GLshortArray(raw); 103 | public static inline function alloc(count:Int):GLshortArray return GL.allocBuffer(GL.SHORT, count); 104 | public static inline function view(arr:GLArray, byteOffset:Int, count:Int) { 105 | var ret = new GLshortArray(arr.vector); 106 | arr = ret; arr.view(byteOffset, count); 107 | return ret; 108 | } 109 | 110 | public var size(get, never):Int; 111 | inline function get_size() return 2; 112 | public var raw(get, never):GLbuffer; 113 | inline function get_raw() return this.vector; 114 | public var count(get, never):Int; 115 | inline function get_count() return this.count; 116 | 117 | @:arrayAccess public inline function get(i:Int):GLshort 118 | return Lib.load("ogl", "hx_gl_vector_get_short", 3)(this.vector, this.byteOffset, i); 119 | @:arrayAccess public inline function set(i:Int, x:GLshort):GLshort 120 | return Lib.load("ogl", "hx_gl_vector_set_short", 4)(this.vector, this.byteOffset, i, x); 121 | 122 | inline public function resize(count:Int) GL.load("arrvector_resize", 2)(this.vector, count*this.size); 123 | } 124 | 125 | abstract GLuintArray(GLArray) to GLArray { 126 | inline public function new(raw:GLbuffer) this = new GLArray(raw, 4, GL.UNSIGNED_INT); 127 | @:from public static inline function fromData(b:BytesData):GLuintArray return new GLuintArray(GL.dataBuffer(b, GL.UNSIGNED_INT)); 128 | @:from public static inline function fromArr(arr:Array):GLuintArray return new GLuintArray(GL.buffer(arr, GL.UNSIGNED_INT)); 129 | @:from public static inline function fromRaw(raw:GLbuffer) return new GLuintArray(raw); 130 | public static inline function alloc(count:Int):GLuintArray return GL.allocBuffer(GL.UNSIGNED_INT, count); 131 | public static inline function view(arr:GLArray, byteOffset:Int, count:Int) { 132 | var ret = new GLuintArray(arr.vector); 133 | arr = ret; arr.view(byteOffset, count); 134 | return ret; 135 | } 136 | 137 | public var size(get, never):Int; 138 | inline function get_size() return 4; 139 | public var raw(get, never):GLbuffer; 140 | inline function get_raw() return this.vector; 141 | public var count(get, never):Int; 142 | inline function get_count() return this.count; 143 | 144 | @:arrayAccess public inline function get(i:Int):GLuint 145 | return Lib.load("ogl", "hx_gl_vector_get_int", 3)(this.vector, this.byteOffset, i); 146 | @:arrayAccess public inline function set(i:Int, x:GLuint):GLuint 147 | return Lib.load("ogl", "hx_gl_vector_set_int", 4)(this.vector, this.byteOffset, i, x); 148 | 149 | inline public function resize(count:Int) GL.load("arrvector_resize", 2)(this.vector, count*this.size); 150 | } 151 | 152 | abstract GLintArray(GLArray) to GLArray { 153 | inline public function new(raw:GLbuffer) this = new GLArray(raw, 4, GL.INT); 154 | @:from public static inline function fromData(b:BytesData):GLintArray return new GLintArray(GL.dataBuffer(b, GL.INT)); 155 | @:from public static inline function fromArr(arr:Array):GLintArray return new GLintArray(GL.buffer(arr, GL.INT)); 156 | @:from public static inline function fromRaw(raw:GLbuffer) return new GLintArray(raw); 157 | public static inline function alloc(count:Int):GLintArray return GL.allocBuffer(GL.INT, count); 158 | public static inline function view(arr:GLArray, byteOffset:Int, count:Int) { 159 | var ret = new GLintArray(arr.vector); 160 | arr = ret; arr.view(byteOffset, count); 161 | return ret; 162 | } 163 | 164 | public var size(get, never):Int; 165 | inline function get_size() return 4; 166 | public var raw(get, never):GLbuffer; 167 | inline function get_raw() return this.vector; 168 | public var count(get, never):Int; 169 | inline function get_count() return this.count; 170 | 171 | @:arrayAccess public inline function get(i:Int):GLint 172 | return Lib.load("ogl", "hx_gl_vector_get_int", 3)(this.vector, this.byteOffset, i); 173 | @:arrayAccess public inline function set(i:Int, x:GLint):GLint 174 | return Lib.load("ogl", "hx_gl_vector_set_int", 4)(this.vector, this.byteOffset, i, x); 175 | 176 | inline public function resize(count:Int) GL.load("arrvector_resize", 2)(this.vector, count*this.size); 177 | } 178 | 179 | abstract GLfloatArray(GLArray) to GLArray { 180 | inline public function new(raw:GLbuffer) this = new GLArray(raw, 4, GL.FLOAT); 181 | @:from public static inline function fromData(b:BytesData):GLfloatArray return new GLfloatArray(GL.dataBuffer(b, GL.FLOAT)); 182 | @:from public static inline function fromArr(arr:Array):GLfloatArray return new GLfloatArray(GL.buffer(arr, GL.FLOAT)); 183 | @:from public static inline function fromRaw(raw:GLbuffer) return new GLfloatArray(raw); 184 | public static inline function alloc(count:Int):GLfloatArray return GL.allocBuffer(GL.FLOAT, count); 185 | public static inline function view(arr:GLArray, byteOffset:Int, count:Int) { 186 | var ret = new GLfloatArray(arr.vector); 187 | arr = ret; arr.view(byteOffset, count); 188 | return ret; 189 | } 190 | 191 | public inline function subData(data:Array, offset:Int=0, count:Int=-1) { 192 | if (count == -1) count = data.length; 193 | Lib.load("ogl", "hx_gl_vector_set_floats", 5)(this.vector, this.byteOffset, offset, data, count); 194 | } 195 | public inline function subDataVec(data:GLfloatArray, offset:Int=0) { 196 | var dat:GLArray = untyped data; 197 | Lib.load("ogl", "hx_gl_vector_set_floats_vec", -1)(this.vector, this.byteOffset, offset, dat.vector, dat.byteOffset, dat.count); 198 | } 199 | 200 | public var size(get, never):Int; 201 | inline function get_size() return 4; 202 | public var raw(get, never):GLbuffer; 203 | inline function get_raw() return this.vector; 204 | public var count(get, never):Int; 205 | inline function get_count() return this.count; 206 | 207 | @:arrayAccess public inline function get(i:Int):GLfloat 208 | return Lib.load("ogl", "hx_gl_vector_get_float", 3)(this.vector, this.byteOffset, i); 209 | @:arrayAccess public inline function set(i:Int, x:T):GLfloat 210 | return Lib.load("ogl", "hx_gl_vector_set_float", 4)(this.vector, this.byteOffset, i, x); 211 | 212 | inline public function resize(count:Int) GL.load("arrvector_resize", 2)(this.vector, count*this.size); 213 | } 214 | 215 | abstract GLdoubleArray(GLArray) to GLArray { 216 | inline public function new(raw:GLbuffer) this = new GLArray(raw, 8, GL.DOUBLE); 217 | @:from public static inline function fromData(b:BytesData):GLdoubleArray return new GLdoubleArray(GL.dataBuffer(b, GL.DOUBLE)); 218 | @:from public static inline function fromArr(arr:Array):GLdoubleArray return new GLdoubleArray(GL.buffer(arr, GL.DOUBLE)); 219 | @:from public static inline function fromRaw(raw:GLbuffer) return new GLdoubleArray(raw); 220 | public static inline function alloc(count:Int):GLdoubleArray return GL.allocBuffer(GL.DOUBLE, count); 221 | public static inline function view(arr:GLArray, byteOffset:Int, count:Int) { 222 | var ret = new GLdoubleArray(arr.vector); 223 | arr = ret; arr.view(byteOffset, count); 224 | return ret; 225 | } 226 | 227 | public var size(get, never):Int; 228 | inline function get_size() return 8; 229 | public var raw(get, never):GLbuffer; 230 | inline function get_raw() return this.vector; 231 | public var count(get, never):Int; 232 | inline function get_count() return this.count; 233 | 234 | @:arrayAccess public inline function get(i:Int):GLdouble 235 | return Lib.load("ogl", "hx_gl_vector_get_double", 3)(this.vector, this.byteOffset, i); 236 | @:arrayAccess public inline function set(i:Int, x:T):GLdouble 237 | return Lib.load("ogl", "hx_gl_vector_set_double", 4)(this.vector, this.byteOffset, i, x); 238 | 239 | inline public function resize(count:Int) GL.load("arrvector_resize", 2)(this.vector, count*this.size); 240 | } 241 | 242 | class GLArray { 243 | public var isView:Bool = false; 244 | public var fixedCount:Int = 0; 245 | public var byteOffset:GLsizeiptr = 0; 246 | 247 | public var size:Int; // element size 248 | public var type:GLenum; 249 | public var vector:GLbuffer; 250 | public var count(get, never):Int; 251 | inline function get_count() 252 | return if (isView) fixedCount else Std.int(ByteUtils.length(vector) / size); 253 | 254 | public function new(vector:GLbuffer, size:Int, type:Int) { 255 | this.vector = vector; 256 | this.size = size; 257 | this.type = type; 258 | } 259 | public inline function view(offset:Int, count:Int) { 260 | fixedCount = count; 261 | byteOffset = offset; 262 | isView = true; 263 | } 264 | 265 | inline public function toString() { 266 | var t = if (type == GL.BYTE) "BYTE" 267 | else if (type == GL.UNSIGNED_BYTE) "UNSIGNED_BYTE" 268 | else if (type == GL.SHORT) "SHORT" 269 | else if (type == GL.UNSIGNED_SHORT) "UNSIGNED_SHORT" 270 | else if (type == GL.INT) "INT" 271 | else if (type == GL.UNSIGNED_INT) "UNSIGNED_INT" 272 | else if (type == GL.FLOAT) "FLOAT" 273 | else "DOUBLE"; 274 | return if (isView) 'GLArrayView ${byteOffset}b + ($t)x$count' 275 | else 'GLArray ($t)x$count'; 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /ogl/GLM.hx: -------------------------------------------------------------------------------- 1 | package ogl; 2 | 3 | import ogl.Macros; 4 | import ogl.GL; 5 | import ogl.GLArray; 6 | 7 | class Padder { 8 | public static function pad(x:String, y:Array) { 9 | var z = []; 10 | var max = 0; 11 | for (yt in y) { 12 | var ys = Std.string(Math.fround(yt*1e10)*1e-10); 13 | if (ys.length > max) max = ys.length; 14 | z.push(ys); 15 | } 16 | for (i in 0...z.length) { 17 | z[i] = StringTools.rpad(z[i], " ", max); 18 | } 19 | return (~/\$([0-9]+)/g).map(x, function (t) return z[Std.parseInt(t.matched(0).substr(1))]); 20 | } 21 | } 22 | 23 | @:build(ogl.GLVector.run(2)) abstract Vec2(Array) to Array from Array { 24 | public inline function new(x:Array) this = x; 25 | @:from public static inline function fromFloatArr2(xs:Array>) { 26 | var ys = []; 27 | for (x in xs) ys = ys.concat(x); 28 | return new Vec2(ys); 29 | } 30 | @:from public static inline function fromAnon(x:{x:Float,y:Float}) return new Vec2([x.x,x.y]); 31 | @:from public static inline function fromGL(x:GLfloatArray) return new Vec2([x[0],x[1]]); 32 | @:to public inline function toGL() return GLfloatArray.fromArr(this); 33 | @:to public inline function toAnon() return {x:x, y:y}; 34 | 35 | // .xy 36 | public var x(get,set):Float; inline function get_x() return this[0]; inline function set_x(x:Float) return this[0] = x; 37 | public var y(get,set):Float; inline function get_y() return this[1]; inline function set_y(y:Float) return this[1] = y; 38 | 39 | // .rg 40 | public var r(get,set):Float; inline function get_r() return this[0]; inline function set_r(r:Float) return this[0] = r; 41 | public var g(get,set):Float; inline function get_g() return this[1]; inline function set_g(g:Float) return this[1] = g; 42 | 43 | // .st 44 | public var s(get,set):Float; inline function get_s() return this[0]; inline function set_s(s:Float) return this[0] = s; 45 | public var t(get,set):Float; inline function get_t() return this[1]; inline function set_t(t:Float) return this[1] = t; 46 | 47 | // array access 48 | @:arrayAccess public inline function geti(i:Int):Float return this[i]; 49 | @:arrayAccess public inline function getf(i:Int):Float return this[i]; 50 | @:arrayAccess public inline function seti(i:Int,x:Int) :Float return this[i]=x; 51 | @:arrayAccess public inline function setf(i:Int,x:Float):Float return this[i]=x; 52 | 53 | @:op(A==B) public static inline function eq(a:Vec2, b:Vec2) return a != null && b != null && (a.x == b.x && a.y == b.y) || a == null && b == null; 54 | 55 | public static inline function length (a:Vec2) return Math.sqrt(a.x*a.x+a.y*a.y); 56 | public static inline function normalise(a:Vec2) return a*(1/length(a)); 57 | public static inline function distance (a:Vec2, b:Vec2) return length(a - b); 58 | 59 | @:to public inline function toString() { 60 | var a:Vec2 = this; 61 | return Padder.pad("<$0 $1>",[a.x,a.y]); 62 | } 63 | } 64 | 65 | @:build(ogl.GLVector.run(3)) abstract Vec3(Array) to Array from Array { 66 | public inline function new(x:Array) this = x; 67 | @:from public static inline function fromFloatArr2(xs:Array>) { 68 | var ys = []; 69 | for (x in xs) ys = ys.concat(x); 70 | return new Vec3(ys); 71 | } 72 | @:from public static inline function fromAnon(x:{x:Float,y:Float,z:Float}) return new Vec3([x.x,x.y,x.z]); 73 | @:from public static inline function fromGL(x:GLfloatArray) return new Vec3([x[0],x[1],x[2]]); 74 | @:to public inline function toGL() return GLfloatArray.fromArr(this); 75 | @:to public inline function toAnon() return {x:x, y:y, z:z}; 76 | 77 | // .xyz 78 | public var x(get,set):Float; inline function get_x() return this[0]; inline function set_x(x:Float) return this[0] = x; 79 | public var y(get,set):Float; inline function get_y() return this[1]; inline function set_y(y:Float) return this[1] = y; 80 | public var z(get,set):Float; inline function get_z() return this[2]; inline function set_z(z:Float) return this[2] = z; 81 | 82 | // .rgb 83 | public var r(get,set):Float; inline function get_r() return this[0]; inline function set_r(r:Float) return this[0] = r; 84 | public var g(get,set):Float; inline function get_g() return this[1]; inline function set_g(g:Float) return this[1] = g; 85 | public var b(get,set):Float; inline function get_b() return this[2]; inline function set_b(b:Float) return this[2] = b; 86 | 87 | // .stp 88 | public var s(get,set):Float; inline function get_s() return this[0]; inline function set_s(s:Float) return this[0] = s; 89 | public var t(get,set):Float; inline function get_t() return this[1]; inline function set_t(t:Float) return this[1] = t; 90 | public var p(get,set):Float; inline function get_p() return this[2]; inline function set_p(p:Float) return this[2] = p; 91 | 92 | // array access 93 | @:arrayAccess public inline function geti(i:Int):Float return this[i]; 94 | @:arrayAccess public inline function getf(i:Int):Float return this[i]; 95 | @:arrayAccess public inline function seti(i:Int,x:Int) :Float return this[i]=x; 96 | @:arrayAccess public inline function setf(i:Int,x:Float):Float return this[i]=x; 97 | 98 | @:op(A==B) public static inline function eq(a:Vec3, b:Vec3) return a != null && b != null && (a.x == b.x && a.y == b.y && a.z == b.z) || a == null && b == null; 99 | 100 | public static inline function length (a:Vec3) return Math.sqrt(a.x*a.x+a.y*a.y+a.z*a.z); 101 | public static inline function normalise(a:Vec3) return a*(1/length(a)); 102 | public static inline function distance (a:Vec3, b:Vec3) return length(a - b); 103 | 104 | @:to public inline function toString() { 105 | var a:Vec3 = this; 106 | return Padder.pad("<$0 $1 $2>",[a.x,a.y,a.z]); 107 | } 108 | } 109 | 110 | @:build(ogl.GLVector.run(4)) abstract Vec4(Array) to Array from Array { 111 | public inline function new(x:Array) this = x; 112 | @:from public static inline function fromFloatArr2(xs:Array>) { 113 | var ys = []; 114 | for (x in xs) ys = ys.concat(x); 115 | return new Vec4(ys); 116 | } 117 | @:from public static inline function fromAnon(x:{x:Float,y:Float,z:Float,w:Float}) return new Vec4([x.x,x.y,x.z,x.w]); 118 | @:from public static inline function fromGL(x:GLfloatArray) return new Vec4([x[0],x[1],x[2],x[3]]); 119 | @:to public inline function toGL() return GLfloatArray.fromArr(this); 120 | @:to public inline function toAnon() return {x:x, y:y, z:z, w:w}; 121 | 122 | // .xyzw 123 | public var x(get,set):Float; inline function get_x() return this[0]; inline function set_x(x:Float) return this[0] = x; 124 | public var y(get,set):Float; inline function get_y() return this[1]; inline function set_y(y:Float) return this[1] = y; 125 | public var z(get,set):Float; inline function get_z() return this[2]; inline function set_z(z:Float) return this[2] = z; 126 | public var w(get,set):Float; inline function get_w() return this[3]; inline function set_w(w:Float) return this[3] = w; 127 | 128 | // .rgba 129 | public var r(get,set):Float; inline function get_r() return this[0]; inline function set_r(r:Float) return this[0] = r; 130 | public var g(get,set):Float; inline function get_g() return this[1]; inline function set_g(g:Float) return this[1] = g; 131 | public var b(get,set):Float; inline function get_b() return this[2]; inline function set_b(b:Float) return this[2] = b; 132 | public var a(get,set):Float; inline function get_a() return this[3]; inline function set_a(a:Float) return this[3] = a; 133 | 134 | // .stpq 135 | public var s(get,set):Float; inline function get_s() return this[0]; inline function set_s(s:Float) return this[0] = s; 136 | public var t(get,set):Float; inline function get_t() return this[1]; inline function set_t(t:Float) return this[1] = t; 137 | public var p(get,set):Float; inline function get_p() return this[2]; inline function set_p(p:Float) return this[2] = p; 138 | public var q(get,set):Float; inline function get_q() return this[3]; inline function set_q(q:Float) return this[3] = q; 139 | 140 | // array access 141 | @:arrayAccess public inline function geti(i:Int):Float return this[i]; 142 | @:arrayAccess public inline function getf(i:Int):Float return this[i]; 143 | @:arrayAccess public inline function seti(i:Int,x:Int) :Float return this[i]=x; 144 | @:arrayAccess public inline function setf(i:Int,x:Float):Float return this[i]=x; 145 | 146 | @:op(A==B) public static inline function eq(a:Vec4, b:Vec4) return a != null && b != null && (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w) || a == null && b == null; 147 | 148 | public static inline function length (a:Vec4) return Math.sqrt(a.x*a.x+a.y*a.y+a.z*a.z+a.w*a.w); 149 | public static inline function normalise(a:Vec4) return a*(1/length(a)); 150 | public static inline function distance (a:Vec4, b:Vec4) return length(a - b); 151 | 152 | @:to public inline function toString() { 153 | var a:Vec4 = this; 154 | return Padder.pad("<$0 $1 $2 $3>",[a.x,a.y,a.z,a.w]); 155 | } 156 | } 157 | 158 | abstract Mat3x2(Array) from Array to Array { 159 | public inline function new(x:Array) this = x; 160 | @:from public static inline function fromFloatArr2(xs:Array>) { 161 | var ys = []; 162 | for (x in xs) ys = ys.concat(x); 163 | return new Mat3x2(ys); 164 | } 165 | @:from public static inline function fromGL(x:GLfloatArray) return new Mat3x2([x[0],x[1],x[2],x[3],x[4],x[5]]); 166 | @:to public inline function toGL() return GLfloatArray.fromArr(this); 167 | 168 | // array access 169 | @:arrayAccess public inline function get(i:Int):Float return this[i]; 170 | @:arrayAccess public inline function set(i:Int,x:Float):Float return this[i]=x; 171 | 172 | public static inline function identity():Mat3x2 173 | return [1.0, 0.0, 174 | 0.0, 1.0, 175 | 0.0, 0.0]; 176 | 177 | public static inline function scale(x:Float, y:Float):Mat3x2 178 | return [x, 0.0, 179 | 0.0, y, 180 | 0.0, 0.0]; 181 | 182 | public static inline function translate(x:Float, y:Float):Mat3x2 183 | return [1.0, 0.0, 184 | 0.0, 1.0, 185 | x, y]; 186 | 187 | public static inline function rotate(angle:Float):Mat3x2 { 188 | var c = Math.cos(angle); var s = Math.sin(angle); 189 | return [c, s, 190 | -s, c, 191 | 0, 0]; 192 | } 193 | 194 | // (x, y) => (2*x/w - 1, 1 - 2*y/h) 195 | public static inline function viewportMap(width:Float, height:Float):Mat3x2 196 | return [2.0/width, 0.0, 197 | 0.0, -2.0/height, 198 | -1.0, 1.0 ]; 199 | 200 | @:op(A*B) public static inline function mul(_b:Mat3x2, _a:Mat3x2):Mat3x2 { 201 | var a = _a; 202 | var b = _b; 203 | return [b[0]*a[0] + b[2]*a[1], 204 | b[1]*a[0] + b[3]*a[1], 205 | 206 | b[0]*a[2] + b[2]*a[3], 207 | b[1]*a[2] + b[3]*a[3], 208 | 209 | b[0]*a[4] + b[2]*a[5] + b[4], 210 | b[1]*a[4] + b[3]*a[5] + b[5]]; 211 | } 212 | 213 | @:op(A*B) public static inline function mulv(_b:Mat3x2, _a:Vec2):Vec2 { 214 | var a = _a; 215 | var b = _b; 216 | return [b[0]*a[0] + b[2]*a[1] + b[4], 217 | b[1]*a[0] + b[3]*a[1] + b[5]]; 218 | } 219 | 220 | // Multiply rectangle specified by Vec4 as a pair of Vec2 (point+vector) 221 | @:op(A*B) public static inline function mulrect(_b:Mat3x2, _a:Vec4):Vec4 { 222 | var a = _a; 223 | var b = _b; 224 | return [b[0]*a[0] + b[2]*a[1] + b[4], 225 | b[1]*a[0] + b[3]*a[1] + b[5], 226 | b[0]*a[2] + b[2]*a[3], 227 | b[1]*a[2] + b[3]*a[3]]; 228 | } 229 | 230 | public inline function inverse():Mat3x2 { 231 | var a:Mat3x2 = this; 232 | var det = 1.0/(a[0]*a[3] - a[1]*a[2]); 233 | return [a[3]*det, -a[1]*det, 234 | -a[2]*det, a[0]*det, 235 | (a[2]*a[5] - a[3]*a[4])*det, 236 | (a[1]*a[4] - a[0]*a[5])*det]; 237 | } 238 | 239 | @:to public inline function toString() { 240 | var a:Mat3x2 = this; 241 | return Padder.pad("[$0 $2 $4\n $1 $3 $5]",[a[0],a[1],a[2],a[3],a[4],a[5]]); 242 | } 243 | } 244 | 245 | abstract Mat4(Array) from Array to Array { 246 | public inline function new(x:Array) this = x; 247 | @:from public static inline function fromFloatArr2(xs:Array>) { 248 | var ys = []; 249 | for (x in xs) ys = ys.concat(x); 250 | return new Mat4(ys); 251 | } 252 | @:from public static inline function fromGL(x:GLfloatArray) return new Mat4([ 253 | x[0], x[1], x[2], x[3], 254 | x[4], x[5], x[6], x[7], 255 | x[8], x[9], x[10],x[11], 256 | x[12],x[13],x[14],x[15], 257 | ]); 258 | @:to public inline function toGL() return GLfloatArray.fromArr(this); 259 | 260 | @:from public static inline function from3x2(_x:Mat3x2):Mat4 { 261 | var x = _x; 262 | return [x[0], x[1], 0, 0, 263 | x[2], x[3], 0, 0, 264 | 0, 0, 1, 0, 265 | x[4], x[5], 0, 1]; 266 | } 267 | 268 | // array access 269 | @:arrayAccess public inline function get(i:Int):Float return this[i]; 270 | @:arrayAccess public inline function set(i:Int,x:Float):Float return this[i]=x; 271 | 272 | public static function identity():Mat4 273 | return [1.0, 0.0, 0.0, 0.0, 274 | 0.0, 1.0, 0.0, 0.0, 275 | 0.0, 0.0, 1.0, 0.0, 276 | 0.0, 0.0, 0.0, 1.0]; 277 | public static function translate(x:Float, y:Float, z:Float):Mat4 278 | return [1.0, 0.0, 0.0, 0.0, 279 | 0.0, 1.0, 0.0, 0.0, 280 | 0.0, 0.0, 1.0, 0.0, 281 | x, y, z, 1.0]; 282 | public static function scale(x:Float, y:Float, z:Float):Mat4 283 | return [ x, 0.0, 0.0, 0.0, 284 | 0.0, y, 0.0, 0.0, 285 | 0.0, 0.0, z, 0.0, 286 | 0.0, 0.0, 0.0, 1.0]; 287 | public static function rotateX(angle:Float):Mat4 { 288 | var c = Math.cos(angle); var s = Math.sin(angle); 289 | return [1.0, 0.0, 0.0, 0.0, 290 | 0.0, c, s, 0.0, 291 | 0.0, -s, c, 0.0, 292 | 0.0, 0.0, 0.0, 1.0]; 293 | } 294 | public static function rotateY(angle:Float):Mat4 { 295 | var c = Math.cos(angle); var s = Math.sin(angle); 296 | return [ c, 0.0, -s, 0.0, 297 | 0.0, 1.0, 0.0, 0.0, 298 | s, 0.0, c, 0.0, 299 | 0.0, 0.0, 0.0, 1.0]; 300 | } 301 | public static function rotateZ(angle:Float):Mat4 { 302 | var c = Math.cos(angle); var s = Math.sin(angle); 303 | return [ c, s, 0.0, 0.0, 304 | -s, c, 0.0, 0.0, 305 | 0.0, 0.0, 1.0, 0.0, 306 | 0.0, 0.0, 0.0, 1.0]; 307 | } 308 | public static function perspective(fovY:Float, aspectRatio:Float, zNear:Float, zFar:Float):Mat4 { 309 | var f = 1.0/Math.tan(fovY/2); 310 | var t = 1.0/(zNear-zFar); 311 | return [f/aspectRatio, 0.0, 0.0, 0.0, 312 | 0.0, f, 0.0, 0.0, 313 | 0.0, 0.0, (zFar+zNear)*t, -1.0, 314 | 0.0, 0.0, 2*zFar*zNear*t , 0.0]; 315 | } 316 | public static function lookAt(_eye:Vec3, _centre:Vec3, ?_up:Null):Mat4 { 317 | var eye = _eye; 318 | var centre = _centre; 319 | var up = _up; 320 | 321 | var e0 = eye.x; 322 | var e1 = eye.y; 323 | var e2 = eye.z; 324 | 325 | var u0 = (up == null ? 0 : up.x); 326 | var u1 = (up == null ? 1 : up.y); 327 | var u2 = (up == null ? 0 : up.z); 328 | 329 | var f0 = centre.x - e0; 330 | var f1 = centre.y - e1; 331 | var f2 = centre.z - e2; 332 | var n = 1/Math.sqrt(f0*f0+f1*f1+f2*f2); 333 | f0 *= n; 334 | f1 *= n; 335 | f2 *= n; 336 | 337 | var s0 = f1*u2 - f2*u1; 338 | var s1 = f2*u0 - f0*u2; 339 | var s2 = f0*u1 - f1*u0; 340 | n = 1/Math.sqrt(s0*s0+s1*s1+s2*s2); 341 | s0 *= n; 342 | s1 *= n; 343 | s2 *= n; 344 | 345 | u0 = s1*f2 - s2*f1; 346 | u1 = s2*f0 - s0*f2; 347 | u2 = s0*f1 - s1*f0; 348 | 349 | var d0 = -e0*s0 - e1*s1 - e2*s2; 350 | var d1 = -e0*u0 - e1*u1 - e2*u2; 351 | var d2 = e0*f0 + e1*f1 + e2*f2; 352 | 353 | return [s0, u0, -f0, 0.0, 354 | s1, u1, -f1, 0.0, 355 | s2, u2, -f2, 0.0, 356 | d0, d1, d2, 1.0]; 357 | } 358 | 359 | @:op(A*B) public static function mul_3(_b:Mat4, _a:Mat3x2):Mat4 { 360 | var b = _b; var a = _a; 361 | return [b[0]*a[0] + b[4]*a[1], 362 | b[1]*a[0] + b[5]*a[1], 363 | b[2]*a[0] + b[6]*a[1], 364 | b[3]*a[0] + b[7]*a[1], 365 | 366 | b[0]*a[2] + b[4]*a[3], 367 | b[1]*a[2] + b[5]*a[3], 368 | b[2]*a[2] + b[6]*a[3], 369 | b[3]*a[2] + b[7]*a[3], 370 | 371 | b[8], 372 | b[9], 373 | b[10], 374 | b[11], 375 | 376 | b[0]*a[4] + b[4]*a[5] + b[12], 377 | b[1]*a[4] + b[5]*a[5] + b[13], 378 | b[2]*a[4] + b[6]*a[5] + b[14], 379 | b[3]*a[4] + b[7]*a[5] + b[15]]; 380 | } 381 | 382 | @:op(A*B) public static function _3_mul(_b:Mat3x2, _a:Mat4):Mat4 { 383 | var b = _b; 384 | var a = _a; 385 | return [b[0]*a[0] + b[2]*a[1] + b[4]*a[3], 386 | b[1]*a[0] + b[3]*a[1] + b[5]*a[3], 387 | a[2], 388 | a[3], 389 | 390 | b[0]*a[4] + b[2]*a[5] + b[4]*a[7], 391 | b[1]*a[4] + b[3]*a[5] + b[5]*a[7], 392 | a[6], 393 | a[7], 394 | 395 | b[0]*a[8] + b[2]*a[9] + b[4]*a[11], 396 | b[1]*a[8] + b[3]*a[9] + b[5]*a[11], 397 | a[10], 398 | a[11], 399 | 400 | b[0]*a[12] + b[2]*a[13] + b[4]*a[15], 401 | b[1]*a[12] + b[3]*a[13] + b[5]*a[15], 402 | a[14], 403 | a[15]]; 404 | } 405 | 406 | @:op(A*B) public static function mul(_b:Mat4, _a:Mat4):Mat4 { 407 | var b = _b; 408 | var a = _a; 409 | return [b[0]*a[0] + b[4]*a[1] + b[8] *a[2] + b[12]*a[3], 410 | b[1]*a[0] + b[5]*a[1] + b[9] *a[2] + b[13]*a[3], 411 | b[2]*a[0] + b[6]*a[1] + b[10]*a[2] + b[14]*a[3], 412 | b[3]*a[0] + b[7]*a[1] + b[11]*a[2] + b[15]*a[3], 413 | 414 | b[0]*a[4] + b[4]*a[5] + b[8] *a[6] + b[12]*a[7], 415 | b[1]*a[4] + b[5]*a[5] + b[9] *a[6] + b[13]*a[7], 416 | b[2]*a[4] + b[6]*a[5] + b[10]*a[6] + b[14]*a[7], 417 | b[3]*a[4] + b[7]*a[5] + b[11]*a[6] + b[15]*a[7], 418 | 419 | b[0]*a[8] + b[4]*a[9] + b[8] *a[10] + b[12]*a[11], 420 | b[1]*a[8] + b[5]*a[9] + b[9] *a[10] + b[13]*a[11], 421 | b[2]*a[8] + b[6]*a[9] + b[10]*a[10] + b[14]*a[11], 422 | b[3]*a[8] + b[7]*a[9] + b[11]*a[10] + b[15]*a[11], 423 | 424 | b[0]*a[12] + b[4]*a[13] + b[8] *a[14] + b[12]*a[15], 425 | b[1]*a[12] + b[5]*a[13] + b[9] *a[14] + b[13]*a[15], 426 | b[2]*a[12] + b[6]*a[13] + b[10]*a[14] + b[14]*a[15], 427 | b[3]*a[12] + b[7]*a[13] + b[11]*a[14] + b[15]*a[15]]; 428 | } 429 | 430 | public inline function inverse():Mat4 { 431 | var a:Mat4 = this; 432 | var s0 = a[0]*a[5] -a[4] *a[1]; var c5 = a[10]*a[15]-a[14]*a[11]; 433 | var s1 = a[0]*a[9] -a[8] *a[1]; var c4 = a[6] *a[15]-a[14]*a[7]; 434 | var s2 = a[0]*a[13]-a[12]*a[1]; var c3 = a[6] *a[11]-a[10]*a[7]; 435 | var s3 = a[4]*a[9] -a[8] *a[5]; var c2 = a[2] *a[15]-a[14]*a[3]; 436 | var s4 = a[4]*a[13]-a[12]*a[5]; var c1 = a[2] *a[11]-a[10]*a[3]; 437 | var s5 = a[8]*a[13]-a[12]*a[9]; var c0 = a[2] *a[7]- a[6] *a[3]; 438 | var D = 1/(s0*c5-s1*c4+s2*c3+s3*c2-s4*c1+s5*c0); 439 | return [ 440 | D*( a[5]*c5-a[9] *c4+a[13]*c3),D*(-a[1]*c5+a[9] *c2-a[13]*c1),D*( a[1]*c4-a[5]*c2+a[13]*c0),D*(-a[1]*c3+a[5]*c1-a[9] *c0), 441 | D*(-a[4]*c5+a[8] *c4-a[12]*c3),D*( a[0]*c5-a[8] *c2+a[12]*c1),D*(-a[0]*c4+a[4]*c2-a[12]*c0),D*( a[0]*c3-a[4]*c1+a[8] *c0), 442 | D*( a[7]*s5-a[11]*s4+a[15]*s3),D*(-a[3]*s5+a[11]*s2-a[15]*s1),D*( a[3]*s4-a[7]*s2+a[15]*s0),D*(-a[3]*s3+a[7]*s1-a[11]*s0), 443 | D*(-a[6]*s5+a[10]*s4-a[14]*s3),D*( a[2]*s5-a[10]*s2+a[14]*s1),D*(-a[2]*s4+a[6]*s2-a[14]*s0),D*( a[2]*s3-a[6]*s1+a[10]*s0), 444 | ]; 445 | } 446 | 447 | @:op(A*B) public static inline function mulv(_b:Mat4, _a:Vec4):Vec4 { 448 | var a = _a; 449 | var b = _b; 450 | return [b[0]*a[0] + b[4]*a[1] + b[8] *a[2] + b[12]*a[3], 451 | b[1]*a[0] + b[5]*a[1] + b[9] *a[2] + b[13]*a[3], 452 | b[2]*a[0] + b[6]*a[1] + b[10]*a[2] + b[14]*a[3], 453 | b[3]*a[0] + b[7]*a[1] + b[11]*a[2] + b[15]*a[3]]; 454 | } 455 | 456 | public inline function transpose():Mat4 { 457 | var a:Mat4 = this; 458 | return [a[0], a[4], a[8], a[12], 459 | a[1], a[5], a[9], a[13], 460 | a[2], a[6], a[10], a[14], 461 | a[3], a[7], a[11], a[15]]; 462 | } 463 | 464 | @:to public inline function toString() { 465 | var a:Mat4 = this; 466 | return Padder.pad("[$0 $4 $8 $12\n $1 $5 $9 $13\n $2 $6 $10 $14\n $3 $7 $11 $15]",[ 467 | a[0],a[1],a[2],a[3], 468 | a[4],a[5],a[6],a[7], 469 | a[8],a[9],a[10],a[11], 470 | a[12],a[13],a[14],a[15]] 471 | ); 472 | } 473 | } 474 | 475 | -------------------------------------------------------------------------------- /ogl/Macros.hx: -------------------------------------------------------------------------------- 1 | package ogl; 2 | 3 | import haxe.macro.Context; 4 | import haxe.macro.Expr; 5 | 6 | import goodies.MacroUtils; 7 | 8 | 9 | 10 | @:autoBuild(ogl.GLProcsImpl.run()) 11 | @:remove extern interface GLProcs {} 12 | 13 | 14 | // 15 | // @:GLProc function x(...) { 16 | // ... 17 | // } 18 | // 19 | // replaced by 20 | // 21 | // public static inline function x(...) { 22 | // #if debug 23 | // if ($param0 == null) throw "x :: $param0 cannot be null"; 24 | // #end 25 | // ... 26 | // } 27 | // 28 | // for any parameter marked non-optional, and of non-basic type. 29 | // 30 | // to override/add additional checks use: 31 | // { 32 | // @:GLCheck(?paramName) if (cond) throw "message" 33 | // ... 34 | // } 35 | // with any default check on parameter disregarded 36 | // and the message prepended by "x :: " 37 | // 38 | // @:GLProc(cname) modifies the C lib name used in the ndll loading 39 | // if the haxe name differs. 40 | // 41 | class GLProcsImpl { 42 | #if macro 43 | static function isProc(f:Metadata) { 44 | for (m in f) { 45 | if (m.name == ":GLProc") return true; 46 | } 47 | return false; 48 | } 49 | 50 | static function skippedType(t:ComplexType):Bool { 51 | return switch(t) { 52 | case macro :Int: true; 53 | case macro :Float: true; 54 | case macro :Bool: true; 55 | case macro :Dynamic: true; 56 | case TPath({name:"Null"}): true; 57 | case TPath({name:name}) if(name.substr(0,2)=="GL" && name != "GLsync"): true; 58 | default: false; 59 | } 60 | } 61 | 62 | // e:Null => (e:T => *) 63 | // e:Int, Float, String, Bool => e 64 | // e:Point => NativeBinding.native(e) 65 | // e:Array => e 66 | // e:Array => NativeBinding.mapNative(e) 67 | static function transformArg(e:Expr, t:ComplexType):Null { 68 | function targ(e:Expr, t:ComplexType) { 69 | return switch(t) { 70 | case TPath({name:"Null",params:[TPType(t)]}): targ(e, t); 71 | case macro :Int: null; 72 | case macro :Float: null; 73 | case macro :String: null; 74 | case macro :Bool: null; 75 | case TPath({name:name}) if (name.substr(0,2)=="GL" && name != "GLsync"): null; 76 | case TFunction(_,_): null; 77 | case TPath({name:"Array",params:[TPType(t)]}): 78 | var e2 = targ(e, t); 79 | if (e2 == null || switch (t) { 80 | case TPath({name:"T"}): true; 81 | default: false; 82 | }) e; 83 | else macro NativeBinding.mapNative($e); 84 | default: macro NativeBinding.native($e); 85 | } 86 | } 87 | 88 | var e2 = targ(e, t); 89 | if (e2 == null) e2 = e; 90 | return e2; 91 | } 92 | 93 | static function typeToIdent(t:ComplexType):Expr { 94 | return macro $p{haxe.macro.ComplexTypeTools.toString(t).split(".")}; 95 | } 96 | 97 | static function transformRet(e:Expr, t:ComplexType):Null { 98 | switch (t) { 99 | case macro :Void: return e; 100 | default: 101 | } 102 | 103 | function tret(e:Expr, t:ComplexType) { 104 | return switch(t) { 105 | case TPath({name:"Null",params:[TPType(t)]}): tret(e, t); 106 | case macro :Int: null; 107 | case macro :Float: null; 108 | case macro :String: null; 109 | case macro :Bool: null; 110 | case TPath({name:name}) if (name.substr(0,2)=="GL" && name != "GLsync"): null; 111 | case TFunction(_,_): null; 112 | case TPath({name:"Array",params:[TPType(_)]}): 113 | Context.error("@:GLProc doesn't know how to handle generating body of Array returned methods", e.pos); 114 | null; 115 | case TPath(_): 116 | macro $e{typeToIdent(t)}.cvt($e); 117 | default: 118 | Context.error("@:GLProc doesn't know hot to handle generating body with this return type", e.pos); 119 | null; 120 | }; 121 | } 122 | 123 | var e2 = tret(e, t); 124 | if (e2 == null) e2 = e; 125 | return macro return $e2; 126 | } 127 | 128 | static function params(f:Field):Array { 129 | for (m in f.meta) { 130 | if (m.name == ":GLProc") { 131 | return m.params; 132 | } 133 | } 134 | return []; 135 | } 136 | static function paramName(f:Field):Null { 137 | for (p in params(f)) { 138 | switch (p.expr) { 139 | case EConst(CIdent(n)): 140 | p.expr = EConst(CString(n)); 141 | return p; 142 | default: 143 | } 144 | } 145 | return null; 146 | } 147 | 148 | static var printer:haxe.macro.Printer; 149 | static function process(field:Field, f:Function) { 150 | if (printer == null) printer = new haxe.macro.Printer(); 151 | var skipped = new Map(); 152 | 153 | // process manual checks 154 | if (f.expr == null) { 155 | var build = if (f.ret != null) function (e:Expr) return macro return $e; else function (e:Expr) return e; 156 | var args = []; 157 | for (i in f.args) { 158 | var e2 = transformArg(macro $i{i.name}, i.type); 159 | args.push(e2); 160 | } 161 | 162 | var name = paramName(field); 163 | if (name == null) name = macro $v{field.name}; 164 | 165 | f.expr = macro load($name, $v{f.args.length})($a{args}); 166 | 167 | if (f.ret != null) { 168 | f.expr = transformRet(f.expr, f.ret); 169 | } 170 | } 171 | else { 172 | f.expr.expr = switch (f.expr.expr) { 173 | case EBlock(xs): 174 | var ys = []; 175 | for (x in xs) { 176 | switch (x.expr) { 177 | case EMeta({name:":GLCheck", params:params, pos:p}, y): 178 | if (!Context.defined("debug")) continue; 179 | if (params.length > 1) { 180 | for (n in params) { 181 | skipped.set(switch (n.expr) { 182 | case EConst(CIdent(n)): n; 183 | default: 184 | Context.warning("@:GLCheck param should be identifier name", p); 185 | null; 186 | }, true); 187 | } 188 | } 189 | switch (y) { 190 | case (macro if ($cond) throw $err else $e) if (e == null): 191 | var err2 = '${field.name} :: '; 192 | ys.push(macro if ($cond) { 193 | throw Std.string($v{err2}+$err); 194 | }); 195 | default: 196 | Context.warning("@:GLCheck expr was not if (..) throw ..", p); 197 | } 198 | default: ys.push(x); 199 | } 200 | } 201 | EBlock(ys); 202 | default: 203 | f.expr.expr; 204 | } 205 | } 206 | 207 | var checks = []; 208 | if (Context.defined("debug")) { 209 | for (arg in f.args) { 210 | if (arg.type == null) Context.warning("@:GLProc should have arg types declared", field.pos); 211 | if (arg.opt || skippedType(arg.type)) continue; 212 | 213 | if (skipped.get(arg.name)) continue; 214 | 215 | var err = '${field.name} :: ${arg.name} cannot be null'; 216 | checks.push(macro { 217 | if ($i{arg.name} == null) { 218 | throw $v{err}; 219 | } 220 | }); 221 | } 222 | f.expr = macro { $b{checks}; $e{f.expr} }; 223 | } 224 | 225 | for (p in params(field)) { 226 | switch (p) { 227 | case macro $n=$v: 228 | f.expr = macro { 229 | if ($n == null) $n = $v; 230 | $e{f.expr}; 231 | }; 232 | default: 233 | } 234 | } 235 | 236 | field.access.push(AStatic); 237 | field.access.push(APublic); 238 | field.access.push(AInline); 239 | 240 | if (Context.defined("ogl-dont-check-errors")) return; 241 | if (field.name == "getError") return; //!!!! 242 | if (MacroUtils.hasMeta(field, ":oglNoErrors") != null) return; 243 | 244 | var check = macro { 245 | var errs = []; 246 | var err; 247 | while ((err = GL.getError()) != GL.NO_ERROR) errs.push( 248 | if (err == GL.INVALID_ENUM) "INVALID_ENUM" 249 | else if(err == GL.INVALID_VALUE) "INVALID_VALUE" 250 | else if(err == GL.INVALID_OPERATION) "INVALID_OPERATION" 251 | else if(err == GL.INVALID_FRAMEBUFFER_OPERATION) "INVALID_FRAMEBUFFER_OPERATION" 252 | else if(err == GL.OUT_OF_MEMORY) "OUT_OF_MEMORY" 253 | else "???" 254 | ); 255 | if (errs.length != 0) { 256 | errs.unshift("GL."+$v{field.name}); 257 | throw Std.string(errs); 258 | } 259 | }; 260 | 261 | if (f.ret != null && !switch(f.ret) { case macro :Void: true; default: false; }) 262 | f.expr = macro { var ret = (function () ${f.expr})(); $check; return ret; }; 263 | else 264 | f.expr = macro { ${f.expr}; $check; }; 265 | } 266 | 267 | static function run() { 268 | var fields = Context.getBuildFields(); 269 | 270 | for (f in fields) { 271 | if (!isProc(f.meta)) continue; 272 | 273 | switch (f.kind) { 274 | case FFun(g): 275 | process(f, g); 276 | default: 277 | Context.warning("@:GLProc used on non-method type", f.pos); 278 | } 279 | } 280 | return fields; 281 | } 282 | #end 283 | } 284 | 285 | 286 | // 287 | // Add same type vector operations 288 | // for GL vector type. 289 | // 290 | class GLVec { 291 | #if macro 292 | static var N:Int; 293 | static var fields:Array; 294 | static var selfT:ComplexType; 295 | 296 | static function unop(name:String, op:Unop, post:Bool) { 297 | var es = []; 298 | for (i in 0...N) { 299 | es.push({ 300 | pos: Context.currentPos(), 301 | expr: EUnop(op, post, macro u[$v{i}]) 302 | }); 303 | } 304 | fields.push({ 305 | pos: Context.currentPos(), 306 | name: name, 307 | meta: [{ 308 | pos: Context.currentPos(), 309 | name: ":op", 310 | params: [{ 311 | expr: EUnop(op, post, macro A), 312 | pos: Context.currentPos() 313 | }] 314 | }], 315 | kind: FFun({ 316 | ret: selfT, 317 | params: [], 318 | args: [{ 319 | value: null, 320 | type: selfT, 321 | opt: false, 322 | name: "_u", 323 | }], 324 | expr: macro { var u = _u; return $a{es}; } 325 | }), 326 | doc: null, 327 | access: [AInline, AStatic, APublic] 328 | }); 329 | } 330 | 331 | static function binop(name:String, op:Binop, self:Bool=false, com:Bool=false) { 332 | var es = []; 333 | for (i in 0...N) { 334 | es.push({ 335 | pos: Context.currentPos(), 336 | expr: EBinop(op, macro u[$v{i}], macro v[$v{i}]) 337 | }); 338 | } 339 | fields.push({ 340 | pos: Context.currentPos(), 341 | name: name, 342 | meta: [{ 343 | pos: Context.currentPos(), 344 | name: ":op", 345 | params: [{ 346 | expr: EBinop(op, macro A, macro B), 347 | pos: Context.currentPos() 348 | }] 349 | }], 350 | kind: FFun({ 351 | ret: selfT, 352 | params: [], 353 | args: [{ 354 | value: null, 355 | type: selfT, 356 | opt: false, 357 | name: "_u", 358 | }, { 359 | value: null, 360 | type: selfT, 361 | opt: false, 362 | name: "_v", 363 | }], 364 | expr: self ? macro { var u = _u; var v = _v; $b{es}; return _u; } 365 | : macro { var u = _u; var v = _v; return $a{es}; } 366 | }), 367 | doc: null, 368 | access: [AInline, AStatic, APublic] 369 | }); 370 | 371 | var es = []; 372 | for (i in 0...N) { 373 | es.push({ 374 | pos: Context.currentPos(), 375 | expr: EBinop(op, macro u[$v{i}], macro v) 376 | }); 377 | } 378 | fields.push({ 379 | pos: Context.currentPos(), 380 | name: name+"f", 381 | meta: [{ 382 | pos: Context.currentPos(), 383 | name: ":op", 384 | params: [{ 385 | expr: EBinop(op, macro A, macro B), 386 | pos: Context.currentPos() 387 | }] 388 | }].concat(!com ? [] : [{ 389 | pos: Context.currentPos(), 390 | name: ":commutative", 391 | params: [] 392 | }]), 393 | kind: FFun({ 394 | ret: selfT, 395 | params: [], 396 | args: [{ 397 | value: null, 398 | type: selfT, 399 | opt: false, 400 | name: "_u", 401 | }, { 402 | value: null, 403 | type: macro :Float, 404 | opt: false, 405 | name: "_v", 406 | }], 407 | expr: self ? macro { var u = _u; var v = _v; $b{es}; return _u; } : 408 | macro { var u = _u; var v = _v; return $a{es}; } 409 | }), 410 | doc: null, 411 | access: [AInline, AStatic, APublic] 412 | }); 413 | fields.push({ 414 | pos: Context.currentPos(), 415 | name: name+"i", 416 | meta: [{ 417 | pos: Context.currentPos(), 418 | name: ":op", 419 | params: [{ 420 | expr: EBinop(op, macro A, macro B), 421 | pos: Context.currentPos() 422 | }] 423 | }].concat(!com ? [] : [{ 424 | pos: Context.currentPos(), 425 | name: ":commutative", 426 | params: [] 427 | }]), 428 | kind: FFun({ 429 | ret: selfT, 430 | params: [], 431 | args: [{ 432 | value: null, 433 | type: selfT, 434 | opt: false, 435 | name: "_u", 436 | }, { 437 | value: null, 438 | type: macro :Int, 439 | opt: false, 440 | name: "_v", 441 | }], 442 | expr: self ? macro { var u = _u; var v = _v; $b{es}; return _u; } : 443 | macro { var u = _u; var v = _v; return $a{es}; } 444 | }), 445 | doc: null, 446 | access: [AInline, AStatic, APublic] 447 | }); 448 | } 449 | 450 | public static function run(n:Int) { 451 | N = n; 452 | fields = Context.getBuildFields(); 453 | 454 | selfT = TPath({sub:null,params:[],pack:[],name:"Vector"+N}); 455 | 456 | binop("add", OpAdd, false, true); 457 | binop("sub", OpSub, false, true); 458 | binop("div", OpDiv, false, true); 459 | binop("mul", OpMult, false, true); 460 | 461 | binop("assign", OpAssign, true); 462 | binop("addAssign", OpAssignOp(OpAdd), true); 463 | binop("subAssign", OpAssignOp(OpSub), true); 464 | binop("divAssign", OpAssignOp(OpDiv), true); 465 | binop("mulAssign", OpAssignOp(OpMult), true); 466 | 467 | unop("neg", OpNeg, false); 468 | 469 | return fields; 470 | } 471 | #end 472 | } 473 | // 474 | // Add same type vector operations 475 | // for GL vector type. 476 | // 477 | class GLVector { 478 | #if macro 479 | static var N:Int; 480 | static var fields:Array; 481 | static var selfT:ComplexType; 482 | 483 | static function unop(name:String, op:Unop, post:Bool) { 484 | var es = []; 485 | for (i in 0...N) { 486 | es.push({ 487 | pos: Context.currentPos(), 488 | expr: EUnop(op, post, macro u[$v{i}]) 489 | }); 490 | } 491 | fields.push({ 492 | pos: Context.currentPos(), 493 | name: name, 494 | meta: [{ 495 | pos: Context.currentPos(), 496 | name: ":op", 497 | params: [{ 498 | expr: EUnop(op, post, macro A), 499 | pos: Context.currentPos() 500 | }] 501 | }], 502 | kind: FFun({ 503 | ret: selfT, 504 | params: [], 505 | args: [{ 506 | value: null, 507 | type: selfT, 508 | opt: false, 509 | name: "_u", 510 | }], 511 | expr: macro { var u = _u; return $a{es}; } 512 | }), 513 | doc: null, 514 | access: [AInline, AStatic, APublic] 515 | }); 516 | } 517 | 518 | static function binop(name:String, op:Binop, self:Bool=false, com:Bool=false) { 519 | var es = []; 520 | for (i in 0...N) { 521 | es.push({ 522 | pos: Context.currentPos(), 523 | expr: EBinop(op, macro u[$v{i}], macro v[$v{i}]) 524 | }); 525 | } 526 | fields.push({ 527 | pos: Context.currentPos(), 528 | name: name, 529 | meta: [{ 530 | pos: Context.currentPos(), 531 | name: ":op", 532 | params: [{ 533 | expr: EBinop(op, macro A, macro B), 534 | pos: Context.currentPos() 535 | }] 536 | }], 537 | kind: FFun({ 538 | ret: selfT, 539 | params: [], 540 | args: [{ 541 | value: null, 542 | type: selfT, 543 | opt: false, 544 | name: "_u", 545 | }, { 546 | value: null, 547 | type: selfT, 548 | opt: false, 549 | name: "_v", 550 | }], 551 | expr: self ? macro { var u = _u; var v = _v; $b{es}; return _u; } 552 | : macro { var u = _u; var v = _v; return $a{es}; } 553 | }), 554 | doc: null, 555 | access: [AInline, AStatic, APublic] 556 | }); 557 | 558 | var es = []; 559 | for (i in 0...N) { 560 | es.push({ 561 | pos: Context.currentPos(), 562 | expr: EBinop(op, macro u[$v{i}], macro v) 563 | }); 564 | } 565 | fields.push({ 566 | pos: Context.currentPos(), 567 | name: name+"f", 568 | meta: [{ 569 | pos: Context.currentPos(), 570 | name: ":op", 571 | params: [{ 572 | expr: EBinop(op, macro A, macro B), 573 | pos: Context.currentPos() 574 | }] 575 | }].concat(!com ? [] : [{ 576 | pos: Context.currentPos(), 577 | name: ":commutative", 578 | params: [] 579 | }]), 580 | kind: FFun({ 581 | ret: selfT, 582 | params: [], 583 | args: [{ 584 | value: null, 585 | type: selfT, 586 | opt: false, 587 | name: "_u", 588 | }, { 589 | value: null, 590 | type: macro :Float, 591 | opt: false, 592 | name: "_v", 593 | }], 594 | expr: self ? macro { var u = _u; var v = _v; $b{es}; return _u; } : 595 | macro { var u = _u; var v = _v; return $a{es}; } 596 | }), 597 | doc: null, 598 | access: [AInline, AStatic, APublic] 599 | }); 600 | fields.push({ 601 | pos: Context.currentPos(), 602 | name: name+"i", 603 | meta: [{ 604 | pos: Context.currentPos(), 605 | name: ":op", 606 | params: [{ 607 | expr: EBinop(op, macro A, macro B), 608 | pos: Context.currentPos() 609 | }] 610 | }].concat(!com ? [] : [{ 611 | pos: Context.currentPos(), 612 | name: ":commutative", 613 | params: [] 614 | }]), 615 | kind: FFun({ 616 | ret: selfT, 617 | params: [], 618 | args: [{ 619 | value: null, 620 | type: selfT, 621 | opt: false, 622 | name: "_u", 623 | }, { 624 | value: null, 625 | type: macro :Int, 626 | opt: false, 627 | name: "_v", 628 | }], 629 | expr: self ? macro { var u = _u; var v = _v; $b{es}; return _u; } : 630 | macro { var u = _u; var v = _v; return $a{es}; } 631 | }), 632 | doc: null, 633 | access: [AInline, AStatic, APublic] 634 | }); 635 | } 636 | 637 | public static function run(n:Int) { 638 | N = n; 639 | fields = Context.getBuildFields(); 640 | 641 | selfT = TPath({sub:null,params:[],pack:[],name:"Vec"+N}); 642 | 643 | binop("add", OpAdd, false, true); 644 | binop("sub", OpSub, false, true); 645 | binop("div", OpDiv, false, true); 646 | binop("mul", OpMult, false, true); 647 | 648 | binop("assign", OpAssign, true); 649 | binop("addAssign", OpAssignOp(OpAdd), true); 650 | binop("subAssign", OpAssignOp(OpSub), true); 651 | binop("divAssign", OpAssignOp(OpDiv), true); 652 | binop("mulAssign", OpAssignOp(OpMult), true); 653 | 654 | unop("neg", OpNeg, false); 655 | 656 | return fields; 657 | } 658 | #end 659 | } 660 | -------------------------------------------------------------------------------- /src/gl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utils.h" 4 | 5 | struct Vector { 6 | void* dat; 7 | unsigned int size; 8 | }; 9 | value hx_gl_vector_len(value b) { 10 | Vector* v = (Vector*)val_data(b); 11 | return alloc(v->size); 12 | } 13 | DEFINE_PRIM(hx_gl_vector_len, 1) 14 | 15 | DECLARE_KIND(k_Vector); 16 | DEFINE_KIND(k_Vector); 17 | 18 | value hx_gl_glewInit() { 19 | glewExperimental = GL_TRUE; 20 | glewInit(); 21 | // ignore errors possibly generated by glewInit, sigh. 22 | while (glGetError() != GL_NO_ERROR); 23 | return val_null; 24 | } 25 | DEFINE_PRIM(hx_gl_glewInit, 0); 26 | 27 | // Get T* pointer to buffer_data + byteOffset 28 | template 29 | T* get_vector(value data, value offset) { 30 | char* dat = (char*)(((Vector*)val_data(data))->dat); 31 | dat += val_get(offset); 32 | return (T*)dat; 33 | } 34 | 35 | GLuint* copy_uints(value ints) { 36 | GLuint* buf = new GLuint[val_array_size(ints)]; 37 | for (int i = 0; i < val_array_size(ints); i++) 38 | buf[i] = val_get(val_array_i(ints, i)); 39 | return buf; 40 | } 41 | GLint* copy_ints(value ints) { 42 | return (GLint*)copy_uints(ints); 43 | } 44 | GLenum* copy_enum(value ints) { 45 | return (GLenum*)copy_uints(ints); 46 | } 47 | 48 | void copy_del_uints(value ints, GLuint* cints, int n) { 49 | val_array_set_size(ints, n); 50 | for (int i = 0; i < n; i++) 51 | val_array_set_i(ints, i, alloc(cints[i])); 52 | delete[] cints; 53 | } 54 | void copy_del_ints(value ints, GLint* cints, int n) { 55 | copy_del_uints(ints, (GLuint*)cints, n); 56 | } 57 | 58 | // Convert Array, Array and 59 | // Array into hxcpp buffer 60 | // based on GL type 61 | int byte_kind(int T) { 62 | int t = (T == GL_UNSIGNED_BYTE || T == GL_BYTE) ? 0 : 63 | (T == GL_UNSIGNED_SHORT || T == GL_SHORT) ? 1 : 64 | (T == GL_UNSIGNED_INT || T == GL_INT) ? 2 : 65 | (T == GL_FLOAT) ? 3 : 66 | (T == GL_DOUBLE) ? 4 : -1; 67 | return t; 68 | } 69 | int byte_size(int T) { 70 | int t = byte_kind(T); 71 | return t == 0 ? 1 : t == 1 ? 2 : (t == 2 || t == 3) ? 4 : 8; 72 | } 73 | 74 | value hx_gl_vector_set_floats(value data, value offset, value i, value xs, value count) { 75 | float* dat = get_vector(data, offset) + val_get(i); 76 | for (int j = 0; j < val_get(count); j++) 77 | *(dat++) = val_get(val_array_i(xs, j)); 78 | return val_null; 79 | } 80 | value hx_gl_vector_set_floats_vec(value* args, int cnt) { 81 | float* dat = get_vector(args[0], args[1]) + val_get(args[2]); 82 | float* vec = get_vector(args[3], args[4]); 83 | for (int j = 0; j < val_get(args[5]); j++) 84 | *(dat++) = *(vec++); 85 | return val_null; 86 | } 87 | DEFINE_PRIM(hx_gl_vector_set_floats, 5) 88 | DEFINE_PRIM_MULT(hx_gl_vector_set_floats_vec) 89 | 90 | value hx_gl_vector_get_byte(value data, value offset, value i) { 91 | char* dat = get_vector(data, offset); 92 | return alloc(dat[val_get(i)]); 93 | } 94 | value hx_gl_vector_get_short(value data, value offset, value i) { 95 | short* dat = get_vector(data, offset); 96 | return alloc(dat[val_get(i)]); 97 | } 98 | value hx_gl_vector_get_int(value data, value offset, value i) { 99 | int* dat = get_vector(data, offset); 100 | return alloc(dat[val_get(i)]); 101 | } 102 | value hx_gl_vector_get_float(value data, value offset, value i) { 103 | float* dat = get_vector(data, offset); 104 | return alloc(dat[val_get(i)]); 105 | } 106 | value hx_gl_vector_get_double(value data, value offset, value i) { 107 | double* dat = get_vector(data, offset); 108 | return alloc(dat[val_get(i)]); 109 | } 110 | DEFINE_PRIM(hx_gl_vector_get_byte, 3) 111 | DEFINE_PRIM(hx_gl_vector_get_short, 3) 112 | DEFINE_PRIM(hx_gl_vector_get_int, 3) 113 | DEFINE_PRIM(hx_gl_vector_get_float, 3) 114 | DEFINE_PRIM(hx_gl_vector_get_double, 3) 115 | 116 | value hx_gl_vector_set_byte(value data, value offset, value i, value x) { 117 | char* dat = get_vector(data, offset); 118 | return alloc(dat[val_get(i)] = val_get(x)); 119 | } 120 | value hx_gl_vector_set_short(value data, value offset, value i, value x) { 121 | short* dat = get_vector(data, offset); 122 | return alloc(dat[val_get(i)] = val_get(x)); 123 | } 124 | value hx_gl_vector_set_int(value data, value offset, value i, value x) { 125 | int* dat = get_vector(data, offset); 126 | return alloc(dat[val_get(i)] = val_get(x)); 127 | } 128 | value hx_gl_vector_set_float(value data, value offset, value i, value x) { 129 | float* dat = get_vector(data, offset); 130 | return alloc(dat[val_get(i)] = val_get(x)); 131 | } 132 | value hx_gl_vector_set_double(value data, value offset, value i, value x) { 133 | double* dat = get_vector(data, offset); 134 | return alloc(dat[val_get(i)] = val_get(x)); 135 | } 136 | DEFINE_PRIM(hx_gl_vector_set_byte, 4) 137 | DEFINE_PRIM(hx_gl_vector_set_short, 4) 138 | DEFINE_PRIM(hx_gl_vector_set_int, 4) 139 | DEFINE_PRIM(hx_gl_vector_set_float, 4) 140 | DEFINE_PRIM(hx_gl_vector_set_double, 4) 141 | 142 | void finalise_vector(value v) { 143 | Vector* dat = (Vector*)val_data(v); 144 | free(dat->dat); 145 | } 146 | value vector_array(value arr, int T) { 147 | int size = val_array_size(arr); 148 | int t = byte_kind(T); 149 | if (t == -1) { 150 | printf("OGL Type not supported for void* data\n"); 151 | neko_error(); 152 | } 153 | 154 | int j = 0; 155 | for (int i = 0; i < size; i++) { 156 | value d = val_array_i(arr, i); 157 | if (val_is_int(d) || val_is_float(d) || val_is_bool(d)) { 158 | j++; 159 | } 160 | else { 161 | j += val_array_size(d); 162 | } 163 | } 164 | 165 | void* dat = malloc(j * byte_size(T)); 166 | j = 0; 167 | for (int i = 0; i < size; i++) { 168 | value d = val_array_i(arr, i); 169 | if (val_is_int(d) || val_is_float(d) || val_is_bool(d)) { 170 | if (t == 0) ((char *)(dat))[j++] = val_get (d); 171 | else if(t == 1) ((short*)(dat))[j++] = val_get (d); 172 | else if(t == 2) ((int *)(dat))[j++] = val_get (d); 173 | else if(t == 3) ((float*)(dat))[j++] = val_get(d); 174 | else ((double*)(dat))[j++] = val_get(d); 175 | } 176 | else { 177 | int size2 = val_array_size(d); 178 | for (int k = 0; k < size2; k++) { 179 | value e = val_array_i(d, k); 180 | if (val_is_int(e) || val_is_float(e) || val_is_bool(e)) { 181 | if (t == 0) ((char *)(dat))[j++] = val_get (e); 182 | else if(t == 1) ((short*)(dat))[j++] = val_get (e); 183 | else if(t == 2) ((int *)(dat))[j++] = val_get (e); 184 | else if(t == 3) ((float*)(dat))[j++] = val_get(e); 185 | else ((double*)(dat))[j++] = val_get(e); 186 | } 187 | else { 188 | printf("arr had dim > 2\n"); 189 | neko_error(); 190 | } 191 | } 192 | } 193 | } 194 | 195 | Vector *vec = new Vector; 196 | vec->dat = dat; 197 | vec->size = j * byte_size(T); 198 | value v = alloc_abstract(k_Vector, vec); 199 | val_gc(v, finalise_vector); 200 | return v; 201 | } 202 | 203 | value hx_gl_allocVector(value type, value count) { 204 | void* dat = malloc(val_get(count) * byte_size(val_get(type))); 205 | Vector *vec = new Vector; 206 | vec->dat = dat; 207 | vec->size = val_get(count) * byte_size(val_get(type)); 208 | value v = alloc_abstract(k_Vector, vec); 209 | val_gc(v, finalise_vector); 210 | return v; 211 | } 212 | value hx_gl_createVector(value arr, value type) { 213 | return vector_array(arr, val_get(type)); 214 | } 215 | value hx_gl_dataVector(value data, value size) { 216 | const char* buf; 217 | if (val_is_string(data)) buf = val_get(data); 218 | else buf = buffer_data(val_to_buffer(data)); 219 | Vector* vec = new Vector; 220 | vec->dat = (void*)buf; 221 | vec->size = val_get(size); 222 | value v = alloc_abstract(k_Vector, vec); 223 | return v; 224 | } 225 | value hx_gl_arrvector_resize(value buf, value size) { 226 | Vector* vec = (Vector*)val_data(buf); 227 | void* ndat = malloc(val_get(size)); 228 | int cpy = val_get(size); 229 | if (cpy > vec->size) cpy = vec->size; 230 | memcpy(ndat, vec->dat, cpy); 231 | free(vec->dat); 232 | vec->dat = ndat; 233 | vec->size = val_get(size); 234 | return buf; 235 | } 236 | DEFINE_PRIM(hx_gl_allocVector, 2); 237 | DEFINE_PRIM(hx_gl_createVector, 2); 238 | DEFINE_PRIM(hx_gl_arrvector_resize, 2); 239 | DEFINE_PRIM(hx_gl_dataVector, 2); 240 | 241 | 242 | DECLARE_KIND(k_Sync); 243 | DEFINE_KIND(k_Sync); 244 | 245 | 246 | // ================================================================================================ 247 | // A 248 | // ================================================================================================ 249 | value hx_gl_activeTexture(value texture) { 250 | glActiveTexture(val_get(texture)); 251 | return val_null; 252 | } 253 | value hx_gl_attachShader(value program, value shader) { 254 | glAttachShader(val_get(program), val_get(shader)); 255 | return val_null; 256 | } 257 | DEFINE_PRIM(hx_gl_activeTexture, 1); 258 | DEFINE_PRIM(hx_gl_attachShader, 2); 259 | 260 | // ================================================================================================ 261 | // B 262 | // ================================================================================================ 263 | value hx_gl_beginConditionalRender(value id, value mode) { 264 | glBeginConditionalRender(val_get(id), val_get(mode)); 265 | return val_null; 266 | } 267 | value hx_gl_beginQuery(value target, value id) { 268 | glBeginQuery(val_get(target), val_get(id)); 269 | return val_null; 270 | } 271 | value hx_gl_beginTransformFeedback(value primitiveMode) { 272 | glBeginTransformFeedback(val_get(primitiveMode)); 273 | return val_null; 274 | } 275 | value hx_gl_bindAttribLocation(value program, value index, value name) { 276 | glBindAttribLocation(val_get(program), val_get(index), val_get(name)); 277 | return val_null; 278 | } 279 | value hx_gl_bindBuffer(value target, value _buffer) { 280 | glBindBuffer(val_get(target), val_get(_buffer)); 281 | return val_null; 282 | } 283 | value hx_gl_bindBufferBase(value target, value index, value _buffer) { 284 | glBindBufferBase(val_get(target), val_get(index), val_get(_buffer)); 285 | return val_null; 286 | } 287 | value hx_gl_bindBufferRange(value target, value index, value _buffer, value offset, value size) { 288 | glBindBufferRange(val_get(target), val_get(index), val_get(_buffer), val_get(offset), val_get(size)); 289 | return val_null; 290 | } 291 | value hx_gl_bindFragDataLocation(value program, value colorNumber, value name) { 292 | glBindFragDataLocation(val_get(program), val_get(colorNumber), val_get(name)); 293 | return val_null; 294 | } 295 | value hx_gl_bindFragDataLocationIndexed(value program, value colorNumber, value index, value name) { 296 | glBindFragDataLocationIndexed(val_get(program), val_get(colorNumber), val_get(index), val_get(name)); 297 | return val_null; 298 | } 299 | value hx_gl_bindFramebuffer(value target, value framebuffer) { 300 | glBindFramebuffer(val_get(target), val_get(framebuffer)); 301 | return val_null; 302 | } 303 | value hx_gl_bindRenderbuffer(value target, value renderbuffer) { 304 | glBindRenderbuffer(val_get(target), val_get(renderbuffer)); 305 | return val_null; 306 | } 307 | value hx_gl_bindSampler(value target, value sampler) { 308 | glBindSampler(val_get(target), val_get(sampler)); 309 | return val_null; 310 | } 311 | value hx_gl_bindTexture(value target, value texture) { 312 | glBindTexture(val_get(target), val_get(texture)); 313 | return val_null; 314 | } 315 | value hx_gl_bindVertexArray(value arr) { 316 | glBindVertexArray(val_get(arr)); 317 | return val_null; 318 | } 319 | value hx_gl_blendColor(value r, value g, value b, value a) { 320 | glBlendColor(val_get(r), val_get(g), val_get(b), val_get(a)); 321 | return val_null; 322 | } 323 | value hx_gl_blendEquation(value mode) { 324 | glBlendEquation(val_get(mode)); 325 | return val_null; 326 | } 327 | value hx_gl_blendEquationSeparate(value modeRGB, value modeAlpha) { 328 | glBlendEquationSeparate(val_get(modeRGB), val_get(modeAlpha)); 329 | return val_null; 330 | } 331 | value hx_gl_blendFunc(value sfactor, value dfactor) { 332 | glBlendFunc(val_get(sfactor), val_get(dfactor)); 333 | return val_null; 334 | } 335 | value hx_gl_blendFuncSeparate(value srcrgb, value dstrgb, value srca, value dsta) { 336 | glBlendFuncSeparate(val_get(srcrgb), val_get(dstrgb), val_get(srca), val_get(dsta)); 337 | return val_null; 338 | } 339 | value hx_gl_blitFramebuffer(value* args, int nargs) { 340 | glBlitFramebuffer( 341 | val_get(args[0]), 342 | val_get(args[1]), 343 | val_get(args[2]), 344 | val_get(args[3]), 345 | val_get(args[4]), 346 | val_get(args[5]), 347 | val_get(args[6]), 348 | val_get(args[7]), 349 | val_get(args[8]), 350 | val_get(args[9]) 351 | ); 352 | return val_null; 353 | } 354 | value hx_gl_bufferData(value target, value size, value data, value dataOffset, value usage) { 355 | glBufferData(val_get(target), val_get(size), get_vector(data, dataOffset), val_get(usage)); 356 | return val_null; 357 | } 358 | value hx_gl_bufferSubData(value target, value offset, value size, value data, value dataOffset) { 359 | glBufferSubData(val_get(target), val_get(offset), val_get(size), get_vector(data, dataOffset)); 360 | return val_null; 361 | } 362 | DEFINE_PRIM(hx_gl_beginConditionalRender, 2); 363 | DEFINE_PRIM(hx_gl_beginQuery, 2); 364 | DEFINE_PRIM(hx_gl_beginTransformFeedback, 1); 365 | DEFINE_PRIM(hx_gl_bindAttribLocation, 3); 366 | DEFINE_PRIM(hx_gl_bindBuffer, 2); 367 | DEFINE_PRIM(hx_gl_bindBufferBase, 3); 368 | DEFINE_PRIM(hx_gl_bindBufferRange, 5); 369 | DEFINE_PRIM(hx_gl_bindFragDataLocation, 3); 370 | DEFINE_PRIM(hx_gl_bindFragDataLocationIndexed,4); 371 | DEFINE_PRIM(hx_gl_bindFramebuffer, 2); 372 | DEFINE_PRIM(hx_gl_bindRenderbuffer, 2); 373 | DEFINE_PRIM(hx_gl_bindSampler, 2); 374 | DEFINE_PRIM(hx_gl_bindTexture, 2); 375 | DEFINE_PRIM(hx_gl_bindVertexArray, 1); 376 | DEFINE_PRIM(hx_gl_blendColor, 4); 377 | DEFINE_PRIM(hx_gl_blendEquation, 1); 378 | DEFINE_PRIM(hx_gl_blendEquationSeparate, 2); 379 | DEFINE_PRIM(hx_gl_blendFunc, 2); 380 | DEFINE_PRIM(hx_gl_blendFuncSeparate, 4); 381 | DEFINE_PRIM_MULT(hx_gl_blitFramebuffer); 382 | DEFINE_PRIM(hx_gl_bufferData, 5); 383 | DEFINE_PRIM(hx_gl_bufferSubData, 5); 384 | 385 | // ================================================================================================ 386 | // C 387 | // ================================================================================================ 388 | value hx_gl_checkFramebufferStatus(value target) { 389 | return alloc(glCheckFramebufferStatus(val_get(target))); 390 | } 391 | value hx_gl_clampColor(value target, value clamp) { 392 | glClampColor(val_get(target), val_get(clamp)); 393 | return val_null; 394 | } 395 | value hx_gl_clear(value mask) { 396 | glClear(val_get(mask)); 397 | return val_null; 398 | } 399 | value hx_gl_clearBufferiv(value _buffer, value drawBuffer, value _value) { 400 | GLint* buf = copy_ints(_value); 401 | glClearBufferiv(val_get(_buffer), val_get(drawBuffer), buf); 402 | delete [] buf; 403 | return val_null; 404 | } 405 | value hx_gl_clearBufferuiv(value _buffer, value drawBuffer, value _value) { 406 | GLuint* buf = copy_uints(_value); 407 | glClearBufferuiv(val_get(_buffer), val_get(drawBuffer), buf); 408 | delete[] buf; 409 | return val_null; 410 | } 411 | value hx_gl_clearBufferfv(value _buffer, value drawBuffer, value _value, value byteOffset) { 412 | glClearBufferfv(val_get(_buffer), val_get(drawBuffer), get_vector(_value, byteOffset)); 413 | return val_null; 414 | } 415 | value hx_gl_clearBufferfi(value _buffer, value drawBuffer, value depth, value stencil) { 416 | glClearBufferfi(val_get(_buffer), val_get(drawBuffer), val_get(depth), val_get(stencil)); 417 | return val_null; 418 | } 419 | value hx_gl_clearColor(value r, value g, value b, value a) { 420 | glClearColor(val_get(r), val_get(g), val_get(b), val_get(a)); 421 | return val_null; 422 | } 423 | value hx_gl_clearDepth(value depth) { 424 | glClearDepth(val_get(depth)); 425 | return val_null; 426 | } 427 | value hx_gl_clearStencil(value stencil) { 428 | glClearStencil(val_get(stencil)); 429 | return val_null; 430 | } 431 | value hx_gl_clientWaitSync(value sync, value flags, value timeLow, value timeHigh) { 432 | val_check_kind(sync, k_Sync); 433 | GLsync syncVal = (GLsync)val_data(sync); 434 | GLuint64 val; 435 | ((int*)&val)[0] = val_get(timeLow); 436 | ((int*)&val)[1] = val_get(timeHigh); 437 | return alloc(glClientWaitSync(syncVal, val_get(flags), val)); 438 | } 439 | value hx_gl_colorMask(value r, value g, value b, value a) { 440 | glColorMask(val_get(r), val_get(g), val_get(b), val_get(a)); 441 | return val_null; 442 | } 443 | value hx_gl_colorMaski(value buf, value r, value g, value b, value a) { 444 | glColorMaski(val_get(buf), val_get(r), val_get(g), val_get(b), val_get(a)); 445 | return val_null; 446 | } 447 | value hx_gl_compileShader(value shader) { 448 | glCompileShader(val_get(shader)); 449 | 450 | int result; 451 | glGetShaderiv(val_get(shader), GL_COMPILE_STATUS, &result); 452 | if (!result) { 453 | int length; 454 | glGetShaderiv(val_get(shader), GL_INFO_LOG_LENGTH, &length); 455 | char* err = new char[length]; 456 | glGetShaderInfoLog(val_get(shader), length, NULL, err); 457 | return alloc(err); 458 | } 459 | else { 460 | return val_null; 461 | } 462 | } 463 | value hx_gl_compressedTexImage1D(value* args, int nargs) { 464 | glCompressedTexImage1D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), get_vector(args[6], args[7])); 465 | return val_null; 466 | } 467 | value hx_gl_compressedTexImage2D(value* args, int nargs) { 468 | glCompressedTexImage2D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), get_vector(args[7], args[8])); 469 | return val_null; 470 | } 471 | value hx_gl_compressedTexImage3D(value* args, int nargs) { 472 | glCompressedTexImage3D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7]), get_vector(args[8], args[9])); 473 | return val_null; 474 | } 475 | value hx_gl_compressedTexSubImage1D(value* args, int nargs) { 476 | glCompressedTexSubImage1D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), get_vector(args[6], args[7])); 477 | return val_null; 478 | } 479 | value hx_gl_compressedTexSubImage2D(value* args, int nargs) { 480 | glCompressedTexSubImage2D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7]), get_vector(args[8], args[9])); 481 | return val_null; 482 | } 483 | value hx_gl_compressedTexSubImage3D(value* args, int nargs) { 484 | glCompressedTexSubImage3D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7]), val_get(args[8]), val_get(args[9]), get_vector(args[10], args[11])); 485 | return val_null; 486 | } 487 | value hx_gl_copyBufferSubData(value readt, value writet, value reado, value writeo, value size) { 488 | glCopyBufferSubData(val_get(readt), val_get(writet), val_get(reado), val_get(writeo), val_get(size)); 489 | return val_null; 490 | } 491 | value hx_gl_copyTexImage1D(value* args, int nargs) { 492 | glCopyTexImage1D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6])); 493 | return val_null; 494 | } 495 | value hx_gl_copyTexImage2D(value* args, int nargs) { 496 | glCopyTexImage2D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7])); 497 | return val_null; 498 | } 499 | value hx_gl_copyTexSubImage1D(value* args, int nargs) { 500 | glCopyTexSubImage1D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5])); 501 | return val_null; 502 | } 503 | value hx_gl_copyTexSubImage2D(value* args, int nargs) { 504 | glCopyTexSubImage2D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7])); 505 | return val_null; 506 | } 507 | value hx_gl_copyTexSubImage3D(value* args, int nargs) { 508 | glCopyTexSubImage3D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7]), val_get(args[8])); 509 | return val_null; 510 | } 511 | value hx_gl_createShader(value type) { 512 | return alloc(glCreateShader(val_get(type))); 513 | } 514 | value hx_gl_createProgram() { 515 | return alloc(glCreateProgram()); 516 | } 517 | value hx_gl_cullFace(value mode) { 518 | glCullFace(val_get(mode)); 519 | return val_null; 520 | } 521 | DEFINE_PRIM(hx_gl_checkFramebufferStatus, 1); 522 | DEFINE_PRIM(hx_gl_clampColor, 2); 523 | DEFINE_PRIM(hx_gl_clear, 1); 524 | DEFINE_PRIM(hx_gl_clearBufferiv, 3); 525 | DEFINE_PRIM(hx_gl_clearBufferuiv, 3); 526 | DEFINE_PRIM(hx_gl_clearBufferfv, 4); 527 | DEFINE_PRIM(hx_gl_clearBufferfi, 4); 528 | DEFINE_PRIM(hx_gl_clearColor, 4); 529 | DEFINE_PRIM(hx_gl_clearDepth, 1); 530 | DEFINE_PRIM(hx_gl_clearStencil, 1); 531 | DEFINE_PRIM(hx_gl_clientWaitSync, 4); 532 | DEFINE_PRIM(hx_gl_colorMask, 4); 533 | DEFINE_PRIM(hx_gl_colorMaski, 5); 534 | DEFINE_PRIM(hx_gl_compileShader, 1); 535 | DEFINE_PRIM_MULT(hx_gl_compressedTexImage1D); 536 | DEFINE_PRIM_MULT(hx_gl_compressedTexImage2D); 537 | DEFINE_PRIM_MULT(hx_gl_compressedTexImage3D); 538 | DEFINE_PRIM_MULT(hx_gl_compressedTexSubImage1D); 539 | DEFINE_PRIM_MULT(hx_gl_compressedTexSubImage2D); 540 | DEFINE_PRIM_MULT(hx_gl_compressedTexSubImage3D); 541 | DEFINE_PRIM(hx_gl_copyBufferSubData, 5); 542 | DEFINE_PRIM_MULT(hx_gl_copyTexImage1D); 543 | DEFINE_PRIM_MULT(hx_gl_copyTexImage2D); 544 | DEFINE_PRIM_MULT(hx_gl_copyTexSubImage1D); 545 | DEFINE_PRIM_MULT(hx_gl_copyTexSubImage2D); 546 | DEFINE_PRIM_MULT(hx_gl_copyTexSubImage3D); 547 | DEFINE_PRIM(hx_gl_createShader, 1); 548 | DEFINE_PRIM(hx_gl_createProgram, 0); 549 | DEFINE_PRIM(hx_gl_cullFace, 1); 550 | 551 | // ================================================================================================ 552 | // D 553 | // ================================================================================================ 554 | value hx_gl_deleteBuffers(value buffers) { 555 | GLuint* buf = copy_uints(buffers); 556 | glDeleteBuffers(val_array_size(buffers), buf); 557 | delete[] buf; 558 | return val_null; 559 | } 560 | value hx_gl_deleteFramebuffers(value buffers) { 561 | GLuint* buf = copy_uints(buffers); 562 | glDeleteFramebuffers(val_array_size(buffers), buf); 563 | delete[] buf; 564 | return val_null; 565 | } 566 | value hx_gl_deleteProgram(value program) { 567 | glDeleteProgram(val_get(program)); 568 | return val_null; 569 | } 570 | value hx_gl_deleteQueries(value queries) { 571 | GLuint* buf = copy_uints(queries); 572 | glDeleteQueries(val_array_size(queries), buf); 573 | delete[] buf; 574 | return val_null; 575 | } 576 | value hx_gl_deleteRenderbuffers(value buffers) { 577 | GLuint* buf = copy_uints(buffers); 578 | glDeleteRenderbuffers(val_array_size(buffers), buf); 579 | delete[] buf; 580 | return val_null; 581 | } 582 | value hx_gl_deleteSamplers(value samplers) { 583 | GLuint* buf = copy_uints(samplers); 584 | glDeleteSamplers(val_array_size(samplers), buf); 585 | delete[] buf; 586 | return val_null; 587 | } 588 | value hx_gl_deleteShader(value shader) { 589 | glDeleteShader(val_get(shader)); 590 | return val_null; 591 | } 592 | value hx_gl_deleteSync(value sync) { 593 | val_check_kind(sync, k_Sync); 594 | glDeleteSync((GLsync)val_data(sync)); 595 | return val_null; 596 | } 597 | value hx_gl_deleteTextures(value textures) { 598 | GLuint* buf = copy_uints(textures); 599 | glDeleteTextures(val_array_size(textures), buf); 600 | delete[] buf; 601 | return val_null; 602 | } 603 | value hx_gl_deleteVertexArrays(value vertexArrays) { 604 | GLuint* buf = copy_uints(vertexArrays); 605 | glDeleteVertexArrays(val_array_size(vertexArrays), buf); 606 | delete[] buf; 607 | return val_null; 608 | } 609 | value hx_gl_depthFunc(value func) { 610 | glDepthFunc(val_get(func)); 611 | return val_null; 612 | } 613 | value hx_gl_depthMask(value flag) { 614 | glDepthMask(val_get(flag)); 615 | return val_null; 616 | } 617 | value hx_gl_depthRange(value near, value far) { 618 | glDepthRange(val_get(near), val_get(far)); 619 | return val_null; 620 | } 621 | value hx_gl_detachShader(value program, value shader) { 622 | glDetachShader(val_get(program), val_get(shader)); 623 | return val_null; 624 | } 625 | value hx_gl_disable(value flag) { 626 | glDisable(val_get(flag)); 627 | return val_null; 628 | } 629 | value hx_gl_disableVertexAttribArray(value index) { 630 | glDisableVertexAttribArray(val_get(index)); 631 | return val_null; 632 | } 633 | value hx_gl_disablei(value cap, value index) { 634 | glDisablei(val_get(cap), val_get(index)); 635 | return val_null; 636 | } 637 | value hx_gl_drawArrays(value mode, value first, value count) { 638 | glDrawArrays(val_get(mode), val_get(first), val_get(count)); 639 | return val_null; 640 | } 641 | value hx_gl_drawArraysInstanced(value mode, value first, value count, value primcount) { 642 | glDrawArraysInstanced(val_get(mode), val_get(first), val_get(count), val_get(primcount)); 643 | return val_null; 644 | } 645 | value hx_gl_drawBuffer(value mode) { 646 | glDrawBuffer(val_get(mode)); 647 | return val_null; 648 | } 649 | value hx_gl_drawBuffers(value bufs) { 650 | GLenum* buf = copy_enum(bufs); 651 | glDrawBuffers(val_array_size(bufs), buf); 652 | delete[] buf; 653 | return val_null; 654 | } 655 | value hx_gl_drawElements(value mode, value count, value type, value indices, value byteOffset) { 656 | glDrawElements(val_get(mode), val_get(count), val_get(type), get_vector(indices, byteOffset)); 657 | return val_null; 658 | } 659 | value hx_gl_drawElementsBaseVertex(value* args, int narg) { 660 | glDrawElementsBaseVertex(val_get(args[0]), val_get(args[1]), val_get(args[2]), get_vector(args[3], args[4]), val_get(args[5])); 661 | return val_null; 662 | } 663 | value hx_gl_drawElementsInstanced(value* args, int narg) { 664 | glDrawElementsInstanced(val_get(args[0]), val_get(args[1]), val_get(args[2]), get_vector(args[3], args[4]), val_get(args[5])); 665 | return val_null; 666 | } 667 | value hx_gl_drawElementsInstancedBaseVertex(value* args, int nargs) { 668 | glDrawElementsInstancedBaseVertex(val_get(args[0]), val_get(args[1]), val_get(args[2]), get_vector(args[3], args[4]), val_get(args[5]), val_get(args[6])); 669 | return val_null; 670 | } 671 | value hx_gl_drawRangeElements(value* args, int nargs) { 672 | glDrawRangeElements(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), get_vector(args[5], args[6])); 673 | return val_null; 674 | } 675 | value hx_gl_drawRangeElementsBaseVertex(value* args, int nargs) { 676 | glDrawRangeElementsBaseVertex(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), get_vector(args[5], args[6]), val_get(args[7])); 677 | return val_null; 678 | } 679 | DEFINE_PRIM(hx_gl_deleteBuffers, 1); 680 | DEFINE_PRIM(hx_gl_deleteFramebuffers, 1); 681 | DEFINE_PRIM(hx_gl_deleteProgram, 1); 682 | DEFINE_PRIM(hx_gl_deleteQueries, 1); 683 | DEFINE_PRIM(hx_gl_deleteRenderbuffers, 1); 684 | DEFINE_PRIM(hx_gl_deleteSamplers, 1); 685 | DEFINE_PRIM(hx_gl_deleteShader, 1); 686 | DEFINE_PRIM(hx_gl_deleteSync, 1); 687 | DEFINE_PRIM(hx_gl_deleteTextures, 1); 688 | DEFINE_PRIM(hx_gl_deleteVertexArrays, 1); 689 | DEFINE_PRIM(hx_gl_depthFunc, 1); 690 | DEFINE_PRIM(hx_gl_depthMask, 1); 691 | DEFINE_PRIM(hx_gl_depthRange, 2); 692 | DEFINE_PRIM(hx_gl_detachShader, 2); 693 | DEFINE_PRIM(hx_gl_disable, 1); 694 | DEFINE_PRIM(hx_gl_disablei, 2); 695 | DEFINE_PRIM(hx_gl_disableVertexAttribArray, 1); 696 | DEFINE_PRIM(hx_gl_drawArrays, 3); 697 | DEFINE_PRIM(hx_gl_drawArraysInstanced, 4); 698 | DEFINE_PRIM(hx_gl_drawBuffer, 1); 699 | DEFINE_PRIM(hx_gl_drawBuffers, 1); 700 | DEFINE_PRIM(hx_gl_drawElements, 4); 701 | DEFINE_PRIM_MULT(hx_gl_drawElementsBaseVertex); 702 | DEFINE_PRIM_MULT(hx_gl_drawElementsInstanced); 703 | DEFINE_PRIM_MULT(hx_gl_drawElementsInstancedBaseVertex); 704 | DEFINE_PRIM_MULT(hx_gl_drawRangeElements); 705 | DEFINE_PRIM_MULT(hx_gl_drawRangeElementsBaseVertex); 706 | 707 | // ================================================================================================ 708 | // E 709 | // ================================================================================================ 710 | value hx_gl_enable(value cap) { 711 | glEnable(val_get(cap)); 712 | return val_null; 713 | } 714 | value hx_gl_enableVertexAttribArray(value index) { 715 | glEnableVertexAttribArray(val_get(index)); 716 | return val_null; 717 | } 718 | value hx_gl_enablei(value cap, value index) { 719 | glEnablei(val_get(cap), val_get(index)); 720 | return val_null; 721 | } 722 | value hx_gl_endConditionalRender() { 723 | glEndConditionalRender(); 724 | return val_null; 725 | } 726 | value hx_gl_endQuery(value target) { 727 | glEndQuery(val_get(target)); 728 | return val_null; 729 | } 730 | value hx_gl_endTransformFeedback() { 731 | glEndTransformFeedback(); 732 | return val_null; 733 | } 734 | DEFINE_PRIM(hx_gl_enable, 1); 735 | DEFINE_PRIM(hx_gl_enableVertexAttribArray, 1); 736 | DEFINE_PRIM(hx_gl_enablei, 2); 737 | DEFINE_PRIM(hx_gl_endConditionalRender, 0); 738 | DEFINE_PRIM(hx_gl_endQuery, 1); 739 | DEFINE_PRIM(hx_gl_endTransformFeedback, 0); 740 | 741 | // ================================================================================================ 742 | // F 743 | // ================================================================================================ 744 | value hx_gl_fenceSync(value condition, value flags) { 745 | glFenceSync(val_get(condition), val_get(flags)); 746 | return val_null; 747 | } 748 | value hx_gl_finish() { 749 | glFinish(); 750 | return val_null; 751 | } 752 | value hx_gl_flush() { 753 | glFlush(); 754 | return val_null; 755 | } 756 | value hx_gl_flushMappedBufferRange(value target, value offset, value length) { 757 | glFlushMappedBufferRange(val_get(target), val_get(offset), val_get(length)); 758 | return val_null; 759 | } 760 | value hx_gl_framebufferRenderbuffer(value target, value att, value rtarget, value rbuffer) { 761 | glFramebufferRenderbuffer(val_get(target), val_get(att), val_get(rtarget), val_get(rbuffer)); 762 | return val_null; 763 | } 764 | value hx_gl_framebufferTexture(value target, value att, value tex, value level) { 765 | glFramebufferTexture(val_get(target), val_get(att), val_get(tex), val_get(level)); 766 | return val_null; 767 | } 768 | value hx_gl_framebufferTexture1D(value target, value att, value textarg, value tex, value level) { 769 | glFramebufferTexture1D(val_get(target), val_get(att), val_get(textarg), val_get(tex), val_get(level)); 770 | return val_null; 771 | } 772 | value hx_gl_framebufferTexture2D(value target, value att, value textarg, value tex, value level) { 773 | glFramebufferTexture2D(val_get(target), val_get(att), val_get(textarg), val_get(tex), val_get(level)); 774 | return val_null; 775 | } 776 | value hx_gl_framebufferTexture3D(value* args, int nargs) { 777 | glFramebufferTexture3D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5])); 778 | return val_null; 779 | } 780 | value hx_gl_framebufferTextureLayer(value target, value att, value texture, value level, value layer) { 781 | glFramebufferTextureLayer(val_get(target), val_get(att), val_get(texture), val_get(level), val_get(layer)); 782 | return val_null; 783 | } 784 | value hx_gl_frontFace(value mode) { 785 | glFrontFace(val_get(mode)); 786 | return val_null; 787 | } 788 | DEFINE_PRIM(hx_gl_fenceSync, 2); 789 | DEFINE_PRIM(hx_gl_finish, 0); 790 | DEFINE_PRIM(hx_gl_flush, 0); 791 | DEFINE_PRIM(hx_gl_flushMappedBufferRange, 3); 792 | DEFINE_PRIM(hx_gl_framebufferRenderbuffer, 4); 793 | DEFINE_PRIM(hx_gl_framebufferTexture, 4); 794 | DEFINE_PRIM(hx_gl_framebufferTexture1D, 5); 795 | DEFINE_PRIM(hx_gl_framebufferTexture2D, 5); 796 | DEFINE_PRIM_MULT(hx_gl_framebufferTexture3D); 797 | DEFINE_PRIM(hx_gl_framebufferTextureLayer, 5); 798 | DEFINE_PRIM(hx_gl_frontFace, 1); 799 | 800 | // ================================================================================================ 801 | // G 802 | // ================================================================================================ 803 | value hx_gl_genBuffers(value n, value buffers) { 804 | GLuint* buf = new GLuint[val_get(n)]; 805 | glGenBuffers(val_get(n), buf); 806 | copy_del_uints(buffers, buf, val_get(n)); 807 | return val_null; 808 | } 809 | value hx_gl_genFramebuffers(value n, value buffers) { 810 | GLuint* buf = new GLuint[val_get(n)]; 811 | glGenFramebuffers(val_get(n), buf); 812 | copy_del_uints(buffers, buf, val_get(n)); 813 | return val_null; 814 | } 815 | value hx_gl_genQueries(value n, value queries) { 816 | GLuint* buf = new GLuint[val_get(n)]; 817 | glGenQueries(val_get(n), buf); 818 | copy_del_uints(queries, buf, val_get(n)); 819 | return val_null; 820 | } 821 | value hx_gl_genRenderbuffers(value n, value buffers) { 822 | GLuint* buf = new GLuint[val_get(n)]; 823 | glGenRenderbuffers(val_get(n), buf); 824 | copy_del_uints(buffers, buf, val_get(n)); 825 | return val_null; 826 | } 827 | value hx_gl_genSamplers(value n, value samplers) { 828 | GLuint* buf = new GLuint[val_get(n)]; 829 | glGenSamplers(val_get(n), buf); 830 | copy_del_uints(samplers, buf, val_get(n)); 831 | return val_null; 832 | } 833 | value hx_gl_genTextures(value n, value arrays) { 834 | GLuint* buf = new GLuint[val_get(n)]; 835 | glGenTextures(val_get(n), buf); 836 | copy_del_uints(arrays, buf, val_get(n)); 837 | return val_null; 838 | } 839 | value hx_gl_genVertexArrays(value n, value arrays) { 840 | GLuint* buf = new GLuint[val_get(n)]; 841 | glGenVertexArrays(val_get(n), buf); 842 | copy_del_uints(arrays, buf, val_get(n)); 843 | return val_null; 844 | } 845 | value hx_gl_generateMipmap(value target) { 846 | glGenerateMipmap(val_get(target)); 847 | return val_null; 848 | } 849 | int glGetICount(value pname) { 850 | int p = val_get(pname); 851 | if (p==GL_ALIASED_LINE_WIDTH_RANGE) return 2; 852 | else if (p==GL_SMOOTH_LINE_WIDTH_RANGE) return 2; 853 | else if (p==GL_BLEND_COLOR) return 4; 854 | else if (p==GL_COLOR_CLEAR_VALUE) return 4; 855 | else if (p==GL_COLOR_WRITEMASK) return 4; 856 | else if (p==GL_COMPRESSED_TEXTURE_FORMATS) return GL_NUM_COMPRESSED_TEXTURE_FORMATS; 857 | else if (p==GL_DEPTH_RANGE) return 2; 858 | else if (p==GL_LINE_WIDTH_RANGE) return 2; 859 | else if (p==GL_MAX_VIEWPORT_DIMS) return 2; 860 | else if (p==GL_POINT_SIZE_RANGE) return 2; 861 | else if (p==GL_SCISSOR_BOX) return 4; 862 | else if (p==GL_VIEWPORT) return 4; 863 | return 1; 864 | } 865 | #define GLGETV(N,T,G) \ 866 | value hx_gl_get##N##v(value pname, value outparams) { \ 867 | int count = glGetICount(pname); \ 868 | G* params = new G[count]; \ 869 | val_array_set_size(outparams, count); \ 870 | glGet##N##v(val_get(pname), params); \ 871 | for (int i = 0; i < count; i++) val_array_set_i(outparams, i, alloc(params[i])); \ 872 | delete[] params; \ 873 | return val_null; \ 874 | } \ 875 | DEFINE_PRIM(hx_gl_get##N##v, 2) 876 | GLGETV(Boolean, bool, GLboolean); 877 | GLGETV(Double, double, GLdouble); 878 | GLGETV(Float, double, GLfloat); 879 | GLGETV(Integer, int, GLint); 880 | value hx_gl_getInteger64v(value pname, value outparams) { 881 | int count = glGetICount(pname); 882 | GLint64* params = new GLint64[count]; 883 | val_array_set_size(outparams, count*2); 884 | glGetInteger64v(val_get(pname), params); 885 | for (int i = 0; i < count; i++) { 886 | val_array_set_i(outparams, i*2, alloc(((int*)¶ms[i])[0])); 887 | val_array_set_i(outparams, i*2+1, alloc(((int*)¶ms[i])[1])); 888 | } 889 | delete[] params; 890 | return val_null; 891 | } 892 | DEFINE_PRIM(hx_gl_getInteger64v, 2); 893 | #define GLGETIV(N,T,G) \ 894 | value hx_gl_get##N##i_v(value pname, value index, value outparams) { \ 895 | int count = glGetICount(pname); \ 896 | G* params = new G[count]; \ 897 | val_array_set_size(outparams, count); \ 898 | glGet##N##i_v(val_get(pname), val_get(index), params); \ 899 | for (int i = 0; i < count; i++) val_array_set_i(outparams, i, alloc(params[i])); \ 900 | delete[] params; \ 901 | return val_null; \ 902 | } \ 903 | DEFINE_PRIM(hx_gl_get##N##v, 3) 904 | GLGETIV(Boolean, bool, GLboolean); 905 | GLGETIV(Integer, int, GLint); 906 | value hx_gl_getInteger64i_v(value pname, value index, value outparams) { 907 | int count = glGetICount(pname); 908 | GLint64* params = new GLint64[count]; 909 | val_array_set_size(outparams, count*2); 910 | glGetInteger64i_v(val_get(pname), val_get(index), params); 911 | for (int i = 0; i < count; i++) { 912 | val_array_set_i(outparams, i*2, alloc(((int*)¶ms[i])[0])); 913 | val_array_set_i(outparams, i*2+1, alloc(((int*)¶ms[i])[1])); 914 | } 915 | delete[] params; 916 | return val_null; 917 | } 918 | DEFINE_PRIM(hx_gl_getInteger64i_v, 3); 919 | value hx_gl_getActiveAttrib(value program, value index) { 920 | GLchar* name = new GLchar[1024]; 921 | name[0] = '\0'; 922 | GLint size = 0; 923 | GLenum type = 0; 924 | glGetActiveAttrib(val_get(program), val_get(index), 1024, NULL, &size, &type, name); 925 | 926 | value v = alloc_empty_object(); 927 | alloc_field(v, val_id("name"), alloc(name)); 928 | alloc_field(v, val_id("size"), alloc(size)); 929 | alloc_field(v, val_id("type"), alloc(type)); 930 | return v; 931 | } 932 | value hx_gl_getActiveUniform(value program, value index) { 933 | GLchar* name = new GLchar[1024]; 934 | name[0] = '\0'; 935 | GLint size = 0; 936 | GLenum type = 0; 937 | glGetActiveUniform(val_get(program), val_get(index), 1024, NULL, &size, &type, name); 938 | 939 | value v = alloc_empty_object(); 940 | alloc_field(v, val_id("name"), alloc(name)); 941 | alloc_field(v, val_id("size"), alloc(size)); 942 | alloc_field(v, val_id("type"), alloc(type)); 943 | return v; 944 | } 945 | value hx_gl_getActiveUniformBlockiv(value program, value index, value pname) { 946 | GLint ret; 947 | glGetActiveUniformBlockiv(val_get(program), val_get(index), val_get(pname), &ret); 948 | return alloc(ret); 949 | } 950 | value hx_gl_getActiveUniformBlockName(value program, value index) { 951 | GLchar* name = new GLchar[1024]; 952 | name[0] = '\0'; 953 | glGetActiveUniformBlockName(val_get(program), val_get(index), 1024, NULL, name); 954 | return alloc(name); 955 | } 956 | value hx_gl_getActiveUniformName(value program, value index) { 957 | GLchar* name = new GLchar[1024]; 958 | name[0] = '\0'; 959 | glGetActiveUniformName(val_get(program), val_get(index), 1024, NULL, name); 960 | return alloc(name); 961 | } 962 | value hx_gl_getActiveUniformsiv(value program, value uniforms, value pname, value params) { 963 | val_array_set_size(params, val_array_size(uniforms)); 964 | GLuint* buf = copy_uints(uniforms); 965 | GLint* pbuf = new GLint[val_array_size(uniforms)]; 966 | glGetActiveUniformsiv(val_get(program), val_array_size(uniforms), buf, val_get(pname), pbuf); 967 | copy_del_ints(params, pbuf, val_array_size(uniforms)); 968 | delete[] buf; 969 | return val_null; 970 | } 971 | value hx_gl_getAttachedShaders(value program, value ret) { 972 | GLuint* shaders = new GLuint[0xff]; 973 | GLsizei count; 974 | glGetAttachedShaders(val_get(program), 0xff, &count, shaders); 975 | val_array_set_size(ret, count); 976 | for (int i = 0; i < count; i++) val_array_set_i(ret, i, alloc(shaders[i])); 977 | delete[] shaders; 978 | return val_null; 979 | } 980 | value hx_gl_getAttribLocation(value program, value name) { 981 | return alloc(glGetAttribLocation(val_get(program), val_get(name))); 982 | } 983 | value hx_gl_getBufferParameteriv(value target, value value) { 984 | GLint ret; 985 | glGetBufferParameteriv(val_get(target), val_get(value), &ret); 986 | return alloc(ret); 987 | } 988 | value hx_gl_getBufferSubData(value target, value offset, value size, value data, value byteOffset) { 989 | glGetBufferSubData(val_get(target), val_get(offset), val_get(size), get_vector(data, byteOffset)); 990 | return val_null; 991 | } 992 | value hx_gl_getCompressedTexImage(value target, value lod, value img, value byteOffset) { 993 | glGetCompressedTexImage(val_get(target), val_get(lod), get_vector(img, byteOffset)); 994 | return val_null; 995 | } 996 | value hx_gl_getError() { 997 | return alloc(glGetError()); 998 | } 999 | value hx_gl_getFragDataIndex(value program, value name) { 1000 | return alloc(glGetFragDataIndex(val_get(program), val_get(name))); 1001 | } 1002 | value hx_gl_getFragDataLocation(value program, value name) { 1003 | return alloc(glGetFragDataLocation(val_get(program), val_get(name))); 1004 | } 1005 | value hx_gl_getFramebufferAttachmentParameteriv(value target, value attachment, value pname) { 1006 | GLint ret; 1007 | glGetFramebufferAttachmentParameteriv(val_get(target), val_get(attachment), val_get(pname), &ret); 1008 | return alloc(ret); 1009 | } 1010 | value hx_gl_getMultisamplefv(value pname, value index) { 1011 | GLfloat val[2]; 1012 | glGetMultisamplefv(val_get(pname), val_get(index), val); 1013 | value v = alloc_empty_object(); 1014 | alloc_field(v, val_id("x"), alloc(val[0])); 1015 | alloc_field(v, val_id("y"), alloc(val[1])); 1016 | return v; 1017 | } 1018 | value hx_gl_getProgramiv(value program, value pname) { 1019 | GLint ret; 1020 | glGetProgramiv(val_get(program), val_get(pname), &ret); 1021 | return alloc(ret); 1022 | } 1023 | value hx_gl_getQueryObjectiv(value id, value pname) { 1024 | GLint ret; 1025 | glGetQueryObjectiv(val_get(id), val_get(pname), &ret); 1026 | return alloc(ret); 1027 | } 1028 | value hx_gl_getQueryObjectuiv(value id, value pname) { 1029 | GLuint ret; 1030 | glGetQueryObjectuiv(val_get(id), val_get(pname), &ret); 1031 | return alloc(ret); 1032 | } 1033 | value hx_gl_getQueryObjecti64v(value id, value pname, value out) { 1034 | GLint64 ret; 1035 | glGetQueryObjecti64v(val_get(id), val_get(pname), &ret); 1036 | val_array_set_i(out, 0, alloc(((int*)&ret)[0])); 1037 | val_array_set_i(out, 1, alloc(((int*)&ret)[1])); 1038 | return val_null; 1039 | } 1040 | value hx_gl_getQueryObjectui64v(value id, value pname, value out) { 1041 | GLuint64 ret; 1042 | glGetQueryObjectui64v(val_get(id), val_get(pname), &ret); 1043 | val_array_set_i(out, 0, alloc(((int*)&ret)[0])); 1044 | val_array_set_i(out, 1, alloc(((int*)&ret)[1])); 1045 | return val_null; 1046 | } 1047 | value hx_gl_getQueryiv(value target, value pname) { 1048 | GLint ret; 1049 | glGetQueryiv(val_get(target), val_get(pname), &ret); 1050 | return alloc(ret); 1051 | } 1052 | value hx_gl_getRenderbufferParameteriv(value target, value pname) { 1053 | GLint ret; 1054 | glGetRenderbufferParameteriv(val_get(target), val_get(pname), &ret); 1055 | return alloc(ret); 1056 | } 1057 | 1058 | int glGetSamplerPCount(value pname) { 1059 | int p = val_get(pname); 1060 | if (p == GL_TEXTURE_BORDER_COLOR) return 4; 1061 | return 1; 1062 | } 1063 | #define GETSAMPLEP(N,T,G) \ 1064 | value hx_gl_getSamplerParameter##N##v(value sampler, value pname, value params) { \ 1065 | int cnt = glGetSamplerPCount(pname); \ 1066 | val_array_set_size(params, cnt); \ 1067 | glGetSamplerParameter##N##v(val_get(sampler), val_get(pname), (G*)val_array_##T(params)); \ 1068 | return params; \ 1069 | } \ 1070 | DEFINE_PRIM(hx_gl_getSamplerParameter##N##v, 3) 1071 | value hx_gl_getSamplerParameterfv(value sampler, value pname, value params) { 1072 | int cnt = glGetSamplerPCount(pname); 1073 | val_array_set_size(params, cnt); 1074 | GLfloat outs[4]; 1075 | glGetSamplerParameterfv(val_get(sampler), val_get(pname), outs); 1076 | for (int i = 0; i < cnt; i++) val_array_set_i(params, i, alloc(outs[i])); 1077 | return params; 1078 | } 1079 | DEFINE_PRIM(hx_gl_getSamplerParameterfv, 3); 1080 | GETSAMPLEP(i, int, GLint); 1081 | GETSAMPLEP(Ii, int, GLint); 1082 | GETSAMPLEP(Iui, int, GLuint); 1083 | 1084 | value hx_gl_getShaderiv(value shader, value pname) { 1085 | GLint ret; 1086 | glGetShaderiv(val_get(shader), val_get(pname), &ret); 1087 | return alloc(ret); 1088 | } 1089 | value hx_gl_getShaderSource(value shader) { 1090 | GLchar* source = new GLchar[0xffff]; 1091 | source[0] = '\0'; 1092 | glGetShaderSource(val_get(shader), 0xffff, NULL, source); 1093 | return alloc(source); 1094 | } 1095 | value hx_gl_getString(value name) { 1096 | const GLubyte* str = glGetString(val_get(name)); 1097 | char* ret = new GLchar[strlen((const char*)str)]; 1098 | strcpy(ret, (const char*)str); 1099 | return alloc(ret); 1100 | } 1101 | value hx_gl_getStringi(value name, value index) { 1102 | const GLubyte* str = glGetStringi(val_get(name), val_get(index)); 1103 | char* ret = new GLchar[strlen((const char*)str)]; 1104 | strcpy(ret, (const char*)str); 1105 | return alloc(ret); 1106 | } 1107 | value hx_gl_getSynciv(value sync, value pname) { 1108 | GLint ret; 1109 | glGetSynciv((GLsync)val_data(sync), val_get(pname), 1, NULL, &ret); 1110 | return alloc(ret); 1111 | } 1112 | value hx_gl_getTexImage(value* args, int narg) { 1113 | glGetTexImage(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), get_vector(args[4], args[5])); 1114 | return val_null; 1115 | } 1116 | value hx_gl_getTexLevelParameterfv(value target, value level, value pname) { 1117 | GLfloat ret; 1118 | glGetTexLevelParameterfv(val_get(target), val_get(level), val_get(pname), &ret); 1119 | return alloc(ret); 1120 | } 1121 | value hx_gl_getTexLevelParameteriv(value target, value level, value pname) { 1122 | GLint ret; 1123 | glGetTexLevelParameteriv(val_get(target), val_get(level), val_get(pname), &ret); 1124 | return alloc(ret); 1125 | } 1126 | 1127 | int glGetTexPCount(value pname) { 1128 | int p = val_get(pname); 1129 | if (p == GL_TEXTURE_BORDER_COLOR) return 4; 1130 | return 1; 1131 | } 1132 | #define GETTEXP(N,T,G) \ 1133 | value hx_gl_getTexParameter##N##v(value texture, value pname, value params) { \ 1134 | int cnt = glGetTexPCount(pname); \ 1135 | val_array_set_size(params, cnt); \ 1136 | glGetTexParameter##N##v(val_get(texture), val_get(pname), (G*)val_array_##T(params)); \ 1137 | return params; \ 1138 | } \ 1139 | DEFINE_PRIM(hx_gl_getTexParameter##N##v, 3) 1140 | value hx_gl_getTexParameterfv(value texture, value pname, value params) { 1141 | int cnt = glGetTexPCount(pname); 1142 | val_array_set_size(params, cnt); 1143 | GLfloat outs[4]; 1144 | glGetTexParameterfv(val_get(texture), val_get(pname), outs); 1145 | for (int i = 0; i < cnt; i++) val_array_set_i(params, i, alloc(outs[i])); 1146 | return params; 1147 | } 1148 | DEFINE_PRIM(hx_gl_getTexParameterfv, 3); 1149 | GETTEXP(i, int, GLint); 1150 | GETTEXP(Ii, int, GLint); 1151 | GETTEXP(Iui, int, GLuint); 1152 | 1153 | value hx_gl_getTransformFeedbackVarying(value program, value index) { 1154 | char* name = new char[0xff]; 1155 | GLsizei size; 1156 | GLenum type; 1157 | glGetTransformFeedbackVarying(val_get(program), val_get(index), 0xff, NULL, &size, &type, name); 1158 | value v = alloc_empty_object(); 1159 | alloc_field(v, val_id("name"), alloc(name)); 1160 | alloc_field(v, val_id("size"), alloc(size)); 1161 | alloc_field(v, val_id("type"), alloc(type)); 1162 | return v; 1163 | } 1164 | 1165 | #define GETUNIFORMP(N,T,G) \ 1166 | value hx_gl_getUniform##N##v(value program, value location, value params) { \ 1167 | val_array_set_size(params, 16); \ 1168 | glGetUniform##N##v(val_get(program), val_get(location), (G*)val_array_##T(params)); \ 1169 | return params; \ 1170 | } \ 1171 | DEFINE_PRIM(hx_gl_getUniform##N##v, 3) 1172 | value hx_gl_getUniformfv(value program, value location, value params) { 1173 | val_array_set_size(params, 16); //m4x4 1174 | GLfloat outs[16]; 1175 | glGetUniformfv(val_get(program), val_get(location), outs); 1176 | for (int i = 0; i < 16; i++) val_array_set_i(params, i, alloc(outs[i])); 1177 | return params; 1178 | } 1179 | DEFINE_PRIM(hx_gl_getUniformfv, 3); 1180 | GETUNIFORMP(i, int, GLint); 1181 | GETUNIFORMP(ui, int, GLuint); 1182 | 1183 | value hx_gl_getUniformBlockIndex(value program, value name) { 1184 | return alloc(glGetUniformBlockIndex(val_get(program), val_get(name))); 1185 | } 1186 | value hx_gl_getUniformIndices(value program, value names, value indices) { 1187 | int cnt = val_array_size(names); 1188 | const char** cnames = new const char*[cnt]; 1189 | for (int i = 0; i < cnt; i++) cnames[i] = val_get(val_array_i(names, i)); 1190 | GLuint* buf = copy_uints(indices); 1191 | glGetUniformIndices(val_get(program), cnt, cnames, buf); 1192 | copy_del_uints(indices, buf, val_array_size(indices)); 1193 | delete[] cnames; 1194 | return indices; 1195 | } 1196 | 1197 | int glGetVertexPCount(value pname) { 1198 | int p = val_get(pname); 1199 | if (p == GL_CURRENT_VERTEX_ATTRIB) return 4; 1200 | return 1; 1201 | } 1202 | #define GETVERTP(N,T,G) \ 1203 | value hx_gl_getVertexAttrib##N##v(value index, value pname, value params) { \ 1204 | int cnt = glGetVertexPCount(pname); \ 1205 | val_array_set_size(params, cnt); \ 1206 | glGetVertexAttrib##N##v(val_get(index), val_get(pname), (G*)val_array_##T(params)); \ 1207 | return params; \ 1208 | } \ 1209 | DEFINE_PRIM(hx_gl_getVertexAttrib##N##v, 3) 1210 | value hx_gl_getVertexAttribfv(value index, value pname, value params) { 1211 | int cnt = glGetVertexPCount(pname); 1212 | val_array_set_size(params, cnt); 1213 | GLfloat outs[4]; 1214 | glGetVertexAttribfv(val_get(index), val_get(pname), outs); 1215 | for (int i = 0; i < cnt; i++) val_array_set_i(params, i, alloc(outs[i])); 1216 | return params; 1217 | } 1218 | DEFINE_PRIM(hx_gl_getVertexAttribfv, 3); 1219 | GETVERTP(d, double, GLdouble); 1220 | GETVERTP(i, int, GLint); 1221 | GETVERTP(Ii, int, GLint); 1222 | GETVERTP(Iui, int, GLuint); 1223 | 1224 | value hx_gl_getUniformLocation(value program, value name) { 1225 | return alloc(glGetUniformLocation(val_get(program), val_get(name))); 1226 | } 1227 | DEFINE_PRIM(hx_gl_genBuffers, 2); 1228 | DEFINE_PRIM(hx_gl_genFramebuffers, 2); 1229 | DEFINE_PRIM(hx_gl_genQueries, 2); 1230 | DEFINE_PRIM(hx_gl_genRenderbuffers, 2); 1231 | DEFINE_PRIM(hx_gl_genSamplers, 2); 1232 | DEFINE_PRIM(hx_gl_genTextures, 2); 1233 | DEFINE_PRIM(hx_gl_genVertexArrays, 2); 1234 | DEFINE_PRIM(hx_gl_generateMipmap, 1); 1235 | DEFINE_PRIM(hx_gl_getActiveAttrib, 2); 1236 | DEFINE_PRIM(hx_gl_getActiveUniform, 2); 1237 | DEFINE_PRIM(hx_gl_getActiveUniformBlockiv, 3); 1238 | DEFINE_PRIM(hx_gl_getActiveUniformBlockName, 2); 1239 | DEFINE_PRIM(hx_gl_getActiveUniformName, 2); 1240 | DEFINE_PRIM(hx_gl_getActiveUniformsiv, 4); 1241 | DEFINE_PRIM(hx_gl_getAttachedShaders, 2); 1242 | DEFINE_PRIM(hx_gl_getAttribLocation, 2); 1243 | DEFINE_PRIM(hx_gl_getBufferParameteriv, 2); 1244 | DEFINE_PRIM(hx_gl_getBufferSubData, 5); 1245 | DEFINE_PRIM(hx_gl_getCompressedTexImage, 4); 1246 | DEFINE_PRIM(hx_gl_getError, 0); 1247 | DEFINE_PRIM(hx_gl_getFragDataIndex, 2); 1248 | DEFINE_PRIM(hx_gl_getFragDataLocation, 2); 1249 | DEFINE_PRIM(hx_gl_getFramebufferAttachmentParameteriv, 3); 1250 | DEFINE_PRIM(hx_gl_getMultisamplefv, 2); 1251 | DEFINE_PRIM(hx_gl_getProgramiv, 2); 1252 | DEFINE_PRIM(hx_gl_getQueryObjectiv, 2); 1253 | DEFINE_PRIM(hx_gl_getQueryObjectuiv, 2); 1254 | DEFINE_PRIM(hx_gl_getQueryObjecti64v, 3); 1255 | DEFINE_PRIM(hx_gl_getQueryObjectui64v, 3); 1256 | DEFINE_PRIM(hx_gl_getQueryiv, 2); 1257 | DEFINE_PRIM(hx_gl_getRenderbufferParameteriv, 2); 1258 | DEFINE_PRIM(hx_gl_getShaderiv, 2); 1259 | DEFINE_PRIM(hx_gl_getShaderSource, 1); 1260 | DEFINE_PRIM(hx_gl_getString, 1); 1261 | DEFINE_PRIM(hx_gl_getStringi, 2); 1262 | DEFINE_PRIM(hx_gl_getSynciv, 2); 1263 | DEFINE_PRIM_MULT(hx_gl_getTexImage); 1264 | DEFINE_PRIM(hx_gl_getTexLevelParameterfv, 3); 1265 | DEFINE_PRIM(hx_gl_getTexLevelParameteriv, 3); 1266 | DEFINE_PRIM(hx_gl_getTransformFeedbackVarying, 2); 1267 | DEFINE_PRIM(hx_gl_getUniformBlockIndex, 2); 1268 | DEFINE_PRIM(hx_gl_getUniformIndices, 3); 1269 | DEFINE_PRIM(hx_gl_getUniformLocation, 2); 1270 | 1271 | // ================================================================================================ 1272 | // H 1273 | // ================================================================================================ 1274 | value hx_gl_hint(value target, value mode) { 1275 | glHint(val_get(target), val_get(mode)); 1276 | return val_null; 1277 | } 1278 | DEFINE_PRIM(hx_gl_hint, 2); 1279 | 1280 | // ================================================================================================ 1281 | // I 1282 | // ================================================================================================ 1283 | value hx_gl_isBuffer(value buffer) { 1284 | return alloc(glIsBuffer(val_get(buffer))); 1285 | } 1286 | value hx_gl_isEnabled(value cap) { 1287 | return alloc(glIsEnabled(val_get(cap))); 1288 | } 1289 | value hx_gl_isEnabledi(value cap, value index) { 1290 | return alloc(glIsEnabledi(val_get(cap), val_get(index))); 1291 | } 1292 | value hx_gl_isFramebuffer(value buf) { 1293 | return alloc(glIsFramebuffer(val_get(buf))); 1294 | } 1295 | value hx_gl_isProgram(value program) { 1296 | return alloc(glIsProgram(val_get(program))); 1297 | } 1298 | value hx_gl_isQuery(value id) { 1299 | return alloc(glIsQuery(val_get(id))); 1300 | } 1301 | value hx_gl_isRenderbuffer(value buf) { 1302 | return alloc(glIsRenderbuffer(val_get(buf))); 1303 | } 1304 | value hx_gl_isSampler(value id) { 1305 | return alloc(glIsSampler(val_get(id))); 1306 | } 1307 | value hx_gl_isShader(value shader) { 1308 | return alloc(glIsShader(val_get(shader))); 1309 | } 1310 | value hx_gl_isSync(value sync) { 1311 | return alloc(glIsSync((GLsync)val_data(sync))); 1312 | } 1313 | value hx_gl_isTexture(value texture) { 1314 | return alloc(glIsTexture(val_get(texture))); 1315 | } 1316 | value hx_gl_isVertexArray(value array) { 1317 | return alloc(glIsVertexArray(val_get(array))); 1318 | } 1319 | DEFINE_PRIM(hx_gl_isBuffer, 1); 1320 | DEFINE_PRIM(hx_gl_isEnabled, 1); 1321 | DEFINE_PRIM(hx_gl_isEnabledi, 2); 1322 | DEFINE_PRIM(hx_gl_isFramebuffer, 1); 1323 | DEFINE_PRIM(hx_gl_isProgram, 1); 1324 | DEFINE_PRIM(hx_gl_isQuery, 1); 1325 | DEFINE_PRIM(hx_gl_isRenderbuffer, 1); 1326 | DEFINE_PRIM(hx_gl_isSampler, 1); 1327 | DEFINE_PRIM(hx_gl_isShader, 1); 1328 | DEFINE_PRIM(hx_gl_isSync, 1); 1329 | DEFINE_PRIM(hx_gl_isTexture, 1); 1330 | DEFINE_PRIM(hx_gl_isVertexArray, 1); 1331 | 1332 | // ================================================================================================ 1333 | // L 1334 | // ================================================================================================ 1335 | value hx_gl_lineWidth(value width) { 1336 | glLineWidth(val_get(width)); 1337 | return val_null; 1338 | } 1339 | value hx_gl_linkProgram(value program) { 1340 | glLinkProgram(val_get(program)); 1341 | 1342 | int result; 1343 | glGetProgramiv(val_get(program), GL_LINK_STATUS, &result); 1344 | if (!result) { 1345 | int length; 1346 | glGetProgramiv(val_get(program), GL_INFO_LOG_LENGTH, &length); 1347 | char* err = new char[length]; 1348 | glGetProgramInfoLog(val_get(program), length, NULL, err); 1349 | return alloc(err); 1350 | } 1351 | else { 1352 | return val_null; 1353 | } 1354 | } 1355 | value hx_gl_logicOp(value op) { 1356 | glLogicOp(val_get(op)); 1357 | return val_null; 1358 | } 1359 | DEFINE_PRIM(hx_gl_lineWidth, 1); 1360 | DEFINE_PRIM(hx_gl_linkProgram, 1); 1361 | DEFINE_PRIM(hx_gl_logicOp, 1); 1362 | 1363 | // ================================================================================================ 1364 | // M 1365 | // ================================================================================================ 1366 | value hx_gl_multiDrawArrays(value mode, value first, value count) { 1367 | GLint* buf1 = copy_ints(first); 1368 | GLint* buf2 = copy_ints(count); 1369 | glMultiDrawArrays(val_get(mode), buf1, buf2, val_array_size(first)); 1370 | delete[] buf1; 1371 | delete[] buf2; 1372 | return val_null; 1373 | } 1374 | value hx_gl_multiDrawElements(value mode, value count, value type, value indices, value byteOffsets) { 1375 | int cnt = val_array_size(indices); 1376 | const GLvoid** cindices = new const GLvoid*[cnt]; 1377 | for (int i = 0; i < cnt; i++) cindices[i] = get_vector(val_array_i(indices, i), val_array_i(byteOffsets, i)); 1378 | GLsizei* buf = (GLsizei*)copy_uints(count); 1379 | glMultiDrawElements(val_get(mode), buf, val_get(type), cindices, cnt); 1380 | delete[] buf; 1381 | delete[] cindices; 1382 | return val_null; 1383 | } 1384 | value hx_gl_multiDrawElementsBaseVertex(value* args, int narg) { 1385 | int cnt = val_array_size(args[3]); 1386 | GLvoid** cindices = new GLvoid*[cnt]; 1387 | for (int i = 0; i < cnt; i++) cindices[i] = get_vector(val_array_i(args[3], i), val_array_i(args[4], i)); 1388 | GLint* buf1 = copy_ints(args[1]); 1389 | GLint* buf2 = copy_ints(args[5]); 1390 | glMultiDrawElementsBaseVertex(val_get(args[0]), buf1, val_get(args[2]), cindices, cnt, buf2); 1391 | delete[] buf1; 1392 | delete[] buf2; 1393 | delete[] cindices; 1394 | return val_null; 1395 | } 1396 | DEFINE_PRIM(hx_gl_multiDrawArrays, 3); 1397 | DEFINE_PRIM(hx_gl_multiDrawElements, 5); 1398 | DEFINE_PRIM_MULT(hx_gl_multiDrawElementsBaseVertex); 1399 | 1400 | // ================================================================================================ 1401 | // P 1402 | // ================================================================================================ 1403 | value hx_gl_pixelStoref(value pname, value param) { 1404 | glPixelStoref(val_get(pname), val_get(param)); 1405 | return val_null; 1406 | } 1407 | value hx_gl_pixelStorei(value pname, value param) { 1408 | glPixelStorei(val_get(pname), val_get(param)); 1409 | return val_null; 1410 | } 1411 | value hx_gl_pointParameterf(value pname, value param) { 1412 | glPixelStoref(val_get(pname), val_get(param)); 1413 | return val_null; 1414 | } 1415 | value hx_gl_pointParameteri(value pname, value param) { 1416 | glPixelStorei(val_get(pname), val_get(param)); 1417 | return val_null; 1418 | } 1419 | value hx_gl_pointSize(value size) { 1420 | glPointSize(val_get(size)); 1421 | return val_null; 1422 | } 1423 | value hx_gl_polygonMode(value face, value mode) { 1424 | glPolygonMode(val_get(face), val_get(mode)); 1425 | return val_null; 1426 | } 1427 | value hx_gl_polygonOffset(value factor, value units) { 1428 | glPolygonOffset(val_get(factor), val_get(units)); 1429 | return val_null; 1430 | } 1431 | value hx_gl_primitiveRestartIndex(value index) { 1432 | glPrimitiveRestartIndex(val_get(index)); 1433 | return val_null; 1434 | } 1435 | value hx_gl_provokingVertex(value provokeMode) { 1436 | glProvokingVertex(val_get(provokeMode)); 1437 | return val_null; 1438 | } 1439 | DEFINE_PRIM(hx_gl_pixelStoref, 2); 1440 | DEFINE_PRIM(hx_gl_pixelStorei, 2); 1441 | DEFINE_PRIM(hx_gl_pointParameterf, 2); 1442 | DEFINE_PRIM(hx_gl_pointParameteri, 2); 1443 | DEFINE_PRIM(hx_gl_pointSize, 1); 1444 | DEFINE_PRIM(hx_gl_polygonMode, 2); 1445 | DEFINE_PRIM(hx_gl_polygonOffset, 2); 1446 | DEFINE_PRIM(hx_gl_primitiveRestartIndex, 1); 1447 | DEFINE_PRIM(hx_gl_provokingVertex, 1); 1448 | 1449 | // ================================================================================================ 1450 | // Q 1451 | // ================================================================================================ 1452 | value hx_gl_queryCounter(value id, value target) { 1453 | glQueryCounter(val_get(id), val_get(target)); 1454 | return val_null; 1455 | } 1456 | DEFINE_PRIM(hx_gl_queryCounter, 2); 1457 | 1458 | // ================================================================================================ 1459 | // R 1460 | // ================================================================================================ 1461 | value hx_gl_readBuffer(value mode) { 1462 | glReadBuffer(val_get(mode)); 1463 | return val_null; 1464 | } 1465 | value hx_gl_readPixels(value* args, int nargs) { 1466 | glReadPixels(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), get_vector(args[6], args[7])); 1467 | return val_null; 1468 | } 1469 | value hx_gl_renderbufferStorage(value target, value internalFormat, value width, value height) { 1470 | glRenderbufferStorage(val_get(target), val_get(internalFormat), val_get(width), val_get(height)); 1471 | return val_null; 1472 | } 1473 | value hx_gl_renderbufferStorageMultisample(value target, value samples, value internalFormat, value width, value height) { 1474 | glRenderbufferStorageMultisample(val_get(target), val_get(samples), val_get(internalFormat), val_get(width), val_get(height)); 1475 | return val_null; 1476 | } 1477 | DEFINE_PRIM(hx_gl_readBuffer, 1); 1478 | DEFINE_PRIM_MULT(hx_gl_readPixels); 1479 | DEFINE_PRIM(hx_gl_renderbufferStorage, 4); 1480 | DEFINE_PRIM(hx_gl_renderbufferStorageMultisample, 5); 1481 | 1482 | // ================================================================================================ 1483 | // S 1484 | // ================================================================================================ 1485 | value hx_gl_sampleCoverage(value val, value invert) { 1486 | glSampleCoverage(val_get(val), val_get(invert)); 1487 | return val_null; 1488 | } 1489 | value hx_gl_sampleMaski(value maskn, value mask) { 1490 | glSampleMaski(val_get(maskn), val_get(mask)); 1491 | return val_null; 1492 | } 1493 | value hx_gl_samplerParameterf(value sampler, value pname, value param) { 1494 | glSamplerParameterf(val_get(sampler), val_get(pname), val_get(param)); 1495 | return val_null; 1496 | } 1497 | value hx_gl_samplerParameteri(value sampler, value pname, value param) { 1498 | glSamplerParameteri(val_get(sampler), val_get(pname), val_get(param)); 1499 | return val_null; 1500 | } 1501 | value hx_gl_scissor(value x, value y, value width, value height) { 1502 | glScissor(val_get(x), val_get(y), val_get(width), val_get(height)); 1503 | return val_null; 1504 | } 1505 | value hx_gl_shaderSource(value shader, value strings) { 1506 | string* _strings = new string[val_array_size(strings)]; 1507 | for (int i = 0; i < val_array_size(strings); i++) 1508 | _strings[i] = val_get(val_array_i(strings, i)); 1509 | glShaderSource(val_get(shader), val_array_size(strings), _strings, NULL); 1510 | delete[] _strings; 1511 | return val_null; 1512 | } 1513 | value hx_gl_stencilFunc(value func, value ref, value mask) { 1514 | glStencilFunc(val_get(func), val_get(ref), val_get(mask)); 1515 | return val_null; 1516 | } 1517 | value hx_gl_stencilFuncSeparate(value face, value func, value ref, value mask) { 1518 | glStencilFuncSeparate(val_get(face), val_get(func), val_get(ref), val_get(mask)); 1519 | return val_null; 1520 | } 1521 | value hx_gl_stencilMask(value mask) { 1522 | glStencilMask(val_get(mask)); 1523 | return val_null; 1524 | } 1525 | value hx_gl_stencilMaskSeparate(value face, value mask) { 1526 | glStencilMaskSeparate(val_get(face), val_get(mask)); 1527 | return val_null; 1528 | } 1529 | value hx_gl_stencilOp(value sfail, value dpfail, value dppass) { 1530 | glStencilOp(val_get(sfail), val_get(dpfail), val_get(dppass)); 1531 | return val_null; 1532 | } 1533 | value hx_gl_stencilOpSeparate(value face, value sfail, value dpfail, value dppass) { 1534 | glStencilOpSeparate(val_get(face), val_get(sfail), val_get(dpfail), val_get(dppass)); 1535 | return val_null; 1536 | } 1537 | DEFINE_PRIM(hx_gl_sampleCoverage, 2); 1538 | DEFINE_PRIM(hx_gl_sampleMaski, 2); 1539 | DEFINE_PRIM(hx_gl_samplerParameterf, 3); 1540 | DEFINE_PRIM(hx_gl_samplerParameteri, 3); 1541 | DEFINE_PRIM(hx_gl_scissor, 4); 1542 | DEFINE_PRIM(hx_gl_shaderSource, 2); 1543 | DEFINE_PRIM(hx_gl_stencilFunc, 3); 1544 | DEFINE_PRIM(hx_gl_stencilFuncSeparate, 4); 1545 | DEFINE_PRIM(hx_gl_stencilMask, 1); 1546 | DEFINE_PRIM(hx_gl_stencilMaskSeparate, 2); 1547 | DEFINE_PRIM(hx_gl_stencilOp, 3); 1548 | DEFINE_PRIM(hx_gl_stencilOpSeparate, 4); 1549 | 1550 | // ================================================================================================ 1551 | // T 1552 | // ================================================================================================ 1553 | value hx_gl_texBuffer(value target, value format, value buf) { 1554 | glTexBuffer(val_get(target), val_get(format), val_get(buf)); 1555 | return val_null; 1556 | } 1557 | value hx_gl_texImage1D(value* args, int narg) { 1558 | void* data = NULL; 1559 | value buf = args[7]; 1560 | if (!val_is_null(buf)) data = get_vector(buf, args[8]); 1561 | glTexImage1D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), data); 1562 | return val_null; 1563 | } 1564 | value hx_gl_texImage2D(value* args, int narg) { 1565 | void* data = NULL; 1566 | value buf = args[8]; 1567 | if (!val_is_null(buf)) data = get_vector(buf, args[9]); 1568 | glTexImage2D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7]), data); 1569 | return val_null; 1570 | } 1571 | value hx_gl_texImage2DMultisample(value* args, int narg) { 1572 | glTexImage2DMultisample(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5])); 1573 | return val_null; 1574 | } 1575 | value hx_gl_texImage3D(value* args, int narg) { 1576 | void* data = NULL; 1577 | value buf = args[9]; 1578 | if (!val_is_null(buf)) data = get_vector(buf, args[10]); 1579 | glTexImage3D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7]), val_get(args[8]), data); 1580 | return val_null; 1581 | } 1582 | value hx_gl_texImage3DMultisample(value* args, int narg) { 1583 | glTexImage3DMultisample(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6])); 1584 | return val_null; 1585 | } 1586 | value hx_gl_texParameterf(value target, value pname, value param) { 1587 | glTexParameterf(val_get(target), val_get(pname), val_get(param)); 1588 | return val_null; 1589 | } 1590 | value hx_gl_texParameteri(value target, value pname, value param) { 1591 | glTexParameteri(val_get(target), val_get(pname), val_get(param)); 1592 | return val_null; 1593 | } 1594 | value hx_gl_texSubImage1D(value* args, int narg) { 1595 | glTexSubImage1D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), get_vector(args[6], args[7])); 1596 | return val_null; 1597 | } 1598 | value hx_gl_texSubImage2D(value* args, int narg) { 1599 | glTexSubImage2D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7]), get_vector(args[8], args[9])); 1600 | return val_null; 1601 | } 1602 | value hx_gl_texSubImage3D(value* args, int narg) { 1603 | glTexSubImage3D(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), val_get(args[5]), val_get(args[6]), val_get(args[7]), val_get(args[8]), val_get(args[9]), get_vector(args[10], args[11])); 1604 | return val_null; 1605 | } 1606 | value hx_gl_transformFeedbackVaryings(value program, value varyings, value bufferMode) { 1607 | int cnt = val_array_size(varyings); 1608 | const char** cstrings = new const char*[cnt]; 1609 | for (int i = 0; i < cnt; i++) cstrings[i] = val_get(val_array_i(varyings, i)); 1610 | glTransformFeedbackVaryings(val_get(program), cnt, cstrings, val_get(bufferMode)); 1611 | delete[] cstrings; 1612 | return val_null; 1613 | } 1614 | DEFINE_PRIM(hx_gl_texBuffer, 3); 1615 | DEFINE_PRIM_MULT(hx_gl_texImage1D); 1616 | DEFINE_PRIM_MULT(hx_gl_texImage2D); 1617 | DEFINE_PRIM_MULT(hx_gl_texImage2DMultisample); 1618 | DEFINE_PRIM_MULT(hx_gl_texImage3D); 1619 | DEFINE_PRIM_MULT(hx_gl_texImage3DMultisample); 1620 | DEFINE_PRIM(hx_gl_texParameterf, 3); 1621 | DEFINE_PRIM(hx_gl_texParameteri, 3); 1622 | DEFINE_PRIM_MULT(hx_gl_texSubImage1D); 1623 | DEFINE_PRIM_MULT(hx_gl_texSubImage2D); 1624 | DEFINE_PRIM_MULT(hx_gl_texSubImage3D); 1625 | DEFINE_PRIM(hx_gl_transformFeedbackVaryings, 3); 1626 | 1627 | // ================================================================================================ 1628 | // U 1629 | // ================================================================================================ 1630 | #define UNIFORM1(N, T) \ 1631 | value hx_gl_uniform1##N(value loc, value v0) { \ 1632 | glUniform1##N(val_get(loc), val_get(v0)); \ 1633 | return val_null; \ 1634 | } \ 1635 | DEFINE_PRIM(hx_gl_uniform1##N, 2) 1636 | UNIFORM1(f, double); 1637 | UNIFORM1(i, int); 1638 | UNIFORM1(ui, int); 1639 | #define UNIFORM2(N, T) \ 1640 | value hx_gl_uniform2##N(value loc, value v0, value v1) { \ 1641 | glUniform2##N(val_get(loc), val_get(v0), val_get(v1)); \ 1642 | return val_null; \ 1643 | } \ 1644 | DEFINE_PRIM(hx_gl_uniform2##N, 3) 1645 | UNIFORM2(f, double); 1646 | UNIFORM2(i, int); 1647 | UNIFORM2(ui, int); 1648 | #define UNIFORM3(N, T) \ 1649 | value hx_gl_uniform3##N(value loc, value v0, value v1, value v2) { \ 1650 | glUniform3##N(val_get(loc), val_get(v0), val_get(v1), val_get(v2)); \ 1651 | return val_null; \ 1652 | } \ 1653 | DEFINE_PRIM(hx_gl_uniform3##N, 4) 1654 | UNIFORM3(f, double); 1655 | UNIFORM3(i, int); 1656 | UNIFORM3(ui, int); 1657 | #define UNIFORM4(N, T) \ 1658 | value hx_gl_uniform4##N(value loc, value v0, value v1, value v2, value v3) { \ 1659 | glUniform4##N(val_get(loc), val_get(v0), val_get(v1), val_get(v2), val_get(v3)); \ 1660 | return val_null; \ 1661 | } \ 1662 | DEFINE_PRIM(hx_gl_uniform4##N, 5) 1663 | UNIFORM4(f, double); 1664 | UNIFORM4(i, int); 1665 | UNIFORM4(ui, int); 1666 | 1667 | #define UNIFORMF(N) \ 1668 | value hx_gl_uniform##N##fv(value loc, value cnt, value val, value off) { \ 1669 | glUniform##N##fv(val_get(loc), val_get(cnt)/N, get_vector(val, off)); \ 1670 | return val_null; \ 1671 | } \ 1672 | DEFINE_PRIM(hx_gl_uniform##N##fv, 4) 1673 | UNIFORMF(1); 1674 | UNIFORMF(2); 1675 | UNIFORMF(3); 1676 | UNIFORMF(4); 1677 | #define UNIFORMI(N, G, T) \ 1678 | value hx_gl_uniform##N##G##v(value loc, value val) { \ 1679 | T* buf = (T*)copy_ints(val); \ 1680 | glUniform##N##G##v(val_get(loc), val_array_size(val)/N, buf); \ 1681 | delete[] buf; \ 1682 | return val_null; \ 1683 | } \ 1684 | DEFINE_PRIM(hx_gl_uniform##N##G##v, 3) 1685 | UNIFORMI(1, i, GLint); UNIFORMI(1, ui, GLuint); 1686 | UNIFORMI(2, i, GLint); UNIFORMI(2, ui, GLuint); 1687 | UNIFORMI(3, i, GLint); UNIFORMI(3, ui, GLuint); 1688 | UNIFORMI(4, i, GLint); UNIFORMI(4, ui, GLuint); 1689 | 1690 | #define UNIFORMMAT(N, T) \ 1691 | value hx_gl_uniformMatrix##N##fv(value loc, value cnt, value transpose, value val, value off) { \ 1692 | glUniformMatrix##N##fv(val_get(loc), val_get(cnt)/T, val_get(transpose), get_vector(val, off)); \ 1693 | return val_null; \ 1694 | } \ 1695 | DEFINE_PRIM(hx_gl_uniformMatrix##N##fv, 5) 1696 | UNIFORMMAT(2, 4); 1697 | UNIFORMMAT(3, 9); 1698 | UNIFORMMAT(4, 16); 1699 | UNIFORMMAT(2x3, 6); 1700 | UNIFORMMAT(3x2, 6); 1701 | UNIFORMMAT(2x4, 8); 1702 | UNIFORMMAT(4x2, 8); 1703 | UNIFORMMAT(3x4, 12); 1704 | UNIFORMMAT(4x3, 12); 1705 | 1706 | value hx_gl_uniformBlockBinding(value program, value ind, value bind) { 1707 | glUniformBlockBinding(val_get(program), val_get(ind), val_get(bind)); 1708 | return val_null; 1709 | } 1710 | value hx_gl_useProgram(value program) { 1711 | glUseProgram(val_get(program)); 1712 | return val_null; 1713 | } 1714 | DEFINE_PRIM(hx_gl_uniformBlockBinding, 3); 1715 | DEFINE_PRIM(hx_gl_useProgram, 1); 1716 | 1717 | // ================================================================================================ 1718 | // V 1719 | // ================================================================================================ 1720 | value hx_gl_validateProgram(value program) { 1721 | glValidateProgram(val_get(program)); 1722 | 1723 | int result; 1724 | glGetProgramiv(val_get(program), GL_VALIDATE_STATUS, &result); 1725 | if (!result) { 1726 | int length; 1727 | glGetProgramiv(val_get(program), GL_INFO_LOG_LENGTH, &length); 1728 | char* err = new char[length]; 1729 | glGetProgramInfoLog(val_get(program), length, NULL, err); 1730 | return alloc(err); 1731 | } 1732 | else { 1733 | return val_null; 1734 | } 1735 | } 1736 | DEFINE_PRIM(hx_gl_validateProgram, 1); 1737 | 1738 | #define VERTEXATTRv(N, G) \ 1739 | value hx_gl_vertexAttrib##N##v(value index, value v, value off) { \ 1740 | glVertexAttrib##N##v(val_get(index), get_vector(v, off)); \ 1741 | return val_null; \ 1742 | } \ 1743 | DEFINE_PRIM(hx_gl_vertexAttrib##N##v, 3) 1744 | #define VERTEXATTRa(N, T, G) \ 1745 | value hx_gl_vertexAttrib##N##v(value index, value v) { \ 1746 | glVertexAttrib##N##v(val_get(index), (const G*)val_array_##T(v)); \ 1747 | return val_null; \ 1748 | } \ 1749 | DEFINE_PRIM(hx_gl_vertexAttrib##N##v, 2) 1750 | 1751 | #define VERTEXATTR1(N, T, G) \ 1752 | value hx_gl_vertexAttrib##N(value index, value v0) { \ 1753 | glVertexAttrib##N(val_get(index), val_get(v0)); \ 1754 | return val_null; \ 1755 | } \ 1756 | DEFINE_PRIM(hx_gl_vertexAttrib##N, 2) 1757 | VERTEXATTR1(1f, double, GLfloat); VERTEXATTRv(1f, GLfloat); 1758 | VERTEXATTR1(1s, int, GLshort); VERTEXATTRv(1s, GLshort); 1759 | VERTEXATTR1(1d, double, GLdouble); VERTEXATTRa(1d, double, GLdouble); 1760 | VERTEXATTR1(I1i, int, GLint); VERTEXATTRa(I1i, int, GLint); 1761 | VERTEXATTR1(I1ui, int, GLuint); VERTEXATTRa(I1ui, int, GLuint); 1762 | #define VERTEXATTR2(N, T, G) \ 1763 | value hx_gl_vertexAttrib##N(value index, value v0, value v1) { \ 1764 | glVertexAttrib##N(val_get(index), val_get(v0), val_get(v1)); \ 1765 | return val_null; \ 1766 | } \ 1767 | DEFINE_PRIM(hx_gl_vertexAttrib##N, 3) 1768 | VERTEXATTR2(2f, double, GLfloat); VERTEXATTRv(2f, GLfloat); 1769 | VERTEXATTR2(2s, int, GLshort); VERTEXATTRv(2s, GLshort); 1770 | VERTEXATTR2(2d, double, GLdouble); VERTEXATTRa(2d, double, GLdouble); 1771 | VERTEXATTR2(I2i, int, GLint); VERTEXATTRa(I2i, int, GLint); 1772 | VERTEXATTR2(I2ui, int, GLuint); VERTEXATTRa(I2ui, int, GLuint); 1773 | #define VERTEXATTR3(N, T, G) \ 1774 | value hx_gl_vertexAttrib##N(value index, value v0, value v1, value v2) { \ 1775 | glVertexAttrib##N(val_get(index), val_get(v0), val_get(v1), val_get(v2)); \ 1776 | return val_null; \ 1777 | } \ 1778 | DEFINE_PRIM(hx_gl_vertexAttrib##N, 4) 1779 | VERTEXATTR3(3f, double, GLfloat); VERTEXATTRv(3f, GLfloat); 1780 | VERTEXATTR3(3s, int, GLshort); VERTEXATTRv(3s, GLshort); 1781 | VERTEXATTR3(3d, double, GLdouble); VERTEXATTRa(3d, double, GLdouble); 1782 | VERTEXATTR3(I3i, int, GLint); VERTEXATTRa(I3i, int, GLint); 1783 | VERTEXATTR3(I3ui, int, GLuint); VERTEXATTRa(I3ui, int, GLuint); 1784 | #define VERTEXATTR4(N, T, G) \ 1785 | value hx_gl_vertexAttrib##N(value index, value v0, value v1, value v2, value v3) { \ 1786 | glVertexAttrib##N(val_get(index), val_get(v0), val_get(v1), val_get(v2), val_get(v3)); \ 1787 | return val_null; \ 1788 | } \ 1789 | DEFINE_PRIM(hx_gl_vertexAttrib##N, 5) 1790 | VERTEXATTR4(4f, double, GLfloat); VERTEXATTRv(4f, GLfloat); 1791 | VERTEXATTR4(4s, int, GLshort); VERTEXATTRv(4s, GLshort); 1792 | VERTEXATTR4(4d, double, GLdouble); VERTEXATTRa(4d, double, GLdouble); 1793 | VERTEXATTR4(I4i, int, GLint); VERTEXATTRa(I4i, int, GLint); 1794 | VERTEXATTR4(I4ui, int, GLuint); VERTEXATTRa(I4ui, int, GLuint); 1795 | VERTEXATTRa(4i, int, GLint); 1796 | VERTEXATTRv(4b, GLbyte); 1797 | VERTEXATTRv(4ub, GLubyte); 1798 | VERTEXATTRv(4us, GLushort); 1799 | VERTEXATTRa(4ui, int, GLuint); 1800 | VERTEXATTRv(4Nb, GLbyte); 1801 | VERTEXATTRv(4Ns, GLshort); 1802 | VERTEXATTRa(4Ni, int, GLint); 1803 | VERTEXATTRv(4Nus, GLushort); 1804 | VERTEXATTRa(4Nui, int, GLuint); 1805 | VERTEXATTRv(I4b, GLbyte); 1806 | VERTEXATTRv(I4ub, GLubyte); 1807 | VERTEXATTRv(I4s, GLshort); 1808 | 1809 | value hx_gl_vertexAttribP1ui(value index, value type, value normalized, value value) { 1810 | glVertexAttribP1ui(val_get(index), val_get(type), val_get(normalized), val_get(value)); 1811 | return val_null; 1812 | } 1813 | value hx_gl_vertexAttribP2ui(value index, value type, value normalized, value value) { 1814 | glVertexAttribP2ui(val_get(index), val_get(type), val_get(normalized), val_get(value)); 1815 | return val_null; 1816 | } 1817 | value hx_gl_vertexAttribP3ui(value index, value type, value normalized, value value) { 1818 | glVertexAttribP3ui(val_get(index), val_get(type), val_get(normalized), val_get(value)); 1819 | return val_null; 1820 | } 1821 | value hx_gl_vertexAttribP4ui(value index, value type, value normalized, value value) { 1822 | glVertexAttribP4ui(val_get(index), val_get(type), val_get(normalized), val_get(value)); 1823 | return val_null; 1824 | } 1825 | DEFINE_PRIM(hx_gl_vertexAttribP1ui, 4); 1826 | DEFINE_PRIM(hx_gl_vertexAttribP2ui, 4); 1827 | DEFINE_PRIM(hx_gl_vertexAttribP3ui, 4); 1828 | DEFINE_PRIM(hx_gl_vertexAttribP4ui, 4); 1829 | 1830 | value hx_gl_vertexAttribDivisor(value index, value divisor) { 1831 | glVertexAttribDivisor(val_get(index), val_get(divisor)); 1832 | return val_null; 1833 | } 1834 | value hx_gl_vertexAttribPointer(value* args, int narg) { 1835 | glVertexAttribPointer(val_get(args[0]), val_get(args[1]), val_get(args[2]), val_get(args[3]), val_get(args[4]), (GLvoid*)val_get(args[5])); 1836 | return val_null; 1837 | } 1838 | value hx_gl_vertexAttribIPointer(value index, value size, value type, value stride, value offset) { 1839 | glVertexAttribIPointer(val_get(index), val_get(size), val_get(type), val_get(stride), (GLvoid*)val_get(offset)); 1840 | return val_null; 1841 | } 1842 | value hx_gl_viewport(value x, value y, value width, value height) { 1843 | glViewport(val_get(x), val_get(y), val_get(width), val_get(height)); 1844 | return val_null; 1845 | } 1846 | DEFINE_PRIM(hx_gl_vertexAttribDivisor, 2); 1847 | DEFINE_PRIM_MULT(hx_gl_vertexAttribPointer); 1848 | DEFINE_PRIM(hx_gl_vertexAttribIPointer, 5); 1849 | DEFINE_PRIM(hx_gl_viewport, 4); 1850 | 1851 | // ================================================================================================ 1852 | // W 1853 | // ================================================================================================ 1854 | value hx_gl_waitSync(value sync, value flags, value timeLow, value timeHigh) { 1855 | val_check_kind(sync, k_Sync); 1856 | GLsync syncVal = (GLsync)val_data(sync); 1857 | GLuint64 val; 1858 | ((int*)&val)[0] = val_get(timeLow); 1859 | ((int*)&val)[1] = val_get(timeHigh); 1860 | glWaitSync(syncVal, val_get(flags), val); 1861 | return val_null; 1862 | } 1863 | DEFINE_PRIM(hx_gl_waitSync, 4); 1864 | 1865 | // ================================================================================================ 1866 | 1867 | extern "C" void gl_allocateKinds() { 1868 | k_Sync = alloc_kind(); 1869 | k_Vector = alloc_kind(); 1870 | } 1871 | --------------------------------------------------------------------------------