Skip to content

Commit

Permalink
manage RenderStates per GL context
Browse files Browse the repository at this point in the history
  • Loading branch information
bcamper committed Jul 7, 2016
1 parent 5fc0869 commit 8b4d285
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 39 deletions.
53 changes: 29 additions & 24 deletions src/gl/render_state.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

export default class RenderState {
export class RenderState {
constructor (value, setup) {
setup(value);
this.value = value;
Expand All @@ -13,28 +13,32 @@ export default class RenderState {
this.value = value;
}
}
}

export default class RenderStateManager {

constructor (gl) {
this.defaults = {};

static initialize (gl) {
RenderState.defaults = {};
// Culling
RenderState.defaults.culling = true;
RenderState.defaults.culling_face = gl.BACK;
this.defaults.culling = true;
this.defaults.culling_face = gl.BACK;

// Blending
RenderState.defaults.blending = false;
RenderState.defaults.blending_src = gl.ONE_MINUS_SRC_ALPHA;
RenderState.defaults.blending_dst = gl.ONE_MINUS_SRC_ALPHA;
RenderState.defaults.blending_src_alpha = gl.ONE;
RenderState.defaults.blending_dst_alpha = gl.ONE_MINUS_SRC_ALPHA;
this.defaults.blending = false;
this.defaults.blending_src = gl.ONE_MINUS_SRC_ALPHA;
this.defaults.blending_dst = gl.ONE_MINUS_SRC_ALPHA;
this.defaults.blending_src_alpha = gl.ONE;
this.defaults.blending_dst_alpha = gl.ONE_MINUS_SRC_ALPHA;

// Depth test/write
RenderState.defaults.depth_write = true;
RenderState.defaults.depth_test = true;
this.defaults.depth_write = true;
this.defaults.depth_test = true;
gl.depthFunc(gl.LESS); // depth function only needs to be set once

// Culling
RenderState.culling = new RenderState(
{ cull: RenderState.defaults.culling, face: RenderState.defaults.culling_face },
this.culling = new RenderState(
{ cull: this.defaults.culling, face: this.defaults.culling_face },
(value) => {
if (value.cull) {
gl.enable(gl.CULL_FACE);
Expand All @@ -46,12 +50,12 @@ export default class RenderState {
);

// Blending mode
RenderState.blending = new RenderState({
blend: RenderState.defaults.blending,
src: RenderState.defaults.blending_src,
dst: RenderState.defaults.blending_dst,
src_alpha: RenderState.defaults.blending_src_alpha,
dst_alpha: RenderState.defaults.blending_dst_alpha
this.blending = new RenderState({
blend: this.defaults.blending,
src: this.defaults.blending_src,
dst: this.defaults.blending_dst,
src_alpha: this.defaults.blending_src_alpha,
dst_alpha: this.defaults.blending_dst_alpha
},
(value) => {
if (value.blend) {
Expand All @@ -70,16 +74,16 @@ export default class RenderState {
);

// Depth write
RenderState.depth_write = new RenderState(
{ depth_write: RenderState.defaults.depth_write },
this.depth_write = new RenderState(
{ depth_write: this.defaults.depth_write },
(value) => {
gl.depthMask(value.depth_write);
}
);

// Depth test
RenderState.depth_test = new RenderState(
{ depth_test: RenderState.defaults.depth_test },
this.depth_test = new RenderState(
{ depth_test: this.defaults.depth_test },
(value) => {
if (value.depth_test) {
gl.enable(gl.DEPTH_TEST);
Expand All @@ -90,4 +94,5 @@ export default class RenderState {
);

}

}
31 changes: 16 additions & 15 deletions src/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Light from './light';
import TileManager from './tile_manager';
import DataSource from './sources/data_source';
import FeatureSelection from './selection';
import RenderState from './gl/render_state';
import RenderStateManager from './gl/render_state';
import CanvasText from './styles/text/canvas_text';

import {Polygons} from './styles/polygons/polygons';
Expand Down Expand Up @@ -234,7 +234,7 @@ export default class Scene {

this.resizeMap(this.container.clientWidth, this.container.clientHeight);
VertexArrayObject.init(this.gl);
RenderState.initialize(this.gl);
this.render_states = new RenderStateManager(this.gl);

// Let VertexElements know if 32 bit indices for element arrays are available
var Uint32_flag = this.gl.getExtension("OES_element_index_uint") ? true : false;
Expand Down Expand Up @@ -571,7 +571,7 @@ export default class Scene {
clear_depth = (clear_depth === false) ? false : true; // default true

// Set GL state
RenderState.depth_write.set({ depth_write: clear_depth });
this.render_states.depth_write.set({ depth_write: clear_depth });

let gl = this.gl;
if (clear_color || clear_depth) {
Expand All @@ -587,56 +587,57 @@ export default class Scene {

// Defaults
// TODO: when we abstract out support for multiple render passes, these can be per-pass config options
depth_test = (depth_test === false) ? false : RenderState.defaults.depth_test; // default true
depth_write = (depth_write === false) ? false : RenderState.defaults.depth_write; // default true
cull_face = (cull_face === false) ? false : RenderState.defaults.culling; // default true
blend = (blend != null) ? blend : RenderState.defaults.blending; // default false
let render_states = this.render_states;
depth_test = (depth_test === false) ? false : render_states.defaults.depth_test; // default true
depth_write = (depth_write === false) ? false : render_states.defaults.depth_write; // default true
cull_face = (cull_face === false) ? false : render_states.defaults.culling; // default true
blend = (blend != null) ? blend : render_states.defaults.blending; // default false

// Reset frame state
let gl = this.gl;

RenderState.depth_test.set({ depth_test: depth_test });
RenderState.depth_write.set({ depth_write: depth_write });
RenderState.culling.set({ cull: cull_face, face: RenderState.defaults.culling_face });
render_states.depth_test.set({ depth_test: depth_test });
render_states.depth_write.set({ depth_write: depth_write });
render_states.culling.set({ cull: cull_face, face: render_states.defaults.culling_face });

// Blending of alpha channel is modified to account for WebGL alpha behavior, see:
// http://webglfundamentals.org/webgl/lessons/webgl-and-alpha.html
// http://stackoverflow.com/a/11533416
if (blend) {
// Opaque: all source, no destination
if (blend === 'opaque') {
RenderState.blending.set({
render_states.blending.set({
blend: true,
src: gl.SRC_ALPHA, dst: gl.ZERO
});
}
// Traditional alpha blending
else if (blend === 'overlay' || blend === 'inlay') {
RenderState.blending.set({
render_states.blending.set({
blend: true,
src: gl.SRC_ALPHA, dst: gl.ONE_MINUS_SRC_ALPHA,
src_alpha: gl.ONE, dst_alpha: gl.ONE_MINUS_SRC_ALPHA
});
}
// Additive blending
else if (blend === 'add') {
RenderState.blending.set({
render_states.blending.set({
blend: true,
src: gl.ONE, dst: gl.ONE,
src_alpha: gl.ONE, dst_alpha: gl.ONE_MINUS_SRC_ALPHA
});
}
// Multiplicative blending
else if (blend === 'multiply') {
RenderState.blending.set({
render_states.blending.set({
blend: true,
src: gl.ZERO, dst: gl.SRC_COLOR,
src_alpha: gl.ONE, dst_alpha: gl.ONE_MINUS_SRC_ALPHA
});
}
}
else {
RenderState.blending.set({ blend: false });
render_states.blending.set({ blend: false });
}
}

Expand Down

0 comments on commit 8b4d285

Please sign in to comment.