Import WebGL code from WebGL Maps

This commit is contained in:
Tom Payne
2012-07-13 19:27:48 +02:00
parent a35cd158be
commit 19ea6a0cba
13 changed files with 892 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
goog.provide('ol.webglrenderer.ArrayBuffer');
goog.require('goog.webgl');
goog.require('ol.webglrenderer.StaticGLObject');
/**
* @constructor
* @extends {ol.webglrenderer.StaticGLObject}
* @param {WebGLRenderingContext} gl GL.
* @param {ArrayBuffer|ArrayBufferView|null|number} data Data.
* @param {number} usage Usage.
*/
ol.webglrenderer.ArrayBuffer = function(gl, data, usage) {
goog.base(this, gl);
/**
* @private
* @type {WebGLBuffer}
*/
this.buffer_ = gl.createBuffer();
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, this.buffer_);
gl.bufferData(goog.webgl.ARRAY_BUFFER, data, usage);
};
goog.inherits(ol.webglrenderer.ArrayBuffer, ol.webglrenderer.StaticGLObject);
/**
*/
ol.webglrenderer.ArrayBuffer.prototype.bind = function() {
var gl = this.getGL();
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, this.buffer_);
};
/**
* @inheritDoc
*/
ol.webglrenderer.ArrayBuffer.prototype.disposeInternal = function() {
var gl = this.getGL();
gl.deleteBuffer(this.buffer_);
this.buffer_ = null;
goog.base(this, 'disposeInternal');
};

View File

@@ -0,0 +1,118 @@
goog.provide('ol.webglrenderer.Framebuffer');
goog.require('goog.asserts');
goog.require('goog.webgl');
goog.require('ol.webglrenderer.GLObject');
/**
* @constructor
* @extends {ol.webglrenderer.GLObject}
* @param {number} size Size.
*/
ol.webglrenderer.Framebuffer = function(size) {
goog.base(this);
/**
* @private
* @type {WebGLFramebuffer}
*/
this.framebuffer_ = null;
/**
* @private
* @type {WebGLTexture}
*/
this.texture_ = null;
/**
* @private
* @type {number}
*/
this.size_ = size;
};
goog.inherits(ol.webglrenderer.Framebuffer, ol.webglrenderer.GLObject);
/**
*/
ol.webglrenderer.Framebuffer.prototype.bind = function() {
var gl = this.getGL();
var framebuffer = this.get();
gl.bindFramebuffer(goog.webgl.FRAMEBUFFER, framebuffer);
};
/**
* @param {number} size Size.
* @private
* @return {WebGLTexture} Texture.
*/
ol.webglrenderer.Framebuffer.prototype.createTexture_ = function(size) {
var gl = this.getGL();
var texture = gl.createTexture();
gl.bindTexture(goog.webgl.TEXTURE_2D, this.texture_);
gl.texImage2D(goog.webgl.TEXTURE_2D, 0, goog.webgl.RGBA, size, size, 0,
goog.webgl.RGBA, goog.webgl.UNSIGNED_BYTE, null);
gl.texParameteri(
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MAG_FILTER, goog.webgl.LINEAR);
gl.texParameteri(
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MIN_FILTER, goog.webgl.LINEAR);
return texture;
};
/**
* @return {WebGLFramebuffer} Framebuffer.
*/
ol.webglrenderer.Framebuffer.prototype.get = function() {
goog.asserts.assert(!goog.isNull(this.framebuffer_));
return this.framebuffer_;
};
/**
* @param {WebGLRenderingContext} gl GL.
*/
ol.webglrenderer.Framebuffer.prototype.setGL = function(gl) {
if (!goog.isNull(this.gl)) {
if (!goog.isNull(this.framebuffer_)) {
this.gl.deleteFramebuffer(this.framebuffer_);
this.framebuffer_ = null;
}
if (!goog.isNull(this.texture_)) {
this.gl.deleteTexture(this.texture_);
this.texture_ = null;
}
}
goog.base(this, 'setGL', gl);
if (!goog.isNull(gl)) {
this.texture_ = this.createTexture_(this.size_);
this.framebuffer_ = gl.createFramebuffer();
gl.bindFramebuffer(goog.webgl.FRAMEBUFFER, this.framebuffer_);
gl.framebufferTexture2D(goog.webgl.FRAMEBUFFER,
goog.webgl.COLOR_ATTACHMENT0, goog.webgl.TEXTURE_2D, this.texture_, 0);
}
};
/**
* @param {number} size Size.
*/
ol.webglrenderer.Framebuffer.prototype.setSize = function(size) {
var gl = this.getGL();
goog.asserts.assert(!(size & (size - 1)));
if (this.size_ != size && !goog.isNull(gl)) {
var texture = this.createTexture_(size);
goog.asserts.assert(!goog.isNull(this.framebuffer_));
gl.bindFramebuffer(goog.webgl.FRAMEBUFFER, this.framebuffer_);
gl.framebufferTexture2D(goog.webgl.FRAMEBUFFER,
goog.webgl.COLOR_ATTACHMENT0, goog.webgl.TEXTURE_2D, texture, 0);
goog.asserts.assert(!goog.isNull(this.texture_));
gl.deleteTexture(this.texture_);
this.texture = texture;
}
};

View File

@@ -0,0 +1,50 @@
goog.provide('ol.webglrenderer.GLObject');
goog.require('goog.Disposable');
goog.require('ol.webglrenderer.IGLObject');
/**
* @constructor
* @extends {goog.Disposable}
* @implements {ol.webglrenderer.IGLObject}
*/
ol.webglrenderer.GLObject = function() {
goog.base(this);
/**
* @private
* @type {WebGLRenderingContext}
*/
this.gl_ = null;
};
goog.inherits(ol.webglrenderer.GLObject, goog.Disposable);
/**
* @inheritDoc
*/
ol.webglrenderer.GLObject.prototype.disposeInternal = function() {
this.setGL(null);
goog.base(this, 'disposeInternal');
};
/**
* @inheritDoc
*/
ol.webglrenderer.GLObject.prototype.getGL = function() {
goog.asserts.assert(!goog.isNull(this.gl_));
return this.gl_;
};
/**
* @inheritDoc
*/
ol.webglrenderer.GLObject.prototype.setGL = function(gl) {
this.gl_ = gl;
};

View File

@@ -0,0 +1,79 @@
goog.provide('ol.webglrenderer.Program');
goog.require('goog.asserts');
goog.require('goog.webgl');
goog.require('ol.webglrenderer.GLObject');
goog.require('ol.webglrenderer.VertexAttrib');
goog.require('ol.webglrenderer.shader.Fragment');
goog.require('ol.webglrenderer.shader.Vertex');
/**
* @constructor
* @extends {ol.webglrenderer.GLObject}
* @param {ol.webglrenderer.shader.Fragment} fragmentShader Fragment shader.
* @param {ol.webglrenderer.shader.Vertex} vertexShader Vertex shader.
*/
ol.webglrenderer.Program = function(fragmentShader, vertexShader) {
goog.base(this);
/**
* @private
* @type {ol.webglrenderer.shader.Fragment}
*/
this.fragmentShader_ = fragmentShader;
/**
* @private
* @type {ol.webglrenderer.shader.Vertex}
*/
this.vertexShader_ = vertexShader;
/**
* @private
* @type {WebGLProgram}
*/
this.program_ = null;
};
goog.inherits(ol.webglrenderer.Program, ol.webglrenderer.GLObject);
/**
* @inheritDoc
*/
ol.webglrenderer.Program.prototype.setGL = function(gl) {
if (!goog.isNull(this.gl)) {
if (!goog.isNull(this.program_)) {
this.gl.deleteProgram(this.program_);
this.program_ = null;
}
this.fragmentShader_.setGL(null);
this.vertexShader_.setGL(null);
}
goog.base(this, 'setGL', gl);
if (!goog.isNull(gl)) {
this.fragmentShader_.setGL(gl);
this.vertexShader_.setGL(gl);
var program = gl.createProgram();
gl.attachShader(program, this.fragmentShader_.get());
gl.attachShader(program, this.vertexShader_.get());
gl.linkProgram(program);
if (!gl.getProgramParameter(program, goog.webgl.LINK_STATUS)) {
window.console.log(gl.getProgramInfoLog(program));
goog.asserts.assert(
gl.getProgramParameter(program, goog.webgl.LINK_STATUS));
}
this.program_ = program;
}
};
/**
*/
ol.webglrenderer.Program.prototype.use = function() {
var gl = this.getGL();
gl.useProgram(this.program_);
};

View File

@@ -0,0 +1,64 @@
goog.provide('ol.webglrenderer.ProgramCache');
goog.require('goog.dispose');
goog.require('goog.object');
goog.require('ol.webglrenderer.GLObject');
goog.require('ol.webglrenderer.Program');
goog.require('ol.webglrenderer.shader.Fragment');
goog.require('ol.webglrenderer.shader.Vertex');
/**
* @constructor
* @extends {ol.webglrenderer.GLObject}
*/
ol.webglrenderer.ProgramCache = function() {
goog.base(this);
/**
* @private
* @type {Object.<string, Object.<string, ol.webglrenderer.Program>>}
*/
this.programss_ = {};
};
goog.inherits(ol.webglrenderer.ProgramCache, ol.webglrenderer.GLObject);
/**
* @param {ol.webglrenderer.shader.Fragment} fragmentShader Fragment shader.
* @param {ol.webglrenderer.shader.Vertex} vertexShader Vertex shader.
* @return {ol.webglrenderer.Program} Program.
*/
ol.webglrenderer.ProgramCache.prototype.get =
function(fragmentShader, vertexShader) {
var program, programs;
var fragmentShaderKey = goog.getUid(fragmentShader);
if (fragmentShaderKey in this.programss_) {
programs = this.programss_[fragmentShaderKey];
} else {
programs = {};
this.programss_[fragmentShaderKey] = programs;
}
var vertexShaderKey = goog.getUid(vertexShader);
if (vertexShaderKey in programs) {
program = programs[vertexShaderKey];
} else {
program = new ol.webglrenderer.Program(fragmentShader, vertexShader);
programs[vertexShaderKey] = program;
}
return program;
};
/**
* @inheritDoc
*/
ol.webglrenderer.ProgramCache.prototype.setGL = function(gl) {
goog.object.forEach(this.programss_, function(programs) {
goog.disposeAll(goog.object.getValues(programs));
});
goog.base(this, 'setGL', gl);
};

View File

@@ -0,0 +1,117 @@
goog.provide('ol.webglrenderer.Shader');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.webgl');
goog.require('ol.webglrenderer.GLObject');
goog.require('ol.webglrenderer.Uniform');
/**
* @constructor
* @extends {ol.webglrenderer.GLObject}
* @param {string} source Source.
* @param {Array.<ol.webglrenderer.Uniform>=} opt_uniforms Uniforms.
*/
ol.webglrenderer.Shader = function(source, opt_uniforms) {
goog.base(this);
/**
* @private
* @type {WebGLShader}
*/
this.shader_ = null;
/**
* @private
* @type {string}
*/
this.source_ = source;
/**
* @private
* @type {Array.<ol.webglrenderer.Uniform>}
*/
this.uniforms_ = opt_uniforms || [];
};
goog.inherits(ol.webglrenderer.Shader, ol.webglrenderer.GLObject);
/**
*/
ol.webglrenderer.Shader.prototype.compile = function() {
var gl = this.getGL();
this.shader_ = this.create();
gl.shaderSource(this.shader_, this.source_);
gl.compileShader(this.shader_);
if (!gl.getShaderParameter(this.shader_, goog.webgl.COMPILE_STATUS)) {
window.console.log(gl.getShaderInfoLog(this.shader_));
goog.asserts.assert(
gl.getShaderParameter(this.shader_, goog.webgl.COMPILE_STATUS));
}
};
/**
* @protected
* @return {WebGLShader} Shader.
*/
ol.webglrenderer.Shader.prototype.create = goog.abstractMethod;
/**
* @return {WebGLShader} Shader.
*/
ol.webglrenderer.Shader.prototype.get = function() {
return this.shader_;
};
/**
* @return {boolean} Is animated?
*/
ol.webglrenderer.Shader.prototype.isAnimated = function() {
return false;
};
/**
* @inheritDoc
*/
ol.webglrenderer.Shader.prototype.setGL = function(gl) {
if (!goog.isNull(this.gl)) {
goog.array.forEach(this.uniforms_, function(uniform) {
uniform.setGL(null);
});
if (!goog.isNull(this.shader_)) {
this.gl.deleteShader(this.shader_);
this.shader_ = null;
}
}
goog.base(this, 'setGL', gl);
if (!goog.isNull(gl)) {
this.compile();
goog.array.forEach(this.uniforms_, function(uniform) {
uniform.setGL(gl);
});
}
};
/**
* @param {WebGLProgram} program Program.
*/
ol.webglrenderer.Shader.prototype.setProgram = function(program) {
goog.array.forEach(this.uniforms_, function(uniform) {
uniform.setProgram(program);
});
};
/**
*/
ol.webglrenderer.Shader.prototype.setUniforms = function() {
};

View File

@@ -0,0 +1,27 @@
goog.provide('ol.webglrenderer.shader.Fragment');
goog.require('goog.asserts');
goog.require('ol.webglrenderer.Shader');
/**
* @constructor
* @extends {ol.webglrenderer.Shader}
* @param {string} source Source.
* @param {Array.<ol.webglrenderer.Uniform>=} opt_uniforms Uniforms.
*/
ol.webglrenderer.shader.Fragment = function(source, opt_uniforms) {
goog.base(this, source, opt_uniforms);
};
goog.inherits(ol.webglrenderer.shader.Fragment, ol.webglrenderer.Shader);
/**
* @protected
* @return {WebGLShader} Shader.
*/
ol.webglrenderer.shader.Fragment.prototype.create = function() {
var gl = this.getGL();
return gl.createShader(gl.FRAGMENT_SHADER);
};

View File

@@ -0,0 +1,27 @@
goog.provide('ol.webglrenderer.shader.Vertex');
goog.require('goog.asserts');
goog.require('ol.webglrenderer.Shader');
/**
* @constructor
* @extends {ol.webglrenderer.Shader}
* @param {string} source Source.
* @param {Array.<ol.webglrenderer.Uniform>=} opt_uniforms Uniforms.
*/
ol.webglrenderer.shader.Vertex = function(source, opt_uniforms) {
goog.base(this, source, opt_uniforms);
};
goog.inherits(ol.webglrenderer.shader.Vertex, ol.webglrenderer.Shader);
/**
* @protected
* @return {WebGLShader} Shader.
*/
ol.webglrenderer.shader.Vertex.prototype.create = function() {
var gl = this.getGL();
return gl.createShader(gl.VERTEX_SHADER);
};

View File

@@ -0,0 +1,49 @@
goog.provide('ol.webglrenderer.StaticGLObject');
goog.require('goog.Disposable');
/**
* @constructor
* @extends {goog.Disposable}
* @param {WebGLRenderingContext} gl GL.
*/
ol.webglrenderer.StaticGLObject = function(gl) {
goog.asserts.assert(!goog.isNull(gl));
/**
* @protected
* @type {WebGLRenderingContext}
*/
this.gl = gl;
};
goog.inherits(ol.webglrenderer.StaticGLObject, goog.Disposable);
/**
* @inheritDoc
*/
ol.webglrenderer.StaticGLObject.prototype.disposeInternal = function() {
this.gl = null;
goog.base(this, 'disposeInternal');
};
/**
* @return {!WebGLRenderingContext} GL.
*/
ol.webglrenderer.StaticGLObject.prototype.getGL = function() {
goog.asserts.assert(!goog.isNull(this.gl));
return this.gl;
};
/**
* @return {WebGLRenderingContext} GL.
*/
ol.webglrenderer.StaticGLObject.prototype.unsafeGetGL = function() {
return this.gl;
};

View File

@@ -0,0 +1,64 @@
goog.provide('ol.webglrenderer.Texture');
goog.require('goog.asserts');
goog.require('ol.webglrenderer.GLObject');
/**
* @constructor
* @extends {ol.webglrenderer.GLObject}
* @param {Image} image Image.
*/
ol.webglrenderer.Texture = function(image) {
goog.base(this);
/**
* @private
* @type {WebGLTexture}
*/
this.texture_ = null;
/**
* @private
* @type {Image}
*/
this.image_ = image;
};
goog.inherits(ol.webglrenderer.Texture, ol.webglrenderer.GLObject);
/**
*/
ol.webglrenderer.Texture.prototype.bind = function() {
var gl = this.getGL();
if (goog.isNull(this.texture_)) {
var texture = gl.createTexture();
gl.bindTexture(goog.webgl.TEXTURE_2D, texture);
gl.texImage2D(goog.webgl.TEXTURE_2D, 0, goog.webgl.RGBA, goog.webgl.RGBA,
goog.webgl.UNSIGNED_BYTE, this.image_);
gl.texParameteri(goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MAG_FILTER,
goog.webgl.NEAREST);
gl.texParameteri(goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MIN_FILTER,
goog.webgl.NEAREST);
this.texture_ = texture;
} else {
gl.bindTexture(goog.webgl.TEXTURE_2D, this.texture_);
}
};
/**
* @inheritDoc
*/
ol.webglrenderer.Texture.prototype.setGL = function(gl) {
if (!goog.isNull(this.gl)) {
if (!goog.isNull(this.texture_)) {
this.gl.deleteTexture(this.texture_);
this.texture_ = null;
}
}
goog.base(this, 'setGL', gl);
};

View File

@@ -0,0 +1,71 @@
goog.provide('ol.webglrenderer.TileLayerRenderer');
goog.require('goog.events.EventType');
goog.require('ol.LayerRenderer');
goog.require('ol.webglrenderer.IGLObject');
/**
* @constructor
* @extends {ol.LayerRenderer}
* @implements {ol.webglrenderer.IGLObject}
* @param {ol.Layer} layer Layer.
* @param {WebGLRenderingContext} gl GL.
*/
ol.webglrenderer.TileLayerRenderer = function(layer, gl) {
goog.base(this, layer);
/**
* @type {WebGLRenderingContext}
* @private
*/
this.gl_ = null;
this.setGL(gl);
};
goog.inherits(ol.webglrenderer.TileLayerRenderer, ol.LayerRenderer);
/**
* @protected
*/
ol.webglrenderer.TileLayerRenderer.prototype.dispatchChangeEvent = function() {
this.dispatchEvent(goog.events.EventType.CHANGE);
};
/**
* @inheritDoc
*/
ol.webglrenderer.TileLayerRenderer.prototype.getGL = function() {
return this.gl_;
};
/**
* @inheritDoc
*/
ol.webglrenderer.TileLayerRenderer.prototype.handleLayerOpacityChange =
function() {
this.dispatchChangeEvent();
};
/**
* @inheritDoc
*/
ol.webglrenderer.TileLayerRenderer.prototype.handleLayerVisibleChange =
function() {
this.dispatchChangeEvent();
};
/**
* @inheritDoc
*/
ol.webglrenderer.TileLayerRenderer.prototype.setGL = function(gl) {
this.gl_ = gl;
};

View File

@@ -0,0 +1,101 @@
goog.provide('ol.webglrenderer.Uniform');
goog.require('goog.asserts');
goog.require('goog.vec.Mat4');
goog.require('ol.webglrenderer.GLObject');
/**
* @constructor
* @extends {ol.webglrenderer.GLObject}
* @param {string} name Name.
*/
ol.webglrenderer.Uniform = function(name) {
goog.base(this);
/**
* @private
* @type {WebGLProgram}
*/
this.program_ = null;
/**
* @private
* @type {string}
*/
this.name_ = name;
/**
* @private
* @type {WebGLUniformLocation}
*/
this.location_ = null;
};
goog.inherits(ol.webglrenderer.Uniform, ol.webglrenderer.GLObject);
/**
* @return {string} Name.
*/
ol.webglrenderer.Uniform.prototype.getName = function() {
return this.name_;
};
/**
* @param {WebGLRenderingContext} gl GL.
*/
ol.webglrenderer.Uniform.prototype.setGL = function(gl) {
this.location_ = null;
goog.base(this, 'setGL', gl);
};
/**
* @param {number} value Value.
*/
ol.webglrenderer.Uniform.prototype.set1f = function(value) {
var gl = this.getGL();
if (!goog.isNull(this.location_)) {
gl.uniform1f(this.location_, value);
}
};
/**
* @param {number} value Value.
*/
ol.webglrenderer.Uniform.prototype.set1i = function(value) {
var gl = this.getGL();
if (!goog.isNull(this.location_)) {
gl.uniform1i(this.location_, value);
}
};
/**
* @param {boolean} transpose Transpose.
* @param {goog.vec.Mat4.Mat4Like} value Value.
*/
ol.webglrenderer.Uniform.prototype.setMatrix4fv = function(transpose, value) {
var gl = this.getGL();
if (!goog.isNull(this.location_)) {
gl.uniformMatrix4fv(this.location_, transpose, value);
}
};
/**
* @param {WebGLProgram} program Program.
*/
ol.webglrenderer.Uniform.prototype.setProgram = function(program) {
if (goog.isNull(program)) {
this.location_ = null;
} else {
var gl = this.getGL();
this.location_ = gl.getUniformLocation(program, this.name_);
}
};

View File

@@ -0,0 +1,78 @@
goog.provide('ol.webglrenderer.VertexAttrib');
goog.require('goog.asserts');
goog.require('ol.webglrenderer.GLObject');
/**
* @constructor
* @extends {ol.webglrenderer.GLObject}
* @param {string} name Name.
*/
ol.webglrenderer.VertexAttrib = function(name) {
goog.base(this);
/**
* @private
* @type {string}
*/
this.name_ = name;
/**
* @private
* @type {number}
*/
this.location_ = -1;
};
goog.inherits(ol.webglrenderer.VertexAttrib, ol.webglrenderer.GLObject);
/**
*/
ol.webglrenderer.VertexAttrib.prototype.enableArray = function() {
var gl = this.getGL();
goog.asserts.assert(this.location_ != -1);
gl.enableVertexAttribArray(this.location_);
};
/**
* @param {number} size Size.
* @param {number} type Type.
* @param {boolean} normalize Normalized.
* @param {number} stride Stride.
* @param {number} offset Offset.
*/
ol.webglrenderer.VertexAttrib.prototype.pointer =
function(size, type, normalize, stride, offset) {
var gl = this.getGL();
goog.asserts.assert(this.location_ != -1);
gl.vertexAttribPointer(
this.location_, size, type, normalize, stride, offset);
};
/**
* @param {WebGLRenderingContext} gl GL.
*/
ol.webglrenderer.VertexAttrib.prototype.setGL = function(gl) {
this.location_ = -1;
goog.base(this, 'setGL', gl);
};
/**
* @param {WebGLProgram} program Program.
*/
ol.webglrenderer.VertexAttrib.prototype.setProgram = function(program) {
if (goog.isNull(program)) {
this.location_ = -1;
} else {
var gl = this.getGL();
this.location_ = gl.getAttribLocation(program, this.name_);
goog.asserts.assert(!goog.isNull(this.location_));
}
};