diff --git a/src/data/bucket/fill_extrusion_bucket.js b/src/data/bucket/fill_extrusion_bucket.js index d1b8c47e1f0..2d1f47042f7 100644 --- a/src/data/bucket/fill_extrusion_bucket.js +++ b/src/data/bucket/fill_extrusion_bucket.js @@ -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; @@ -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; diff --git a/src/gl/context.js b/src/gl/context.js index e7b35e654dd..8c183868d65 100644 --- a/src/gl/context.js +++ b/src/gl/context.js @@ -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'; @@ -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; @@ -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); @@ -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; @@ -196,6 +203,16 @@ class Context { gl.clear(mask); } + setCullFace(cullFaceMode: $ReadOnly) { + 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) { if (depthMode.func === this.gl.ALWAYS && !depthMode.mask) { this.depthTest.set(false); diff --git a/src/gl/cull_face_mode.js b/src/gl/cull_face_mode.js new file mode 100644 index 00000000000..c6088208354 --- /dev/null +++ b/src/gl/cull_face_mode.js @@ -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; + static backCCW: $ReadOnly; +} + +CullFaceMode.disabled = new CullFaceMode(false, BACK, CCW); +CullFaceMode.backCCW = new CullFaceMode(true, BACK, CCW); + +export default CullFaceMode; diff --git a/src/gl/types.js b/src/gl/types.js index e51da77d556..834be5cad89 100644 --- a/src/gl/types.js +++ b/src/gl/types.js @@ -73,3 +73,12 @@ export type StencilTest = | { func: $PropertyType, mask: number } | { func: $PropertyType, mask: number } | { func: $PropertyType, mask: 0 }; + +export type CullFaceModeType = + | $PropertyType + | $PropertyType + | $PropertyType + +export type FrontFaceType = + | $PropertyType + | $PropertyType diff --git a/src/gl/value.js b/src/gl/value.js index 93f8c1fbcfe..819e55d2927 100644 --- a/src/gl/value.js +++ b/src/gl/value.js @@ -14,6 +14,8 @@ import type { DepthFuncType, TextureUnitType, ViewportType, + CullFaceModeType, + FrontFaceType, } from './types'; export interface Value { @@ -358,37 +360,6 @@ export class DepthFunc implements Value { } } -export class CullFace implements Value { - 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 { context: Context; current: boolean; @@ -501,6 +472,93 @@ export class BlendEquation implements Value { } } +export class CullFace implements Value { + 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 { + 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 { + 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 { context: Context; current: ?WebGLProgram; diff --git a/src/render/draw_background.js b/src/render/draw_background.js index 8ac2757f691..43c0aca157c 100644 --- a/src/render/draw_background.js +++ b/src/render/draw_background.js @@ -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 @@ -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); } diff --git a/src/render/draw_circle.js b/src/render/draw_circle.js index 34d86f7f0ff..fee50eaa7de 100644 --- a/src/render/draw_circle.js +++ b/src/render/draw_circle.js @@ -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'; @@ -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); diff --git a/src/render/draw_collision_debug.js b/src/render/draw_collision_debug.js index ba78c5ee865..9ba15cfe497 100644 --- a/src/render/draw_collision_debug.js +++ b/src/render/draw_collision_debug.js @@ -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; @@ -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, diff --git a/src/render/draw_debug.js b/src/render/draw_debug.js index 7bdbe19281b..a818263710f 100644 --- a/src/render/draw_debug.js +++ b/src/render/draw_debug.js @@ -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'; @@ -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); @@ -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], @@ -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); } diff --git a/src/render/draw_fill.js b/src/render/draw_fill.js index d5ce2ec1dde..9a55a8df978 100644 --- a/src/render/draw_fill.js +++ b/src/render/draw_fill.js @@ -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, @@ -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); } diff --git a/src/render/draw_fill_extrusion.js b/src/render/draw_fill_extrusion.js index 84c9751d645..32d865821bd 100644 --- a/src/render/draw_fill_extrusion.js +++ b/src/render/draw_fill_extrusion.js @@ -2,6 +2,7 @@ import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; +import CullFaceMode from '../gl/cull_face_mode'; import { fillExtrusionUniformValues, fillExtrusionPatternUniformValues, @@ -74,7 +75,7 @@ function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMo fillExtrusionUniformValues(matrix, painter); - program.draw(context, context.gl.TRIANGLES, depthMode, stencilMode, colorMode, + program.draw(context, context.gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.backCCW, uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration); diff --git a/src/render/draw_heatmap.js b/src/render/draw_heatmap.js index f90c302499d..df9475e97b1 100644 --- a/src/render/draw_heatmap.js +++ b/src/render/draw_heatmap.js @@ -5,6 +5,7 @@ import Color from '../style-spec/util/color'; import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; import ColorMode from '../gl/color_mode'; +import CullFaceMode from '../gl/cull_face_mode'; import { heatmapUniformValues, heatmapTextureUniformValues @@ -54,7 +55,7 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS const program = painter.useProgram('heatmap', programConfiguration); const {zoom} = painter.transform; - program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, heatmapUniformValues(coord.posMatrix, tile, zoom, layer.paint.get('heatmap-intensity')), layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, @@ -133,7 +134,7 @@ function renderTextureToMap(painter, layer) { colorRampTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); painter.useProgram('heatmapTexture').draw(context, gl.TRIANGLES, - DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), + DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), CullFaceMode.disabled, heatmapTextureUniformValues(painter, layer, 0, 1), layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer, painter.viewportSegments, layer.paint, painter.transform.zoom); diff --git a/src/render/draw_hillshade.js b/src/render/draw_hillshade.js index b724ca7dbbe..a16ae8df277 100644 --- a/src/render/draw_hillshade.js +++ b/src/render/draw_hillshade.js @@ -3,6 +3,7 @@ import Texture from './texture'; import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; +import CullFaceMode from '../gl/cull_face_mode'; import { hillshadeUniformValues, hillshadeUniformPrepareValues @@ -52,11 +53,11 @@ function renderHillshade(painter, tile, layer, depthMode, stencilMode, colorMode const uniformValues = hillshadeUniformValues(painter, tile, layer); if (tile.maskedBoundsBuffer && tile.maskedIndexBuffer && tile.segments) { - program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, tile.maskedBoundsBuffer, tile.maskedIndexBuffer, tile.segments); } else { - program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } @@ -113,7 +114,7 @@ function prepareHillshade(painter, tile, layer, sourceMaxZoom, depthMode, stenci context.viewport.set([0, 0, tileSize, tileSize]); painter.useProgram('hillshadePrepare').draw(context, gl.TRIANGLES, - depthMode, stencilMode, colorMode, + depthMode, stencilMode, colorMode, CullFaceMode.disabled, hillshadeUniformPrepareValues(tile, sourceMaxZoom), layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); diff --git a/src/render/draw_line.js b/src/render/draw_line.js index 3b5e71d1654..3d12a3a5fc9 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -1,6 +1,7 @@ // @flow import DepthMode from '../gl/depth_mode'; +import CullFaceMode from '../gl/cull_face_mode'; import Texture from './texture'; import { lineUniformValues, @@ -86,7 +87,7 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay } program.draw(context, gl.TRIANGLES, depthMode, - painter.stencilModeForClipping(coord), colorMode, uniformValues, + painter.stencilModeForClipping(coord), colorMode, CullFaceMode.disabled, uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, layer.paint, painter.transform.zoom, programConfiguration); diff --git a/src/render/draw_raster.js b/src/render/draw_raster.js index 481971710be..f8ec292ee47 100644 --- a/src/render/draw_raster.js +++ b/src/render/draw_raster.js @@ -6,6 +6,7 @@ import ImageSource from '../source/image_source'; import browser from '../util/browser'; import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; +import CullFaceMode from '../gl/cull_face_mode'; import { rasterUniformValues } from './program/raster_program'; import type Painter from './painter'; @@ -63,16 +64,16 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty const uniformValues = rasterUniformValues(posMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer); if (source instanceof ImageSource) { - program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, source.boundsBuffer, painter.quadTriangleIndexBuffer, source.boundsSegments); } else if (tile.maskedBoundsBuffer && tile.maskedIndexBuffer && tile.segments) { - program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, tile.maskedBoundsBuffer, tile.maskedIndexBuffer, tile.segments, layer.paint, painter.transform.zoom); } else { - program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, painter.rasterBoundsBuffer, painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index b7b88d277f3..80b4f60a6e4 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -11,6 +11,7 @@ import properties from '../style/style_layer/symbol_style_layer_properties'; const symbolLayoutProperties = properties.layout; import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; +import CullFaceMode from '../gl/cull_face_mode'; import { symbolIconUniformValues, symbolSDFUniformValues @@ -152,7 +153,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate function drawSymbolElements(buffers, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues) { const context = painter.context; const gl = context.gl; - program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, buffers.segments, layer.paint, painter.transform.zoom, buffers.programConfigurations.get(layer.id), diff --git a/src/render/offscreen.js b/src/render/offscreen.js index a894df77907..30e7bb1ec64 100644 --- a/src/render/offscreen.js +++ b/src/render/offscreen.js @@ -4,6 +4,7 @@ import Texture from './texture'; import Color from '../style-spec/util/color'; import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; +import CullFaceMode from '../gl/cull_face_mode'; import {extrusionTextureUniformValues} from './program/fill_extrusion_program'; import type Painter from './painter'; @@ -56,6 +57,7 @@ export function drawOffscreenTexture(painter: Painter, layer: CustomStyleLayer | painter.useProgram('extrusionTexture').draw(context, gl.TRIANGLES, DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), + CullFaceMode.disabled, extrusionTextureUniformValues(painter, opacity, 0), layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer, painter.viewportSegments, layer.paint, painter.transform.zoom); diff --git a/src/render/painter.js b/src/render/painter.js index 6d1632644c8..12e633e59ce 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -19,6 +19,7 @@ import Context from '../gl/context'; import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; import ColorMode from '../gl/color_mode'; +import CullFaceMode from '../gl/cull_face_mode'; import Texture from './texture'; import updateTileMasks from './tile_mask'; import { clippingMaskUniformValues } from './program/clipping_mask_program'; @@ -227,7 +228,7 @@ class Painter { mat4.scale(matrix, matrix, [gl.drawingBufferWidth, gl.drawingBufferHeight, 0]); this.useProgram('clippingMask').draw(context, gl.TRIANGLES, - DepthMode.disabled, this.stencilClearMode, ColorMode.disabled, + DepthMode.disabled, this.stencilClearMode, ColorMode.disabled, CullFaceMode.disabled, clippingMaskUniformValues(matrix), '$clipping', this.viewportBuffer, this.quadTriangleIndexBuffer, this.viewportSegments); @@ -251,7 +252,7 @@ class Painter { program.draw(context, gl.TRIANGLES, DepthMode.disabled, // Tests will always pass, and ref value will be written to stencil buffer. new StencilMode({ func: gl.ALWAYS, mask: 0 }, id, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE), - ColorMode.disabled, clippingMaskUniformValues(tileID.posMatrix), + ColorMode.disabled, CullFaceMode.disabled, clippingMaskUniformValues(tileID.posMatrix), '$clipping', this.tileExtentBuffer, this.quadTriangleIndexBuffer, this.tileExtentSegments); } diff --git a/src/render/program.js b/src/render/program.js index cd3730f7d18..58c2e9d1758 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -14,6 +14,7 @@ import type IndexBuffer from '../gl/index_buffer'; import type DepthMode from '../gl/depth_mode'; import type StencilMode from '../gl/stencil_mode'; import type ColorMode from '../gl/color_mode'; +import type CullFaceMode from '../gl/cull_face_mode'; import type {UniformBindings, UniformValues, UniformLocations} from './uniform_binding'; export type DrawMode = @@ -97,6 +98,7 @@ class Program { depthMode: $ReadOnly, stencilMode: $ReadOnly, colorMode: $ReadOnly, + cullFaceMode: $ReadOnly, uniformValues: UniformValues, layerID: string, layoutVertexBuffer: VertexBuffer, @@ -114,6 +116,7 @@ class Program { context.setDepthMode(depthMode); context.setStencilMode(stencilMode); context.setColorMode(colorMode); + context.setCullFace(cullFaceMode); for (const name in this.fixedUniforms) { this.fixedUniforms[name].set(uniformValues[name]); diff --git a/test/integration/render-tests/fill-extrusion-pattern/@2x/expected.png b/test/integration/render-tests/fill-extrusion-pattern/@2x/expected.png index edc737bdd6e..c7bdf3b886e 100644 Binary files a/test/integration/render-tests/fill-extrusion-pattern/@2x/expected.png and b/test/integration/render-tests/fill-extrusion-pattern/@2x/expected.png differ diff --git a/test/integration/render-tests/fill-extrusion-pattern/feature-expression/expected.png b/test/integration/render-tests/fill-extrusion-pattern/feature-expression/expected.png index 17a4a353183..aa2ef97b9d5 100644 Binary files a/test/integration/render-tests/fill-extrusion-pattern/feature-expression/expected.png and b/test/integration/render-tests/fill-extrusion-pattern/feature-expression/expected.png differ diff --git a/test/integration/render-tests/fill-extrusion-pattern/function-2/expected.png b/test/integration/render-tests/fill-extrusion-pattern/function-2/expected.png index ee7b6d474b5..367f73f7545 100644 Binary files a/test/integration/render-tests/fill-extrusion-pattern/function-2/expected.png and b/test/integration/render-tests/fill-extrusion-pattern/function-2/expected.png differ diff --git a/test/integration/render-tests/fill-extrusion-pattern/function/expected.png b/test/integration/render-tests/fill-extrusion-pattern/function/expected.png index 15ed6e56cd6..753a82851c4 100644 Binary files a/test/integration/render-tests/fill-extrusion-pattern/function/expected.png and b/test/integration/render-tests/fill-extrusion-pattern/function/expected.png differ diff --git a/test/integration/render-tests/fill-extrusion-pattern/literal/expected.png b/test/integration/render-tests/fill-extrusion-pattern/literal/expected.png index 15ed6e56cd6..753a82851c4 100644 Binary files a/test/integration/render-tests/fill-extrusion-pattern/literal/expected.png and b/test/integration/render-tests/fill-extrusion-pattern/literal/expected.png differ diff --git a/test/integration/render-tests/fill-extrusion-pattern/opacity/expected.png b/test/integration/render-tests/fill-extrusion-pattern/opacity/expected.png index 0f34b31cdff..09f7eb3e18d 100644 Binary files a/test/integration/render-tests/fill-extrusion-pattern/opacity/expected.png and b/test/integration/render-tests/fill-extrusion-pattern/opacity/expected.png differ