Skip to content

Commit

Permalink
Enable face culling for fill-extrusion layers. (#7178)
Browse files Browse the repository at this point in the history
  • Loading branch information
brunoabinader authored and ansis committed Sep 10, 2018
1 parent 02d6fa9 commit e682aa6
Show file tree
Hide file tree
Showing 25 changed files with 191 additions and 57 deletions.
12 changes: 9 additions & 3 deletions src/data/bucket/fill_extrusion_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,12 @@ class FillExtrusionBucket implements Bucket {

const bottomRight = segment.vertexLength;

this.indexArray.emplaceBack(bottomRight, bottomRight + 1, bottomRight + 2);
// ┌──────┐
// │ 0 1 │ Counter-clockwise winding order.
// │ │ Triangle 1: 0 => 2 => 1
// │ 2 3 │ Triangle 2: 1 => 2 => 3
// └──────┘
this.indexArray.emplaceBack(bottomRight, bottomRight + 2, bottomRight + 1);
this.indexArray.emplaceBack(bottomRight + 1, bottomRight + 2, bottomRight + 3);

segment.vertexLength += 4;
Expand Down Expand Up @@ -238,10 +243,11 @@ class FillExtrusionBucket implements Bucket {
assert(indices.length % 3 === 0);

for (let j = 0; j < indices.length; j += 3) {
// Counter-clockwise winding order.
this.indexArray.emplaceBack(
triangleIndex + indices[j],
triangleIndex + indices[j + 1],
triangleIndex + indices[j + 2]);
triangleIndex + indices[j + 2],
triangleIndex + indices[j + 1]);
}

segment.primitiveLength += indices.length / 3;
Expand Down
25 changes: 21 additions & 4 deletions src/gl/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import Framebuffer from './framebuffer';
import DepthMode from './depth_mode';
import StencilMode from './stencil_mode';
import ColorMode from './color_mode';
import CullFaceMode from './cull_face_mode';
import { deepEqual } from '../util/util';
import { ClearColor, ClearDepth, ClearStencil, ColorMask, DepthMask, StencilMask, StencilFunc, StencilOp, StencilTest, DepthRange, DepthTest, DepthFunc, CullFace, Blend, BlendFunc, BlendColor, BlendEquation, Program, ActiveTextureUnit, Viewport, BindFramebuffer, BindRenderbuffer, BindTexture, BindVertexBuffer, BindElementBuffer, BindVertexArrayOES, PixelStoreUnpack, PixelStoreUnpackPremultiplyAlpha, PixelStoreUnpackFlipY } from './value';
import { ClearColor, ClearDepth, ClearStencil, ColorMask, DepthMask, StencilMask, StencilFunc, StencilOp, StencilTest, DepthRange, DepthTest, DepthFunc, Blend, BlendFunc, BlendColor, BlendEquation, CullFace, CullFaceSide, FrontFace, Program, ActiveTextureUnit, Viewport, BindFramebuffer, BindRenderbuffer, BindTexture, BindVertexBuffer, BindElementBuffer, BindVertexArrayOES, PixelStoreUnpack, PixelStoreUnpackPremultiplyAlpha, PixelStoreUnpackFlipY } from './value';


import type {TriangleIndexArray, LineIndexArray, LineStripIndexArray} from '../data/index_array_type';
Expand Down Expand Up @@ -41,11 +42,13 @@ class Context {
depthRange: DepthRange;
depthTest: DepthTest;
depthFunc: DepthFunc;
cullFace: CullFace;
blend: Blend;
blendFunc: BlendFunc;
blendColor: BlendColor;
blendEquation: BlendEquation;
cullFace: CullFace;
cullFaceSide: CullFaceSide;
frontFace: FrontFace;
program: Program;
activeTexture: ActiveTextureUnit;
viewport: Viewport;
Expand Down Expand Up @@ -79,11 +82,13 @@ class Context {
this.depthRange = new DepthRange(this);
this.depthTest = new DepthTest(this);
this.depthFunc = new DepthFunc(this);
this.cullFace = new CullFace(this);
this.blend = new Blend(this);
this.blendFunc = new BlendFunc(this);
this.blendColor = new BlendColor(this);
this.blendEquation = new BlendEquation(this);
this.cullFace = new CullFace(this);
this.cullFaceSide = new CullFaceSide(this);
this.frontFace = new FrontFace(this);
this.program = new Program(this);
this.activeTexture = new ActiveTextureUnit(this);
this.viewport = new Viewport(this);
Expand Down Expand Up @@ -126,11 +131,13 @@ class Context {
this.depthRange.dirty = true;
this.depthTest.dirty = true;
this.depthFunc.dirty = true;
this.cullFace.dirty = true;
this.blend.dirty = true;
this.blendFunc.dirty = true;
this.blendColor.dirty = true;
this.blendEquation.dirty = true;
this.cullFace.dirty = true;
this.cullFaceSide.dirty = true;
this.frontFace.dirty = true;
this.program.dirty = true;
this.activeTexture.dirty = true;
this.viewport.dirty = true;
Expand Down Expand Up @@ -196,6 +203,16 @@ class Context {
gl.clear(mask);
}

setCullFace(cullFaceMode: $ReadOnly<CullFaceMode>) {
if (cullFaceMode.enable === false) {
this.cullFace.set(false);
} else {
this.cullFace.set(true);
this.cullFaceSide.set(cullFaceMode.mode);
this.frontFace.set(cullFaceMode.frontFace);
}
}

setDepthMode(depthMode: $ReadOnly<DepthMode>) {
if (depthMode.func === this.gl.ALWAYS && !depthMode.mask) {
this.depthTest.set(false);
Expand Down
26 changes: 26 additions & 0 deletions src/gl/cull_face_mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// @flow

import type {CullFaceModeType, FrontFaceType} from './types';

const BACK = 0x0405;
const CCW = 0x0901;

class CullFaceMode {
enable: boolean;
mode: CullFaceModeType;
frontFace: FrontFaceType;

constructor(enable: boolean, mode: CullFaceModeType, frontFace: FrontFaceType) {
this.enable = enable;
this.mode = mode;
this.frontFace = frontFace;
}

static disabled: $ReadOnly<CullFaceMode>;
static backCCW: $ReadOnly<CullFaceMode>;
}

CullFaceMode.disabled = new CullFaceMode(false, BACK, CCW);
CullFaceMode.backCCW = new CullFaceMode(true, BACK, CCW);

export default CullFaceMode;
9 changes: 9 additions & 0 deletions src/gl/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,12 @@ export type StencilTest =
| { func: $PropertyType<WebGLRenderingContext, 'NOTEQUAL'>, mask: number }
| { func: $PropertyType<WebGLRenderingContext, 'GEQUAL'>, mask: number }
| { func: $PropertyType<WebGLRenderingContext, 'ALWAYS'>, mask: 0 };

export type CullFaceModeType =
| $PropertyType<WebGLRenderingContext, 'FRONT'>
| $PropertyType<WebGLRenderingContext, 'BACK'>
| $PropertyType<WebGLRenderingContext, 'FRONT_AND_BACK'>

export type FrontFaceType =
| $PropertyType<WebGLRenderingContext, 'CW'>
| $PropertyType<WebGLRenderingContext, 'CCW'>
120 changes: 89 additions & 31 deletions src/gl/value.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import type {
DepthFuncType,
TextureUnitType,
ViewportType,
CullFaceModeType,
FrontFaceType,
} from './types';

export interface Value<T> {
Expand Down Expand Up @@ -358,37 +360,6 @@ export class DepthFunc implements Value<DepthFuncType> {
}
}

export class CullFace implements Value<boolean> {
context: Context;
current: boolean;
default: boolean;
dirty: boolean;

constructor(context: Context) {
this.context = context;
this.default = false;
this.current = this.default;
this.dirty = false;
}

get(): boolean { return this.current; }

setDefault(): void { this.set(this.default); }

set(v: boolean): void {
if (this.current !== v || this.dirty === true) {
const gl = this.context.gl;
if (v) {
gl.enable(gl.CULL_FACE);
} else {
gl.disable(gl.CULL_FACE);
}
this.current = v;
this.dirty = false;
}
}
}

export class Blend implements Value<boolean> {
context: Context;
current: boolean;
Expand Down Expand Up @@ -501,6 +472,93 @@ export class BlendEquation implements Value<BlendEquationType> {
}
}

export class CullFace implements Value<boolean> {
context: Context;
current: boolean;
default: boolean;
dirty: boolean;

constructor(context: Context) {
this.context = context;
this.default = false;
this.current = this.default;
this.dirty = false;
}

get(): boolean { return this.current; }

setDefault(): void { this.set(this.default); }

set(v: boolean): void {
if (this.current !== v || this.dirty === true) {
const gl = this.context.gl;
if (v) {
gl.enable(gl.CULL_FACE);
} else {
gl.disable(gl.CULL_FACE);
}
this.current = v;
this.dirty = false;
}
}
}

export class CullFaceSide implements Value<CullFaceModeType> {
context: Context;
current: CullFaceModeType;
default: CullFaceModeType;
dirty: boolean;

constructor(context: Context) {
this.context = context;
const gl = this.context.gl;
this.default = gl.BACK;
this.current = this.default;
this.dirty = false;
}

get(): CullFaceModeType { return this.current; }

setDefault(): void { this.set(this.default); }

set(v: CullFaceModeType): void {
if (this.current !== v || this.dirty === true) {
const gl = this.context.gl;
gl.cullFace(v);
this.current = v;
this.dirty = false;
}
}
}

export class FrontFace implements Value<FrontFaceType> {
context: Context;
current: FrontFaceType;
default: FrontFaceType;
dirty: boolean;

constructor(context: Context) {
this.context = context;
const gl = this.context.gl;
this.default = gl.CCW;
this.current = this.default;
this.dirty = false;
}

get(): FrontFaceType { return this.current; }

setDefault(): void { this.set(this.default); }

set(v: FrontFaceType): void {
if (this.current !== v || this.dirty === true) {
const gl = this.context.gl;
gl.frontFace(v);
this.current = v;
this.dirty = false;
}
}
}

export class Program implements Value<?WebGLProgram> {
context: Context;
current: ?WebGLProgram;
Expand Down
3 changes: 2 additions & 1 deletion src/render/draw_background.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import StencilMode from '../gl/stencil_mode';
import DepthMode from '../gl/depth_mode';
import CullFaceMode from '../gl/cull_face_mode';
import {
backgroundUniformValues,
backgroundPatternUniformValues
Expand Down Expand Up @@ -50,7 +51,7 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg
backgroundPatternUniformValues(matrix, opacity, painter, image, {tileID, tileSize}, crossfade) :
backgroundUniformValues(matrix, opacity, color);

program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode,
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
uniformValues, layer.id, painter.tileExtentBuffer,
painter.quadTriangleIndexBuffer, painter.tileExtentSegments);
}
Expand Down
3 changes: 2 additions & 1 deletion src/render/draw_circle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import StencilMode from '../gl/stencil_mode';
import DepthMode from '../gl/depth_mode';
import CullFaceMode from '../gl/cull_face_mode';
import { circleUniformValues } from './program/circle_program';

import type Painter from './painter';
Expand Down Expand Up @@ -42,7 +43,7 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt
const programConfiguration = bucket.programConfigurations.get(layer.id);
const program = painter.useProgram('circle', programConfiguration);

program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode,
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
circleUniformValues(painter, coord, tile, layer), layer.id,
bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments,
layer.paint, painter.transform.zoom, programConfiguration);
Expand Down
2 changes: 2 additions & 0 deletions src/render/draw_collision_debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {OverscaledTileID} from '../source/tile_id';
import type SymbolBucket from '../data/bucket/symbol_bucket';
import DepthMode from '../gl/depth_mode';
import StencilMode from '../gl/stencil_mode';
import CullFaceMode from '../gl/cull_face_mode';
import { collisionUniformValues } from './program/collision_program';

export default drawCollisionDebug;
Expand All @@ -27,6 +28,7 @@ function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache,
program.draw(context, drawCircles ? gl.TRIANGLES : gl.LINES,
DepthMode.disabled, StencilMode.disabled,
painter.colorModeForRenderPass(),
CullFaceMode.disabled,
collisionUniformValues(
coord.posMatrix,
painter.transform,
Expand Down
7 changes: 4 additions & 3 deletions src/render/draw_debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import posAttributes from '../data/pos_attributes';
import SegmentVector from '../data/segment';
import DepthMode from '../gl/depth_mode';
import StencilMode from '../gl/stencil_mode';
import CullFaceMode from '../gl/cull_face_mode';
import { debugUniformValues } from './program/debug_program';
import Color from '../style-spec/util/color';

Expand Down Expand Up @@ -35,7 +36,7 @@ function drawDebugTile(painter, sourceCache, coord) {
const colorMode = painter.colorModeForRenderPass();
const id = '$debug';

program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode,
program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
debugUniformValues(posMatrix, Color.red), id,
painter.debugBuffer, painter.tileBorderIndexBuffer, painter.debugSegments);

Expand All @@ -58,7 +59,7 @@ function drawDebugTile(painter, sourceCache, coord) {
for (let i = 0; i < translations.length; i++) {
const translation = translations[i];

program.draw(context, gl.LINES, depthMode, stencilMode, colorMode,
program.draw(context, gl.LINES, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
debugUniformValues(
mat4.translate([], posMatrix, [
onePixel * translation[0],
Expand All @@ -67,7 +68,7 @@ function drawDebugTile(painter, sourceCache, coord) {
id, debugTextBuffer, debugTextIndexBuffer, debugTextSegment);
}

program.draw(context, gl.LINES, depthMode, stencilMode, colorMode,
program.draw(context, gl.LINES, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
debugUniformValues(posMatrix, Color.black), id,
debugTextBuffer, debugTextIndexBuffer, debugTextSegment);
}
Expand Down
3 changes: 2 additions & 1 deletion src/render/draw_fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import Color from '../style-spec/util/color';
import DepthMode from '../gl/depth_mode';
import CullFaceMode from '../gl/cull_face_mode';
import {
fillUniformValues,
fillPatternUniformValues,
Expand Down Expand Up @@ -116,7 +117,7 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode
}

program.draw(painter.context, drawMode, depthMode,
painter.stencilModeForClipping(coord), colorMode, uniformValues,
painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues,
layer.id, bucket.layoutVertexBuffer, indexBuffer, segments,
layer.paint, painter.transform.zoom, programConfiguration);
}
Expand Down
Loading

0 comments on commit e682aa6

Please sign in to comment.