Appearance.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*global define*/
  2. define([
  3. '../Core/clone',
  4. '../Core/combine',
  5. '../Core/defaultValue',
  6. '../Core/defined',
  7. '../Core/defineProperties',
  8. './BlendingState',
  9. './CullFace'
  10. ], function(
  11. clone,
  12. combine,
  13. defaultValue,
  14. defined,
  15. defineProperties,
  16. BlendingState,
  17. CullFace) {
  18. "use strict";
  19. /**
  20. * An appearance defines the full GLSL vertex and fragment shaders and the
  21. * render state used to draw a {@link Primitive}. All appearances implement
  22. * this base <code>Appearance</code> interface.
  23. *
  24. * @alias Appearance
  25. * @constructor
  26. *
  27. * @param {Object} [options] Object with the following properties:
  28. * @param {Boolean} [options.translucent=true] When <code>true</code>, the geometry is expected to appear translucent so {@link Appearance#renderState} has alpha blending enabled.
  29. * @param {Boolean} [options.closed=false] When <code>true</code>, the geometry is expected to be closed so {@link Appearance#renderState} has backface culling enabled.
  30. * @param {Material} [options.material=Material.ColorType] The material used to determine the fragment color.
  31. * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader.
  32. * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader.
  33. * @param {RenderState} [options.renderState] Optional render state to override the default render state.
  34. *
  35. * @see MaterialAppearance
  36. * @see EllipsoidSurfaceAppearance
  37. * @see PerInstanceColorAppearance
  38. * @see DebugAppearance
  39. * @see PolylineColorAppearance
  40. * @see PolylineMaterialAppearance
  41. *
  42. * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Geometry%20and%20Appearances.html|Geometry and Appearances Demo}
  43. */
  44. var Appearance = function(options) {
  45. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  46. /**
  47. * The material used to determine the fragment color. Unlike other {@link Appearance}
  48. * properties, this is not read-only, so an appearance's material can change on the fly.
  49. *
  50. * @type Material
  51. *
  52. * @see {@link https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric|Fabric}
  53. */
  54. this.material = options.material;
  55. /**
  56. * When <code>true</code>, the geometry is expected to appear translucent.
  57. *
  58. * @type {Boolean}
  59. *
  60. * @default true
  61. */
  62. this.translucent = defaultValue(options.translucent, true);
  63. this._vertexShaderSource = options.vertexShaderSource;
  64. this._fragmentShaderSource = options.fragmentShaderSource;
  65. this._renderState = options.renderState;
  66. this._closed = defaultValue(options.closed, false);
  67. };
  68. defineProperties(Appearance.prototype, {
  69. /**
  70. * The GLSL source code for the vertex shader.
  71. *
  72. * @memberof Appearance.prototype
  73. *
  74. * @type {String}
  75. * @readonly
  76. */
  77. vertexShaderSource : {
  78. get : function() {
  79. return this._vertexShaderSource;
  80. }
  81. },
  82. /**
  83. * The GLSL source code for the fragment shader. The full fragment shader
  84. * source is built procedurally taking into account the {@link Appearance#material}.
  85. * Use {@link Appearance#getFragmentShaderSource} to get the full source.
  86. *
  87. * @memberof Appearance.prototype
  88. *
  89. * @type {String}
  90. * @readonly
  91. */
  92. fragmentShaderSource : {
  93. get : function() {
  94. return this._fragmentShaderSource;
  95. }
  96. },
  97. /**
  98. * The WebGL fixed-function state to use when rendering the geometry.
  99. *
  100. * @memberof Appearance.prototype
  101. *
  102. * @type {Object}
  103. * @readonly
  104. */
  105. renderState : {
  106. get : function() {
  107. return this._renderState;
  108. }
  109. },
  110. /**
  111. * When <code>true</code>, the geometry is expected to be closed.
  112. *
  113. * @memberof Appearance.prototype
  114. *
  115. * @type {Boolean}
  116. * @readonly
  117. *
  118. * @default false
  119. */
  120. closed : {
  121. get : function() {
  122. return this._closed;
  123. }
  124. }
  125. });
  126. /**
  127. * Procedurally creates the full GLSL fragment shader source for this appearance
  128. * taking into account {@link Appearance#fragmentShaderSource} and {@link Appearance#material}.
  129. *
  130. * @returns {String} The full GLSL fragment shader source.
  131. */
  132. Appearance.prototype.getFragmentShaderSource = function() {
  133. var parts = [];
  134. if (this.flat) {
  135. parts.push('#define FLAT');
  136. }
  137. if (this.faceForward) {
  138. parts.push('#define FACE_FORWARD');
  139. }
  140. if (defined(this.material)) {
  141. parts.push(this.material.shaderSource);
  142. }
  143. parts.push(this.fragmentShaderSource);
  144. return parts.join('\n');
  145. };
  146. /**
  147. * Determines if the geometry is translucent based on {@link Appearance#translucent} and {@link Material#isTranslucent}.
  148. *
  149. * @returns {Boolean} <code>true</code> if the appearance is translucent.
  150. */
  151. Appearance.prototype.isTranslucent = function() {
  152. return (defined(this.material) && this.material.isTranslucent()) || (!defined(this.material) && this.translucent);
  153. };
  154. /**
  155. * Creates a render state. This is not the final render state instance; instead,
  156. * it can contain a subset of render state properties identical to the render state
  157. * created in the context.
  158. *
  159. * @returns {Object} The render state.
  160. */
  161. Appearance.prototype.getRenderState = function() {
  162. var translucent = this.isTranslucent();
  163. var rs = clone(this.renderState, false);
  164. if (translucent) {
  165. rs.depthMask = false;
  166. rs.blending = BlendingState.ALPHA_BLEND;
  167. } else {
  168. rs.depthMask = true;
  169. }
  170. return rs;
  171. };
  172. /**
  173. * @private
  174. */
  175. Appearance.getDefaultRenderState = function(translucent, closed, existing) {
  176. var rs = {
  177. depthTest : {
  178. enabled : true
  179. }
  180. };
  181. if (translucent) {
  182. rs.depthMask = false;
  183. rs.blending = BlendingState.ALPHA_BLEND;
  184. }
  185. if (closed) {
  186. rs.cull = {
  187. enabled : true,
  188. face : CullFace.BACK
  189. };
  190. }
  191. if (defined(existing)) {
  192. rs = combine(existing, rs, true);
  193. }
  194. return rs;
  195. };
  196. return Appearance;
  197. });