Manual class transform

This commit is contained in:
Tim Schaub
2018-07-16 17:09:50 -06:00
parent 7b4a73f3b9
commit f78d0d4cfa
96 changed files with 8112 additions and 7964 deletions

View File

@@ -18,36 +18,36 @@ const BufferUsage = {
* @param {number=} opt_usage Usage.
* @struct
*/
const WebGLBuffer = function(opt_arr, opt_usage) {
class WebGLBuffer {
constructor(opt_arr, opt_usage) {
/**
* @private
* @type {Array.<number>}
*/
this.arr_ = opt_arr !== undefined ? opt_arr : [];
/**
* @private
* @type {Array.<number>}
*/
this.arr_ = opt_arr !== undefined ? opt_arr : [];
/**
* @private
* @type {number}
*/
this.usage_ = opt_usage !== undefined ? opt_usage : BufferUsage.STATIC_DRAW;
/**
* @private
* @type {number}
*/
this.usage_ = opt_usage !== undefined ? opt_usage : BufferUsage.STATIC_DRAW;
};
}
/**
* @return {Array.<number>} Array.
*/
getArray() {
return this.arr_;
}
/**
* @return {Array.<number>} Array.
*/
WebGLBuffer.prototype.getArray = function() {
return this.arr_;
};
/**
* @return {number} Usage.
*/
WebGLBuffer.prototype.getUsage = function() {
return this.usage_;
};
/**
* @return {number} Usage.
*/
getUsage() {
return this.usage_;
}
}
export default WebGLBuffer;

View File

@@ -27,295 +27,285 @@ import ContextEventType from '../webgl/ContextEventType.js';
* @param {HTMLCanvasElement} canvas Canvas.
* @param {WebGLRenderingContext} gl GL.
*/
const WebGLContext = function(canvas, gl) {
class WebGLContext {
constructor(canvas, gl) {
/**
* @private
* @type {HTMLCanvasElement}
*/
this.canvas_ = canvas;
/**
* @private
* @type {HTMLCanvasElement}
*/
this.canvas_ = canvas;
/**
* @private
* @type {WebGLRenderingContext}
*/
this.gl_ = gl;
/**
* @private
* @type {WebGLRenderingContext}
*/
this.gl_ = gl;
/**
* @private
* @type {!Object.<string, module:ol/webgl/Context~BufferCacheEntry>}
*/
this.bufferCache_ = {};
/**
* @private
* @type {!Object.<string, module:ol/webgl/Context~BufferCacheEntry>}
*/
this.bufferCache_ = {};
/**
* @private
* @type {!Object.<string, WebGLShader>}
*/
this.shaderCache_ = {};
/**
* @private
* @type {!Object.<string, WebGLShader>}
*/
this.shaderCache_ = {};
/**
* @private
* @type {!Object.<string, WebGLProgram>}
*/
this.programCache_ = {};
/**
* @private
* @type {!Object.<string, WebGLProgram>}
*/
this.programCache_ = {};
/**
* @private
* @type {WebGLProgram}
*/
this.currentProgram_ = null;
/**
* @private
* @type {WebGLProgram}
*/
this.currentProgram_ = null;
/**
* @private
* @type {WebGLFramebuffer}
*/
this.hitDetectionFramebuffer_ = null;
/**
* @private
* @type {WebGLFramebuffer}
*/
this.hitDetectionFramebuffer_ = null;
/**
* @private
* @type {WebGLTexture}
*/
this.hitDetectionTexture_ = null;
/**
* @private
* @type {WebGLTexture}
*/
this.hitDetectionTexture_ = null;
/**
* @private
* @type {WebGLRenderbuffer}
*/
this.hitDetectionRenderbuffer_ = null;
/**
* @private
* @type {WebGLRenderbuffer}
*/
this.hitDetectionRenderbuffer_ = null;
/**
* @type {boolean}
*/
this.hasOESElementIndexUint = includes(WEBGL_EXTENSIONS, 'OES_element_index_uint');
/**
* @type {boolean}
*/
this.hasOESElementIndexUint = includes(WEBGL_EXTENSIONS, 'OES_element_index_uint');
// use the OES_element_index_uint extension if available
if (this.hasOESElementIndexUint) {
gl.getExtension('OES_element_index_uint');
}
listen(this.canvas_, ContextEventType.LOST,
this.handleWebGLContextLost, this);
listen(this.canvas_, ContextEventType.RESTORED,
this.handleWebGLContextRestored, this);
// use the OES_element_index_uint extension if available
if (this.hasOESElementIndexUint) {
gl.getExtension('OES_element_index_uint');
}
listen(this.canvas_, ContextEventType.LOST,
this.handleWebGLContextLost, this);
listen(this.canvas_, ContextEventType.RESTORED,
this.handleWebGLContextRestored, this);
/**
* Just bind the buffer if it's in the cache. Otherwise create
* the WebGL buffer, bind it, populate it, and add an entry to
* the cache.
* @param {number} target Target.
* @param {module:ol/webgl/Buffer} buf Buffer.
*/
bindBuffer(target, buf) {
const gl = this.getGL();
const arr = buf.getArray();
const bufferKey = String(getUid(buf));
if (bufferKey in this.bufferCache_) {
const bufferCacheEntry = this.bufferCache_[bufferKey];
gl.bindBuffer(target, bufferCacheEntry.buffer);
} else {
const buffer = gl.createBuffer();
gl.bindBuffer(target, buffer);
let /** @type {ArrayBufferView} */ arrayBuffer;
if (target == ARRAY_BUFFER) {
arrayBuffer = new Float32Array(arr);
} else if (target == ELEMENT_ARRAY_BUFFER) {
arrayBuffer = this.hasOESElementIndexUint ?
new Uint32Array(arr) : new Uint16Array(arr);
}
gl.bufferData(target, arrayBuffer, buf.getUsage());
this.bufferCache_[bufferKey] = {
buf: buf,
buffer: buffer
};
}
}
};
/**
* @param {module:ol/webgl/Buffer} buf Buffer.
*/
deleteBuffer(buf) {
const gl = this.getGL();
const bufferKey = String(getUid(buf));
const bufferCacheEntry = this.bufferCache_[bufferKey];
if (!gl.isContextLost()) {
gl.deleteBuffer(bufferCacheEntry.buffer);
}
delete this.bufferCache_[bufferKey];
}
/**
* @inheritDoc
*/
disposeInternal() {
unlistenAll(this.canvas_);
const gl = this.getGL();
if (!gl.isContextLost()) {
for (const key in this.bufferCache_) {
gl.deleteBuffer(this.bufferCache_[key].buffer);
}
for (const key in this.programCache_) {
gl.deleteProgram(this.programCache_[key]);
}
for (const key in this.shaderCache_) {
gl.deleteShader(this.shaderCache_[key]);
}
// delete objects for hit-detection
gl.deleteFramebuffer(this.hitDetectionFramebuffer_);
gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_);
gl.deleteTexture(this.hitDetectionTexture_);
}
}
/**
* @return {HTMLCanvasElement} Canvas.
*/
getCanvas() {
return this.canvas_;
}
/**
* Get the WebGL rendering context
* @return {WebGLRenderingContext} The rendering context.
* @api
*/
getGL() {
return this.gl_;
}
/**
* Get the frame buffer for hit detection.
* @return {WebGLFramebuffer} The hit detection frame buffer.
*/
getHitDetectionFramebuffer() {
if (!this.hitDetectionFramebuffer_) {
this.initHitDetectionFramebuffer_();
}
return this.hitDetectionFramebuffer_;
}
/**
* Get shader from the cache if it's in the cache. Otherwise, create
* the WebGL shader, compile it, and add entry to cache.
* @param {module:ol/webgl/Shader} shaderObject Shader object.
* @return {WebGLShader} Shader.
*/
getShader(shaderObject) {
const shaderKey = String(getUid(shaderObject));
if (shaderKey in this.shaderCache_) {
return this.shaderCache_[shaderKey];
} else {
const gl = this.getGL();
const shader = gl.createShader(shaderObject.getType());
gl.shaderSource(shader, shaderObject.getSource());
gl.compileShader(shader);
this.shaderCache_[shaderKey] = shader;
return shader;
}
}
/**
* Get the program from the cache if it's in the cache. Otherwise create
* the WebGL program, attach the shaders to it, and add an entry to the
* cache.
* @param {module:ol/webgl/Fragment} fragmentShaderObject Fragment shader.
* @param {module:ol/webgl/Vertex} vertexShaderObject Vertex shader.
* @return {WebGLProgram} Program.
*/
getProgram(fragmentShaderObject, vertexShaderObject) {
const programKey = getUid(fragmentShaderObject) + '/' + getUid(vertexShaderObject);
if (programKey in this.programCache_) {
return this.programCache_[programKey];
} else {
const gl = this.getGL();
const program = gl.createProgram();
gl.attachShader(program, this.getShader(fragmentShaderObject));
gl.attachShader(program, this.getShader(vertexShaderObject));
gl.linkProgram(program);
this.programCache_[programKey] = program;
return program;
}
}
/**
* FIXME empty description for jsdoc
*/
handleWebGLContextLost() {
clear(this.bufferCache_);
clear(this.shaderCache_);
clear(this.programCache_);
this.currentProgram_ = null;
this.hitDetectionFramebuffer_ = null;
this.hitDetectionTexture_ = null;
this.hitDetectionRenderbuffer_ = null;
}
/**
* FIXME empty description for jsdoc
*/
handleWebGLContextRestored() {
}
/**
* Creates a 1x1 pixel framebuffer for the hit-detection.
* @private
*/
initHitDetectionFramebuffer_() {
const gl = this.gl_;
const framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
const texture = createEmptyTexture(gl, 1, 1);
const renderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
gl.framebufferTexture2D(
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER, renderbuffer);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
this.hitDetectionFramebuffer_ = framebuffer;
this.hitDetectionTexture_ = texture;
this.hitDetectionRenderbuffer_ = renderbuffer;
}
/**
* Use a program. If the program is already in use, this will return `false`.
* @param {WebGLProgram} program Program.
* @return {boolean} Changed.
* @api
*/
useProgram(program) {
if (program == this.currentProgram_) {
return false;
} else {
const gl = this.getGL();
gl.useProgram(program);
this.currentProgram_ = program;
return true;
}
}
}
inherits(WebGLContext, Disposable);
/**
* Just bind the buffer if it's in the cache. Otherwise create
* the WebGL buffer, bind it, populate it, and add an entry to
* the cache.
* @param {number} target Target.
* @param {module:ol/webgl/Buffer} buf Buffer.
*/
WebGLContext.prototype.bindBuffer = function(target, buf) {
const gl = this.getGL();
const arr = buf.getArray();
const bufferKey = String(getUid(buf));
if (bufferKey in this.bufferCache_) {
const bufferCacheEntry = this.bufferCache_[bufferKey];
gl.bindBuffer(target, bufferCacheEntry.buffer);
} else {
const buffer = gl.createBuffer();
gl.bindBuffer(target, buffer);
let /** @type {ArrayBufferView} */ arrayBuffer;
if (target == ARRAY_BUFFER) {
arrayBuffer = new Float32Array(arr);
} else if (target == ELEMENT_ARRAY_BUFFER) {
arrayBuffer = this.hasOESElementIndexUint ?
new Uint32Array(arr) : new Uint16Array(arr);
}
gl.bufferData(target, arrayBuffer, buf.getUsage());
this.bufferCache_[bufferKey] = {
buf: buf,
buffer: buffer
};
}
};
/**
* @param {module:ol/webgl/Buffer} buf Buffer.
*/
WebGLContext.prototype.deleteBuffer = function(buf) {
const gl = this.getGL();
const bufferKey = String(getUid(buf));
const bufferCacheEntry = this.bufferCache_[bufferKey];
if (!gl.isContextLost()) {
gl.deleteBuffer(bufferCacheEntry.buffer);
}
delete this.bufferCache_[bufferKey];
};
/**
* @inheritDoc
*/
WebGLContext.prototype.disposeInternal = function() {
unlistenAll(this.canvas_);
const gl = this.getGL();
if (!gl.isContextLost()) {
for (const key in this.bufferCache_) {
gl.deleteBuffer(this.bufferCache_[key].buffer);
}
for (const key in this.programCache_) {
gl.deleteProgram(this.programCache_[key]);
}
for (const key in this.shaderCache_) {
gl.deleteShader(this.shaderCache_[key]);
}
// delete objects for hit-detection
gl.deleteFramebuffer(this.hitDetectionFramebuffer_);
gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_);
gl.deleteTexture(this.hitDetectionTexture_);
}
};
/**
* @return {HTMLCanvasElement} Canvas.
*/
WebGLContext.prototype.getCanvas = function() {
return this.canvas_;
};
/**
* Get the WebGL rendering context
* @return {WebGLRenderingContext} The rendering context.
* @api
*/
WebGLContext.prototype.getGL = function() {
return this.gl_;
};
/**
* Get the frame buffer for hit detection.
* @return {WebGLFramebuffer} The hit detection frame buffer.
*/
WebGLContext.prototype.getHitDetectionFramebuffer = function() {
if (!this.hitDetectionFramebuffer_) {
this.initHitDetectionFramebuffer_();
}
return this.hitDetectionFramebuffer_;
};
/**
* Get shader from the cache if it's in the cache. Otherwise, create
* the WebGL shader, compile it, and add entry to cache.
* @param {module:ol/webgl/Shader} shaderObject Shader object.
* @return {WebGLShader} Shader.
*/
WebGLContext.prototype.getShader = function(shaderObject) {
const shaderKey = String(getUid(shaderObject));
if (shaderKey in this.shaderCache_) {
return this.shaderCache_[shaderKey];
} else {
const gl = this.getGL();
const shader = gl.createShader(shaderObject.getType());
gl.shaderSource(shader, shaderObject.getSource());
gl.compileShader(shader);
this.shaderCache_[shaderKey] = shader;
return shader;
}
};
/**
* Get the program from the cache if it's in the cache. Otherwise create
* the WebGL program, attach the shaders to it, and add an entry to the
* cache.
* @param {module:ol/webgl/Fragment} fragmentShaderObject Fragment shader.
* @param {module:ol/webgl/Vertex} vertexShaderObject Vertex shader.
* @return {WebGLProgram} Program.
*/
WebGLContext.prototype.getProgram = function(fragmentShaderObject, vertexShaderObject) {
const programKey = getUid(fragmentShaderObject) + '/' + getUid(vertexShaderObject);
if (programKey in this.programCache_) {
return this.programCache_[programKey];
} else {
const gl = this.getGL();
const program = gl.createProgram();
gl.attachShader(program, this.getShader(fragmentShaderObject));
gl.attachShader(program, this.getShader(vertexShaderObject));
gl.linkProgram(program);
this.programCache_[programKey] = program;
return program;
}
};
/**
* FIXME empty description for jsdoc
*/
WebGLContext.prototype.handleWebGLContextLost = function() {
clear(this.bufferCache_);
clear(this.shaderCache_);
clear(this.programCache_);
this.currentProgram_ = null;
this.hitDetectionFramebuffer_ = null;
this.hitDetectionTexture_ = null;
this.hitDetectionRenderbuffer_ = null;
};
/**
* FIXME empty description for jsdoc
*/
WebGLContext.prototype.handleWebGLContextRestored = function() {
};
/**
* Creates a 1x1 pixel framebuffer for the hit-detection.
* @private
*/
WebGLContext.prototype.initHitDetectionFramebuffer_ = function() {
const gl = this.gl_;
const framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
const texture = createEmptyTexture(gl, 1, 1);
const renderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
gl.framebufferTexture2D(
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
gl.RENDERBUFFER, renderbuffer);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
this.hitDetectionFramebuffer_ = framebuffer;
this.hitDetectionTexture_ = texture;
this.hitDetectionRenderbuffer_ = renderbuffer;
};
/**
* Use a program. If the program is already in use, this will return `false`.
* @param {WebGLProgram} program Program.
* @return {boolean} Changed.
* @api
*/
WebGLContext.prototype.useProgram = function(program) {
if (program == this.currentProgram_) {
return false;
} else {
const gl = this.getGL();
gl.useProgram(program);
this.currentProgram_ = program;
return true;
}
};
/**
* @param {WebGLRenderingContext} gl WebGL rendering context.
* @param {number=} opt_wrapS wrapS.

View File

@@ -11,17 +11,20 @@ import WebGLShader from '../webgl/Shader.js';
* @param {string} source Source.
* @struct
*/
const WebGLFragment = function(source) {
WebGLShader.call(this, source);
};
class WebGLFragment {
constructor(source) {
WebGLShader.call(this, source);
}
/**
* @inheritDoc
*/
getType() {
return FRAGMENT_SHADER;
}
}
inherits(WebGLFragment, WebGLShader);
/**
* @inheritDoc
*/
WebGLFragment.prototype.getType = function() {
return FRAGMENT_SHADER;
};
export default WebGLFragment;

View File

@@ -9,30 +9,30 @@ import {FALSE} from '../functions.js';
* @param {string} source Source.
* @struct
*/
const WebGLShader = function(source) {
class WebGLShader {
constructor(source) {
/**
* @private
* @type {string}
*/
this.source_ = source;
/**
* @private
* @type {string}
*/
this.source_ = source;
};
}
/**
* @abstract
* @return {number} Type.
*/
getType() {}
/**
* @abstract
* @return {number} Type.
*/
WebGLShader.prototype.getType = function() {};
/**
* @return {string} Source.
*/
WebGLShader.prototype.getSource = function() {
return this.source_;
};
/**
* @return {string} Source.
*/
getSource() {
return this.source_;
}
}
/**

View File

@@ -11,17 +11,20 @@ import WebGLShader from '../webgl/Shader.js';
* @param {string} source Source.
* @struct
*/
const WebGLVertex = function(source) {
WebGLShader.call(this, source);
};
class WebGLVertex {
constructor(source) {
WebGLShader.call(this, source);
}
/**
* @inheritDoc
*/
getType() {
return VERTEX_SHADER;
}
}
inherits(WebGLVertex, WebGLShader);
/**
* @inheritDoc
*/
WebGLVertex.prototype.getType = function() {
return VERTEX_SHADER;
};
export default WebGLVertex;

View File

@@ -12,23 +12,28 @@ import {DEBUG as DEBUG_WEBGL} from '../../../../webgl.js';
* @param {WebGLProgram} program Program.
* @struct
*/
const Locations = function(gl, program) {
{{#uniforms}}
class Locations {
/**
* @type {WebGLUniformLocation}
*/
this.{{originalName}} = gl.getUniformLocation(
program, DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
{{/uniforms}}
{{#attributes}}
constructor(gl, program) {
{{#uniforms}}
/**
* @type {number}
*/
this.{{originalName}} = gl.getAttribLocation(
program, DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
{{/attributes}}
};
/**
* @type {WebGLUniformLocation}
*/
this.{{originalName}} = gl.getUniformLocation(
program, DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
{{/uniforms}}
{{#attributes}}
/**
* @type {number}
*/
this.{{originalName}} = gl.getAttribLocation(
program, DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
{{/attributes}}
}
}
export default Locations;