1 | import IndexBuffer from './index_buffer';
|
2 |
|
3 | import VertexBuffer from './vertex_buffer';
|
4 | import Framebuffer from './framebuffer';
|
5 | import DepthMode from './depth_mode';
|
6 | import StencilMode from './stencil_mode';
|
7 | import ColorMode from './color_mode';
|
8 | import CullFaceMode from './cull_face_mode';
|
9 | import {deepEqual} from '../util/util';
|
10 | import {ClearColor, ClearDepth, ClearStencil, ColorMask, DepthMask, StencilMask, StencilFunc, StencilOp, StencilTest, DepthRange, DepthTest, DepthFunc, Blend, BlendFunc, BlendColor, BlendEquation, CullFace, CullFaceSide, FrontFace, ProgramValue, ActiveTextureUnit, Viewport, BindFramebuffer, BindRenderbuffer, BindTexture, BindVertexBuffer, BindElementBuffer, BindVertexArrayOES, PixelStoreUnpack, PixelStoreUnpackPremultiplyAlpha, PixelStoreUnpackFlipY} from './value';
|
11 |
|
12 | import type {TriangleIndexArray, LineIndexArray, LineStripIndexArray} from '../data/index_array_type';
|
13 | import type {
|
14 | StructArray,
|
15 | StructArrayMember
|
16 | } from '../util/struct_array';
|
17 | import type Color from '../style-spec/util/color';
|
18 |
|
19 | type ClearArgs = {
|
20 | color?: Color;
|
21 | depth?: number;
|
22 | stencil?: number;
|
23 | };
|
24 |
|
25 | class Context {
|
26 | gl: WebGLRenderingContext;
|
27 | extVertexArrayObject: any;
|
28 | currentNumAttributes: number;
|
29 | maxTextureSize: number;
|
30 |
|
31 | clearColor: ClearColor;
|
32 | clearDepth: ClearDepth;
|
33 | clearStencil: ClearStencil;
|
34 | colorMask: ColorMask;
|
35 | depthMask: DepthMask;
|
36 | stencilMask: StencilMask;
|
37 | stencilFunc: StencilFunc;
|
38 | stencilOp: StencilOp;
|
39 | stencilTest: StencilTest;
|
40 | depthRange: DepthRange;
|
41 | depthTest: DepthTest;
|
42 | depthFunc: DepthFunc;
|
43 | blend: Blend;
|
44 | blendFunc: BlendFunc;
|
45 | blendColor: BlendColor;
|
46 | blendEquation: BlendEquation;
|
47 | cullFace: CullFace;
|
48 | cullFaceSide: CullFaceSide;
|
49 | frontFace: FrontFace;
|
50 | program: ProgramValue;
|
51 | activeTexture: ActiveTextureUnit;
|
52 | viewport: Viewport;
|
53 | bindFramebuffer: BindFramebuffer;
|
54 | bindRenderbuffer: BindRenderbuffer;
|
55 | bindTexture: BindTexture;
|
56 | bindVertexBuffer: BindVertexBuffer;
|
57 | bindElementBuffer: BindElementBuffer;
|
58 | bindVertexArrayOES: BindVertexArrayOES;
|
59 | pixelStoreUnpack: PixelStoreUnpack;
|
60 | pixelStoreUnpackPremultiplyAlpha: PixelStoreUnpackPremultiplyAlpha;
|
61 | pixelStoreUnpackFlipY: PixelStoreUnpackFlipY;
|
62 |
|
63 | extTextureFilterAnisotropic: any;
|
64 | extTextureFilterAnisotropicMax: any;
|
65 | extTextureHalfFloat: any;
|
66 | extRenderToTextureHalfFloat: any;
|
67 | extTimerQuery: any;
|
68 |
|
69 | constructor(gl: WebGLRenderingContext) {
|
70 | this.gl = gl;
|
71 | this.extVertexArrayObject = this.gl.getExtension('OES_vertex_array_object');
|
72 |
|
73 | this.clearColor = new ClearColor(this);
|
74 | this.clearDepth = new ClearDepth(this);
|
75 | this.clearStencil = new ClearStencil(this);
|
76 | this.colorMask = new ColorMask(this);
|
77 | this.depthMask = new DepthMask(this);
|
78 | this.stencilMask = new StencilMask(this);
|
79 | this.stencilFunc = new StencilFunc(this);
|
80 | this.stencilOp = new StencilOp(this);
|
81 | this.stencilTest = new StencilTest(this);
|
82 | this.depthRange = new DepthRange(this);
|
83 | this.depthTest = new DepthTest(this);
|
84 | this.depthFunc = new DepthFunc(this);
|
85 | this.blend = new Blend(this);
|
86 | this.blendFunc = new BlendFunc(this);
|
87 | this.blendColor = new BlendColor(this);
|
88 | this.blendEquation = new BlendEquation(this);
|
89 | this.cullFace = new CullFace(this);
|
90 | this.cullFaceSide = new CullFaceSide(this);
|
91 | this.frontFace = new FrontFace(this);
|
92 | this.program = new ProgramValue(this);
|
93 | this.activeTexture = new ActiveTextureUnit(this);
|
94 | this.viewport = new Viewport(this);
|
95 | this.bindFramebuffer = new BindFramebuffer(this);
|
96 | this.bindRenderbuffer = new BindRenderbuffer(this);
|
97 | this.bindTexture = new BindTexture(this);
|
98 | this.bindVertexBuffer = new BindVertexBuffer(this);
|
99 | this.bindElementBuffer = new BindElementBuffer(this);
|
100 | this.bindVertexArrayOES = this.extVertexArrayObject && new BindVertexArrayOES(this);
|
101 | this.pixelStoreUnpack = new PixelStoreUnpack(this);
|
102 | this.pixelStoreUnpackPremultiplyAlpha = new PixelStoreUnpackPremultiplyAlpha(this);
|
103 | this.pixelStoreUnpackFlipY = new PixelStoreUnpackFlipY(this);
|
104 |
|
105 | this.extTextureFilterAnisotropic = (
|
106 | gl.getExtension('EXT_texture_filter_anisotropic') ||
|
107 | gl.getExtension('MOZ_EXT_texture_filter_anisotropic') ||
|
108 | gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic')
|
109 | );
|
110 | if (this.extTextureFilterAnisotropic) {
|
111 | this.extTextureFilterAnisotropicMax = gl.getParameter(this.extTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
|
112 | }
|
113 |
|
114 | this.extTextureHalfFloat = gl.getExtension('OES_texture_half_float');
|
115 | if (this.extTextureHalfFloat) {
|
116 | gl.getExtension('OES_texture_half_float_linear');
|
117 | this.extRenderToTextureHalfFloat = gl.getExtension('EXT_color_buffer_half_float');
|
118 | }
|
119 |
|
120 | this.extTimerQuery = gl.getExtension('EXT_disjoint_timer_query');
|
121 | this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
|
122 | }
|
123 |
|
124 | setDefault() {
|
125 | this.unbindVAO();
|
126 |
|
127 | this.clearColor.setDefault();
|
128 | this.clearDepth.setDefault();
|
129 | this.clearStencil.setDefault();
|
130 | this.colorMask.setDefault();
|
131 | this.depthMask.setDefault();
|
132 | this.stencilMask.setDefault();
|
133 | this.stencilFunc.setDefault();
|
134 | this.stencilOp.setDefault();
|
135 | this.stencilTest.setDefault();
|
136 | this.depthRange.setDefault();
|
137 | this.depthTest.setDefault();
|
138 | this.depthFunc.setDefault();
|
139 | this.blend.setDefault();
|
140 | this.blendFunc.setDefault();
|
141 | this.blendColor.setDefault();
|
142 | this.blendEquation.setDefault();
|
143 | this.cullFace.setDefault();
|
144 | this.cullFaceSide.setDefault();
|
145 | this.frontFace.setDefault();
|
146 | this.program.setDefault();
|
147 | this.activeTexture.setDefault();
|
148 | this.bindFramebuffer.setDefault();
|
149 | this.pixelStoreUnpack.setDefault();
|
150 | this.pixelStoreUnpackPremultiplyAlpha.setDefault();
|
151 | this.pixelStoreUnpackFlipY.setDefault();
|
152 | }
|
153 |
|
154 | setDirty() {
|
155 | this.clearColor.dirty = true;
|
156 | this.clearDepth.dirty = true;
|
157 | this.clearStencil.dirty = true;
|
158 | this.colorMask.dirty = true;
|
159 | this.depthMask.dirty = true;
|
160 | this.stencilMask.dirty = true;
|
161 | this.stencilFunc.dirty = true;
|
162 | this.stencilOp.dirty = true;
|
163 | this.stencilTest.dirty = true;
|
164 | this.depthRange.dirty = true;
|
165 | this.depthTest.dirty = true;
|
166 | this.depthFunc.dirty = true;
|
167 | this.blend.dirty = true;
|
168 | this.blendFunc.dirty = true;
|
169 | this.blendColor.dirty = true;
|
170 | this.blendEquation.dirty = true;
|
171 | this.cullFace.dirty = true;
|
172 | this.cullFaceSide.dirty = true;
|
173 | this.frontFace.dirty = true;
|
174 | this.program.dirty = true;
|
175 | this.activeTexture.dirty = true;
|
176 | this.viewport.dirty = true;
|
177 | this.bindFramebuffer.dirty = true;
|
178 | this.bindRenderbuffer.dirty = true;
|
179 | this.bindTexture.dirty = true;
|
180 | this.bindVertexBuffer.dirty = true;
|
181 | this.bindElementBuffer.dirty = true;
|
182 | if (this.extVertexArrayObject) {
|
183 | this.bindVertexArrayOES.dirty = true;
|
184 | }
|
185 | this.pixelStoreUnpack.dirty = true;
|
186 | this.pixelStoreUnpackPremultiplyAlpha.dirty = true;
|
187 | this.pixelStoreUnpackFlipY.dirty = true;
|
188 | }
|
189 |
|
190 | createIndexBuffer(array: TriangleIndexArray | LineIndexArray | LineStripIndexArray, dynamicDraw?: boolean) {
|
191 | return new IndexBuffer(this, array, dynamicDraw);
|
192 | }
|
193 |
|
194 | createVertexBuffer(array: StructArray, attributes: ReadonlyArray<StructArrayMember>, dynamicDraw?: boolean) {
|
195 | return new VertexBuffer(this, array, attributes, dynamicDraw);
|
196 | }
|
197 |
|
198 | createRenderbuffer(storageFormat: number, width: number, height: number) {
|
199 | const gl = this.gl;
|
200 |
|
201 | const rbo = gl.createRenderbuffer();
|
202 | this.bindRenderbuffer.set(rbo);
|
203 | gl.renderbufferStorage(gl.RENDERBUFFER, storageFormat, width, height);
|
204 | this.bindRenderbuffer.set(null);
|
205 |
|
206 | return rbo;
|
207 | }
|
208 |
|
209 | createFramebuffer(width: number, height: number, hasDepth: boolean) {
|
210 | return new Framebuffer(this, width, height, hasDepth);
|
211 | }
|
212 |
|
213 | clear({
|
214 | color,
|
215 | depth
|
216 | }: ClearArgs) {
|
217 | const gl = this.gl;
|
218 | let mask = 0;
|
219 |
|
220 | if (color) {
|
221 | mask |= gl.COLOR_BUFFER_BIT;
|
222 | this.clearColor.set(color);
|
223 | this.colorMask.set([true, true, true, true]);
|
224 | }
|
225 |
|
226 | if (typeof depth !== 'undefined') {
|
227 | mask |= gl.DEPTH_BUFFER_BIT;
|
228 |
|
229 |
|
230 |
|
231 | this.depthRange.set([0, 1]);
|
232 |
|
233 | this.clearDepth.set(depth);
|
234 | this.depthMask.set(true);
|
235 | }
|
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 | gl.clear(mask);
|
245 | }
|
246 |
|
247 | setCullFace(cullFaceMode: Readonly<CullFaceMode>) {
|
248 | if (cullFaceMode.enable === false) {
|
249 | this.cullFace.set(false);
|
250 | } else {
|
251 | this.cullFace.set(true);
|
252 | this.cullFaceSide.set(cullFaceMode.mode);
|
253 | this.frontFace.set(cullFaceMode.frontFace);
|
254 | }
|
255 | }
|
256 |
|
257 | setDepthMode(depthMode: Readonly<DepthMode>) {
|
258 | if (depthMode.func === this.gl.ALWAYS && !depthMode.mask) {
|
259 | this.depthTest.set(false);
|
260 | } else {
|
261 | this.depthTest.set(true);
|
262 | this.depthFunc.set(depthMode.func);
|
263 | this.depthMask.set(depthMode.mask);
|
264 | this.depthRange.set(depthMode.range);
|
265 | }
|
266 | }
|
267 |
|
268 | setStencilMode(stencilMode: Readonly<StencilMode>) {
|
269 | if (stencilMode.test.func === this.gl.ALWAYS && !stencilMode.mask) {
|
270 | this.stencilTest.set(false);
|
271 | } else {
|
272 | this.stencilTest.set(true);
|
273 | this.stencilMask.set(stencilMode.mask);
|
274 | this.stencilOp.set([stencilMode.fail, stencilMode.depthFail, stencilMode.pass]);
|
275 | this.stencilFunc.set({
|
276 | func: stencilMode.test.func,
|
277 | ref: stencilMode.ref,
|
278 | mask: stencilMode.test.mask
|
279 | });
|
280 | }
|
281 | }
|
282 |
|
283 | setColorMode(colorMode: Readonly<ColorMode>) {
|
284 | if (deepEqual(colorMode.blendFunction, ColorMode.Replace)) {
|
285 | this.blend.set(false);
|
286 | } else {
|
287 | this.blend.set(true);
|
288 | this.blendFunc.set(colorMode.blendFunction);
|
289 | this.blendColor.set(colorMode.blendColor);
|
290 | }
|
291 |
|
292 | this.colorMask.set(colorMode.mask);
|
293 | }
|
294 |
|
295 | unbindVAO() {
|
296 |
|
297 |
|
298 | if (this.extVertexArrayObject) {
|
299 | this.bindVertexArrayOES.set(null);
|
300 | }
|
301 | }
|
302 | }
|
303 |
|
304 | export default Context;
|