/*global define*/
define([
'../Core/BoundingRectangle',
'../Core/Color',
'../Core/defined',
'../Core/destroyObject',
'../Core/DeveloperError',
'../Renderer/RenderState',
'../Renderer/ShaderSource',
'../Shaders/ViewportQuadFS',
'./BlendingState',
'./Material',
'./Pass'
], function(
BoundingRectangle,
Color,
defined,
destroyObject,
DeveloperError,
RenderState,
ShaderSource,
ViewportQuadFS,
BlendingState,
Material,
Pass) {
'use strict';
/**
* A viewport aligned quad.
*
* @alias ViewportQuad
* @constructor
*
* @param {BoundingRectangle} [rectangle] The {@link BoundingRectangle} defining the quad's position within the viewport.
* @param {Material} [material] The {@link Material} defining the surface appearance of the viewport quad.
*
* @example
* var viewportQuad = new Cesium.ViewportQuad(new Cesium.BoundingRectangle(0, 0, 80, 40));
* viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 0.0, 0.0, 1.0);
*/
function ViewportQuad(rectangle, material) {
/**
* Determines if the viewport quad primitive will be shown.
*
* @type {Boolean}
* @default true
*/
this.show = true;
if (!defined(rectangle)) {
rectangle = new BoundingRectangle();
}
/**
* The BoundingRectangle defining the quad's position within the viewport.
*
* @type {BoundingRectangle}
*
* @example
* viewportQuad.rectangle = new Cesium.BoundingRectangle(0, 0, 80, 40);
*/
this.rectangle = BoundingRectangle.clone(rectangle);
if (!defined(material)) {
material = Material.fromType(Material.ColorType, {
color : new Color(1.0, 1.0, 1.0, 1.0)
});
}
/**
* The surface appearance of the viewport quad. This can be one of several built-in {@link Material} objects or a custom material, scripted with
* {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}.
* <p>
* The default material is <code>Material.ColorType</code>.
* </p>
*
* @type Material
*
* @example
* // 1. Change the color of the default material to yellow
* viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0);
*
* // 2. Change material to horizontal stripes
* viewportQuad.material = Cesium.Material.fromType(Cesium.Material.StripeType);
*
* @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}
*/
this.material = material;
this._material = undefined;
this._overlayCommand = undefined;
this._rs = undefined;
}
/**
* Called when {@link Viewer} or {@link CesiumWidget} render the scene to
* get the draw commands needed to render this primitive.
* <p>
* Do not call this function directly. This is documented just to
* list the exceptions that may be propagated when the scene is rendered:
* </p>
*
* @exception {DeveloperError} this.material must be defined.
* @exception {DeveloperError} this.rectangle must be defined.
*/
ViewportQuad.prototype.update = function(frameState) {
if (!this.show) {
return;
}
//>>includeStart('debug', pragmas.debug);
if (!defined(this.material)) {
throw new DeveloperError('this.material must be defined.');
}
if (!defined(this.rectangle)) {
throw new DeveloperError('this.rectangle must be defined.');
}
//>>includeEnd('debug');
var rs = this._rs;
if ((!defined(rs)) || !BoundingRectangle.equals(rs.viewport, this.rectangle)) {
this._rs = RenderState.fromCache({
blending : BlendingState.ALPHA_BLEND,
viewport : this.rectangle
});
}
var pass = frameState.passes;
if (pass.render) {
var context = frameState.context;
if (this._material !== this.material || !defined(this._overlayCommand)) {
// Recompile shader when material changes
this._material = this.material;
if (defined(this._overlayCommand)) {
this._overlayCommand.shaderProgram.destroy();
}
var fs = new ShaderSource({
sources : [this._material.shaderSource, ViewportQuadFS]
});
this._overlayCommand = context.createViewportQuadCommand(fs, {
renderState : this._rs,
uniformMap : this._material._uniforms,
owner : this
});
this._overlayCommand.pass = Pass.OVERLAY;
}
this._material.update(context);
this._overlayCommand.uniformMap = this._material._uniforms;
frameState.commandList.push(this._overlayCommand);
}
};
/**
* Returns true if this object was destroyed; otherwise, false.
* <br /><br />
* If this object was destroyed, it should not be used; calling any function other than
* <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
*
* @returns {Boolean} True if this object was destroyed; otherwise, false.
*
* @see ViewportQuad#destroy
*/
ViewportQuad.prototype.isDestroyed = function() {
return false;
};
/**
* Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
* release of WebGL resources, instead of relying on the garbage collector to destroy this object.
* <br /><br />
* Once an object is destroyed, it should not be used; calling any function other than
* <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
* assign the return value (<code>undefined</code>) to the object as done in the example.
*
* @returns {undefined}
*
* @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
*
*
* @example
* quad = quad && quad.destroy();
*
* @see ViewportQuad#isDestroyed
*/
ViewportQuad.prototype.destroy = function() {
if (defined(this._overlayCommand)) {
this._overlayCommand.shaderProgram = this._overlayCommand.shaderProgram && this._overlayCommand.shaderProgram.destroy();
}
return destroyObject(this);
};
return ViewportQuad;
});