Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support GL face culling #7178

Merged
merged 1 commit into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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