diff --git a/lime/_backend/html5/HTML5GLRenderContext.hx b/lime/_backend/html5/HTML5GLRenderContext.hx
index 5b8c39ebf..a688f7e0b 100644
--- a/lime/_backend/html5/HTML5GLRenderContext.hx
+++ b/lime/_backend/html5/HTML5GLRenderContext.hx
@@ -1,6 +1,7 @@
package lime._backend.html5;
+import haxe.io.Bytes;
import js.html.webgl.RenderingContext in WebGLRenderingContext;
import js.html.CanvasElement;
import lime.graphics.opengl.GLActiveInfo;
@@ -16,6 +17,7 @@ import lime.graphics.opengl.GLTexture;
import lime.graphics.opengl.GLUniformLocation;
import lime.utils.ArrayBuffer;
import lime.utils.ArrayBufferView;
+import lime.utils.BytePointer;
import lime.utils.Float32Array;
import lime.utils.Int32Array;
import lime.utils.UInt8Array;
@@ -503,15 +505,34 @@ class HTML5GLRenderContext {
//public function bufferData (target:Int, srcData:ArrayBuffer, usage:Int):Void {
//public function bufferData (target:Int, size:Int, usage:Int):Void {
//public function bufferData (target:Int, srcData:ArrayBufferView, usage:Int, srcOffset:Int = 0, length:Int = 0):Void {
- public function bufferData (target:Int, srcData:Dynamic, usage:Int, ?srcOffset:Int, ?length:Int):Void {
+ public function bufferData (target:Int, size:Dynamic, srcData:Dynamic, ?usage:Int, ?srcOffset:Int, ?length:Int):Void {
- if (version > 1) {
+ if (!Std.is (srcData, Int)) {
- __context.bufferData (target, srcData, usage, srcOffset, length);
+ srcData = __prepareData (size, srcData);
+ if (srcData == null) return;
+
+ if (version > 1) {
+
+ __context.bufferData (target, srcData, usage, srcOffset, length);
+
+ } else {
+
+ __context.bufferData (target, srcData, usage);
+
+ }
} else {
- __context.bufferData (target, srcData, usage);
+ if (version > 1) {
+
+ __context.bufferData (target, size, srcData, usage, srcOffset); // target, srcData, usage, srcOffset, length
+
+ } else {
+
+ __context.bufferData (target, size, srcData); // target, srcData, usage
+
+ }
}
@@ -521,15 +542,34 @@ class HTML5GLRenderContext {
//public function bufferSubData (target:Int, dstByteOffset:Int, srcData:ArrayBufferView):Void {
//public function bufferSubData (target:Int, dstByteOffset:Int, srcData:ArrayBuffer):Void {
//public function bufferSubData (target:Int, dstByteOffset:Int, srcData:ArrayBufferView, srcOffset:Int = 0, length:Int = 0):Void {
- public function bufferSubData (target:Int, dstByteOffset:Int, srcData:Dynamic, ?srcOffset:Int, ?length:Int):Void {
+ public function bufferSubData (target:Int, dstByteOffset:Int, size:Dynamic, ?srcData:Dynamic, ?srcOffset:Int, ?length:Int):Void {
- if (version > 1) {
+ if (Std.is (size, Int)) {
- __context.bufferSubData (target, dstByteOffset, srcData, srcOffset, length);
+ srcData = __prepareData (size, srcData);
+ if (srcData == null) return;
+
+ if (version > 1) {
+
+ __context.bufferSubData (target, dstByteOffset, srcData, srcOffset, length);
+
+ } else {
+
+ __context.bufferSubData (target, dstByteOffset, srcData);
+
+ }
} else {
- __context.bufferSubData (target, dstByteOffset, srcData);
+ if (version > 1) {
+
+ __context.bufferSubData (target, dstByteOffset, size, srcData, srcOffset); // target, dstByteOffset, srcData, srcOffset, length
+
+ } else {
+
+ __context.bufferSubData (target, dstByteOffset, srcData); // target, dstByteOffset, srcData
+
+ }
}
@@ -590,6 +630,9 @@ class HTML5GLRenderContext {
//public function compressedTexImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, offset:Int):Void {
public function compressedTexImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, srcData:Dynamic, ?srcOffset:Int, ?srcLengthOverride:Int):Void {
+ srcData = __prepareData (null, srcData);
+ if (srcData == null) return;
+
if (version > 1) {
__context.compressedTexImage2D (target, level, internalformat, width, height, border, srcData, srcOffset, srcLengthOverride);
@@ -608,6 +651,9 @@ class HTML5GLRenderContext {
//public function compressedTexSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, offset::Int):Void {
public function compressedTexSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, srcData:Dynamic, ?srcOffset:Int, ?srcLengthOverride:Int):Void {
+ srcData = __prepareData (null, srcData);
+ if (srcData == null) return;
+
if (version > 1) {
__context.compressedTexSubImage2D (target, level, xoffset, yoffset, width, height, format, srcData, srcOffset, srcLengthOverride);
@@ -866,6 +912,23 @@ class HTML5GLRenderContext {
}
+ public inline function getBoolean (pname:Int):Bool {
+
+ return __context.getParameter (pname);
+
+ }
+
+
+ public function getBooleanv (pname:Int):Array {
+
+ var result = __context.getParameter (pname);
+ if (result == null) return null;
+
+ return untyped __js__("Array.prototype.slice.call (result)");
+
+ }
+
+
public inline function getBufferParameter (target:Int, pname:Int):Int /*Dynamic*/ {
return __context.getBufferParameter (target, pname);
@@ -894,6 +957,23 @@ class HTML5GLRenderContext {
}
+ public inline function getFloat (pname:Int):Float {
+
+ return __context.getParameter (pname);
+
+ }
+
+
+ public function getFloatv (pname:Int):Array {
+
+ var result:Float32Array = __context.getParameter (pname);
+ if (result == null) return null;
+
+ return untyped __js__("Array.prototype.slice.call (result)");
+
+ }
+
+
public inline function getFramebufferAttachmentParameter (target:Int, attachment:Int, pname:Int):Int /*Dynamic*/ {
return __context.getFramebufferAttachmentParameter (target, attachment, pname);
@@ -901,6 +981,23 @@ class HTML5GLRenderContext {
}
+ public inline function getInteger (pname:Int):Int {
+
+ return __context.getParameter (pname);
+
+ }
+
+
+ public function getIntegerv (pname:Int):Array {
+
+ var result:Int32Array = __context.getParameter (pname);
+ if (result == null) return null;
+
+ return untyped __js__("Array.prototype.slice.call (result)");
+
+ }
+
+
public inline function getParameter (pname:Int):Dynamic {
return __context.getParameter (pname);
@@ -957,6 +1054,13 @@ class HTML5GLRenderContext {
}
+ public inline function getString (pname:Int):String {
+
+ return __context.getParameter (pname);
+
+ }
+
+
public inline function getSupportedExtensions ():Array {
return __context.getSupportedExtensions ();
@@ -1180,7 +1284,7 @@ class HTML5GLRenderContext {
//public function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, offset:Int):Void {
//public function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, pixels:VideoElement):Void {
//public function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, srcData:ArrayBufferView, srcOffset:Int):Void {
- public function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Dynamic, ?format:Int, ?type:Int, ?srcData:ArrayBufferView, ?srcOffset:Int):Void {
+ public function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Dynamic, ?format:Int, ?type:Int, ?srcData:Dynamic, ?srcOffset:Int):Void {
if (version > 1) {
@@ -1194,6 +1298,10 @@ class HTML5GLRenderContext {
} else {
+ srcData = __prepareData (null, srcData);
+ if (srcData == null) return;
+ if (Std.is (srcData, ArrayBuffer)) srcData = new UInt8Array (srcData);
+
__context.texImage2D (target, level, internalformat, width, height, border, format, type, srcData, srcOffset);
}
@@ -1202,10 +1310,14 @@ class HTML5GLRenderContext {
if (format == null) {
- __context.texImage2D (target, level, internalformat, width, height, border); // format, type, pixels
+ __context.texImage2D (target, level, internalformat, width, height, border); // target, level, internalformat, format, type, pixels
} else {
+ srcData = __prepareData (null, srcData);
+ if (srcData == null) return;
+ if (Std.is (srcData, ArrayBuffer)) srcData = new UInt8Array (srcData);
+
__context.texImage2D (target, level, internalformat, width, height, border, format, type, srcData);
}
@@ -1248,10 +1360,14 @@ class HTML5GLRenderContext {
if (type == null) {
- __context.texSubImage2D (target, level, xoffset, yoffset, width, height, format); // format, type, pixels/offset
+ __context.texSubImage2D (target, level, xoffset, yoffset, width, height, format); // target, level, xoffset, yoffset, format, type, pixels
} else {
+ srcData = __prepareData (null, srcData);
+ if (srcData == null) return;
+ if (Std.is (srcData, ArrayBuffer)) srcData = new UInt8Array (srcData);
+
__context.texSubImage2D (target, level, xoffset, yoffset, width, height, format, type, srcData, srcOffset);
}
@@ -1260,10 +1376,14 @@ class HTML5GLRenderContext {
if (type == null) {
- __context.texSubImage2D (target, level, xoffset, yoffset, width, height, format); // format, type, pixels
+ __context.texSubImage2D (target, level, xoffset, yoffset, width, height, format); // target, level, xoffset, yoffset, format, type, pixels
} else {
+ srcData = __prepareData (null, srcData);
+ if (srcData == null) return;
+ if (Std.is (srcData, ArrayBuffer)) srcData = new UInt8Array (srcData);
+
__context.texSubImage2D (target, level, xoffset, yoffset, width, height, format, type, srcData);
}
@@ -1490,6 +1610,77 @@ class HTML5GLRenderContext {
}
+ private function __isArrayBufferView (object:Dynamic):Bool {
+
+ return untyped __js__ ("object && object.buffer instanceof ArrayBuffer && object.byteLength !== undefined");
+
+ }
+
+
+ private function __prepareData (size:Null, data:Dynamic):Dynamic {
+
+ if (data != null) {
+
+ if (size != null) {
+
+ if (size <= 0) {
+
+ return null;
+
+ } else if (__isArrayBufferView (data)) {
+
+ var arrayBufferView:ArrayBufferView = data;
+ return new UInt8Array (arrayBufferView.buffer, arrayBufferView.byteOffset, size);
+
+ } else if (Std.is (data, ArrayBuffer)) {
+
+ var arrayBuffer:ArrayBuffer = data;
+ return new UInt8Array (arrayBuffer, 0, size);
+
+ } else if (Std.is (data, BytePointerData)) {
+
+ var bytePointer:BytePointer = data;
+ return new UInt8Array (bytePointer.bytes.getData (), bytePointer.offset, size);
+
+ } else if (Std.is (data, Bytes)) {
+
+ var bytes:Bytes = data;
+ return new UInt8Array (bytes.getData (), 0, size);
+
+ }
+
+ } else {
+
+ if (Std.is (data, BytePointerData)) {
+
+ var bytePointer:BytePointer = data;
+
+ if (bytePointer.offset != 0) {
+
+ return new UInt8Array (bytePointer.bytes.getData (), bytePointer.offset);
+
+ } else {
+
+ return bytePointer.bytes.getData ();
+
+ }
+
+ } else if (Std.is (data, Bytes)) {
+
+ var bytes:Bytes = data;
+ return bytes.getData ();
+
+ }
+
+ }
+
+ }
+
+ return data;
+
+ }
+
+
#if (js && html5)
private function get_canvas ():CanvasElement {
diff --git a/lime/_backend/native/NativeApplication.hx b/lime/_backend/native/NativeApplication.hx
index c4330a010..49ccfa285 100644
--- a/lime/_backend/native/NativeApplication.hx
+++ b/lime/_backend/native/NativeApplication.hx
@@ -424,7 +424,18 @@ class NativeApplication {
case RENDER_CONTEXT_LOST:
- if (renderer.backend.useHardware) {
+ if (renderer.backend.useHardware && renderer.context != null) {
+
+ switch (renderer.context) {
+
+ case OPENGL (gl):
+
+ (gl:NativeGLRenderContext).__contextLost ();
+ if (GL.context == gl) GL.context = null;
+
+ default:
+
+ }
renderer.context = null;
renderer.onContextLost.dispatch ();
diff --git a/lime/_backend/native/NativeCFFI.hx b/lime/_backend/native/NativeCFFI.hx
index 8b4f28630..43d087f30 100644
--- a/lime/_backend/native/NativeCFFI.hx
+++ b/lime/_backend/native/NativeCFFI.hx
@@ -466,19 +466,26 @@ class NativeCFFI {
@:cffi private static function lime_gl_get_active_attrib (program:CFFIPointer, index:Int):Dynamic;
@:cffi private static function lime_gl_get_active_uniform (program:CFFIPointer, index:Int):Dynamic;
@:cffi private static function lime_gl_get_attrib_location (program:CFFIPointer, name:String):Int;
+ @:cffi private static function lime_gl_get_boolean (pname:Int):Bool;
+ @:cffi private static function lime_gl_get_booleanv (pname:Int):Array;
@:cffi private static function lime_gl_get_buffer_parameter (target:Int, pname:Int):Int;
@:cffi private static function lime_gl_get_context_attributes ():Dynamic;
@:cffi private static function lime_gl_get_error ():Int;
@:cffi private static function lime_gl_get_extension (name:String):Dynamic;
+ @:cffi private static function lime_gl_get_float (pname:Int):Float;
+ @:cffi private static function lime_gl_get_floatv (pname:Int):Array;
@:cffi private static function lime_gl_get_framebuffer_attachment_parameter (target:Int, attachment:Int, pname:Int):Int;
+ @:cffi private static function lime_gl_get_integer (pname:Int):Int;
+ @:cffi private static function lime_gl_get_integerv (pname:Int):Array;
@:cffi private static function lime_gl_get_parameter (pname:Int):Dynamic;
@:cffi private static function lime_gl_get_program_info_log (program:CFFIPointer):Dynamic;
- @:cffi private static function lime_gl_get_program_parameter (program:CFFIPointer, pname:Int):Int;
+ @:cffi private static function lime_gl_get_program_parameter (program:CFFIPointer, pname:Int):Dynamic;
@:cffi private static function lime_gl_get_render_buffer_parameter (target:Int, pname:Int):Int;
@:cffi private static function lime_gl_get_shader_info_log (shader:CFFIPointer):Dynamic;
@:cffi private static function lime_gl_get_shader_parameter (shader:CFFIPointer, pname:Int):Int;
@:cffi private static function lime_gl_get_shader_precision_format (shadertype:Int, precisiontype:Int):Dynamic;
@:cffi private static function lime_gl_get_shader_source (shader:CFFIPointer):Dynamic;
+ @:cffi private static function lime_gl_get_string (pname:Int):String;
@:cffi private static function lime_gl_get_supported_extensions (result:Dynamic):Void;
@:cffi private static function lime_gl_get_tex_parameter (target:Int, pname:Int):Int;
@:cffi private static function lime_gl_get_uniform (program:CFFIPointer, location:Int):Dynamic;
diff --git a/lime/_backend/native/NativeGLRenderContext.hx b/lime/_backend/native/NativeGLRenderContext.hx
index c54ec36d5..f1e74667a 100644
--- a/lime/_backend/native/NativeGLRenderContext.hx
+++ b/lime/_backend/native/NativeGLRenderContext.hx
@@ -13,8 +13,10 @@ import lime.graphics.opengl.GLShader;
import lime.graphics.opengl.GLShaderPrecisionFormat;
import lime.graphics.opengl.GLTexture;
import lime.graphics.opengl.GLUniformLocation;
+import lime.graphics.opengl.GL;
import lime.utils.ArrayBuffer;
import lime.utils.ArrayBufferView;
+import lime.utils.BytePointer;
import lime.utils.Float32Array;
import lime.utils.Int32Array;
import lime.system.CFFIPointer;
@@ -401,8 +403,15 @@ class NativeGLRenderContext {
public var type (default, null):GLContextType;
public var version (default, null):Float;
+ private var __arrayBufferBinding:GLBuffer;
+ private var __elementBufferBinding:GLBuffer;
private var __contextID:Int;
private var __currentProgram:GLProgram;
+ private var __framebufferBinding:GLFramebuffer;
+ private var __isContextLost:Bool;
+ private var __renderbufferBinding:GLRenderbuffer;
+ private var __texture2DBinding:GLTexture;
+ private var __textureCubeMapBinding:GLTexture;
private function new () {
@@ -563,6 +572,9 @@ class NativeGLRenderContext {
public function bindBuffer (target:Int, buffer:GLBuffer):Void {
+ if (target == ARRAY_BUFFER) __arrayBufferBinding = buffer;
+ if (target == ELEMENT_ARRAY_BUFFER) __elementBufferBinding = buffer;
+
#if (lime_cffi && lime_opengl && !macro)
NativeCFFI.lime_gl_bind_buffer (target, buffer == null ? null : buffer.id);
#end
@@ -572,6 +584,8 @@ class NativeGLRenderContext {
public function bindFramebuffer (target:Int, framebuffer:GLFramebuffer):Void {
+ __framebufferBinding = framebuffer;
+
#if (lime_cffi && lime_opengl && !macro)
NativeCFFI.lime_gl_bind_framebuffer (target, framebuffer == null ? null : framebuffer.id);
#end
@@ -581,6 +595,8 @@ class NativeGLRenderContext {
public function bindRenderbuffer (target:Int, renderbuffer:GLRenderbuffer):Void {
+ __renderbufferBinding = renderbuffer;
+
#if (lime_cffi && lime_opengl && !macro)
NativeCFFI.lime_gl_bind_renderbuffer (target, renderbuffer == null ? null : renderbuffer.id);
#end
@@ -590,6 +606,9 @@ class NativeGLRenderContext {
public function bindTexture (target:Int, texture:GLTexture):Void {
+ if (target == TEXTURE_2D) __texture2DBinding = texture;
+ if (target == TEXTURE_CUBE_MAP) __textureCubeMapBinding = texture;
+
#if (lime_cffi && lime_opengl && !macro)
NativeCFFI.lime_gl_bind_texture (target, texture == null ? null : texture.id);
#end
@@ -642,23 +661,23 @@ class NativeGLRenderContext {
}
- public function bufferData (target:Int, data:ArrayBufferView, usage:Int, srcOffset:Int = 0, length:Int = 0):Void {
+ public function bufferData (target:Int, size:Int, srcData:BytePointer, usage:Int, srcOffset:Int = 0, length:Int = 0):Void {
#if (lime_cffi && !nodejs && lime_opengl && !macro)
- NativeCFFI.lime_gl_buffer_data (target, data.buffer, data.byteOffset, data.byteLength, usage);
+ NativeCFFI.lime_gl_buffer_data (target, srcData.bytes, srcData.offset, size, usage);
#elseif (nodejs && lime_opengl && !macro)
- NativeCFFI.lime_gl_buffer_data (target, data, data.byteOffset, data.byteLength, usage);
+ NativeCFFI.lime_gl_buffer_data (target, srcData.bytes.getData (), srcData.offset, size, usage);
#end
}
- public function bufferSubData (target:Int, offset:Int, data:ArrayBufferView, srcOffset:Int = 0, length:Int = 0):Void {
+ public function bufferSubData (target:Int, dstByteOffset:Int, size:Int, srcData:BytePointer, srcOffset:Int = 0, length:Int = 0):Void {
#if (lime_cffi && !nodejs && lime_opengl && !macro)
- NativeCFFI.lime_gl_buffer_sub_data (target, offset, data.buffer, data.byteOffset, data.byteLength);
+ NativeCFFI.lime_gl_buffer_sub_data (target, dstByteOffset, srcData.bytes, srcData.offset, size);
#elseif (nodejs && lime_opengl && !macro)
- NativeCFFI.lime_gl_buffer_sub_data (target, offset, data, data.byteOffset, data.byteLength);
+ NativeCFFI.lime_gl_buffer_sub_data (target, dstByteOffset, srcData.bytes.getData (), srcData.offset, size);
#end
}
@@ -729,25 +748,25 @@ class NativeGLRenderContext {
}
- public function compressedTexImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, data:ArrayBufferView, srcOffset:Int = 0, length:Int = 0):Void {
+ public function compressedTexImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, srcData:BytePointer, srcOffset:Int = 0, srcLengthOverride:Int = 0):Void {
#if (lime_cffi && !nodejs && lime_opengl && !macro)
- var buffer = data == null ? null : data.buffer;
- NativeCFFI.lime_gl_compressed_tex_image_2d (target, level, internalformat, width, height, border, buffer, data == null ? 0 : data.byteOffset);
+ var buffer = srcData == null ? null : srcData.bytes;
+ NativeCFFI.lime_gl_compressed_tex_image_2d (target, level, internalformat, width, height, border, buffer, srcData == null ? 0 : srcData.offset);
#elseif (nodejs && lime_opengl && !macro)
- NativeCFFI.lime_gl_compressed_tex_image_2d (target, level, internalformat, width, height, border, data == null ? null : data , data == null ? null : data.byteOffset);
+ NativeCFFI.lime_gl_compressed_tex_image_2d (target, level, internalformat, width, height, border, srcData == null ? null : srcData.bytes.getData (), srcData == null ? null : srcData.offset);
#end
}
- public function compressedTexSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, data:ArrayBufferView, srcOffset:Int = 0, length:Int = 0):Void {
+ public function compressedTexSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, srcData:BytePointer, srcOffset:Int = 0, srcLengthOverride:Int = 0):Void {
#if (lime_cffi && !nodejs && lime_opengl && !macro)
- var buffer = data == null ? null : data.buffer;
- NativeCFFI.lime_gl_compressed_tex_sub_image_2d (target, level, xoffset, yoffset, width, height, format, buffer, data == null ? 0 : data.byteOffset);
+ var buffer = srcData == null ? null : srcData.bytes;
+ NativeCFFI.lime_gl_compressed_tex_sub_image_2d (target, level, xoffset, yoffset, width, height, format, buffer, srcData == null ? 0 : srcData.offset);
#elseif (nodejs && lime_opengl && !macro)
- NativeCFFI.lime_gl_compressed_tex_sub_image_2d (target, level, xoffset, yoffset, width, height, format, data == null ? null : data, data == null ? null : data.byteOffset);
+ NativeCFFI.lime_gl_compressed_tex_sub_image_2d (target, level, xoffset, yoffset, width, height, format, srcData == null ? null : srcData.bytes.getData (), srcData == null ? null : srcData.offset);
#end
}
@@ -1096,6 +1115,28 @@ class NativeGLRenderContext {
}
+ public function getBoolean (pname:Int):Bool {
+
+ #if (lime_cffi && lime_opengl && !macro)
+ return NativeCFFI.lime_gl_get_boolean (pname);
+ #else
+ return false;
+ #end
+
+ }
+
+
+ public function getBooleanv (pname:Int):Array {
+
+ #if (lime_cffi && lime_opengl && !macro)
+ return NativeCFFI.lime_gl_get_booleanv (pname);
+ #else
+ return null;
+ #end
+
+ }
+
+
public function getBufferParameter (target:Int, pname:Int):Int /*Dynamic*/ {
#if (lime_cffi && lime_opengl && !macro)
@@ -1153,7 +1194,31 @@ class NativeGLRenderContext {
}
- public function getFramebufferAttachmentParameter (target:Int, attachment:Int, pname:Int):Int /*Dynamic*/ {
+ public function getFloat (pname:Int):Float {
+
+ #if (lime_cffi && lime_opengl && !macro)
+ return NativeCFFI.lime_gl_get_float (pname);
+ #else
+ return 0;
+ #end
+
+ }
+
+
+ public function getFloatv (pname:Int):Array {
+
+ #if (lime_cffi && lime_opengl && !macro)
+ return NativeCFFI.lime_gl_get_floatv (pname);
+ #else
+ return null;
+ #end
+
+ }
+
+
+ public function getFramebufferAttachmentParameter (target:Int, attachment:Int, pname:Int):Dynamic {
+
+ // TODO: FRAMEBUFFER_ATTACHMENT_OBJECT_NAME
#if (lime_cffi && lime_opengl && !macro)
return NativeCFFI.lime_gl_get_framebuffer_attachment_parameter (target, attachment, pname);
@@ -1164,10 +1229,21 @@ class NativeGLRenderContext {
}
- public function getParameter (pname:Int):Dynamic {
+ public function getInteger (pname:Int):Int {
#if (lime_cffi && lime_opengl && !macro)
- return NativeCFFI.lime_gl_get_parameter (pname);
+ return NativeCFFI.lime_gl_get_integer (pname);
+ #else
+ return 0;
+ #end
+
+ }
+
+
+ public function getIntegerv (pname:Int):Array {
+
+ #if (lime_cffi && lime_opengl && !macro)
+ return NativeCFFI.lime_gl_get_integerv (pname);
#else
return null;
#end
@@ -1175,6 +1251,73 @@ class NativeGLRenderContext {
}
+ public function getParameter (pname:Int):Dynamic {
+
+ switch (pname) {
+
+ case GL.BLEND, GL.CULL_FACE, GL.DEPTH_TEST, GL.DEPTH_WRITEMASK, GL.DITHER, GL.POLYGON_OFFSET_FILL, GL.SAMPLE_COVERAGE_INVERT, GL.SCISSOR_TEST, GL.STENCIL_TEST, GL.UNPACK_FLIP_Y_WEBGL, GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+
+ return getBoolean (pname);
+
+ case GL.COLOR_WRITEMASK:
+
+ return getBooleanv (pname);
+
+ case GL.DEPTH_CLEAR_VALUE, GL.LINE_WIDTH, GL.POLYGON_OFFSET_FACTOR, GL.POLYGON_OFFSET_UNITS, GL.SAMPLE_COVERAGE_VALUE:
+
+ return getFloat (pname);
+
+ case GL.ALIASED_LINE_WIDTH_RANGE, GL.ALIASED_POINT_SIZE_RANGE, GL.BLEND_COLOR, GL.COLOR_CLEAR_VALUE, GL.DEPTH_RANGE:
+
+ return getFloatv (pname);
+
+ case GL.ACTIVE_TEXTURE, GL.ALPHA_BITS, GL.BLEND_DST_ALPHA, GL.BLEND_DST_RGB, GL.BLEND_EQUATION, GL.BLEND_EQUATION_ALPHA, GL.BLEND_EQUATION_RGB, GL.BLEND_SRC_ALPHA, GL.BLEND_SRC_RGB, GL.BLUE_BITS, GL.CULL_FACE_MODE, GL.DEPTH_BITS, GL.DEPTH_FUNC, GL.FRONT_FACE, GL.GENERATE_MIPMAP_HINT, GL.GREEN_BITS, GL.IMPLEMENTATION_COLOR_READ_FORMAT, GL.IMPLEMENTATION_COLOR_READ_TYPE, GL.MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL.MAX_CUBE_MAP_TEXTURE_SIZE, GL.MAX_FRAGMENT_UNIFORM_VECTORS, GL.MAX_RENDERBUFFER_SIZE, GL.MAX_TEXTURE_IMAGE_UNITS, GL.MAX_TEXTURE_SIZE, GL.MAX_VARYING_VECTORS, GL.MAX_VERTEX_ATTRIBS, GL.MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL.MAX_VERTEX_UNIFORM_VECTORS, GL.PACK_ALIGNMENT, GL.RED_BITS, GL.SAMPLE_BUFFERS, GL.SAMPLES, GL.STENCIL_BACK_FAIL, GL.STENCIL_BACK_FUNC, GL.STENCIL_BACK_PASS_DEPTH_FAIL, GL.STENCIL_BACK_PASS_DEPTH_PASS, GL.STENCIL_BACK_REF, GL.STENCIL_BACK_VALUE_MASK, GL.STENCIL_BACK_WRITEMASK, GL.STENCIL_BITS, GL.STENCIL_CLEAR_VALUE, GL.STENCIL_FAIL, GL.STENCIL_FUNC, GL.STENCIL_PASS_DEPTH_FAIL, GL.STENCIL_PASS_DEPTH_PASS, GL.STENCIL_REF, GL.STENCIL_VALUE_MASK, GL.STENCIL_WRITEMASK, GL.SUBPIXEL_BITS, GL.UNPACK_ALIGNMENT, GL.UNPACK_COLORSPACE_CONVERSION_WEBGL:
+
+ return getInteger (pname);
+
+ case GL.COMPRESSED_TEXTURE_FORMATS, GL.MAX_VIEWPORT_DIMS, GL.SCISSOR_BOX, GL.VIEWPORT:
+
+ return getIntegerv (pname);
+
+ case GL.RENDERER, GL.SHADING_LANGUAGE_VERSION, GL.VENDOR, GL.VERSION:
+
+ return getString (pname);
+
+ // TODO: Handle if context is modified elsewhere
+
+ case GL.ARRAY_BUFFER_BINDING:
+
+ return __arrayBufferBinding;
+
+ case GL.ELEMENT_ARRAY_BUFFER_BINDING:
+
+ return __elementBufferBinding;
+
+ case GL.CURRENT_PROGRAM:
+
+ return __currentProgram;
+
+ case GL.FRAMEBUFFER_BINDING:
+
+ return __framebufferBinding;
+
+ case GL.TEXTURE_BINDING_2D:
+
+ return __texture2DBinding;
+
+ case GL.TEXTURE_BINDING_CUBE_MAP:
+
+ return __textureCubeMapBinding;
+
+ default:
+
+ return null;
+
+ }
+
+ }
+
+
public function getProgramInfoLog (program:GLProgram):String {
#if (lime_cffi && lime_opengl && !macro)
@@ -1186,7 +1329,7 @@ class NativeGLRenderContext {
}
- public function getProgramParameter (program:GLProgram, pname:Int):Int {
+ public function getProgramParameter (program:GLProgram, pname:Int):Dynamic {
#if (lime_cffi && lime_opengl && !macro)
return NativeCFFI.lime_gl_get_program_parameter (program.id, pname);
@@ -1253,6 +1396,17 @@ class NativeGLRenderContext {
}
+ public function getString (pname:Int):String {
+
+ #if (lime_cffi && lime_opengl && !macro)
+ return NativeCFFI.lime_gl_get_string (pname);
+ #else
+ return null;
+ #end
+
+ }
+
+
public function getSupportedExtensions ():Array {
if (__supportedExtensions == null) {
@@ -1357,7 +1511,7 @@ class NativeGLRenderContext {
public function isContextLost ():Bool {
- return false;
+ return __isContextLost;
}
@@ -1566,13 +1720,13 @@ class NativeGLRenderContext {
}
- public function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, pixels:ArrayBufferView):Void {
+ public function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, srcData:BytePointer, srcOffset:Int = 0):Void {
#if (lime_cffi && !nodejs && lime_opengl && !macro)
- var buffer = pixels == null ? null : pixels.buffer;
- NativeCFFI.lime_gl_tex_image_2d (target, level, internalformat, width, height, border, format, type, buffer, pixels == null ? 0 : pixels.byteOffset);
+ var buffer = srcData == null ? null : srcData.bytes;
+ NativeCFFI.lime_gl_tex_image_2d (target, level, internalformat, width, height, border, format, type, buffer, srcData == null ? 0 : srcData.offset);
#elseif (nodejs && lime_opengl && !macro)
- NativeCFFI.lime_gl_tex_image_2d (target, level, internalformat, width, height, border, format, type, pixels == null ? null : pixels, pixels == null ? null : pixels.byteOffset);
+ NativeCFFI.lime_gl_tex_image_2d (target, level, internalformat, width, height, border, format, type, srcData == null ? null : srcData.bytes.getData (), srcData == null ? null : srcData.offset);
#end
}
@@ -1801,13 +1955,6 @@ class NativeGLRenderContext {
}
- /*public function uniformMatrix3D(location:GLUniformLocation, transpose:Bool, matrix:Matrix3D):Void {
-
- NativeCFFI.lime_gl_uniform_matrix(location, transpose, Float32Array.fromMatrix(matrix).getByteBuffer() , 4);
-
- }*/
-
-
public function useProgram (program:GLProgram):Void {
__currentProgram = program;
@@ -1926,4 +2073,18 @@ class NativeGLRenderContext {
}
+ private function __contextLost ():Void {
+
+ __isContextLost = true;
+ __arrayBufferBinding = null;
+ __elementBufferBinding = null;
+ __currentProgram = null;
+ __framebufferBinding = null;
+ __renderbufferBinding = null;
+ __texture2DBinding = null;
+ __textureCubeMapBinding = null;
+
+ }
+
+
}
\ No newline at end of file
diff --git a/lime/graphics/GLRenderContext.hx b/lime/graphics/GLRenderContext.hx
index 7f6f45d0e..bf1b9ead9 100644
--- a/lime/graphics/GLRenderContext.hx
+++ b/lime/graphics/GLRenderContext.hx
@@ -350,8 +350,8 @@ extern class GLRenderContext {
public function blendEquationSeparate (modeRGB:Int, modeAlpha:Int):Void;
public function blendFunc (sfactor:Int, dfactor:Int):Void;
public function blendFuncSeparate (srcRGB:Int, dstRGB:Int, srcAlpha:Int, dstAlpha:Int):Void;
- public function bufferData (target:Int, srcData:lime.utils.ArrayBufferView, usage:Int, srcOffset:Int = 0, length:Int = 0):Void;
- public function bufferSubData (target:Int, offset:Int, srcData:lime.utils.ArrayBufferView, srcOffset:Int = 0, length:Int = 0):Void;
+ public function bufferData (target:Int, size:Int, srcData:lime.utils.ArrayBufferView, usage:Int, srcOffset:Int = 0, length:Int = 0):Void;
+ public function bufferSubData (target:Int, dstByteOffset:Int, size:Int, srcData:lime.utils.ArrayBufferView, srcOffset:Int = 0, length:Int = 0):Void;
public function checkFramebufferStatus (target:Int):Int;
public function clear (mask:Int):Void;
public function clearColor (red:Float, green:Float, blue:Float, alpha:Float):Void;
@@ -396,7 +396,7 @@ extern class GLRenderContext {
public function getActiveUniform (program:GLProgram, index:Int):GLActiveInfo;
public function getAttachedShaders (program:GLProgram):Array;
public function getAttribLocation (program:GLProgram, name:String):Int;
- public function getBufferParameter (target:Int, pname:Int):Dynamic;
+ public function getBufferParameter (target:Int, pname:Int):Int;
public function getContextAttributes ():GLContextAttributes;
public function getError ():Int;
public function getExtension (name:String):Dynamic;
@@ -404,7 +404,7 @@ extern class GLRenderContext {
public function getParameter (pname:Int):Dynamic;
public function getProgramInfoLog (program:GLProgram):String;
public function getProgramParameter (program:GLProgram, pname:Int):Dynamic;
- public function getRenderbufferParameter (target:Int, pname:Int):Dynamic;
+ public function getRenderbufferParameter (target:Int, pname:Int):Int;
public function getShaderInfoLog (shader:GLShader):String;
public function getShaderParameter (shader:GLShader, pname:Int):Dynamic;
public function getShaderPrecisionFormat (shadertype:Int, precisiontype:Int):GLShaderPrecisionFormat;
diff --git a/lime/graphics/opengl/GL.hx b/lime/graphics/opengl/GL.hx
index 581ba99a4..f38227120 100644
--- a/lime/graphics/opengl/GL.hx
+++ b/lime/graphics/opengl/GL.hx
@@ -2,6 +2,7 @@ package lime.graphics.opengl;
import lime.utils.ArrayBufferView;
+import lime.utils.BytePointer;
import lime.utils.Float32Array;
import lime.utils.Int32Array;
@@ -300,6 +301,9 @@ class GL {
public static inline var VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
public static inline var VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+ public static inline var IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
+ public static inline var IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
+
public static inline var VERTEX_PROGRAM_POINT_SIZE = 0x8642;
public static inline var POINT_SPRITE = 0x8861;
@@ -455,16 +459,16 @@ class GL {
}
- public static inline function bufferData (target:Int, data:ArrayBufferView, usage:Int):Void {
+ public static inline function bufferData (target:Int, size:Int, data:BytePointer, usage:Int):Void {
- context.bufferData (target, data, usage);
+ context.bufferData (target, size, data, usage);
}
- public static inline function bufferSubData (target:Int, offset:Int, data:ArrayBufferView):Void {
+ public static inline function bufferSubData (target:Int, offset:Int, size:Int, data:BytePointer):Void {
- context.bufferSubData (target, offset, data);
+ context.bufferSubData (target, offset, size, data);
}
@@ -518,14 +522,14 @@ class GL {
}
- public static inline function compressedTexImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, data:ArrayBufferView):Void {
+ public static inline function compressedTexImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, data:BytePointer):Void {
context.compressedTexImage2D (target, level, internalformat, width, height, border, data);
}
- public static inline function compressedTexSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, data:ArrayBufferView):Void {
+ public static inline function compressedTexSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, data:BytePointer):Void {
context.compressedTexSubImage2D (target, level, xoffset, yoffset, width, height, format, data);
@@ -1078,9 +1082,9 @@ class GL {
}
- public static inline function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, pixels:ArrayBufferView):Void {
+ public static inline function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, data:BytePointer):Void {
- context.texImage2D (target, level, internalformat, width, height, border, format, type, pixels);
+ context.texImage2D (target, level, internalformat, width, height, border, format, type, data);
}
diff --git a/lime/graphics/opengl/GLES2Context.hx b/lime/graphics/opengl/GLES2Context.hx
index d37de7347..a02d81e1f 100644
--- a/lime/graphics/opengl/GLES2Context.hx
+++ b/lime/graphics/opengl/GLES2Context.hx
@@ -1,7 +1,9 @@
package lime.graphics.opengl;
+import haxe.io.Bytes;
import lime.utils.ArrayBufferView;
+import lime.utils.BytePointer;
import lime.utils.Float32Array;
import lime.utils.Int32Array;
@@ -9,6 +11,10 @@ import lime.utils.Int32Array;
abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
+ private static var __extensions:String;
+
+ public var EXTENSIONS (get, never):Int;
+
public var DEPTH_BUFFER_BIT (get, never):Int;
public var STENCIL_BUFFER_BIT (get, never):Int;
public var COLOR_BUFFER_BIT (get, never):Int;
@@ -158,8 +164,6 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
public var ALPHA (get, never):Int;
public var RGB (get, never):Int;
public var RGBA (get, never):Int;
- public var BGR_EXT (get, never):Int;
- public var BGRA_EXT (get, never):Int;
public var LUMINANCE (get, never):Int;
public var LUMINANCE_ALPHA (get, never):Int;
@@ -361,6 +365,7 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
public var type (get, never):GLContextType;
public var version (get, never):Float;
+ private inline function get_EXTENSIONS ():Int { return 0x1F03; }
private inline function get_DEPTH_BUFFER_BIT ():Int { return this.DEPTH_BUFFER_BIT; }
private inline function get_STENCIL_BUFFER_BIT ():Int { return this.STENCIL_BUFFER_BIT; }
private inline function get_COLOR_BUFFER_BIT ():Int { return this.COLOR_BUFFER_BIT; }
@@ -488,8 +493,6 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
private inline function get_ALPHA ():Int { return this.ALPHA; }
private inline function get_RGB ():Int { return this.RGB; }
private inline function get_RGBA ():Int { return this.RGBA; }
- private inline function get_BGR_EXT ():Int { #if (js && html5) return 0; #else return this.BGR_EXT; #end } // TODO
- private inline function get_BGRA_EXT ():Int { #if (js && html5) return 0; #else return this.BGRA_EXT; #end } // TODO
private inline function get_LUMINANCE ():Int { return this.LUMINANCE; }
private inline function get_LUMINANCE_ALPHA ():Int { return this.LUMINANCE_ALPHA; }
private inline function get_UNSIGNED_SHORT_4_4_4_4 ():Int { return this.UNSIGNED_SHORT_4_4_4_4; }
@@ -748,16 +751,16 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function bufferData (target:Int, data:ArrayBufferView, usage:Int):Void {
+ public inline function bufferData (target:Int, size:Int, data:BytePointer, usage:Int):Void {
- this.bufferData (target, data, usage);
+ this.bufferData (target, size, data, usage);
}
- public inline function bufferSubData (target:Int, offset:Int, data:ArrayBufferView):Void {
+ public inline function bufferSubData (target:Int, offset:Int, size:Int, data:BytePointer):Void {
- this.bufferSubData (target, offset, data);
+ this.bufferSubData (target, offset, size, data);
}
@@ -783,7 +786,7 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function clearDepth (depth:Float):Void {
+ public inline function clearDepthf (depth:Float):Void {
this.clearDepth (depth);
@@ -811,14 +814,14 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function compressedTexImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, data:ArrayBufferView):Void {
+ public inline function compressedTexImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, imageSize:Int, data:BytePointer):Void {
this.compressedTexImage2D (target, level, internalformat, width, height, border, data);
}
- public inline function compressedTexSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, data:ArrayBufferView):Void {
+ public inline function compressedTexSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, imageSize:Int, data:BytePointer):Void {
this.compressedTexSubImage2D (target, level, xoffset, yoffset, width, height, format, data);
@@ -944,7 +947,7 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function depthRange (zNear:Float, zFar:Float):Void {
+ public inline function depthRangef (zNear:Float, zFar:Float):Void {
this.depthRange (zNear, zFar);
@@ -979,9 +982,9 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function drawElements (mode:Int, count:Int, type:Int, offset:Int):Void {
+ public inline function drawElements (mode:Int, count:Int, type:Int, pointer:Int):Void {
- this.drawElements (mode, count, type, offset);
+ this.drawElements (mode, count, type, pointer);
}
@@ -1035,6 +1038,21 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
+ public function genBuffers (n:Int, buffers:Array = null):Array {
+
+ if (buffers == null) buffers = [];
+
+ for (i in 0...n) {
+
+ buffers[i] = createBuffer ();
+
+ }
+
+ return buffers;
+
+ }
+
+
public inline function generateMipmap (target:Int):Void {
this.generateMipmap (target);
@@ -1042,6 +1060,51 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
+ public function genFramebuffers (n:Int, framebuffers:Array = null):Array {
+
+ if (framebuffers == null) framebuffers = [];
+
+ for (i in 0...n) {
+
+ framebuffers[i] = createFramebuffer ();
+
+ }
+
+ return framebuffers;
+
+ }
+
+
+ public function genRenderbuffers (n:Int, renderbuffers:Array = null):Array {
+
+ if (renderbuffers == null) renderbuffers = [];
+
+ for (i in 0...n) {
+
+ renderbuffers[i] = createRenderbuffer ();
+
+ }
+
+ return renderbuffers;
+
+ }
+
+
+ public function genTextures (n:Int, textures:Array = null):Array {
+
+ if (textures == null) textures = [];
+
+ for (i in 0...n) {
+
+ textures[i] = createTexture ();
+
+ }
+
+ return textures;
+
+ }
+
+
public inline function getActiveAttrib (program:GLProgram, index:Int):GLActiveInfo {
return this.getActiveAttrib (program, index);
@@ -1070,16 +1133,65 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function getBufferParameter (target:Int, pname:Int):Int /*Dynamic*/ {
+ public inline function getBoolean (pname:Int):Bool {
+
+ return this.getBoolean (pname);
+
+ }
+
+
+ public function getBooleanv (pname:Int, params:Array = null):Array {
+
+ var result = this.getBooleanv (pname);
+
+ if (params != null) {
+
+ for (i in 0...result.length) {
+
+ params[i] = result[i];
+
+ }
+
+ return params;
+
+ }
+
+ return result;
+
+ }
+
+
+ public inline function getBufferParameteri (target:Int, pname:Int):Int {
return this.getBufferParameter (target, pname);
}
- public inline function getContextAttributes ():GLContextAttributes {
+ public function getBufferParameteriv (target:Int, pname:Int, params:Array = null):Array {
- return this.getContextAttributes ();
+ var result:Int = this.getBufferParameter (target, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result = this.getBufferParameter (target, attachment, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];;
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
}
@@ -1091,23 +1203,93 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function getExtension (name:String):Dynamic {
+ public inline function getFloat (pname:Int):Float {
- return this.getExtension (name);
+ return this.getFloat (pname);
}
- public inline function getFramebufferAttachmentParameter (target:Int, attachment:Int, pname:Int):Int /*Dynamic*/ {
+ public function getFloatv (pname:Int, params:Array = null):Array {
+
+ var result = this.getFloatv (pname);
+
+ if (params != null) {
+
+ for (i in 0...result.length) {
+
+ params[i] = result[i];
+
+ }
+
+ return params;
+
+ }
+
+ return result;
+
+ }
+
+
+ public inline function getFramebufferAttachmentParameteri (target:Int, attachment:Int, pname:Int):Dynamic {
return this.getFramebufferAttachmentParameter (target, attachment, pname);
}
- public inline function getParameter (pname:Int):Dynamic {
+ public function getFramebufferAttachmentParameteriv (target:Int, attachment:Int, pname:Int, params:Array = null):Array {
- return this.getParameter (pname);
+ var result:Dynamic = this.getFramebufferAttachmentParameter (target, attachment, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result = this.getFramebufferAttachmentParameter (target, attachment, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];;
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
+
+ }
+
+
+ public inline function getInteger (pname:Int):Int {
+
+ return this.getInteger (pname);
+
+ }
+
+
+ public function getIntegerv (pname:Int, params:Array = null):Array {
+
+ var result = this.getIntegerv (pname);
+
+ if (params != null) {
+
+ for (i in 0...result.length) {
+
+ params[i] = result[i];
+
+ }
+
+ return params;
+
+ }
+
+ return result;
}
@@ -1119,20 +1301,83 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function getProgramParameter (program:GLProgram, pname:Int):Int {
+ public inline function getProgrami (program:GLProgram, pname:Int):Dynamic {
return this.getProgramParameter (program, pname);
}
- public inline function getRenderbufferParameter (target:Int, pname:Int):Int /*Dynamic*/ {
+ public function getProgramiv (program:GLProgram, pname:Int, params:Array = null):Array {
+
+ var result:Dynamic = this.getProgramParameter (program, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result:Array = this.getProgramParameter (program, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
+
+ }
+
+
+ public inline function getRenderbufferParameteri (target:Int, pname:Int):Dynamic {
return this.getRenderbufferParameter (target, pname);
}
+ public function getRenderbufferParameteriv (target:Int, pname:Int, params:Array = null):Array {
+
+ var result:Dynamic = this.getRenderbufferParameter (target, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result:Array = this.getRenderbufferParameter (target, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
+
+ }
+
+
+ public inline function getShaderi (shader:GLShader, pname:Int):Dynamic {
+
+ return this.getShaderParameter (shader, pname);
+
+ }
+
+
public inline function getShaderInfoLog (shader:GLShader):String {
return this.getShaderInfoLog (shader);
@@ -1140,9 +1385,30 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function getShaderParameter (shader:GLShader, pname:Int):Int {
+ public function getShaderiv (shader:GLShader, pname:Int, params:Array = null):Array {
- return this.getShaderParameter (shader, pname);
+ var result:Dynamic = this.getShaderParameter (shader, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result:Array = this.getShaderParameter (shader, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
}
@@ -1161,20 +1427,97 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function getSupportedExtensions ():Array {
+ public inline function getString (name:Int):String {
- return this.getSupportedExtensions ();
+ if (name == EXTENSIONS) {
+
+ if (__extensions == null) {
+
+ __extensions = this.getSupportedExtensions ().join (" ");
+
+ }
+
+ return __extensions;
+
+ } else {
+
+ return this.getString (name);
+
+ }
}
- public inline function getTexParameter (target:Int, pname:Int):Int /*Dynamic*/ {
+ public inline function getTexParameterf (target:Int, pname:Int):Float {
return this.getTexParameter (target, pname);
}
+ public function getTexParameterfv (target:Int, pname:Int, params:Array = null):Array {
+
+ var result:Float = this.getTexParameter (target, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result:Array = this.getTexParameter (target, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
+
+ }
+
+
+ public inline function getTexParameteri (target:Int, pname:Int):Dynamic {
+
+ return this.getTexParameter (target, pname);
+
+ }
+
+
+ public function getTexParameteriv (target:Int, pname:Int, params:Array = null):Array {
+
+ var result:Dynamic = this.getTexParameter (target, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result:Array = this.getTexParameter (target, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
+
+ }
+
+
public inline function getUniform (program:GLProgram, location:GLUniformLocation):Dynamic {
return this.getUniform (program, location);
@@ -1189,14 +1532,77 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function getVertexAttrib (index:Int, pname:Int):Int /*Dynamic*/ {
+ public inline function getVertexAttribf (index:Int, pname:Int):Float {
return this.getVertexAttrib (index, pname);
}
- public inline function getVertexAttribOffset (index:Int, pname:Int):Int {
+ public function getVertexAttribfv (index:Int, pname:Int, params:Array = null):Array {
+
+ var result:Float = this.getVertexAttrib (index, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result:Array = this.getVertexAttrib (index, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
+
+ }
+
+
+ public inline function getVertexAttribi (index:Int, pname:Int):Dynamic {
+
+ return this.getVertexAttrib (index, pname);
+
+ }
+
+
+ public function getVertexAttribiv (index:Int, pname:Int, params:Array = null):Array {
+
+ var result:Dynamic = this.getTexParameter (index, pname);
+
+ if (params == null) params = [];
+ params[0] = result;
+
+ return params;
+
+ //var result:Array = this.getVertexAttrib (target, pname);
+ //
+ //if (params != null) {
+ //
+ //for (i in 0...result.length) {
+ //
+ //params[i] = result[i];
+ //
+ //}
+ //
+ //return params;
+ //
+ //}
+ //
+ //return result;
+
+ }
+
+
+ public inline function getVertexAttribPointerv (index:Int, pname:Int):Int {
return this.getVertexAttribOffset (index, pname);
@@ -1217,13 +1623,6 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function isContextLost ():Bool {
-
- return this.isContextLost ();
-
- }
-
-
public inline function isEnabled (cap:Int):Bool {
return this.isEnabled (cap);
@@ -1294,9 +1693,16 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function readPixels (x:Int, y:Int, width:Int, height:Int, format:Int, type:Int, pixels:ArrayBufferView):Void {
+ public inline function readPixels (x:Int, y:Int, width:Int, height:Int, format:Int, type:Int, data:BytePointer):Void {
+
+ this.readPixels (x, y, width, height, format, type, data);
+
+ }
+
+
+ public inline function releaseShaderCompiler ():Void {
+
- this.readPixels (x, y, width, height, format, type, pixels);
}
@@ -1322,6 +1728,13 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
+ public inline function shaderBinary (n:Int, shaders:Array, binaryformat:Int, binary:BytePointer, length:Int):Void {
+
+
+
+ }
+
+
public inline function shaderSource (shader:GLShader, source:String):Void {
this.shaderSource (shader, source);
@@ -1357,23 +1770,23 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function stencilOp (fail:Int, zfail:Int, zpass:Int):Void {
+ public inline function stencilOp (sfail:Int, dpfail:Int, dppass:Int):Void {
- this.stencilOp (fail, zfail, zpass);
+ this.stencilOp (sfail, dpfail, dppass);
}
- public inline function stencilOpSeparate (face:Int, fail:Int, zfail:Int, zpass:Int):Void {
+ public inline function stencilOpSeparate (face:Int, sfail:Int, dpfail:Int, dppass:Int):Void {
- this.stencilOpSeparate (face, fail, zfail, zpass);
+ this.stencilOpSeparate (face, sfail, dpfail, dppass);
}
- public inline function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, pixels:ArrayBufferView):Void {
+ public inline function texImage2D (target:Int, level:Int, internalformat:Int, width:Int, height:Int, border:Int, format:Int, type:Int, data:BytePointer):Void {
- this.texImage2D (target, level, internalformat, width, height, border, format, type, pixels);
+ this.texImage2D (target, level, internalformat, width, height, border, format, type, data);
}
@@ -1392,9 +1805,9 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function texSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, type:Int, pixels:ArrayBufferView):Void {
+ public inline function texSubImage2D (target:Int, level:Int, xoffset:Int, yoffset:Int, width:Int, height:Int, format:Int, type:Int, data:BytePointer):Void {
- this.texSubImage2D (target, level, xoffset, yoffset, width, height, format, type, pixels);
+ this.texSubImage2D (target, level, xoffset, yoffset, width, height, format, type, data);
}
@@ -1532,13 +1945,6 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- /*public inline function uniformMatrix3D(location:GLUniformLocation, transpose:Bool, matrix:Matrix3D):Void {
-
- lime_gl_uniform_matrix(location, transpose, Float32Array.fromMatrix(matrix).getByteBuffer() , 4);
-
- }*/
-
-
public inline function useProgram (program:GLProgram):Void {
this.useProgram (program);
@@ -1609,9 +2015,9 @@ abstract GLES2Context(GLRenderContext) from GLRenderContext to GLRenderContext {
}
- public inline function vertexAttribPointer (indx:Int, size:Int, type:Int, normalized:Bool, stride:Int, offset:Int):Void {
+ public inline function vertexAttribPointer (indx:Int, size:Int, type:Int, normalized:Bool, stride:Int, pointer:Int):Void {
- this.vertexAttribPointer (indx, size, type, normalized, stride, offset);
+ this.vertexAttribPointer (indx, size, type, normalized, stride, pointer);
}
diff --git a/lime/utils/BytePointer.hx b/lime/utils/BytePointer.hx
new file mode 100644
index 000000000..3d12b3b9f
--- /dev/null
+++ b/lime/utils/BytePointer.hx
@@ -0,0 +1,213 @@
+package lime.utils;
+
+
+import haxe.io.BytesData;
+import haxe.io.Bytes;
+import lime.utils.Bytes in LimeBytes;
+
+@:access(haxe.io.Bytes)
+@:access(lime.utils.BytePointerData)
+@:forward()
+
+
+abstract BytePointer(BytePointerData) from BytePointerData to BytePointerData {
+
+
+ public inline function new (bytes:Bytes, offset:Int = 0):Void {
+
+ this = new BytePointerData (bytes, offset);
+
+ }
+
+
+ @:arrayAccess @:noCompletion private inline function get (index:Int):Int {
+
+ return this.bytes.get (index + this.offset);
+
+ }
+
+
+ @:arrayAccess @:noCompletion private inline function set (index:Int, value:Int):Int {
+
+ this.bytes.set (index + this.offset, value);
+ return value;
+
+ }
+
+
+ @:from @:noCompletion public static function fromArrayBufferView (arrayBufferView:ArrayBufferView):BytePointer {
+
+ if (arrayBufferView == null) return null;
+
+ #if js
+ return new BytePointerData (Bytes.ofData (arrayBufferView.buffer), arrayBufferView.byteOffset);
+ #else
+ return new BytePointerData ((arrayBufferView.buffer:Bytes), arrayBufferView.byteOffset);
+ #end
+
+ }
+
+
+ @:from @:noCompletion public static function fromArrayBuffer (buffer:ArrayBuffer):BytePointer {
+
+ if (buffer == null) return null;
+
+ #if js
+ return new BytePointerData (Bytes.ofData (buffer), 0);
+ #else
+ return new BytePointerData ((buffer:Bytes), 0);
+ #end
+
+ }
+
+
+ @:from @:noCompletion public static function fromBytes (bytes:Bytes):BytePointer {
+
+ if (bytes == null) return null;
+
+ return new BytePointerData (bytes, 0);
+
+ }
+
+
+ @:from @:noCompletion public static function fromBytesData (bytesData:BytesData):BytePointer {
+
+ if (bytesData == null) return null;
+
+ return new BytePointerData (Bytes.ofData (bytesData), 0);
+
+ }
+
+
+ public static function fromFile (path:String):BytePointer {
+
+ return new BytePointerData (LimeBytes.fromFile (path), 0);
+
+ }
+
+
+ @:from @:noCompletion public static function fromLimeBytes (bytes:LimeBytes):BytePointer {
+
+ return new BytePointerData (bytes, 0);
+
+ }
+
+
+ @:to @:noCompletion public static function toUInt8Array (bytePointer:BytePointer):UInt8Array {
+
+ #if js
+ return new UInt8Array (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 8));
+ #else
+ return new UInt8Array (bytePointer.bytes, Std.int (bytePointer.offset / 8));
+ #end
+
+ }
+
+
+ @:to @:noCompletion public static function toUInt8ClampedArray (bytePointer:BytePointer):UInt8ClampedArray {
+
+ #if js
+ return new UInt8ClampedArray (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 8));
+ #else
+ return new UInt8ClampedArray (bytePointer.bytes, Std.int (bytePointer.offset / 8));
+ #end
+
+ }
+
+
+ @:to @:noCompletion public static function toInt8Array (bytePointer:BytePointer):Int8Array {
+
+ #if js
+ return new Int8Array (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 8));
+ #else
+ return new Int8Array (bytePointer.bytes, Std.int (bytePointer.offset / 8));
+ #end
+
+ }
+
+
+ @:to @:noCompletion public static function toUInt16Array (bytePointer:BytePointer):UInt16Array {
+
+ #if js
+ return new UInt16Array (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 16));
+ #else
+ return new UInt16Array (bytePointer.bytes, Std.int (bytePointer.offset / 16));
+ #end
+
+ }
+
+
+ @:to @:noCompletion public static function toInt16Array (bytePointer:BytePointer):Int16Array {
+
+ #if js
+ return new Int16Array (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 16));
+ #else
+ return new Int16Array (bytePointer.bytes, Std.int (bytePointer.offset / 16));
+ #end
+
+ }
+
+
+ @:to @:noCompletion public static function toUInt32Array (bytePointer:BytePointer):UInt32Array {
+
+ #if js
+ return new UInt32Array (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 32));
+ #else
+ return new UInt32Array (bytePointer.bytes, Std.int (bytePointer.offset / 32));
+ #end
+
+ }
+
+
+ @:to @:noCompletion public static function toInt32Array (bytePointer:BytePointer):Int32Array {
+
+ #if js
+ return new Int32Array (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 32));
+ #else
+ return new Int32Array (bytePointer.bytes, Std.int (bytePointer.offset / 32));
+ #end
+
+ }
+
+
+ @:to @:noCompletion public static function toFloat32Array (bytePointer:BytePointer):Float32Array {
+
+ #if js
+ return new Float32Array (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 32));
+ #else
+ return new Float32Array (bytePointer.bytes, Std.int (bytePointer.offset / 32));
+ #end
+
+ }
+
+
+ @:to @:noCompletion public static function toFloat64Array (bytePointer:BytePointer):Float64Array {
+
+ #if js
+ return new Float64Array (bytePointer.bytes.getData (), Std.int (bytePointer.offset / 64));
+ #else
+ return new Float64Array (bytePointer.bytes, Std.int (bytePointer.offset / 64));
+ #end
+
+ }
+
+
+}
+
+
+@:noCompletion @:dox(hide) class BytePointerData {
+
+
+ public var bytes:Bytes;
+ public var offset:Int;
+
+
+ public function new (bytes:Bytes, offset:Int) {
+
+ this.bytes = bytes;
+ this.offset = offset;
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/project/src/graphics/opengl/OpenGLBindings.cpp b/project/src/graphics/opengl/OpenGLBindings.cpp
index 913b57d6a..38bb4954b 100644
--- a/project/src/graphics/opengl/OpenGLBindings.cpp
+++ b/project/src/graphics/opengl/OpenGLBindings.cpp
@@ -740,6 +740,38 @@ namespace lime {
}
+ bool lime_gl_get_boolean (int pname) {
+
+ unsigned char val;
+ glGetBooleanv (pname, &val);
+ return val;
+
+ }
+
+
+ value lime_gl_get_booleanv (int pname) {
+
+ unsigned char vals[4] = { 255, 255, 255, 255 };
+ glGetBooleanv (pname, vals);
+
+ int len = 0;
+ for (int i = 0; i < 4; i++) {
+ if (vals[i] != 255) len++;
+ }
+
+ value result = alloc_array (len);
+
+ for (int i = 0; i < len; i++) {
+
+ val_array_set_i (result, i, alloc_bool (vals[i]));
+
+ }
+
+ return result;
+
+ }
+
+
value lime_gl_get_context_attributes () {
value result = alloc_empty_object ();
@@ -790,6 +822,39 @@ namespace lime {
}
+ float lime_gl_get_float (int pname) {
+
+ float val;
+ glGetFloatv (pname, &val);
+ return val;
+
+ }
+
+
+ value lime_gl_get_floatv (int pname) {
+
+ float unset = -0.0012321;
+ float vals[4] = { unset, unset, unset, unset };
+ glGetFloatv (pname, vals);
+
+ int len = 0;
+ for (int i = 0; i < 4; i++) {
+ if (vals[i] != unset) len++;
+ }
+
+ value result = alloc_array (len);
+
+ for (int i = 0; i < len; i++) {
+
+ val_array_set_i (result, i, alloc_float (vals[i]));
+
+ }
+
+ return result;
+
+ }
+
+
int lime_gl_get_framebuffer_attachment_parameter (int target, int attachment, int pname) {
GLint result = 0;
@@ -799,6 +864,39 @@ namespace lime {
}
+ int lime_gl_get_integer (int pname) {
+
+ int val;
+ glGetIntegerv (pname, &val);
+ return val;
+
+ }
+
+
+ value lime_gl_get_integerv (int pname) {
+
+ int unset = -1232123;
+ int vals[4] = { unset, unset, unset, unset };
+ glGetIntegerv (pname, vals);
+
+ int len = 0;
+ for (int i = 0; i < 4; i++) {
+ if (vals[i] != unset) len++;
+ }
+
+ value result = alloc_array (len);
+
+ for (int i = 0; i < len; i++) {
+
+ val_array_set_i (result, i, alloc_int (vals[i]));
+
+ }
+
+ return result;
+
+ }
+
+
value lime_gl_get_parameter (int pname) {
int floats = 0;
@@ -822,7 +920,8 @@ namespace lime {
ints = 4;
break;
- //case GL_COMPRESSED_TEXTURE_FORMATS null
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ glGetIntegerv (GL_NUM_COMPRESSED_TEXTURE_FORMATS, &ints);
case GL_MAX_VIEWPORT_DIMS:
ints = 2;
@@ -949,6 +1048,22 @@ namespace lime {
glGetFloatv (pname, &f);
return alloc_float (f);
+ } else if (ints > 4) {
+
+ int* vals;
+ vals = new int[ints];
+ glGetIntegerv (pname, vals);
+ value result = alloc_array (ints);
+
+ for (int i = 0; i < ints; i++) {
+
+ val_array_set_i (result, i, alloc_int (vals[i]));
+
+ }
+
+ delete[] vals;
+ return result;
+
} else if (ints > 0) {
int vals[4];
@@ -1006,11 +1121,23 @@ namespace lime {
}
- int lime_gl_get_program_parameter (value handle, int inName) {
+ value lime_gl_get_program_parameter (value handle, int inName) {
int result = 0;
glGetProgramiv (reinterpret_cast (val_data (handle)), inName, &result);
- return result;
+
+ switch (inName) {
+
+ case GL_DELETE_STATUS:
+ case GL_LINK_STATUS:
+ case GL_VALIDATE_STATUS:
+
+ return alloc_bool (result);
+ break;
+
+ }
+
+ return alloc_int (result);
}
@@ -1046,11 +1173,22 @@ namespace lime {
}
- int lime_gl_get_shader_parameter (value handle, int inName) {
+ value lime_gl_get_shader_parameter (value handle, int inName) {
int result = 0;
glGetShaderiv (reinterpret_cast (val_data (handle)), inName, &result);
- return result;
+
+ switch (inName) {
+
+ case GL_DELETE_STATUS:
+ case GL_COMPILE_STATUS:
+
+ return alloc_bool (result);
+ break;
+
+ }
+
+ return alloc_int (result);
}
@@ -1101,6 +1239,23 @@ namespace lime {
}
+ value lime_gl_get_string (int pname) {
+
+ const char* val = (const char*)glGetString (pname);
+
+ if (val) {
+
+ return alloc_string (val);
+
+ } else {
+
+ return alloc_null ();
+
+ }
+
+ }
+
+
void lime_gl_get_supported_extensions (value ioList) {
const char *ext = (const char *)glGetString (GL_EXTENSIONS);
@@ -1889,10 +2044,16 @@ namespace lime {
DEFINE_PRIME2 (lime_gl_get_active_uniform);
DEFINE_PRIME2 (lime_gl_get_attrib_location);
DEFINE_PRIME2 (lime_gl_get_buffer_parameter);
+ DEFINE_PRIME1 (lime_gl_get_boolean);
+ DEFINE_PRIME1 (lime_gl_get_booleanv);
DEFINE_PRIME0 (lime_gl_get_context_attributes);
DEFINE_PRIME0 (lime_gl_get_error);
DEFINE_PRIME1 (lime_gl_get_extension);
+ DEFINE_PRIME1 (lime_gl_get_float);
+ DEFINE_PRIME1 (lime_gl_get_floatv);
DEFINE_PRIME3 (lime_gl_get_framebuffer_attachment_parameter);
+ DEFINE_PRIME1 (lime_gl_get_integer);
+ DEFINE_PRIME1 (lime_gl_get_integerv);
DEFINE_PRIME1 (lime_gl_get_parameter);
DEFINE_PRIME1 (lime_gl_get_program_info_log);
DEFINE_PRIME2 (lime_gl_get_program_parameter);
@@ -1901,6 +2062,7 @@ namespace lime {
DEFINE_PRIME2 (lime_gl_get_shader_parameter);
DEFINE_PRIME2 (lime_gl_get_shader_precision_format);
DEFINE_PRIME1 (lime_gl_get_shader_source);
+ DEFINE_PRIME1 (lime_gl_get_string);
DEFINE_PRIME1v (lime_gl_get_supported_extensions);
DEFINE_PRIME2 (lime_gl_get_tex_parameter);
DEFINE_PRIME2 (lime_gl_get_uniform);