diff --git a/Backends/HTML5-Worker/kha/Image.hx b/Backends/HTML5-Worker/kha/Image.hx
index bc055620b..257fb7214 100644
--- a/Backends/HTML5-Worker/kha/Image.hx
+++ b/Backends/HTML5-Worker/kha/Image.hx
@@ -109,6 +109,8 @@ class Image implements Canvas implements Resource {
bytes = Bytes.alloc(2 * width * height);
case RGBA64:
bytes = Bytes.alloc(8 * width * height);
+ case RGBA64U:
+ bytes = Bytes.alloc(8 * width * height);
case A32:
bytes = Bytes.alloc(4 * width * height);
case A16:
@@ -177,6 +179,7 @@ class Image implements Canvas implements Resource {
case RGBA128: 16;
case DEPTH16: 2;
case RGBA64: 8;
+ case RGBA64U: 8;
case A32: 4;
case A16: 2;
default: 4;
diff --git a/Backends/HTML5/kha/SystemImpl.hx b/Backends/HTML5/kha/SystemImpl.hx
index f9960ea42..316925d83 100644
--- a/Backends/HTML5/kha/SystemImpl.hx
+++ b/Backends/HTML5/kha/SystemImpl.hx
@@ -393,7 +393,6 @@ class SystemImpl {
antialias: options.framebuffer.samplesPerPixel > 1,
stencil: true
}); // preserveDrawingBuffer: true } ); Warning: preserveDrawingBuffer can cause huge performance issues on mobile browsers
- SystemImpl.gl.pixelStorei(GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
halfFloat = {HALF_FLOAT_OES: 0x140B}; // GL_HALF_FLOAT
depthTexture = {UNSIGNED_INT_24_8_WEBGL: 0x84FA}; // GL_UNSIGNED_INT_24_8
@@ -422,7 +421,6 @@ class SystemImpl {
antialias: options.framebuffer.samplesPerPixel > 1,
stencil: true
}); // preserveDrawingBuffer: true } ); WARNING: preserveDrawingBuffer causes huge performance issues (on mobile browser)!
- SystemImpl.gl.pixelStorei(GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
SystemImpl.gl.getExtension("OES_texture_float");
SystemImpl.gl.getExtension("OES_texture_float_linear");
halfFloat = SystemImpl.gl.getExtension("OES_texture_half_float");
diff --git a/Backends/HTML5/kha/WebGLImage.hx b/Backends/HTML5/kha/WebGLImage.hx
index 9164a3ccc..3585d8f57 100644
--- a/Backends/HTML5/kha/WebGLImage.hx
+++ b/Backends/HTML5/kha/WebGLImage.hx
@@ -51,6 +51,8 @@ class WebGLImage extends Image {
static inline var GL_R16F = 0x822D;
static inline var GL_R32F = 0x822E;
static inline var GL_RED = 0x1903;
+ static inline var GL_RGBA16UI = 0x8D76;
+ static inline var GL_RGBA_INTEGER = 0x8D99;
static inline var GL_DEPTH_COMPONENT24 = 0x81A6;
static inline var GL_DEPTH24_STENCIL8 = 0x88F0;
static inline var GL_DEPTH32F_STENCIL8 = 0x8CAD;
@@ -209,8 +211,11 @@ class WebGLImage extends Image {
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
// Sys.gl.pixelStorei(Sys.gl.UNPACK_FLIP_Y_WEBGL, true);
- SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
- SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
+ // Integer-format textures cannot use linear filtering in webgl2
+ final isIntegerFormat = myFormat == RGBA64U;
+ final filter = isIntegerFormat ? GL.NEAREST : GL.LINEAR;
+ SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, filter);
+ SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, filter);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
if (renderTarget) {
@@ -227,6 +232,8 @@ class WebGLImage extends Image {
SystemImpl.halfFloat.HALF_FLOAT_OES, null);
case RGBA32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
+ case RGBA64U:
+ SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL_RGBA16UI, realWidth, realHeight, 0, GL_RGBA_INTEGER, GL.UNSIGNED_SHORT, null);
case A32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, realWidth, realHeight, 0,
SystemImpl.gl2 ? GL_RED : GL.ALPHA, GL.FLOAT, null);
@@ -288,7 +295,10 @@ class WebGLImage extends Image {
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
else if (video != null) {
+ // premultiply alpha for dom videos
+ SystemImpl.gl.pixelStorei(GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, video);
+ SystemImpl.gl.pixelStorei(GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
}
else {
switch (myFormat) {
@@ -302,8 +312,13 @@ class WebGLImage extends Image {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, image);
}
else {
+ // premultiply alpha for dom images
+ SystemImpl.gl.pixelStorei(GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, image);
+ SystemImpl.gl.pixelStorei(GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
}
+ case RGBA64U:
+ SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL_RGBA16UI, myWidth, myHeight, 0, GL_RGBA_INTEGER, GL.UNSIGNED_SHORT, image);
case A32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, myWidth, myHeight, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
GL.FLOAT, image);
@@ -313,7 +328,10 @@ class WebGLImage extends Image {
case L8:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.LUMINANCE, myWidth, myHeight, 0, GL.LUMINANCE, GL.UNSIGNED_BYTE, image);
default:
+ // premultiply alpha for dom images
+ SystemImpl.gl.pixelStorei(GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, image);
+ SystemImpl.gl.pixelStorei(GL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
}
}
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
@@ -419,6 +437,7 @@ class WebGLImage extends Image {
case RGBA128: 16;
case DEPTH16: 2;
case RGBA64: 8;
+ case RGBA64U: 8;
case A32: 4;
case A16: 2;
default: 4;
@@ -429,6 +448,8 @@ class WebGLImage extends Image {
return switch (myFormat) {
case RGBA32, L8:
new Uint8Array(bytes.getData());
+ case RGBA64U:
+ new Uint16Array(bytes.getData());
case RGBA128, RGBA64, A32, A16:
new Float32Array(bytes.getData());
default:
@@ -453,8 +474,10 @@ class WebGLImage extends Image {
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
// Sys.gl.pixelStorei(Sys.gl.UNPACK_FLIP_Y_WEBGL, true);
- SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
- SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
+ final isIntegerFormat = myFormat == RGBA64U;
+ final filter = isIntegerFormat ? GL.NEAREST : GL.LINEAR;
+ SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, filter);
+ SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, filter);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
@@ -475,8 +498,7 @@ class WebGLImage extends Image {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(rgbaBytes));
}
case RGBA128:
- SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, width, height, 0, GL.RGBA, GL.FLOAT,
- bytesToArray(bytes));
+ SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, width, height, 0, GL.RGBA, GL.FLOAT, bytesToArray(bytes));
case RGBA64:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, width, height, 0, GL.RGBA,
SystemImpl.halfFloat.HALF_FLOAT_OES, bytesToArray(bytes));
@@ -488,6 +510,10 @@ class WebGLImage extends Image {
SystemImpl.halfFloat.HALF_FLOAT_OES, bytesToArray(bytes));
case RGBA32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(bytes));
+ case RGBA64U:
+ SystemImpl.gl.pixelStorei(GL.UNPACK_ALIGNMENT, 2);
+ SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL_RGBA16UI, width, height, 0, GL_RGBA_INTEGER, GL.UNSIGNED_SHORT, bytesToArray(bytes));
+ SystemImpl.gl.pixelStorei(GL.UNPACK_ALIGNMENT, 4);
default:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(bytes));
}
@@ -509,7 +535,7 @@ class WebGLImage extends Image {
switch (myFormat) {
case RGBA128, A32:
pixels = new Float32Array(Std.int(formatByteSize(myFormat) / 4) * width * height);
- case RGBA64, A16:
+ case RGBA64, A16, RGBA64U:
pixels = new Uint16Array(Std.int(formatByteSize(myFormat) / 2) * width * height);
case RGBA32, L8:
pixels = new Uint8Array(formatByteSize(myFormat) * width * height);
@@ -525,6 +551,8 @@ class WebGLImage extends Image {
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, SystemImpl.halfFloat.HALF_FLOAT_OES, pixels);
case RGBA32:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, GL.UNSIGNED_BYTE, pixels);
+ case RGBA64U:
+ SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL_RGBA_INTEGER, GL.UNSIGNED_SHORT, pixels);
case A32:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, SystemImpl.gl2 ? GL_RED : GL.ALPHA, GL.FLOAT, pixels);
case A16:
@@ -575,6 +603,14 @@ class WebGLImage extends Image {
SystemImpl.halfFloat.HALF_FLOAT_OES, cast(mipmaps[i], WebGLImage).image);
}
}
+ else if (myFormat == TextureFormat.RGBA64U) {
+ SystemImpl.gl.pixelStorei(GL.UNPACK_ALIGNMENT, 2);
+ for (i in 0...mipmaps.length) {
+ SystemImpl.gl.texImage2D(GL.TEXTURE_2D, i + 1, GL_RGBA16UI, mipmaps[i].width, mipmaps[i].height, 0, GL_RGBA_INTEGER, GL.UNSIGNED_SHORT,
+ cast(mipmaps[i], WebGLImage).image);
+ }
+ SystemImpl.gl.pixelStorei(GL.UNPACK_ALIGNMENT, 4);
+ }
else {
for (i in 0...mipmaps.length) {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, i + 1, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, cast(mipmaps[i], WebGLImage).image);
diff --git a/Backends/Kore-HL/kha/Image.hx b/Backends/Kore-HL/kha/Image.hx
index 4168f8f6c..1fd3a6f99 100644
--- a/Backends/Kore-HL/kha/Image.hx
+++ b/Backends/Kore-HL/kha/Image.hx
@@ -103,6 +103,8 @@ class Image implements Canvas implements Resource {
return 5;
case A16: // Target16BitRedFloat
return 6;
+ case RGBA64U: // Target64BitInteger
+ return 7;
default:
return 0;
}
@@ -142,6 +144,8 @@ class Image implements Canvas implements Resource {
return 5;
case A16:
return 7;
+ case RGBA64U:
+ return 8;
default:
return 1; // Grey8
}
@@ -154,7 +158,7 @@ class Image implements Canvas implements Resource {
if (renderTarget)
image.initRenderTarget(width, height, getDepthBufferBits(depthStencil), getRenderTargetFormat(format), getStencilBufferBits(depthStencil));
else
- image.init(width, height, format);
+ image.init(width, height, getTextureFormat(format));
return image;
}
@@ -334,6 +338,7 @@ class Image implements Canvas implements Resource {
case RGBA128: 16;
case DEPTH16: 2;
case RGBA64: 8;
+ case RGBA64U: 8;
case A32: 4;
case A16: 2;
default: 4;
diff --git a/Backends/Kore-HL/kha/graphics4/CubeMap.hx b/Backends/Kore-HL/kha/graphics4/CubeMap.hx
index e038d86e4..03bb7c3f1 100644
--- a/Backends/Kore-HL/kha/graphics4/CubeMap.hx
+++ b/Backends/Kore-HL/kha/graphics4/CubeMap.hx
@@ -38,6 +38,8 @@ class CubeMap implements Canvas implements Resource {
return 3;
case DEPTH16: // Target16BitDepth
return 4;
+ case RGBA64U: // Target64BitInteger
+ return 7;
default:
return 0;
}
@@ -75,6 +77,8 @@ class CubeMap implements Canvas implements Resource {
return 4;
case A32:
return 5;
+ case RGBA64U:
+ return 8;
default:
return 1; // Grey 8
}
diff --git a/Backends/Kore-hxcpp/kha/Image.hx b/Backends/Kore-hxcpp/kha/Image.hx
index 24eab5843..70717d787 100644
--- a/Backends/Kore-hxcpp/kha/Image.hx
+++ b/Backends/Kore-hxcpp/kha/Image.hx
@@ -195,6 +195,8 @@ class Image implements Canvas implements Resource {
return 5; // Target8BitRed
case A16:
return 6; // Target16BitRedFloat
+ case RGBA64U:
+ return 7; // Target64BitInteger
default:
return 0;
}
@@ -234,6 +236,8 @@ class Image implements Canvas implements Resource {
return 5;
case A16:
return 7;
+ case RGBA64U:
+ return 8;
default:
return 1; // Grey8
}
@@ -519,6 +523,7 @@ class Image implements Canvas implements Resource {
case RGBA128: 16;
case DEPTH16: 2;
case RGBA64: 8;
+ case RGBA64U: 8;
case A32: 4;
case A16: 2;
default: 4;
diff --git a/Backends/Kore-hxcpp/kha/graphics4/CubeMap.hx b/Backends/Kore-hxcpp/kha/graphics4/CubeMap.hx
index 46e8b5aa7..f678e5851 100644
--- a/Backends/Kore-hxcpp/kha/graphics4/CubeMap.hx
+++ b/Backends/Kore-hxcpp/kha/graphics4/CubeMap.hx
@@ -37,6 +37,8 @@ class CubeMap implements Canvas implements Resource {
return 3;
case DEPTH16: // Target16BitDepth
return 4;
+ case RGBA64U: // Target64BitInteger
+ return 7;
default:
return 0;
}
@@ -74,6 +76,8 @@ class CubeMap implements Canvas implements Resource {
return 4;
case A32:
return 5;
+ case RGBA64U:
+ return 8;
default:
return 1; // Grey 8
}
diff --git a/Backends/Krom/kha/Image.hx b/Backends/Krom/kha/Image.hx
index 1139799b2..b20af7727 100644
--- a/Backends/Krom/kha/Image.hx
+++ b/Backends/Krom/kha/Image.hx
@@ -36,6 +36,8 @@ class Image implements Canvas implements Resource {
return 5; // Target8BitRed
case A16:
return 6; // Target16BitRedFloat
+ case RGBA64U:
+ return 7; // Target64BitInteger
default:
return 0;
}
@@ -75,6 +77,8 @@ class Image implements Canvas implements Resource {
return 5;
case A16:
return 7;
+ case RGBA64U:
+ return 8;
default:
return 1; // Grey8
}
@@ -198,6 +202,7 @@ class Image implements Canvas implements Resource {
case RGBA128: 16;
case DEPTH16: 2;
case RGBA64: 8;
+ case RGBA64U: 8;
case A32: 4;
case A16: 2;
default: 4;
diff --git a/Backends/Krom/kha/graphics4/CubeMap.hx b/Backends/Krom/kha/graphics4/CubeMap.hx
index 5d0631308..fba47e035 100644
--- a/Backends/Krom/kha/graphics4/CubeMap.hx
+++ b/Backends/Krom/kha/graphics4/CubeMap.hx
@@ -24,6 +24,8 @@ class CubeMap implements Canvas implements Resource {
return 3;
case DEPTH16: // Target16BitDepth
return 4;
+ case RGBA64U: // Target64BitInteger
+ return 7;
default:
return 0;
}
@@ -61,6 +63,8 @@ class CubeMap implements Canvas implements Resource {
return 4;
case A32:
return 5;
+ case RGBA64U:
+ return 8;
default:
return 1; // Grey8
}
diff --git a/Sources/kha/graphics4/TextureFormat.hx b/Sources/kha/graphics4/TextureFormat.hx
index ce2db7479..97ab374f9 100644
--- a/Sources/kha/graphics4/TextureFormat.hx
+++ b/Sources/kha/graphics4/TextureFormat.hx
@@ -8,4 +8,5 @@ enum abstract TextureFormat(Int) to Int {
var RGBA64 = 4; // Half floats
var A32 = 5; // Float
var A16 = 6; // Half float
+ var RGBA64U = 7; // 16-bit uint
}