Skip to content

Commit 1a6ef13

Browse files
committed
add basic support for the half-float texture format
1 parent 18824af commit 1a6ef13

File tree

2 files changed

+72
-2
lines changed

2 files changed

+72
-2
lines changed

src/main.js

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var GL = {
1616
try { gl = canvas.getContext('webgl', options); } catch (e) {}
1717
try { gl = gl || canvas.getContext('experimental-webgl', options); } catch (e) {}
1818
if (!gl) throw new Error('WebGL not supported');
19+
gl.HALF_FLOAT_OES = 0x8D61;
1920
addMatrixStack();
2021
addImmediateMode();
2122
addEventListeners();

src/texture.js

+71-2
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,29 @@ function Texture(width, height, options) {
2929
this.height = height;
3030
this.format = options.format || gl.RGBA;
3131
this.type = options.type || gl.UNSIGNED_BYTE;
32+
var magFilter = options.filter || options.magFilter || gl.LINEAR;
33+
var minFilter = options.filter || options.minFilter || gl.LINEAR;
34+
if (this.type === gl.FLOAT) {
35+
if (!Texture.canUseFloatingPointTextures()) {
36+
throw new Error('OES_texture_float is required but not supported');
37+
}
38+
if ((minFilter !== gl.NEAREST || magFilter !== gl.NEAREST) &&
39+
!Texture.canUseFloatingPointLinearFiltering()) {
40+
throw new Error('OES_texture_float_linear is required but not supported');
41+
}
42+
} else if (this.type === gl.HALF_FLOAT_OES) {
43+
if (!Texture.canUseHalfFloatingPointTextures()) {
44+
throw new Error('OES_texture_half_float is required but not supported');
45+
}
46+
if ((minFilter !== gl.NEAREST || magFilter !== gl.NEAREST) &&
47+
!Texture.canUseHalfFloatingPointLinearFiltering()) {
48+
throw new Error('OES_texture_half_float_linear is required but not supported');
49+
}
50+
}
3251
gl.bindTexture(gl.TEXTURE_2D, this.id);
3352
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
34-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, options.filter || options.magFilter || gl.LINEAR);
35-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, options.filter || options.minFilter || gl.LINEAR);
53+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
54+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
3655
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, options.wrap || options.wrapS || gl.CLAMP_TO_EDGE);
3756
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, options.wrap || options.wrapT || gl.CLAMP_TO_EDGE);
3857
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.format, this.type, null);
@@ -59,6 +78,19 @@ Texture.prototype = {
5978
gl.bindTexture(gl.TEXTURE_2D, null);
6079
},
6180

81+
// ### .canDrawTo()
82+
//
83+
// Check if rendering to this texture is supported. It may not be supported
84+
// for floating-point textures on some configurations.
85+
canDrawTo: function() {
86+
framebuffer = framebuffer || gl.createFramebuffer();
87+
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
88+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.id, 0);
89+
var result = gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE;
90+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
91+
return result;
92+
},
93+
6294
// ### .drawTo(callback)
6395
//
6496
// Render all draw calls in `callback` to this texture. This method sets up
@@ -85,6 +117,9 @@ Texture.prototype = {
85117
}
86118
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.id, 0);
87119
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer);
120+
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
121+
throw new Error('Rendering to this texture is not supported (incomplete framebuffer)');
122+
}
88123
gl.viewport(0, 0, this.width, this.height);
89124

90125
callback();
@@ -154,3 +189,37 @@ Texture.fromURL = function(url, options) {
154189
image.src = url;
155190
return texture;
156191
};
192+
193+
// ### GL.Texture.canUseFloatingPointTextures()
194+
//
195+
// Returns false if `gl.FLOAT` is not supported as a texture type. This is the
196+
// `OES_texture_float` extension.
197+
Texture.canUseFloatingPointTextures = function() {
198+
return !!gl.getExtension('OES_texture_float');
199+
};
200+
201+
// ### GL.Texture.canUseFloatingPointLinearFiltering()
202+
//
203+
// Returns false if `gl.LINEAR` is not supported as a texture filter mode for
204+
// textures of type `gl.FLOAT`. This is the `OES_texture_float_linear`
205+
// extension.
206+
Texture.canUseFloatingPointLinearFiltering = function() {
207+
return !!gl.getExtension('OES_texture_float_linear');
208+
};
209+
210+
// ### GL.Texture.canUseFloatingPointTextures()
211+
//
212+
// Returns false if `gl.HALF_FLOAT_OES` is not supported as a texture type.
213+
// This is the `OES_texture_half_float` extension.
214+
Texture.canUseHalfFloatingPointTextures = function() {
215+
return !!gl.getExtension('OES_texture_half_float');
216+
};
217+
218+
// ### GL.Texture.canUseFloatingPointLinearFiltering()
219+
//
220+
// Returns false if `gl.LINEAR` is not supported as a texture filter mode for
221+
// textures of type `gl.HALF_FLOAT_OES`. This is the
222+
// `OES_texture_half_float_linear` extension.
223+
Texture.canUseHalfFloatingPointLinearFiltering = function() {
224+
return !!gl.getExtension('OES_texture_half_float_linear');
225+
};

0 commit comments

Comments
 (0)