package.src.gl.value.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mapbox-gl Show documentation
Show all versions of mapbox-gl Show documentation
A WebGL interactive maps library
The newest version!
// @flow
import Color from '../style-spec/util/color';
import type Context from './context';
import type {
BlendFuncType,
BlendEquationType,
ColorMaskType,
DepthRangeType,
DepthMaskType,
StencilFuncType,
StencilOpType,
DepthFuncType,
TextureUnitType,
ViewportType,
CullFaceModeType,
FrontFaceType,
} from './types';
export interface Value {
current: T;
default: T;
dirty: boolean;
get(): T;
setDefault(): void;
set(value: T): void;
}
class BaseValue implements Value {
gl: WebGLRenderingContext;
current: T;
default: T;
dirty: boolean;
constructor(context: Context) {
this.gl = context.gl;
this.default = this.getDefault();
this.current = this.default;
this.dirty = false;
}
get(): T {
return this.current;
}
set(value: T) { // eslint-disable-line
// overridden in child classes;
}
getDefault(): T {
return this.default; // overriden in child classes
}
setDefault() {
this.set(this.default);
}
}
export class ClearColor extends BaseValue {
getDefault(): Color {
return Color.transparent;
}
set(v: Color) {
const c = this.current;
if (v.r === c.r && v.g === c.g && v.b === c.b && v.a === c.a && !this.dirty) return;
this.gl.clearColor(v.r, v.g, v.b, v.a);
this.current = v;
this.dirty = false;
}
}
export class ClearDepth extends BaseValue {
getDefault(): number {
return 1;
}
set(v: number) {
if (v === this.current && !this.dirty) return;
this.gl.clearDepth(v);
this.current = v;
this.dirty = false;
}
}
export class ClearStencil extends BaseValue {
getDefault(): number {
return 0;
}
set(v: number) {
if (v === this.current && !this.dirty) return;
this.gl.clearStencil(v);
this.current = v;
this.dirty = false;
}
}
export class ColorMask extends BaseValue {
getDefault(): ColorMaskType {
return [true, true, true, true];
}
set(v: ColorMaskType) {
const c = this.current;
if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && v[3] === c[3] && !this.dirty) return;
this.gl.colorMask(v[0], v[1], v[2], v[3]);
this.current = v;
this.dirty = false;
}
}
export class DepthMask extends BaseValue {
getDefault(): DepthMaskType {
return true;
}
set(v: DepthMaskType): void {
if (v === this.current && !this.dirty) return;
this.gl.depthMask(v);
this.current = v;
this.dirty = false;
}
}
export class StencilMask extends BaseValue {
getDefault(): number {
return 0xFF;
}
set(v: number): void {
if (v === this.current && !this.dirty) return;
this.gl.stencilMask(v);
this.current = v;
this.dirty = false;
}
}
export class StencilFunc extends BaseValue {
getDefault(): StencilFuncType {
return {
func: this.gl.ALWAYS,
ref: 0,
mask: 0xFF
};
}
set(v: StencilFuncType): void {
const c = this.current;
if (v.func === c.func && v.ref === c.ref && v.mask === c.mask && !this.dirty) return;
this.gl.stencilFunc(v.func, v.ref, v.mask);
this.current = v;
this.dirty = false;
}
}
export class StencilOp extends BaseValue {
getDefault(): StencilOpType {
const gl = this.gl;
return [gl.KEEP, gl.KEEP, gl.KEEP];
}
set(v: StencilOpType) {
const c = this.current;
if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && !this.dirty) return;
this.gl.stencilOp(v[0], v[1], v[2]);
this.current = v;
this.dirty = false;
}
}
export class StencilTest extends BaseValue {
getDefault(): boolean {
return false;
}
set(v: boolean) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
if (v) {
gl.enable(gl.STENCIL_TEST);
} else {
gl.disable(gl.STENCIL_TEST);
}
this.current = v;
this.dirty = false;
}
}
export class DepthRange extends BaseValue {
getDefault(): DepthRangeType {
return [0, 1];
}
set(v: DepthRangeType) {
const c = this.current;
if (v[0] === c[0] && v[1] === c[1] && !this.dirty) return;
this.gl.depthRange(v[0], v[1]);
this.current = v;
this.dirty = false;
}
}
export class DepthTest extends BaseValue {
getDefault(): boolean {
return false;
}
set(v: boolean) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
if (v) {
gl.enable(gl.DEPTH_TEST);
} else {
gl.disable(gl.DEPTH_TEST);
}
this.current = v;
this.dirty = false;
}
}
export class DepthFunc extends BaseValue {
getDefault(): DepthFuncType {
return this.gl.LESS;
}
set(v: DepthFuncType) {
if (v === this.current && !this.dirty) return;
this.gl.depthFunc(v);
this.current = v;
this.dirty = false;
}
}
export class Blend extends BaseValue {
getDefault(): boolean {
return false;
}
set(v: boolean) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
if (v) {
gl.enable(gl.BLEND);
} else {
gl.disable(gl.BLEND);
}
this.current = v;
this.dirty = false;
}
}
export class BlendFunc extends BaseValue {
getDefault(): BlendFuncType {
const gl = this.gl;
return [gl.ONE, gl.ZERO];
}
set(v: BlendFuncType) {
const c = this.current;
if (v[0] === c[0] && v[1] === c[1] && !this.dirty) return;
this.gl.blendFunc(v[0], v[1]);
this.current = v;
this.dirty = false;
}
}
export class BlendColor extends BaseValue {
getDefault(): Color {
return Color.transparent;
}
set(v: Color) {
const c = this.current;
if (v.r === c.r && v.g === c.g && v.b === c.b && v.a === c.a && !this.dirty) return;
this.gl.blendColor(v.r, v.g, v.b, v.a);
this.current = v;
this.dirty = false;
}
}
export class BlendEquation extends BaseValue {
getDefault(): BlendEquationType {
return this.gl.FUNC_ADD;
}
set(v: BlendEquationType) {
if (v === this.current && !this.dirty) return;
this.gl.blendEquation(v);
this.current = v;
this.dirty = false;
}
}
export class CullFace extends BaseValue {
getDefault(): boolean {
return false;
}
set(v: boolean) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
if (v) {
gl.enable(gl.CULL_FACE);
} else {
gl.disable(gl.CULL_FACE);
}
this.current = v;
this.dirty = false;
}
}
export class CullFaceSide extends BaseValue {
getDefault(): CullFaceModeType {
return this.gl.BACK;
}
set(v: CullFaceModeType) {
if (v === this.current && !this.dirty) return;
this.gl.cullFace(v);
this.current = v;
this.dirty = false;
}
}
export class FrontFace extends BaseValue {
getDefault(): FrontFaceType {
return this.gl.CCW;
}
set(v: FrontFaceType) {
if (v === this.current && !this.dirty) return;
this.gl.frontFace(v);
this.current = v;
this.dirty = false;
}
}
export class Program extends BaseValue {
getDefault(): WebGLProgram {
return null;
}
set(v: ?WebGLProgram) {
if (v === this.current && !this.dirty) return;
this.gl.useProgram(v);
this.current = v;
this.dirty = false;
}
}
export class ActiveTextureUnit extends BaseValue {
getDefault(): TextureUnitType {
return this.gl.TEXTURE0;
}
set(v: TextureUnitType) {
if (v === this.current && !this.dirty) return;
this.gl.activeTexture(v);
this.current = v;
this.dirty = false;
}
}
export class Viewport extends BaseValue {
getDefault(): ViewportType {
const gl = this.gl;
return [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight];
}
set(v: ViewportType) {
const c = this.current;
if (v[0] === c[0] && v[1] === c[1] && v[2] === c[2] && v[3] === c[3] && !this.dirty) return;
this.gl.viewport(v[0], v[1], v[2], v[3]);
this.current = v;
this.dirty = false;
}
}
export class BindFramebuffer extends BaseValue {
getDefault(): WebGLFramebuffer {
return null;
}
set(v: ?WebGLFramebuffer) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, v);
this.current = v;
this.dirty = false;
}
}
export class BindRenderbuffer extends BaseValue {
getDefault(): WebGLRenderbuffer {
return null;
}
set(v: ?WebGLRenderbuffer) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
gl.bindRenderbuffer(gl.RENDERBUFFER, v);
this.current = v;
this.dirty = false;
}
}
export class BindTexture extends BaseValue {
getDefault(): WebGLTexture {
return null;
}
set(v: ?WebGLTexture) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
gl.bindTexture(gl.TEXTURE_2D, v);
this.current = v;
this.dirty = false;
}
}
export class BindVertexBuffer extends BaseValue {
getDefault(): WebGLBuffer {
return null;
}
set(v: ?WebGLBuffer) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
gl.bindBuffer(gl.ARRAY_BUFFER, v);
this.current = v;
this.dirty = false;
}
}
export class BindElementBuffer extends BaseValue {
getDefault(): WebGLBuffer {
return null;
}
set(v: ?WebGLBuffer) {
// Always rebind
const gl = this.gl;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, v);
this.current = v;
this.dirty = false;
}
}
export class BindVertexArrayOES extends BaseValue {
vao: any;
constructor(context: Context) {
super(context);
this.vao = context.extVertexArrayObject;
}
getDefault(): any {
return null;
}
set(v: any) {
if (!this.vao || v === this.current && !this.dirty) return;
this.vao.bindVertexArrayOES(v);
this.current = v;
this.dirty = false;
}
}
export class PixelStoreUnpack extends BaseValue {
getDefault(): number {
return 4;
}
set(v: number) {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
gl.pixelStorei(gl.UNPACK_ALIGNMENT, v);
this.current = v;
this.dirty = false;
}
}
export class PixelStoreUnpackPremultiplyAlpha extends BaseValue {
getDefault(): boolean {
return false;
}
set(v: boolean): void {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, (v: any));
this.current = v;
this.dirty = false;
}
}
export class PixelStoreUnpackFlipY extends BaseValue {
getDefault(): boolean {
return false;
}
set(v: boolean): void {
if (v === this.current && !this.dirty) return;
const gl = this.gl;
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, (v: any));
this.current = v;
this.dirty = false;
}
}
class FramebufferAttachment extends BaseValue {
parent: WebGLFramebuffer;
context: Context;
constructor(context: Context, parent: WebGLFramebuffer) {
super(context);
this.context = context;
this.parent = parent;
}
getDefault() {
return null;
}
}
export class ColorAttachment extends FramebufferAttachment {
setDirty() {
this.dirty = true;
}
set(v: ?WebGLTexture): void {
if (v === this.current && !this.dirty) return;
this.context.bindFramebuffer.set(this.parent);
// note: it's possible to attach a renderbuffer to the color
// attachment point, but thus far MBGL only uses textures for color
const gl = this.gl;
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, v, 0);
this.current = v;
this.dirty = false;
}
}
export class DepthAttachment extends FramebufferAttachment {
set(v: ?WebGLRenderbuffer): void {
if (v === this.current && !this.dirty) return;
this.context.bindFramebuffer.set(this.parent);
// note: it's possible to attach a texture to the depth attachment
// point, but thus far MBGL only uses renderbuffers for depth
const gl = this.gl;
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, v);
this.current = v;
this.dirty = false;
}
}