1 /*
2 * Copyright (C) 2013 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6 #include "Wt/WClientGLWidget.h"
7 #include "WebUtils.h"
8 #include "Wt/WApplication.h"
9 #include "Wt/WEnvironment.h"
10 #include "Wt/WFileResource.h"
11 #include "Wt/WWebWidget.h"
12 #include "Wt/WMemoryResource.h"
13 #include "Wt/WCanvasPaintDevice.h"
14 #include "Wt/WRasterImage.h"
15 #include "Wt/WImage.h"
16 #include "Wt/WVideo.h"
17
18 #include <ostream>
19 #include <fstream>
20 #include <limits>
21
22 namespace Wt {
23
WClientGLWidget(WGLWidget * glInterface)24 WClientGLWidget::WClientGLWidget(WGLWidget *glInterface)
25 : WAbstractGLImplementation(glInterface),
26 shaders_(0),
27 programs_(0),
28 attributes_(0),
29 uniforms_(0),
30 buffers_(0),
31 arrayBuffers_(0),
32 framebuffers_(0),
33 renderbuffers_(0),
34 textures_(0),
35 images_(1), // id 0 is reserved for the deprecated preloading with
36 // createTextureAndLoad()
37 canvas_(0)
38 {}
39
40 #ifndef WT_TARGET_JAVA
makeFloat(double d,char * buf)41 const char *WClientGLWidget::makeFloat(double d, char *buf)
42 {
43 return Utils::round_js_str(d, 6, buf);
44 }
45
makeInt(int i,char * buf)46 const char *WClientGLWidget::makeInt(int i, char *buf)
47 {
48 return Utils::itoa(i, buf);
49 }
50 #endif
51
toString(WGLWidget::GLenum e)52 const char *WClientGLWidget::toString(WGLWidget::GLenum e)
53 {
54 switch(e) {
55 case WGLWidget::DEPTH_BUFFER_BIT: return "ctx.DEPTH_BUFFER_BIT";
56 case WGLWidget::STENCIL_BUFFER_BIT: return "ctx.STENCIL_BUFFER_BIT";
57 case WGLWidget::COLOR_BUFFER_BIT: return "ctx.COLOR_BUFFER_BIT";
58 case WGLWidget::POINTS: return "ctx.POINTS";
59 case WGLWidget::LINES: return "ctx.LINES";
60 case WGLWidget::LINE_LOOP: return "ctx.LINE_LOOP";
61 case WGLWidget::LINE_STRIP: return "ctx.LINE_STRIP";
62 case WGLWidget::TRIANGLES: return "ctx.TRIANGLES";
63 case WGLWidget::TRIANGLE_STRIP: return "ctx.TRIANGLE_STRIP";
64 case WGLWidget::TRIANGLE_FAN: return "ctx.TRIANGLE_FAN";
65 //case WGLWidget::ZERO: return "ctx.ZERO";
66 //case WGLWidget::ONE: return "ctx.ONE";
67 case WGLWidget::SRC_COLOR: return "ctx.SRC_COLOR";
68 case WGLWidget::ONE_MINUS_SRC_COLOR: return "ctx.ONE_MINUS_SRC_COLOR";
69 case WGLWidget::SRC_ALPHA: return "ctx.SRC_ALPHA";
70 case WGLWidget::ONE_MINUS_SRC_ALPHA: return "ctx.ONE_MINUS_SRC_ALPHA";
71 case WGLWidget::DST_ALPHA: return "ctx.DST_ALPHA";
72 case WGLWidget::ONE_MINUS_DST_ALPHA: return "ctx.ONE_MINUS_DST_ALPHA";
73 case WGLWidget::DST_COLOR: return "ctx.DST_COLOR";
74 case WGLWidget::ONE_MINUS_DST_COLOR: return "ctx.ONE_MINUS_DST_COLOR";
75 case WGLWidget::SRC_ALPHA_SATURATE: return "ctx.SRC_ALPHA_SATURATE";
76 case WGLWidget::FUNC_ADD: return "ctx.FUNC_ADD";
77 case WGLWidget::BLEND_EQUATION: return "ctx.BLEND_EQUATION";
78 //case WGLWidget::BLEND_EQUATION_RGB: return "ctx.BLEND_EQUATION_RGB";
79 case WGLWidget::BLEND_EQUATION_ALPHA: return "ctx.BLEND_EQUATION_ALPHA";
80 case WGLWidget::FUNC_SUBTRACT: return "ctx.FUNC_SUBTRACT";
81 case WGLWidget::FUNC_REVERSE_SUBTRACT: return "ctx.FUNC_REVERSE_SUBTRACT";
82 case WGLWidget::BLEND_DST_RGB: return "ctx.BLEND_DST_RGB";
83 case WGLWidget::BLEND_SRC_RGB: return "ctx.BLEND_SRC_RGB";
84 case WGLWidget::BLEND_DST_ALPHA: return "ctx.BLEND_DST_ALPHA";
85 case WGLWidget::BLEND_SRC_ALPHA: return "ctx.BLEND_SRC_ALPHA";
86 case WGLWidget::CONSTANT_COLOR: return "ctx.CONSTANT_COLOR";
87 case WGLWidget::ONE_MINUS_CONSTANT_COLOR: return "ctx.ONE_MINUS_CONSTANT_COLOR";
88 case WGLWidget::CONSTANT_ALPHA: return "ctx.CONSTANT_ALPHA";
89 case WGLWidget::ONE_MINUS_CONSTANT_ALPHA: return "ctx.ONE_MINUS_CONSTANT_ALPHA";
90 case WGLWidget::BLEND_COLOR: return "ctx.BLEND_COLOR";
91 case WGLWidget::ARRAY_BUFFER: return "ctx.ARRAY_BUFFER";
92 case WGLWidget::ELEMENT_ARRAY_BUFFER: return "ctx.ELEMENT_ARRAY_BUFFER";
93 case WGLWidget::ARRAY_BUFFER_BINDING: return "ctx.ARRAY_BUFFER_BINDING";
94 case WGLWidget::ELEMENT_ARRAY_BUFFER_BINDING: return "ctx.ELEMENT_ARRAY_BUFFER_BINDING";
95 case WGLWidget::STREAM_DRAW: return "ctx.STREAM_DRAW";
96 case WGLWidget::STATIC_DRAW: return "ctx.STATIC_DRAW";
97 case WGLWidget::DYNAMIC_DRAW: return "ctx.DYNAMIC_DRAW";
98 case WGLWidget::BUFFER_SIZE: return "ctx.BUFFER_SIZE";
99 case WGLWidget::BUFFER_USAGE: return "ctx.BUFFER_USAGE";
100 case WGLWidget::CURRENT_VERTEX_ATTRIB: return "ctx.CURRENT_VERTEX_ATTRIB";
101 case WGLWidget::FRONT: return "ctx.FRONT";
102 case WGLWidget::BACK: return "ctx.BACK";
103 case WGLWidget::FRONT_AND_BACK: return "ctx.FRONT_AND_BACK";
104 case WGLWidget::CULL_FACE: return "ctx.CULL_FACE";
105 case WGLWidget::BLEND: return "ctx.BLEND";
106 case WGLWidget::DITHER: return "ctx.DITHER";
107 case WGLWidget::STENCIL_TEST: return "ctx.STENCIL_TEST";
108 case WGLWidget::DEPTH_TEST: return "ctx.DEPTH_TEST";
109 case WGLWidget::SCISSOR_TEST: return "ctx.SCISSOR_TEST";
110 case WGLWidget::POLYGON_OFFSET_FILL: return "ctx.POLYGON_OFFSET_FILL";
111 case WGLWidget::SAMPLE_ALPHA_TO_COVERAGE: return "ctx.SAMPLE_ALPHA_TO_COVERAGE";
112 case WGLWidget::SAMPLE_COVERAGE: return "ctx.SAMPLE_COVERAGE";
113 //case WGLWidget::NO_ERROR: return "ctx.NO_ERROR";
114 case WGLWidget::INVALID_ENUM: return "ctx.INVALID_ENUM";
115 case WGLWidget::INVALID_VALUE: return "ctx.INVALID_VALUE";
116 case WGLWidget::INVALID_OPERATION: return "ctx.INVALID_OPERATION";
117 case WGLWidget::OUT_OF_MEMORY: return "ctx.OUT_OF_MEMORY";
118 case WGLWidget::CW: return "ctx.CW";
119 case WGLWidget::CCW: return "ctx.CCW";
120 case WGLWidget::LINE_WIDTH: return "ctx.LINE_WIDTH";
121 case WGLWidget::ALIASED_POINT_SIZE_RANGE: return "ctx.ALIASED_POINT_SIZE_RANGE";
122 case WGLWidget::ALIASED_LINE_WIDTH_RANGE: return "ctx.ALIASED_LINE_WIDTH_RANGE";
123 case WGLWidget::CULL_FACE_MODE: return "ctx.CULL_FACE_MODE";
124 case WGLWidget::FRONT_FACE: return "ctx.FRONT_FACE";
125 case WGLWidget::DEPTH_RANGE: return "ctx.DEPTH_RANGE";
126 case WGLWidget::DEPTH_WRITEMASK: return "ctx.DEPTH_WRITEMASK";
127 case WGLWidget::DEPTH_CLEAR_VALUE: return "ctx.DEPTH_CLEAR_VALUE";
128 case WGLWidget::DEPTH_FUNC: return "ctx.DEPTH_FUNC";
129 case WGLWidget::STENCIL_CLEAR_VALUE: return "ctx.STENCIL_CLEAR_VALUE";
130 case WGLWidget::STENCIL_FUNC: return "ctx.STENCIL_FUNC";
131 case WGLWidget::STENCIL_FAIL: return "ctx.STENCIL_FAIL";
132 case WGLWidget::STENCIL_PASS_DEPTH_FAIL: return "ctx.STENCIL_PASS_DEPTH_FAIL";
133 case WGLWidget::STENCIL_PASS_DEPTH_PASS: return "ctx.STENCIL_PASS_DEPTH_PASS";
134 case WGLWidget::STENCIL_REF: return "ctx.STENCIL_REF";
135 case WGLWidget::STENCIL_VALUE_MASK: return "ctx.STENCIL_VALUE_MASK";
136 case WGLWidget::STENCIL_WRITEMASK: return "ctx.STENCIL_WRITEMASK";
137 case WGLWidget::STENCIL_BACK_FUNC: return "ctx.STENCIL_BACK_FUNC";
138 case WGLWidget::STENCIL_BACK_FAIL: return "ctx.STENCIL_BACK_FAIL";
139 case WGLWidget::STENCIL_BACK_PASS_DEPTH_FAIL: return "ctx.STENCIL_BACK_PASS_DEPTH_FAIL";
140 case WGLWidget::STENCIL_BACK_PASS_DEPTH_PASS: return "ctx.STENCIL_BACK_PASS_DEPTH_PASS";
141 case WGLWidget::STENCIL_BACK_REF: return "ctx.STENCIL_BACK_REF";
142 case WGLWidget::STENCIL_BACK_VALUE_MASK: return "ctx.STENCIL_BACK_VALUE_MASK";
143 case WGLWidget::STENCIL_BACK_WRITEMASK: return "ctx.STENCIL_BACK_WRITEMASK";
144 case WGLWidget::VIEWPORT: return "ctx.VIEWPORT";
145 case WGLWidget::SCISSOR_BOX: return "ctx.SCISSOR_BOX";
146 case WGLWidget::COLOR_CLEAR_VALUE: return "ctx.COLOR_CLEAR_VALUE";
147 case WGLWidget::COLOR_WRITEMASK: return "ctx.COLOR_WRITEMASK";
148 case WGLWidget::UNPACK_ALIGNMENT: return "ctx.UNPACK_ALIGNMENT";
149 case WGLWidget::PACK_ALIGNMENT: return "ctx.PACK_ALIGNMENT";
150 case WGLWidget::MAX_TEXTURE_SIZE: return "ctx.MAX_TEXTURE_SIZE";
151 case WGLWidget::MAX_VIEWPORT_DIMS: return "ctx.MAX_VIEWPORT_DIMS";
152 case WGLWidget::SUBPIXEL_BITS: return "ctx.SUBPIXEL_BITS";
153 case WGLWidget::RED_BITS: return "ctx.RED_BITS";
154 case WGLWidget::GREEN_BITS: return "ctx.GREEN_BITS";
155 case WGLWidget::BLUE_BITS: return "ctx.BLUE_BITS";
156 case WGLWidget::ALPHA_BITS: return "ctx.ALPHA_BITS";
157 case WGLWidget::DEPTH_BITS: return "ctx.DEPTH_BITS";
158 case WGLWidget::STENCIL_BITS: return "ctx.STENCIL_BITS";
159 case WGLWidget::POLYGON_OFFSET_UNITS: return "ctx.POLYGON_OFFSET_UNITS";
160 case WGLWidget::POLYGON_OFFSET_FACTOR: return "ctx.POLYGON_OFFSET_FACTOR";
161 case WGLWidget::TEXTURE_BINDING_2D: return "ctx.TEXTURE_BINDING_2D";
162 case WGLWidget::SAMPLE_BUFFERS: return "ctx.SAMPLE_BUFFERS";
163 case WGLWidget::SAMPLES: return "ctx.SAMPLES";
164 case WGLWidget::SAMPLE_COVERAGE_VALUE: return "ctx.SAMPLE_COVERAGE_VALUE";
165 case WGLWidget::SAMPLE_COVERAGE_INVERT: return "ctx.SAMPLE_COVERAGE_INVERT";
166 case WGLWidget::NUM_COMPRESSED_TEXTURE_FORMATS: return "ctx.NUM_COMPRESSED_TEXTURE_FORMATS";
167 case WGLWidget::COMPRESSED_TEXTURE_FORMATS: return "ctx.COMPRESSED_TEXTURE_FORMATS";
168 case WGLWidget::DONT_CARE: return "ctx.DONT_CARE";
169 case WGLWidget::FASTEST: return "ctx.FASTEST";
170 case WGLWidget::NICEST: return "ctx.NICEST";
171 case WGLWidget::GENERATE_MIPMAP_HINT: return "ctx.GENERATE_MIPMAP_HINT";
172 case WGLWidget::BYTE: return "ctx.BYTE";
173 case WGLWidget::UNSIGNED_BYTE: return "ctx.UNSIGNED_BYTE";
174 case WGLWidget::SHORT: return "ctx.SHORT";
175 case WGLWidget::UNSIGNED_SHORT: return "ctx.UNSIGNED_SHORT";
176 case WGLWidget::INT: return "ctx.INT";
177 case WGLWidget::UNSIGNED_INT: return "ctx.UNSIGNED_INT";
178 case WGLWidget::FLOAT: return "ctx.FLOAT";
179 case WGLWidget::DEPTH_COMPONENT: return "ctx.DEPTH_COMPONENT";
180 case WGLWidget::ALPHA: return "ctx.ALPHA";
181 case WGLWidget::RGB: return "ctx.RGB";
182 case WGLWidget::RGBA: return "ctx.RGBA";
183 case WGLWidget::LUMINANCE: return "ctx.LUMINANCE";
184 case WGLWidget::LUMINANCE_ALPHA: return "ctx.LUMINANCE_ALPHA";
185 case WGLWidget::UNSIGNED_SHORT_4_4_4_4: return "ctx.UNSIGNED_SHORT_4_4_4_4";
186 case WGLWidget::UNSIGNED_SHORT_5_5_5_1: return "ctx.UNSIGNED_SHORT_5_5_5_1";
187 case WGLWidget::UNSIGNED_SHORT_5_6_5: return "ctx.UNSIGNED_SHORT_5_6_5";
188 case WGLWidget::FRAGMENT_SHADER: return "ctx.FRAGMENT_SHADER";
189 case WGLWidget::VERTEX_SHADER: return "ctx.VERTEX_SHADER";
190 case WGLWidget::MAX_VERTEX_ATTRIBS: return "ctx.MAX_VERTEX_ATTRIBS";
191 case WGLWidget::MAX_VERTEX_UNIFORM_VECTORS: return "ctx.MAX_VERTEX_UNIFORM_VECTORS";
192 case WGLWidget::MAX_VARYING_VECTORS: return "ctx.MAX_VARYING_VECTORS";
193 case WGLWidget::MAX_COMBINED_TEXTURE_IMAGE_UNITS: return "ctx.MAX_COMBINED_TEXTURE_IMAGE_UNITS";
194 case WGLWidget::MAX_VERTEX_TEXTURE_IMAGE_UNITS: return "ctx.MAX_VERTEX_TEXTURE_IMAGE_UNITS";
195 case WGLWidget::MAX_TEXTURE_IMAGE_UNITS: return "ctx.MAX_TEXTURE_IMAGE_UNITS";
196 case WGLWidget::MAX_FRAGMENT_UNIFORM_VECTORS: return "ctx.MAX_FRAGMENT_UNIFORM_VECTORS";
197 case WGLWidget::SHADER_TYPE: return "ctx.SHADER_TYPE";
198 case WGLWidget::DELETE_STATUS: return "ctx.DELETE_STATUS";
199 case WGLWidget::LINK_STATUS: return "ctx.LINK_STATUS";
200 case WGLWidget::VALIDATE_STATUS: return "ctx.VALIDATE_STATUS";
201 case WGLWidget::ATTACHED_SHADERS: return "ctx.ATTACHED_SHADERS";
202 case WGLWidget::ACTIVE_UNIFORMS: return "ctx.ACTIVE_UNIFORMS";
203 case WGLWidget::ACTIVE_UNIFORM_MAX_LENGTH: return "ctx.ACTIVE_UNIFORM_MAX_LENGTH";
204 case WGLWidget::ACTIVE_ATTRIBUTES: return "ctx.ACTIVE_ATTRIBUTES";
205 case WGLWidget::ACTIVE_ATTRIBUTE_MAX_LENGTH: return "ctx.ACTIVE_ATTRIBUTE_MAX_LENGTH";
206 case WGLWidget::SHADING_LANGUAGE_VERSION: return "ctx.SHADING_LANGUAGE_VERSION";
207 case WGLWidget::CURRENT_PROGRAM: return "ctx.CURRENT_PROGRAM";
208 case WGLWidget::NEVER: return "ctx.NEVER";
209 case WGLWidget::LESS: return "ctx.LESS";
210 case WGLWidget::EQUAL: return "ctx.EQUAL";
211 case WGLWidget::LEQUAL: return "ctx.LEQUAL";
212 case WGLWidget::GREATER: return "ctx.GREATER";
213 case WGLWidget::NOTEQUAL: return "ctx.NOTEQUAL";
214 case WGLWidget::GEQUAL: return "ctx.GEQUAL";
215 case WGLWidget::ALWAYS: return "ctx.ALWAYS";
216 case WGLWidget::KEEP: return "ctx.KEEP";
217 case WGLWidget::REPLACE: return "ctx.REPLACE";
218 case WGLWidget::INCR: return "ctx.INCR";
219 case WGLWidget::DECR: return "ctx.DECR";
220 case WGLWidget::INVERT: return "ctx.INVERT";
221 case WGLWidget::INCR_WRAP: return "ctx.INCR_WRAP";
222 case WGLWidget::DECR_WRAP: return "ctx.DECR_WRAP";
223 case WGLWidget::VENDOR: return "ctx.VENDOR";
224 case WGLWidget::RENDERER: return "ctx.RENDERER";
225 case WGLWidget::VERSION: return "ctx.VERSION";
226 case WGLWidget::NEAREST: return "ctx.NEAREST";
227 case WGLWidget::LINEAR: return "ctx.LINEAR";
228 case WGLWidget::NEAREST_MIPMAP_NEAREST: return "ctx.NEAREST_MIPMAP_NEAREST";
229 case WGLWidget::LINEAR_MIPMAP_NEAREST: return "ctx.LINEAR_MIPMAP_NEAREST";
230 case WGLWidget::NEAREST_MIPMAP_LINEAR: return "ctx.NEAREST_MIPMAP_LINEAR";
231 case WGLWidget::LINEAR_MIPMAP_LINEAR: return "ctx.LINEAR_MIPMAP_LINEAR";
232 case WGLWidget::TEXTURE_MAG_FILTER: return "ctx.TEXTURE_MAG_FILTER";
233 case WGLWidget::TEXTURE_MIN_FILTER: return "ctx.TEXTURE_MIN_FILTER";
234 case WGLWidget::TEXTURE_WRAP_S: return "ctx.TEXTURE_WRAP_S";
235 case WGLWidget::TEXTURE_WRAP_T: return "ctx.TEXTURE_WRAP_T";
236 case WGLWidget::TEXTURE_2D: return "ctx.TEXTURE_2D";
237 case WGLWidget::TEXTURE: return "ctx.TEXTURE";
238 case WGLWidget::TEXTURE_CUBE_MAP: return "ctx.TEXTURE_CUBE_MAP";
239 case WGLWidget::TEXTURE_BINDING_CUBE_MAP: return "ctx.TEXTURE_BINDING_CUBE_MAP";
240 case WGLWidget::TEXTURE_CUBE_MAP_POSITIVE_X: return "ctx.TEXTURE_CUBE_MAP_POSITIVE_X";
241 case WGLWidget::TEXTURE_CUBE_MAP_NEGATIVE_X: return "ctx.TEXTURE_CUBE_MAP_NEGATIVE_X";
242 case WGLWidget::TEXTURE_CUBE_MAP_POSITIVE_Y: return "ctx.TEXTURE_CUBE_MAP_POSITIVE_Y";
243 case WGLWidget::TEXTURE_CUBE_MAP_NEGATIVE_Y: return "ctx.TEXTURE_CUBE_MAP_NEGATIVE_Y";
244 case WGLWidget::TEXTURE_CUBE_MAP_POSITIVE_Z: return "ctx.TEXTURE_CUBE_MAP_POSITIVE_Z";
245 case WGLWidget::TEXTURE_CUBE_MAP_NEGATIVE_Z: return "ctx.TEXTURE_CUBE_MAP_NEGATIVE_Z";
246 case WGLWidget::MAX_CUBE_MAP_TEXTURE_SIZE: return "ctx.MAX_CUBE_MAP_TEXTURE_SIZE";
247 case WGLWidget::TEXTURE0: return "ctx.TEXTURE0";
248 case WGLWidget::TEXTURE1: return "ctx.TEXTURE1";
249 case WGLWidget::TEXTURE2: return "ctx.TEXTURE2";
250 case WGLWidget::TEXTURE3: return "ctx.TEXTURE3";
251 case WGLWidget::TEXTURE4: return "ctx.TEXTURE4";
252 case WGLWidget::TEXTURE5: return "ctx.TEXTURE5";
253 case WGLWidget::TEXTURE6: return "ctx.TEXTURE6";
254 case WGLWidget::TEXTURE7: return "ctx.TEXTURE7";
255 case WGLWidget::TEXTURE8: return "ctx.TEXTURE8";
256 case WGLWidget::TEXTURE9: return "ctx.TEXTURE9";
257 case WGLWidget::TEXTURE10: return "ctx.TEXTURE10";
258 case WGLWidget::TEXTURE11: return "ctx.TEXTURE11";
259 case WGLWidget::TEXTURE12: return "ctx.TEXTURE12";
260 case WGLWidget::TEXTURE13: return "ctx.TEXTURE13";
261 case WGLWidget::TEXTURE14: return "ctx.TEXTURE14";
262 case WGLWidget::TEXTURE15: return "ctx.TEXTURE15";
263 case WGLWidget::TEXTURE16: return "ctx.TEXTURE16";
264 case WGLWidget::TEXTURE17: return "ctx.TEXTURE17";
265 case WGLWidget::TEXTURE18: return "ctx.TEXTURE18";
266 case WGLWidget::TEXTURE19: return "ctx.TEXTURE19";
267 case WGLWidget::TEXTURE20: return "ctx.TEXTURE20";
268 case WGLWidget::TEXTURE21: return "ctx.TEXTURE21";
269 case WGLWidget::TEXTURE22: return "ctx.TEXTURE22";
270 case WGLWidget::TEXTURE23: return "ctx.TEXTURE23";
271 case WGLWidget::TEXTURE24: return "ctx.TEXTURE24";
272 case WGLWidget::TEXTURE25: return "ctx.TEXTURE25";
273 case WGLWidget::TEXTURE26: return "ctx.TEXTURE26";
274 case WGLWidget::TEXTURE27: return "ctx.TEXTURE27";
275 case WGLWidget::TEXTURE28: return "ctx.TEXTURE28";
276 case WGLWidget::TEXTURE29: return "ctx.TEXTURE29";
277 case WGLWidget::TEXTURE30: return "ctx.TEXTURE30";
278 case WGLWidget::TEXTURE31: return "ctx.TEXTURE31";
279 case WGLWidget::ACTIVE_TEXTURE: return "ctx.ACTIVE_TEXTURE";
280 case WGLWidget::REPEAT: return "ctx.REPEAT";
281 case WGLWidget::CLAMP_TO_EDGE: return "ctx.CLAMP_TO_EDGE";
282 case WGLWidget::MIRRORED_REPEAT: return "ctx.MIRRORED_REPEAT";
283 case WGLWidget::FLOAT_VEC2: return "ctx.FLOAT_VEC2";
284 case WGLWidget::FLOAT_VEC3: return "ctx.FLOAT_VEC3";
285 case WGLWidget::FLOAT_VEC4: return "ctx.FLOAT_VEC4";
286 case WGLWidget::INT_VEC2: return "ctx.INT_VEC2";
287 case WGLWidget::INT_VEC3: return "ctx.INT_VEC3";
288 case WGLWidget::INT_VEC4: return "ctx.INT_VEC4";
289 case WGLWidget::BOOL: return "ctx.BOOL";
290 case WGLWidget::BOOL_VEC2: return "ctx.BOOL_VEC2";
291 case WGLWidget::BOOL_VEC3: return "ctx.BOOL_VEC3";
292 case WGLWidget::BOOL_VEC4: return "ctx.BOOL_VEC4";
293 case WGLWidget::FLOAT_MAT2: return "ctx.FLOAT_MAT2";
294 case WGLWidget::FLOAT_MAT3: return "ctx.FLOAT_MAT3";
295 case WGLWidget::FLOAT_MAT4: return "ctx.FLOAT_MAT4";
296 case WGLWidget::SAMPLER_2D: return "ctx.SAMPLER_2D";
297 case WGLWidget::SAMPLER_CUBE: return "ctx.SAMPLER_CUBE";
298 case WGLWidget::VERTEX_ATTRIB_ARRAY_ENABLED: return "ctx.VERTEX_ATTRIB_ARRAY_ENABLED";
299 case WGLWidget::VERTEX_ATTRIB_ARRAY_SIZE: return "ctx.VERTEX_ATTRIB_ARRAY_SIZE";
300 case WGLWidget::VERTEX_ATTRIB_ARRAY_STRIDE: return "ctx.VERTEX_ATTRIB_ARRAY_STRIDE";
301 case WGLWidget::VERTEX_ATTRIB_ARRAY_TYPE: return "ctx.VERTEX_ATTRIB_ARRAY_TYPE";
302 case WGLWidget::VERTEX_ATTRIB_ARRAY_NORMALIZED: return "ctx.VERTEX_ATTRIB_ARRAY_NORMALIZED";
303 case WGLWidget::VERTEX_ATTRIB_ARRAY_POINTER: return "ctx.VERTEX_ATTRIB_ARRAY_POINTER";
304 case WGLWidget::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: return "ctx.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING";
305 case WGLWidget::COMPILE_STATUS: return "ctx.COMPILE_STATUS";
306 case WGLWidget::INFO_LOG_LENGTH: return "ctx.INFO_LOG_LENGTH";
307 case WGLWidget::SHADER_SOURCE_LENGTH: return "ctx.SHADER_SOURCE_LENGTH";
308 case WGLWidget::LOW_FLOAT: return "ctx.LOW_FLOAT";
309 case WGLWidget::MEDIUM_FLOAT: return "ctx.MEDIUM_FLOAT";
310 case WGLWidget::HIGH_FLOAT: return "ctx.HIGH_FLOAT";
311 case WGLWidget::LOW_INT: return "ctx.LOW_INT";
312 case WGLWidget::MEDIUM_INT: return "ctx.MEDIUM_INT";
313 case WGLWidget::HIGH_INT: return "ctx.HIGH_INT";
314 case WGLWidget::FRAMEBUFFER: return "ctx.FRAMEBUFFER";
315 case WGLWidget::RENDERBUFFER: return "ctx.RENDERBUFFER";
316 case WGLWidget::RGBA4: return "ctx.RGBA4";
317 case WGLWidget::RGB5_A1: return "ctx.RGB5_A1";
318 case WGLWidget::RGB565: return "ctx.RGB565";
319 case WGLWidget::DEPTH_COMPONENT16: return "ctx.DEPTH_COMPONENT16";
320 case WGLWidget::STENCIL_INDEX: return "ctx.STENCIL_INDEX";
321 case WGLWidget::STENCIL_INDEX8: return "ctx.STENCIL_INDEX8";
322 case WGLWidget::DEPTH_STENCIL: return "ctx.DEPTH_STENCIL";
323 case WGLWidget::RENDERBUFFER_WIDTH: return "ctx.RENDERBUFFER_WIDTH";
324 case WGLWidget::RENDERBUFFER_HEIGHT: return "ctx.RENDERBUFFER_HEIGHT";
325 case WGLWidget::RENDERBUFFER_INTERNAL_FORMAT: return "ctx.RENDERBUFFER_INTERNAL_FORMAT";
326 case WGLWidget::RENDERBUFFER_RED_SIZE: return "ctx.RENDERBUFFER_RED_SIZE";
327 case WGLWidget::RENDERBUFFER_GREEN_SIZE: return "ctx.RENDERBUFFER_GREEN_SIZE";
328 case WGLWidget::RENDERBUFFER_BLUE_SIZE: return "ctx.RENDERBUFFER_BLUE_SIZE";
329 case WGLWidget::RENDERBUFFER_ALPHA_SIZE: return "ctx.RENDERBUFFER_ALPHA_SIZE";
330 case WGLWidget::RENDERBUFFER_DEPTH_SIZE: return "ctx.RENDERBUFFER_DEPTH_SIZE";
331 case WGLWidget::RENDERBUFFER_STENCIL_SIZE: return "ctx.RENDERBUFFER_STENCIL_SIZE";
332 case WGLWidget::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: return "ctx.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE";
333 case WGLWidget::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: return "ctx.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME";
334 case WGLWidget::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: return "ctx.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL";
335 case WGLWidget::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: return "ctx.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE";
336 case WGLWidget::COLOR_ATTACHMENT0: return "ctx.COLOR_ATTACHMENT0";
337 case WGLWidget::DEPTH_ATTACHMENT: return "ctx.DEPTH_ATTACHMENT";
338 case WGLWidget::STENCIL_ATTACHMENT: return "ctx.STENCIL_ATTACHMENT";
339 case WGLWidget::DEPTH_STENCIL_ATTACHMENT: return "ctx.DEPTH_STENCIL_ATTACHMENT";
340 //case WGLWidget::NONE: return "ctx.NONE";
341 case WGLWidget::FRAMEBUFFER_COMPLETE: return "ctx.FRAMEBUFFER_COMPLETE";
342 case WGLWidget::FRAMEBUFFER_INCOMPLETE_ATTACHMENT: return "ctx.FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
343 case WGLWidget::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: return "ctx.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
344 case WGLWidget::FRAMEBUFFER_INCOMPLETE_DIMENSIONS: return "ctx.FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
345 case WGLWidget::FRAMEBUFFER_UNSUPPORTED: return "ctx.FRAMEBUFFER_UNSUPPORTED";
346 case WGLWidget::FRAMEBUFFER_BINDING: return "ctx.FRAMEBUFFER_BINDING";
347 case WGLWidget::RENDERBUFFER_BINDING: return "ctx.RENDERBUFFER_BINDING";
348 case WGLWidget::MAX_RENDERBUFFER_SIZE: return "ctx.MAX_RENDERBUFFER_SIZE";
349 case WGLWidget::INVALID_FRAMEBUFFER_OPERATION: return "ctx.INVALID_FRAMEBUFFER_OPERATION";
350 case WGLWidget::UNPACK_FLIP_Y_WEBGL: return "ctx.UNPACK_FLIP_Y_WEBGL";
351 case WGLWidget::UNPACK_PREMULTIPLY_ALPHA_WEBGL: return "ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL";
352 case WGLWidget::CONTEXT_LOST_WEBGL: return "ctx.CONTEXT_LOST_WEBGL";
353 case WGLWidget::UNPACK_COLORSPACE_CONVERSION_WEBGL: return "ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL";
354 case WGLWidget::BROWSER_DEFAULT_WEBGL: return "ctx.BROWSER_DEFAULT_WEBGL";
355 }
356 return "BAD_GL_ENUM";
357 }
358
debugger()359 void WClientGLWidget::debugger()
360 {
361 js_ << "debugger;\n";
362 }
363
activeTexture(WGLWidget::GLenum texture)364 void WClientGLWidget::activeTexture(WGLWidget::GLenum texture)
365 {
366 js_ << "ctx.activeTexture(" << toString(texture) << ");";
367 GLDEBUG;
368 }
369
attachShader(WGLWidget::Program program,WGLWidget::Shader shader)370 void WClientGLWidget::attachShader(WGLWidget::Program program,
371 WGLWidget::Shader shader)
372 {
373 js_ << "ctx.attachShader(" << program.jsRef()
374 << ", " << shader.jsRef() << ");";
375 GLDEBUG;
376 }
377
bindAttribLocation(WGLWidget::Program program,unsigned index,const std::string & name)378 void WClientGLWidget::bindAttribLocation(WGLWidget::Program program,
379 unsigned index,
380 const std::string &name)
381 {
382 js_ << "ctx.bindAttribLocation(" << program.jsRef() << "," << index
383 << "," << WWebWidget::jsStringLiteral(name) << ");";
384 GLDEBUG;
385 }
386
bindBuffer(WGLWidget::GLenum target,WGLWidget::Buffer buffer)387 void WClientGLWidget::bindBuffer(WGLWidget::GLenum target,
388 WGLWidget::Buffer buffer)
389 {
390 js_ << "ctx.bindBuffer(" << toString(target) << "," << buffer.jsRef() << ");";
391 currentlyBoundBuffer_ = buffer;
392 GLDEBUG;
393 }
394
bindFramebuffer(WGLWidget::GLenum target,WGLWidget::Framebuffer buffer)395 void WClientGLWidget::bindFramebuffer(WGLWidget::GLenum target,
396 WGLWidget::Framebuffer buffer)
397 {
398 js_ << "ctx.bindFramebuffer(" << toString(target) << "," << buffer.jsRef() << ");";
399 GLDEBUG;
400 }
401
bindRenderbuffer(WGLWidget::GLenum target,WGLWidget::Renderbuffer buffer)402 void WClientGLWidget::bindRenderbuffer(WGLWidget::GLenum target,
403 WGLWidget::Renderbuffer buffer)
404 {
405 js_ << "ctx.bindRenderbuffer(" << toString(target) << "," << buffer.jsRef() << ");";
406 GLDEBUG;
407 }
408
bindTexture(WGLWidget::GLenum target,WGLWidget::Texture texture)409 void WClientGLWidget::bindTexture(WGLWidget::GLenum target,
410 WGLWidget::Texture texture)
411 {
412 js_ << "ctx.bindTexture(" << toString(target) << ","
413 << texture.jsRef() << ");";
414 currentlyBoundTexture_ = texture;
415 GLDEBUG;
416 }
417
blendColor(double red,double green,double blue,double alpha)418 void WClientGLWidget::blendColor(double red, double green, double blue,
419 double alpha)
420 {
421 char buf[30];
422 js_ << "ctx.blendColor(" << makeFloat(red, buf) << ",";
423 js_ << makeFloat(green, buf) << ",";
424 js_ << makeFloat(blue, buf) << ",";
425 js_ << makeFloat(alpha, buf) << ");";
426 GLDEBUG;
427 }
428
blendEquation(WGLWidget::GLenum mode)429 void WClientGLWidget::blendEquation(WGLWidget::GLenum mode)
430 {
431 js_ << "ctx.blendEquation(" << toString(mode) << ");";
432 GLDEBUG;
433 }
434
blendEquationSeparate(WGLWidget::GLenum modeRGB,WGLWidget::GLenum modeAlpha)435 void WClientGLWidget::blendEquationSeparate(WGLWidget::GLenum modeRGB,
436 WGLWidget::GLenum modeAlpha)
437 {
438 js_ << "ctx.blendEquationSeparate(" << toString(modeRGB) << ","
439 << toString(modeAlpha) << ");";
440 GLDEBUG;
441 }
442
blendFunc(WGLWidget::GLenum sfactor,WGLWidget::GLenum dfactor)443 void WClientGLWidget::blendFunc(WGLWidget::GLenum sfactor,
444 WGLWidget::GLenum dfactor)
445 {
446 js_ << "ctx.blendFunc(" << toString(sfactor) << ","
447 << toString(dfactor) << ");";
448 GLDEBUG;
449 }
450
blendFuncSeparate(WGLWidget::GLenum srcRGB,WGLWidget::GLenum dstRGB,WGLWidget::GLenum srcAlpha,WGLWidget::GLenum dstAlpha)451 void WClientGLWidget::blendFuncSeparate(WGLWidget::GLenum srcRGB,
452 WGLWidget::GLenum dstRGB,
453 WGLWidget::GLenum srcAlpha,
454 WGLWidget::GLenum dstAlpha)
455 {
456 js_ << "ctx.blendFuncSeparate(" << toString(srcRGB) << ","
457 << toString(dstRGB) << "," << toString(srcAlpha) << ","
458 << toString(dstAlpha) << ");";
459 GLDEBUG;
460 }
461
bufferData(WGLWidget::GLenum target,WGLWidget::ArrayBuffer res,WGLWidget::GLenum usage)462 void WClientGLWidget::bufferData(WGLWidget::GLenum target,
463 WGLWidget::ArrayBuffer res,
464 WGLWidget::GLenum usage)
465 {
466 js_ << "ctx.bufferData(" << toString(target) << ",";
467 js_ << res.jsRef() << ".data, ";
468 js_ << toString(usage) << ");";
469 GLDEBUG;
470 }
471
bufferData(WGLWidget::GLenum target,WGLWidget::ArrayBuffer res,unsigned bufferResourceOffset,unsigned bufferResourceSize,WGLWidget::GLenum usage)472 void WClientGLWidget::bufferData(WGLWidget::GLenum target,
473 WGLWidget::ArrayBuffer res,
474 unsigned bufferResourceOffset,
475 unsigned bufferResourceSize,
476 WGLWidget::GLenum usage)
477 {
478 js_ << "ctx.bufferData(" << toString(target) << ",";
479 js_ << res.jsRef() << ".data.slice(" << bufferResourceOffset << ","
480 << bufferResourceOffset + bufferResourceSize << "),";
481 js_ << toString(usage) << ");";
482 GLDEBUG;
483 }
484
bufferSubData(WGLWidget::GLenum target,unsigned offset,WGLWidget::ArrayBuffer res)485 void WClientGLWidget::bufferSubData(WGLWidget::GLenum target, unsigned offset,
486 WGLWidget::ArrayBuffer res)
487 {
488 js_ << "ctx.bufferSubData(" << toString(target) << ",";
489 js_ << offset << ",";
490 js_ << res.jsRef() << ".data);";
491 GLDEBUG;
492 }
493
bufferSubData(WGLWidget::GLenum target,unsigned offset,WGLWidget::ArrayBuffer res,unsigned bufferResourceOffset,unsigned bufferResourceSize)494 void WClientGLWidget::bufferSubData(WGLWidget::GLenum target, unsigned offset,
495 WGLWidget::ArrayBuffer res,
496 unsigned bufferResourceOffset,
497 unsigned bufferResourceSize)
498 {
499 js_ << "ctx.bufferSubData(" << toString(target) << ",";
500 js_ << offset << ",";
501 js_ << res.jsRef() << ".data.slice("<< bufferResourceOffset <<", "
502 << bufferResourceOffset + bufferResourceSize << "));";
503 GLDEBUG;
504 }
505
bufferData(WGLWidget::GLenum target,int size,WGLWidget::GLenum usage)506 void WClientGLWidget::bufferData(WGLWidget::GLenum target, int size,
507 WGLWidget::GLenum usage)
508 {
509 js_ << "ctx.bufferData(" << toString(target) << ",";
510 js_ << size << ",";
511 js_ << toString(usage) << ");";
512 GLDEBUG;
513 }
514
bufferDatafv(WGLWidget::GLenum target,const FloatBuffer & v,WGLWidget::GLenum usage,bool binary)515 void WClientGLWidget::bufferDatafv(WGLWidget::GLenum target,
516 const FloatBuffer &v,
517 WGLWidget::GLenum usage,
518 bool binary)
519 {
520 if (binary) {
521 std::unique_ptr<WMemoryResource> res
522 (new WMemoryResource("application/octet"));
523 auto resPtr = res.get();
524 res->setData(Utils::toCharPointer(v), v.size()*sizeof(float));
525 binaryResources_.push_back(std::move(res));
526 preloadArrayBuffers_.push_back(PreloadArrayBuffer(currentlyBoundBuffer_.jsRef(), resPtr->url()));
527
528 js_ << "ctx.bufferData(" << toString(target) << ",";
529 js_ << currentlyBoundBuffer_.jsRef() << ".data, ";
530 js_ << toString(usage) << ");";
531 } else {
532 #ifdef WT_TARGET_JAVA
533 bufferDatafv(target, v.asFloatBuffer(), usage);
534 #else
535 js_ << "ctx.bufferData(" << toString(target) << ",";
536 js_ << "new Float32Array([";
537 char buf[30];
538 for (unsigned i = 0; i < v.size(); i++) {
539 js_ << (i == 0 ? "" : ",") << makeFloat(v[i], buf);
540 }
541 js_ << "])";
542 js_ << ","<< toString(usage) << ");";
543 #endif
544 }
545 GLDEBUG;
546 }
547
548 #ifdef WT_TARGET_JAVA
bufferDatafv(WGLWidget::GLenum target,const FloatNotByteBuffer & buffer,WGLWidget::GLenum usage)549 void WClientGLWidget::bufferDatafv(WGLWidget::GLenum target, const FloatNotByteBuffer &buffer, WGLWidget::GLenum usage)
550 {
551 js_ << "ctx.bufferData(" << toString(target) << ",";
552 js_ << "new Float32Array([";
553 char buf[30];
554 for (int i=0; i < buffer.size(); i++) {
555 js_ << (i == 0 ? "" : ",") << makeFloat(buffer[i], buf);
556 }
557 js_ << "])";
558 js_ << ","<< toString(usage) << ");";
559 }
560 #endif
561
bufferDataiv(WGLWidget::GLenum target,IntBuffer & buffer,WGLWidget::GLenum usage,WGLWidget::GLenum type)562 void WClientGLWidget::bufferDataiv(WGLWidget::GLenum target, IntBuffer &buffer, WGLWidget::GLenum usage, WGLWidget::GLenum type)
563 {
564 js_ << "ctx.bufferData(" << toString(target) << ",";
565 renderiv(js_, buffer, type);
566 js_ << ","<< toString(usage) << ");";
567 GLDEBUG;
568 }
569
bufferSubDatafv(WGLWidget::GLenum target,unsigned offset,const FloatBuffer & buffer,bool binary)570 void WClientGLWidget::bufferSubDatafv(WGLWidget::GLenum target, unsigned offset, const FloatBuffer &buffer, bool binary)
571 {
572 if (binary) {
573 std::unique_ptr<WMemoryResource> res
574 (new WMemoryResource("application/octet"));
575 res->setData(Utils::toCharPointer(buffer), buffer.size()*sizeof(float));
576 preloadArrayBuffers_.push_back(PreloadArrayBuffer(currentlyBoundBuffer_.jsRef(), res->url()));
577 binaryResources_.push_back(std::move(res));
578
579 js_ << "ctx.bufferSubData(" << toString(target) << ",";
580 js_ << offset << ",";
581 js_ << currentlyBoundBuffer_.jsRef() << ".data);";
582 } else {
583 #ifdef WT_TARGET_JAVA
584 bufferSubDatafv(target, offset, buffer.asFloatBuffer());
585 #else
586 js_ << "ctx.bufferSubData(" << toString(target) << ",";
587 js_ << offset << ",";
588 js_ << "new Float32Array([";
589 char buf[30];
590 for (unsigned i = 0; i < buffer.size(); i++) {
591 js_ << (i == 0 ? "" : ",") << makeFloat(buffer[i], buf);
592 }
593 js_ << "])";
594 js_ << ");";
595 #endif
596 }
597 GLDEBUG;
598 }
599
600 #ifdef WT_TARGET_JAVA
bufferSubDatafv(WGLWidget::GLenum target,unsigned offset,const FloatNotByteBuffer & buffer)601 void WClientGLWidget::bufferSubDatafv(WGLWidget::GLenum target, unsigned offset, const FloatNotByteBuffer &buffer)
602 {
603 js_ << "ctx.bufferSubData(" << toString(target) << ",";
604 js_ << offset << ",";
605 js_ << "new Float32Array([";
606 char buf[30];
607 for (int i=0; i < buffer.size(); i++) {
608 js_ << (i == 0 ? "" : ",") << makeFloat(buffer[i], buf);
609 }
610 js_ << "])";
611 js_ << ");";
612 }
613 #endif
614
bufferSubDataiv(WGLWidget::GLenum target,unsigned offset,IntBuffer & buffer,WGLWidget::GLenum type)615 void WClientGLWidget::bufferSubDataiv(WGLWidget::GLenum target,
616 unsigned offset, IntBuffer &buffer,
617 WGLWidget::GLenum type)
618 {
619 js_ << "ctx.bufferSubData(" << toString(target) << "," << offset << ",";
620 renderiv(js_, buffer, type);
621 js_ << ");";
622 GLDEBUG;
623 }
624
clearBinaryResources()625 void WClientGLWidget::clearBinaryResources()
626 {
627 binaryResources_.clear();
628 }
629
clear(WFlags<WGLWidget::GLenum> mask)630 void WClientGLWidget::clear(WFlags<WGLWidget::GLenum> mask)
631 {
632 js_ << "ctx.clear(";
633 if (mask & WGLWidget::COLOR_BUFFER_BIT) js_ << "ctx.COLOR_BUFFER_BIT|";
634 if (mask & WGLWidget::DEPTH_BUFFER_BIT) js_ << "ctx.DEPTH_BUFFER_BIT|";
635 if (mask & WGLWidget::STENCIL_BUFFER_BIT) js_ << "ctx.STENCIL_BUFFER_BIT|";
636
637 js_ << "0);";
638 GLDEBUG;
639 }
640
clearColor(double r,double g,double b,double a)641 void WClientGLWidget::clearColor(double r, double g, double b, double a)
642 {
643 char buf[30];
644 js_ << "ctx.clearColor(" << makeFloat(r, buf) << ",";
645 js_ << makeFloat(g, buf) << ",";
646 js_ << makeFloat(b, buf) << ",";
647 js_ << makeFloat(a, buf) << ");";
648 GLDEBUG;
649 }
650
clearDepth(double depth)651 void WClientGLWidget::clearDepth(double depth)
652 {
653 char buf[30];
654 js_ << "ctx.clearDepth(" << makeFloat(depth, buf) << ");";
655 GLDEBUG;
656 }
657
clearStencil(int s)658 void WClientGLWidget::clearStencil(int s)
659 {
660 js_ << "ctx.clearStencil(" << s << ");";
661 GLDEBUG;
662 }
663
colorMask(bool red,bool green,bool blue,bool alpha)664 void WClientGLWidget::colorMask(bool red, bool green, bool blue, bool alpha)
665 {
666 js_ << "ctx.colorMask(" << (red ? "true" : "false") << ","
667 << (green ? "true" : "false") << ","
668 << (blue ? "true" : "false") << ","
669 << (alpha ? "true" : "false") << ");";
670 GLDEBUG;
671 }
672
compileShader(WGLWidget::Shader shader)673 void WClientGLWidget::compileShader(WGLWidget::Shader shader)
674 {
675 js_ << "ctx.compileShader(" << shader.jsRef() << ");";
676 js_ << "if (!ctx.getShaderParameter(" << shader.jsRef()
677 << ", ctx.COMPILE_STATUS)) {"
678 << "alert(ctx.getShaderInfoLog(" << shader.jsRef() << "));}";
679 GLDEBUG;
680 }
681
copyTexImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalFormat,int x,int y,unsigned width,unsigned height,int border)682 void WClientGLWidget::copyTexImage2D(WGLWidget::GLenum target, int level,
683 WGLWidget::GLenum internalFormat,
684 int x, int y,
685 unsigned width, unsigned height,
686 int border)
687 {
688 js_ << "ctx.copyTexImage2D(" << toString(target) << "," << level << ","
689 << toString(internalFormat) << "," << x << "," << y << ","
690 << width << "," << height << "," << border << ");";
691 GLDEBUG;
692 }
693
copyTexSubImage2D(WGLWidget::GLenum target,int level,int xoffset,int yoffset,int x,int y,unsigned width,unsigned height)694 void WClientGLWidget::copyTexSubImage2D(WGLWidget::GLenum target, int level,
695 int xoffset, int yoffset,
696 int x, int y,
697 unsigned width, unsigned height)
698 {
699 js_ << "ctx.copyTexSubImage2D(" << toString(target) << "," << level << ","
700 << xoffset << "," << yoffset << "," << x << "," << y << ","
701 << width << "," << height << ");";
702 GLDEBUG;
703 }
704
createBuffer()705 WGLWidget::Buffer WClientGLWidget::createBuffer()
706 {
707 WGLWidget::Buffer retval(buffers_++);
708 js_ << "if (!" << retval.jsRef() << "){";
709 js_ << retval.jsRef() << "=ctx.createBuffer();";
710 js_ << "\n}";
711 GLDEBUG;
712 return retval;
713 }
714
createAndLoadArrayBuffer(const std::string & url)715 WGLWidget::ArrayBuffer WClientGLWidget::createAndLoadArrayBuffer(const std::string &url)
716 {
717 WGLWidget::ArrayBuffer retval(arrayBuffers_++);
718 preloadArrayBuffers_.push_back(PreloadArrayBuffer(retval.jsRef(), url));
719 return retval;
720 }
721
createFramebuffer()722 WGLWidget::Framebuffer WClientGLWidget::createFramebuffer()
723 {
724 WGLWidget::Framebuffer retval(framebuffers_++);
725 js_ << retval.jsRef() << "=ctx.createFramebuffer();";
726 GLDEBUG;
727 return retval;
728 }
729
createProgram()730 WGLWidget::Program WClientGLWidget::createProgram()
731 {
732 WGLWidget::Program retval(programs_++);
733 js_ << retval.jsRef() << "=ctx.createProgram();";
734 GLDEBUG;
735 return retval;
736 }
737
createRenderbuffer()738 WGLWidget::Renderbuffer WClientGLWidget::createRenderbuffer()
739 {
740 WGLWidget::Renderbuffer retval(renderbuffers_++);
741 js_ << retval.jsRef() << "=ctx.createRenderbuffer();";
742 GLDEBUG;
743 return retval;
744 }
745
createShader(WGLWidget::GLenum shader)746 WGLWidget::Shader WClientGLWidget::createShader(WGLWidget::GLenum shader)
747 {
748 WGLWidget::Shader retval(shaders_++);
749 js_ << retval.jsRef() << "=ctx.createShader(" << toString(shader) << ");";
750 GLDEBUG;
751 return retval;
752 }
753
createTexture()754 WGLWidget::Texture WClientGLWidget::createTexture()
755 {
756 WGLWidget::Texture retval(textures_++);
757 js_ << "if (!" << retval.jsRef() << "){";
758 js_ << retval.jsRef() << "=ctx.createTexture();";
759 js_ << "\n}";
760 GLDEBUG;
761 return retval;
762 }
763
createTextureAndLoad(const std::string & url)764 WGLWidget::Texture WClientGLWidget::createTextureAndLoad(const std::string &url)
765 {
766 WGLWidget::Texture retval(textures_++);
767 preloadImages_.push_back(PreloadImage(retval.jsRef(), url, 0));
768 return retval;
769 }
770
771 std::unique_ptr<WPaintDevice>
createPaintDevice(const WLength & width,const WLength & height)772 WClientGLWidget::createPaintDevice(const WLength& width,
773 const WLength& height)
774 {
775 return std::unique_ptr<WPaintDevice>(new WCanvasPaintDevice(width, height));
776 }
777
cullFace(WGLWidget::GLenum mode)778 void WClientGLWidget::cullFace(WGLWidget::GLenum mode)
779 {
780 js_ << "ctx.cullFace(" << toString(mode) << ");";
781 GLDEBUG;
782 }
783
deleteBuffer(WGLWidget::Buffer buffer)784 void WClientGLWidget::deleteBuffer(WGLWidget::Buffer buffer)
785 {
786 if ((unsigned)buffer.getId() >= buffers_) return;
787 js_ << "ctx.deleteBuffer(" << buffer.jsRef() << ");";
788 js_ << "delete " << buffer.jsRef() << ";";
789 GLDEBUG;
790 }
791
deleteFramebuffer(WGLWidget::Framebuffer buffer)792 void WClientGLWidget::deleteFramebuffer(WGLWidget::Framebuffer buffer)
793 {
794 if ((unsigned)buffer.getId() >= framebuffers_) return;
795 js_ << "ctx.deleteFramebuffer(" << buffer.jsRef() << ");";
796 js_ << "delete " << buffer.jsRef() << ";";
797 GLDEBUG;
798 }
799
deleteProgram(WGLWidget::Program program)800 void WClientGLWidget::deleteProgram(WGLWidget::Program program)
801 {
802 if ((unsigned)program.getId() >= programs_) return;
803 js_ << "ctx.deleteProgram(" << program.jsRef() << ");";
804 js_ << "delete " << program.jsRef() << ";";
805 GLDEBUG;
806 }
807
deleteRenderbuffer(WGLWidget::Renderbuffer buffer)808 void WClientGLWidget::deleteRenderbuffer(WGLWidget::Renderbuffer buffer)
809 {
810 if ((unsigned)buffer.getId() >= renderbuffers_) return;
811 js_ << "ctx.deleteRenderbuffer(" << buffer.jsRef() << ");";
812 js_ << "delete " << buffer.jsRef() << ";";
813 GLDEBUG;
814 }
815
deleteShader(WGLWidget::Shader shader)816 void WClientGLWidget::deleteShader(WGLWidget::Shader shader)
817 {
818 if ((unsigned)shader.getId() >= shaders_) return;
819 js_ << "ctx.deleteShader(" << shader.jsRef() << ");";
820 js_ << "delete " << shader.jsRef() << ";";
821 GLDEBUG;
822 }
823
deleteTexture(WGLWidget::Texture texture)824 void WClientGLWidget::deleteTexture(WGLWidget::Texture texture)
825 {
826 if ((unsigned)texture.getId() >= textures_) return;
827 js_ << "ctx.deleteTexture(" << texture.jsRef() << ");";
828 js_ << "delete " << texture.jsRef() << ";";
829 GLDEBUG;
830 }
831
depthFunc(WGLWidget::GLenum func)832 void WClientGLWidget::depthFunc(WGLWidget::GLenum func)
833 {
834 js_ << "ctx.depthFunc(" << toString(func) << ");";
835 GLDEBUG;
836 }
837
depthMask(bool flag)838 void WClientGLWidget::depthMask(bool flag)
839 {
840 js_ << "ctx.depthMask(" << (flag ? "true" : "false") << ");";
841 GLDEBUG;
842 }
843
depthRange(double zNear,double zFar)844 void WClientGLWidget::depthRange(double zNear, double zFar)
845 {
846 char buf[30];
847 js_ << "ctx.depthRange(" << makeFloat(zNear, buf) << ",";
848 js_ << makeFloat(zFar, buf) << ");";
849 GLDEBUG;
850 }
851
detachShader(WGLWidget::Program program,WGLWidget::Shader shader)852 void WClientGLWidget::detachShader(WGLWidget::Program program,
853 WGLWidget::Shader shader)
854 {
855 if ((unsigned)program.getId() >= programs_ ||
856 (unsigned)shader.getId() >= shaders_)
857 return;
858 js_ << "if (" << program.jsRef() << " && " << shader.jsRef() << ") { ctx.detachShader(" << program.jsRef() << "," << shader.jsRef() << "); }";
859 GLDEBUG;
860 }
861
disable(WGLWidget::GLenum cap)862 void WClientGLWidget::disable(WGLWidget::GLenum cap)
863 {
864 js_ << "ctx.disable(" << toString(cap) << ");";
865 GLDEBUG;
866 }
867
disableVertexAttribArray(WGLWidget::AttribLocation index)868 void WClientGLWidget::disableVertexAttribArray(WGLWidget::AttribLocation index)
869 {
870 js_ << "ctx.disableVertexAttribArray(" << index.jsRef() << ");";
871 GLDEBUG;
872 }
873
drawArrays(WGLWidget::GLenum mode,int first,unsigned count)874 void WClientGLWidget::drawArrays(WGLWidget::GLenum mode,
875 int first, unsigned count)
876 {
877 js_ << "ctx.drawArrays(" << toString(mode) << "," << first << "," << count << ");";
878 GLDEBUG;
879 }
880
drawElements(WGLWidget::GLenum mode,unsigned count,WGLWidget::GLenum type,unsigned offset)881 void WClientGLWidget::drawElements(WGLWidget::GLenum mode, unsigned count, WGLWidget::GLenum type, unsigned offset)
882 {
883 js_ << "ctx.drawElements(" << toString(mode) << "," << count << ","
884 << toString(type) << "," << offset << ");";
885 GLDEBUG;
886 }
887
enable(WGLWidget::GLenum cap)888 void WClientGLWidget::enable(WGLWidget::GLenum cap)
889 {
890 js_ << "ctx.enable(" << toString(cap) << ");";
891 GLDEBUG;
892 }
893
enableVertexAttribArray(WGLWidget::AttribLocation index)894 void WClientGLWidget::enableVertexAttribArray(WGLWidget::AttribLocation index)
895 {
896 js_ << "ctx.enableVertexAttribArray(" << index.jsRef() << ");";
897 GLDEBUG;
898 }
899
finish()900 void WClientGLWidget::finish()
901 {
902 js_ << "ctx.finish();";
903 GLDEBUG;
904 }
905
flush()906 void WClientGLWidget::flush()
907 {
908 js_ << "ctx.flush();";
909 GLDEBUG;
910 }
911
912 void WClientGLWidget
framebufferRenderbuffer(WGLWidget::GLenum target,WGLWidget::GLenum attachment,WGLWidget::GLenum renderbuffertarget,WGLWidget::Renderbuffer renderbuffer)913 ::framebufferRenderbuffer(WGLWidget::GLenum target,
914 WGLWidget::GLenum attachment,
915 WGLWidget::GLenum renderbuffertarget,
916 WGLWidget::Renderbuffer renderbuffer)
917 {
918 js_ << "ctx.framebufferRenderbuffer(" << toString(target) << ","
919 << toString(attachment) << "," << toString(renderbuffertarget) << ","
920 << renderbuffer.jsRef() << ");";
921 GLDEBUG;
922 }
923
framebufferTexture2D(WGLWidget::GLenum target,WGLWidget::GLenum attachment,WGLWidget::GLenum textarget,WGLWidget::Texture texture,int level)924 void WClientGLWidget::framebufferTexture2D(WGLWidget::GLenum target,
925 WGLWidget::GLenum attachment,
926 WGLWidget::GLenum textarget,
927 WGLWidget::Texture texture,
928 int level)
929 {
930 js_ << "ctx.framebufferTexture2D(" << toString(target) << ","
931 << toString(attachment) << "," << toString(textarget) << ","
932 << texture.jsRef() << "," << level << ");";
933 GLDEBUG;
934 }
935
frontFace(WGLWidget::GLenum mode)936 void WClientGLWidget::frontFace(WGLWidget::GLenum mode)
937 {
938 js_ << "ctx.frontFace(" << toString(mode) << ");";
939 GLDEBUG;
940 }
941
generateMipmap(WGLWidget::GLenum target)942 void WClientGLWidget::generateMipmap(WGLWidget::GLenum target)
943 {
944 js_ << "ctx.generateMipmap(" << toString(target) << ");";
945 GLDEBUG;
946 }
947
getAttribLocation(WGLWidget::Program program,const std::string & attrib)948 WGLWidget::AttribLocation WClientGLWidget::getAttribLocation(WGLWidget::Program program, const std::string &attrib)
949 {
950 WGLWidget::AttribLocation retval(attributes_++);
951 js_ << retval.jsRef() << "=ctx.getAttribLocation(" << program.jsRef()
952 << "," << WWebWidget::jsStringLiteral(attrib) << ");";
953 GLDEBUG;
954 return retval;
955 }
956
getUniformLocation(WGLWidget::Program program,const std::string & location)957 WGLWidget::UniformLocation WClientGLWidget::getUniformLocation(WGLWidget::Program program, const std::string &location)
958 {
959 WGLWidget::UniformLocation retval(uniforms_++);
960 js_ << retval.jsRef() << "=ctx.getUniformLocation(" << program.jsRef()
961 << "," << WWebWidget::jsStringLiteral(location) << ");";
962 GLDEBUG;
963 return retval;
964 }
965
hint(WGLWidget::GLenum target,WGLWidget::GLenum mode)966 void WClientGLWidget::hint(WGLWidget::GLenum target, WGLWidget::GLenum mode)
967 {
968 js_ << "ctx.hint(" << toString(target) << "," << toString(mode) << ");";
969 GLDEBUG;
970 }
971
lineWidth(double width)972 void WClientGLWidget::lineWidth(double width)
973 {
974 char buf[30];
975 if (!wApp->environment().agentIsIE())
976 js_ << "ctx.lineWidth(" << makeFloat(width, buf) << ");";
977 GLDEBUG;
978 }
979
linkProgram(WGLWidget::Program program)980 void WClientGLWidget::linkProgram(WGLWidget::Program program)
981 {
982 js_ << "ctx.linkProgram(" << program.jsRef() << ");";
983 js_ << "if(!ctx.getProgramParameter(" << program.jsRef()
984 << ",ctx.LINK_STATUS)){"
985 << "alert('Could not initialize shaders: ' + ctx.getProgramInfoLog("
986 << program.jsRef() << "));}";
987 GLDEBUG;
988 }
989
pixelStorei(WGLWidget::GLenum pname,int param)990 void WClientGLWidget::pixelStorei(WGLWidget::GLenum pname, int param)
991 {
992 js_ << "ctx.pixelStorei(" << toString(pname) << "," << param << ");";
993 GLDEBUG;
994 }
995
polygonOffset(double factor,double units)996 void WClientGLWidget::polygonOffset(double factor, double units) {
997 char buf[30];
998 js_ << "ctx.polygonOffset(" << makeFloat(factor, buf) << ",";
999 js_ << makeFloat(units, buf) << ");";
1000 GLDEBUG;
1001 }
1002
renderbufferStorage(WGLWidget::GLenum target,WGLWidget::GLenum internalformat,unsigned width,unsigned height)1003 void WClientGLWidget::renderbufferStorage(WGLWidget::GLenum target,
1004 WGLWidget::GLenum internalformat,
1005 unsigned width, unsigned height)
1006 {
1007 js_ << "ctx.renderbufferStorage(" << toString(target) << ","
1008 << toString(internalformat) << "," << width << "," << height << ");";
1009 GLDEBUG;
1010 }
1011
sampleCoverage(double value,bool invert)1012 void WClientGLWidget::sampleCoverage(double value, bool invert)
1013 {
1014 char buf[30];
1015 js_ << "ctx.sampleCoverage(" << makeFloat(value, buf) << ","
1016 << (invert ? "true" : "false") << ");";
1017 GLDEBUG;
1018 }
1019
scissor(int x,int y,unsigned width,unsigned height)1020 void WClientGLWidget::scissor(int x, int y, unsigned width, unsigned height)
1021 {
1022 js_ << "ctx.scissor(" << x << "," << y << ","
1023 << width << "," << height << ");";
1024 GLDEBUG;
1025 }
1026
shaderSource(WGLWidget::Shader shader,const std::string & src)1027 void WClientGLWidget::shaderSource(WGLWidget::Shader shader,
1028 const std::string &src)
1029 {
1030 js_ << "ctx.shaderSource(" << shader.jsRef() << ","
1031 << WWebWidget::jsStringLiteral(src) << ");";
1032 GLDEBUG;
1033 }
1034
stencilFunc(WGLWidget::GLenum func,int ref,unsigned mask)1035 void WClientGLWidget::stencilFunc(WGLWidget::GLenum func, int ref,
1036 unsigned mask)
1037 {
1038 js_ << "ctx.stencilFunc(" << toString(func) << "," << ref << "," << mask << ");";
1039 GLDEBUG;
1040 }
1041
stencilFuncSeparate(WGLWidget::GLenum face,WGLWidget::GLenum func,int ref,unsigned mask)1042 void WClientGLWidget::stencilFuncSeparate(WGLWidget::GLenum face,
1043 WGLWidget::GLenum func, int ref,
1044 unsigned mask)
1045 {
1046 js_ << "ctx.stencilFuncSeparate(" << toString(face) << "," << toString(func)
1047 << "," << ref << "," << mask << ");";
1048 GLDEBUG;
1049 }
1050
stencilMask(unsigned mask)1051 void WClientGLWidget::stencilMask(unsigned mask)
1052 {
1053 js_ << "ctx.stencilMask(" << mask << ");";
1054 GLDEBUG;
1055 }
1056
stencilMaskSeparate(WGLWidget::GLenum face,unsigned mask)1057 void WClientGLWidget::stencilMaskSeparate(WGLWidget::GLenum face, unsigned mask)
1058 {
1059 js_ << "ctx.stencilMaskSeparate(" << toString(face) << "," << mask << ");";
1060 GLDEBUG;
1061 }
1062
stencilOp(WGLWidget::GLenum fail,WGLWidget::GLenum zfail,WGLWidget::GLenum zpass)1063 void WClientGLWidget::stencilOp(WGLWidget::GLenum fail, WGLWidget::GLenum zfail,
1064 WGLWidget::GLenum zpass)
1065 {
1066 js_ << "ctx.stencilOp(" << toString(fail) << "," << toString(zfail) << ","
1067 << toString(zpass) << ");";
1068 GLDEBUG;
1069 }
1070
stencilOpSeparate(WGLWidget::GLenum face,WGLWidget::GLenum fail,WGLWidget::GLenum zfail,WGLWidget::GLenum zpass)1071 void WClientGLWidget::stencilOpSeparate(WGLWidget::GLenum face,
1072 WGLWidget::GLenum fail,
1073 WGLWidget::GLenum zfail,
1074 WGLWidget::GLenum zpass)
1075 {
1076 js_ << "ctx.stencilOpSeparate(" << toString(face) << ","
1077 << toString(fail) << "," << toString(zfail) << ","
1078 << toString(zpass) << ");";
1079 GLDEBUG;
1080 }
1081
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,unsigned width,unsigned height,int border,WGLWidget::GLenum format)1082 void WClientGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1083 WGLWidget::GLenum internalformat,
1084 unsigned width, unsigned height, int border,
1085 WGLWidget::GLenum format)
1086 {
1087 js_ << "ctx.texImage2D(" << toString(target) << "," << level << ","
1088 << toString(internalformat) << "," << width << "," << height << ","
1089 << border << "," << toString(format) << "," << toString(WGLWidget::UNSIGNED_BYTE)
1090 << ",null);";
1091 GLDEBUG;
1092 }
1093
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,WImage * image)1094 void WClientGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1095 WGLWidget::GLenum internalformat,
1096 WGLWidget::GLenum format,
1097 WGLWidget::GLenum type,
1098 WImage *image)
1099 {
1100 js_ << "ctx.texImage2D(" << toString(target) << "," << level << ","
1101 << toString(internalformat) << "," << toString(format) << "," << toString(type)
1102 << "," << image->jsRef() << ");";
1103 GLDEBUG;
1104 }
1105
1106
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,WVideo * video)1107 void WClientGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1108 WGLWidget::GLenum internalformat,
1109 WGLWidget::GLenum format,
1110 WGLWidget::GLenum type,
1111 WVideo *video)
1112 {
1113 js_ << "if (" << video->jsMediaRef()<< ")"
1114 " ctx.texImage2D(" << toString(target) << "," << level << ","
1115 << toString(internalformat) << "," << toString(format) << "," << toString(type)
1116 << "," << video->jsMediaRef() << ");";
1117 GLDEBUG;
1118 }
1119
1120 // // >>> Issues with CORS
1121 // void WClientGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1122 // WGLWidget::GLenum internalformat,
1123 // WGLWidget::GLenum format,
1124 // WGLWidget::GLenum type,
1125 // WLink *image)
1126 // {
1127 // unsigned imgNb = images_++;
1128 // preloadImages_.push_back(PreloadImage(currentlyBoundTexture_.jsRef(),
1129 // image->url(), imgNb));
1130
1131 // js_ << "ctx.texImage2D(" << toString(target) << "," << level << ","
1132 // << toString(internalformat) << "," << toString(format)
1133 // << "," << toString(type)
1134 // << "," << currentlyBoundTexture_.jsRef() << ".image" << imgNb << ");";
1135 // GLDEBUG;
1136 // }
1137
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,std::string image)1138 void WClientGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1139 WGLWidget::GLenum internalformat,
1140 WGLWidget::GLenum format,
1141 WGLWidget::GLenum type,
1142 std::string image)
1143 {
1144 unsigned imgNb = images_++;
1145 // note: does not necessarily have to be a png (also tested jpg)
1146 std::unique_ptr<WFileResource> imgFile(new WFileResource("image/png", image));
1147 preloadImages_.push_back(PreloadImage(currentlyBoundTexture_.jsRef(),
1148 imgFile->url(), imgNb));
1149 #ifndef WT_TARGET_JAVA
1150 addChild(std::move(imgFile));
1151 #endif // WT_TARGET_JAVA
1152
1153 js_ << "ctx.texImage2D(" << toString(target) << "," << level << ","
1154 << toString(internalformat) << "," << toString(format)
1155 << "," << toString(type)
1156 << "," << currentlyBoundTexture_.jsRef() << ".image" << imgNb << ");";
1157 GLDEBUG;
1158 }
1159
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,WPaintDevice * paintdevice)1160 void WClientGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1161 WGLWidget::GLenum internalformat,
1162 WGLWidget::GLenum format,
1163 WGLWidget::GLenum type,
1164 WPaintDevice *paintdevice)
1165 {
1166 unsigned imgNb = images_++;
1167 if (dynamic_cast<WCanvasPaintDevice*>(paintdevice) != nullptr) {
1168 WCanvasPaintDevice *cpd
1169 = dynamic_cast<WCanvasPaintDevice*>(paintdevice);
1170 std::string jsRef = currentlyBoundTexture_.jsRef() + "Canvas";
1171 js_ << jsRef << "=document.createElement('canvas');";
1172 js_ << jsRef << ".width=" << cpd->width().value() << ";";
1173 js_ << jsRef << ".height=" << cpd->height().value() << ";";
1174 js_ << "var f = function(myCanvas) {";
1175 cpd->renderPaintCommands(js_, "myCanvas");
1176 js_ << "};";
1177 js_ << "f(" << jsRef << ");";
1178 js_ << currentlyBoundTexture_.jsRef() << ".image" << imgNb << "=" << jsRef << ";";
1179 js_ << "delete " << jsRef << ";";
1180 }
1181 #ifdef WT_HAS_WRASTERIMAGE
1182 else if (dynamic_cast<WRasterImage*>(paintdevice) != nullptr) {
1183 WRasterImage *rpd = dynamic_cast<WRasterImage*>(paintdevice);
1184 rpd->done();
1185 std::unique_ptr<WResource> mr = rpdToMemResource(rpd);
1186 preloadImages_.push_back(PreloadImage(currentlyBoundTexture_.jsRef(),
1187 mr->url(), imgNb));
1188 #ifndef WT_TARGET_JAVA
1189 addChild(std::move(mr));
1190 #endif // WT_TARGET_JAVA
1191 }
1192 #endif
1193
1194 js_ << "ctx.texImage2D(" << toString(target) << "," << level << ","
1195 << toString(internalformat) << "," << toString(format)
1196 << "," << toString(type)
1197 << "," << currentlyBoundTexture_.jsRef() << ".image" << imgNb << ");";
1198 GLDEBUG;
1199 }
1200
1201 #ifndef WT_TARGET_JAVA
rpdToMemResource(WRasterImage * rpd)1202 std::unique_ptr<WResource> WClientGLWidget::rpdToMemResource(WRasterImage *rpd)
1203 {
1204 std::stringstream ss;
1205 rpd->write(ss);
1206 std::unique_ptr<WMemoryResource> mr(new WMemoryResource("image/png"));
1207 mr->setData(reinterpret_cast<const unsigned char*>(ss.str().c_str()),
1208 ss.str().size());
1209 return std::move(mr);
1210 }
1211 #endif
1212
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,WGLWidget::Texture texture)1213 void WClientGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1214 WGLWidget::GLenum internalformat,
1215 WGLWidget::GLenum format,
1216 WGLWidget::GLenum type,
1217 WGLWidget::Texture texture)
1218 {
1219 js_ << "ctx.texImage2D(" << toString(target) << "," << level << ","
1220 << toString(internalformat) << "," << toString(format)
1221 << "," << toString(type)
1222 << "," << texture.jsRef() << ".image0);";
1223 GLDEBUG;
1224 }
1225
texParameteri(WGLWidget::GLenum target,WGLWidget::GLenum pname,WGLWidget::GLenum param)1226 void WClientGLWidget::texParameteri(WGLWidget::GLenum target,
1227 WGLWidget::GLenum pname,
1228 WGLWidget::GLenum param)
1229 {
1230 js_ << "ctx.texParameteri(" << toString(target) << "," << toString(pname)
1231 << "," << toString(param) << ");";
1232 GLDEBUG;
1233 }
1234
uniform1f(const WGLWidget::UniformLocation & location,double x)1235 void WClientGLWidget::uniform1f(const WGLWidget::UniformLocation &location,
1236 double x)
1237 {
1238 char buf[30];
1239 js_ << "ctx.uniform1f(" << location.jsRef()
1240 << "," << makeFloat(x, buf) << ");";
1241 GLDEBUG;
1242 }
1243
uniform1fv(const WGLWidget::UniformLocation & location,const WT_ARRAY float * value)1244 void WClientGLWidget::uniform1fv(const WGLWidget::UniformLocation &location,
1245 const WT_ARRAY float *value)
1246 {
1247 js_ << "ctx.uniform1fv(" << location.jsRef() << ",";
1248 renderfv(js_, value, 1, JsArrayType::Float32Array);
1249 js_ << ");";
1250 GLDEBUG;
1251 }
1252
uniform1fv(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptVector & v)1253 void WClientGLWidget::uniform1fv(const WGLWidget::UniformLocation &location,
1254 const WGLWidget::JavaScriptVector &v)
1255 {
1256 js_ << "ctx.uniform1fv(" << location.jsRef() << ","
1257 << v.jsRef() << ");";
1258 GLDEBUG;
1259 }
1260
uniform1i(const WGLWidget::UniformLocation & location,int x)1261 void WClientGLWidget::uniform1i(const WGLWidget::UniformLocation &location,
1262 int x)
1263 {
1264 char buf[30];
1265 js_ << "ctx.uniform1i(" << location.jsRef() << ",";
1266 js_ << makeInt(x, buf) << ");";
1267 GLDEBUG;
1268 }
1269
uniform1iv(const WGLWidget::UniformLocation & location,const WT_ARRAY int * value)1270 void WClientGLWidget::uniform1iv(const WGLWidget::UniformLocation &location,
1271 const WT_ARRAY int *value)
1272 {
1273 js_ << "ctx.uniform1iv(" << location.jsRef() << ",";
1274 renderiv(js_, value, 1, WGLWidget::INT);
1275 js_ << ");";
1276 GLDEBUG;
1277 }
1278
uniform2f(const WGLWidget::UniformLocation & location,double x,double y)1279 void WClientGLWidget::uniform2f(const WGLWidget::UniformLocation &location,
1280 double x, double y)
1281 {
1282 char buf[30];
1283 js_ << "ctx.uniform2f(" << location.jsRef() << ",";
1284 js_ << makeFloat(x, buf) << ",";
1285 js_ << makeFloat(y, buf) << ");";
1286 GLDEBUG;
1287 }
1288
uniform2fv(const WGLWidget::UniformLocation & location,const WT_ARRAY float * value)1289 void WClientGLWidget::uniform2fv(const WGLWidget::UniformLocation &location,
1290 const WT_ARRAY float *value)
1291 {
1292 js_ << "ctx.uniform2fv(" << location.jsRef() << ",";
1293 renderfv(js_, value, 2, JsArrayType::Float32Array);
1294 js_ << ");";
1295 GLDEBUG;
1296 }
1297
uniform2fv(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptVector & v)1298 void WClientGLWidget::uniform2fv(const WGLWidget::UniformLocation &location,
1299 const WGLWidget::JavaScriptVector &v)
1300 {
1301 js_ << "ctx.uniform2fv(" << location.jsRef() << ","
1302 << v.jsRef() << ");";
1303 GLDEBUG;
1304 }
1305
uniform2i(const WGLWidget::UniformLocation & location,int x,int y)1306 void WClientGLWidget::uniform2i(const WGLWidget::UniformLocation &location,
1307 int x, int y)
1308 {
1309 char buf[30];
1310 js_ << "ctx.uniform2i(" << location.jsRef() << ",";
1311 js_ << makeInt(x, buf) << ",";
1312 js_ << makeInt(y, buf) << ");";
1313 GLDEBUG;
1314 }
1315
uniform2iv(const WGLWidget::UniformLocation & location,const WT_ARRAY int * value)1316 void WClientGLWidget::uniform2iv(const WGLWidget::UniformLocation &location,
1317 const WT_ARRAY int *value)
1318 {
1319 js_ << "ctx.uniform2iv(" << location.jsRef() << ",";
1320 renderiv(js_, value, 2, WGLWidget::INT);
1321 js_ << ");";
1322 GLDEBUG;
1323 }
1324
uniform3f(const WGLWidget::UniformLocation & location,double x,double y,double z)1325 void WClientGLWidget::uniform3f(const WGLWidget::UniformLocation &location,
1326 double x, double y, double z)
1327 {
1328 char buf[30];
1329 js_ << "ctx.uniform3f(" << location.jsRef() << ",";
1330 js_ << makeFloat(x, buf) << ",";
1331 js_ << makeFloat(y, buf) << ",";
1332 js_ << makeFloat(z, buf) << ");";
1333 GLDEBUG;
1334 }
1335
uniform3fv(const WGLWidget::UniformLocation & location,const WT_ARRAY float * value)1336 void WClientGLWidget::uniform3fv(const WGLWidget::UniformLocation &location,
1337 const WT_ARRAY float *value)
1338 {
1339 js_ << "ctx.uniform3fv(" << location.jsRef() << ",";
1340 renderfv(js_, value, 3, JsArrayType::Float32Array);
1341 js_ << ");";
1342 GLDEBUG;
1343 }
1344
uniform3fv(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptVector & v)1345 void WClientGLWidget::uniform3fv(const WGLWidget::UniformLocation &location,
1346 const WGLWidget::JavaScriptVector &v)
1347 {
1348 js_ << "ctx.uniform3fv(" << location.jsRef() << ","
1349 << v.jsRef() << ");";
1350 GLDEBUG;
1351 }
1352
uniform3i(const WGLWidget::UniformLocation & location,int x,int y,int z)1353 void WClientGLWidget::uniform3i(const WGLWidget::UniformLocation &location,
1354 int x, int y, int z)
1355 {
1356 char buf[30];
1357 js_ << "ctx.uniform3i(" << location.jsRef() << ",";
1358 js_ << makeInt(x, buf) << ",";
1359 js_ << makeInt(y, buf) << ",";
1360 js_ << makeInt(z, buf) << ");";
1361 GLDEBUG;
1362 }
1363
uniform3iv(const WGLWidget::UniformLocation & location,const WT_ARRAY int * value)1364 void WClientGLWidget::uniform3iv(const WGLWidget::UniformLocation &location,
1365 const WT_ARRAY int *value)
1366 {
1367 js_ << "ctx.uniform3iv(" << location.jsRef() << ",";
1368 renderiv(js_, value, 3, WGLWidget::INT);
1369 js_ << ");";
1370 GLDEBUG;
1371 }
1372
uniform4f(const WGLWidget::UniformLocation & location,double x,double y,double z,double w)1373 void WClientGLWidget::uniform4f(const WGLWidget::UniformLocation &location,
1374 double x, double y, double z, double w)
1375 {
1376 char buf[30];
1377 js_ << "ctx.uniform4f(" << location.jsRef() << ",";
1378 js_ << makeFloat(x, buf) << ",";
1379 js_ << makeFloat(y, buf) << ",";
1380 js_ << makeFloat(z, buf) << ",";
1381 js_ << makeFloat(w, buf) << ");";
1382 GLDEBUG;
1383 }
1384
uniform4fv(const WGLWidget::UniformLocation & location,const WT_ARRAY float * value)1385 void WClientGLWidget::uniform4fv(const WGLWidget::UniformLocation &location,
1386 const WT_ARRAY float *value)
1387 {
1388 js_ << "ctx.uniform4fv(" << location.jsRef() << ",";
1389 renderfv(js_, value, 4, JsArrayType::Float32Array);
1390 js_ << ");";
1391 GLDEBUG;
1392 }
1393
uniform4fv(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptVector & v)1394 void WClientGLWidget::uniform4fv(const WGLWidget::UniformLocation &location,
1395 const WGLWidget::JavaScriptVector &v)
1396 {
1397 js_ << "ctx.uniform4fv(" << location.jsRef() << ","
1398 << v.jsRef() << ");";
1399 GLDEBUG;
1400 }
1401
uniform4i(const WGLWidget::UniformLocation & location,int x,int y,int z,int w)1402 void WClientGLWidget::uniform4i(const WGLWidget::UniformLocation &location,
1403 int x, int y, int z, int w)
1404 {
1405 char buf[30];
1406 js_ << "ctx.uniform4i(" << location.jsRef() << ",";
1407 js_ << makeInt(x, buf) << ",";
1408 js_ << makeInt(y, buf) << ",";
1409 js_ << makeInt(z, buf) << ",";
1410 js_ << makeInt(w, buf) << ");";
1411 GLDEBUG;
1412 }
1413
uniform4iv(const WGLWidget::UniformLocation & location,const WT_ARRAY int * value)1414 void WClientGLWidget::uniform4iv(const WGLWidget::UniformLocation &location,
1415 const WT_ARRAY int *value)
1416 {
1417 js_ << "ctx.uniform4iv(" << location.jsRef() << ",";
1418 renderiv(js_, value, 4, WGLWidget::INT);
1419 js_ << ");";
1420 GLDEBUG;
1421 }
1422
uniformMatrix2fv(const WGLWidget::UniformLocation & location,bool transpose,const WT_ARRAY double * value)1423 void WClientGLWidget::uniformMatrix2fv(const WGLWidget::UniformLocation &location,
1424 bool transpose,
1425 const WT_ARRAY double *value)
1426 {
1427 js_ << "ctx.uniformMatrix2fv(" << location.jsRef() << ","
1428 << (transpose?"true":"false") << ",";
1429 renderfv(js_, value, 4, JsArrayType::Float32Array);
1430 js_ << ");";
1431 GLDEBUG;
1432 }
1433
uniformMatrix2(const WGLWidget::UniformLocation & location,const WGenericMatrix<double,2,2> & m)1434 void WClientGLWidget::uniformMatrix2(const WGLWidget::UniformLocation &location,
1435 const WGenericMatrix<double, 2, 2> &m)
1436 {
1437 js_ << "ctx.uniformMatrix2fv(" << location.jsRef() << ",false,";
1438 WGenericMatrix<double, 2, 2> t(m.transposed());
1439 renderfv(js_, t, JsArrayType::Float32Array);
1440 js_ << ");";
1441 GLDEBUG;
1442 }
1443
uniformMatrix3fv(const WGLWidget::UniformLocation & location,bool transpose,const WT_ARRAY double * value)1444 void WClientGLWidget::uniformMatrix3fv(const WGLWidget::UniformLocation &location,
1445 bool transpose,
1446 const WT_ARRAY double *value)
1447 {
1448 js_ << "ctx.uniformMatrix3fv(" << location.jsRef() << ","
1449 << (transpose?"true":"false") << ",";
1450 renderfv(js_, value, 9, JsArrayType::Float32Array);
1451 js_ << ");";
1452 GLDEBUG;
1453 }
1454
uniformMatrix3(const WGLWidget::UniformLocation & location,const WGenericMatrix<double,3,3> & m)1455 void WClientGLWidget::uniformMatrix3(const WGLWidget::UniformLocation &location,
1456 const WGenericMatrix<double, 3, 3> &m)
1457 {
1458 js_ << "ctx.uniformMatrix3fv(" << location.jsRef() << ",false,";
1459 WGenericMatrix<double, 3, 3> t(m.transposed());
1460 renderfv(js_, t, JsArrayType::Float32Array);
1461 js_ << ");";
1462 GLDEBUG;
1463 }
1464
uniformMatrix4fv(const WGLWidget::UniformLocation & location,bool transpose,const WT_ARRAY double * value)1465 void WClientGLWidget::uniformMatrix4fv(const WGLWidget::UniformLocation &location,
1466 bool transpose,
1467 const WT_ARRAY double *value)
1468 {
1469 js_ << "ctx.uniformMatrix4fv(" << location.jsRef() << ","
1470 << (transpose?"true":"false") << ",";
1471 renderfv(js_, value, 16, JsArrayType::Float32Array);
1472 js_ << ");";
1473 GLDEBUG;
1474 }
1475
uniformMatrix4(const WGLWidget::UniformLocation & location,const WGenericMatrix<double,4,4> & m)1476 void WClientGLWidget::uniformMatrix4(const WGLWidget::UniformLocation &location,
1477 const WGenericMatrix<double, 4, 4> &m) {
1478 js_ << "ctx.uniformMatrix4fv(" << location.jsRef() << ",false,";
1479 js_ << "new Float32Array([";
1480 char buf[30];
1481 for (int i = 0; i < 4; i++) {
1482 for (int j = 0; j < 4; j++) { // col-major
1483 js_ << ((i == 0 && j == 0) ? "" : ",") << makeFloat(m.at(j, i), buf);
1484 }
1485 }
1486 js_ << "])";
1487 js_ << ");";
1488 GLDEBUG;
1489 }
1490
uniformMatrix4(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptMatrix4x4 & m)1491 void WClientGLWidget::uniformMatrix4(const WGLWidget::UniformLocation &location,
1492 const WGLWidget::JavaScriptMatrix4x4 &m)
1493 {
1494 js_ << "ctx.uniformMatrix4fv(" << location.jsRef() << ",false,";
1495 js_ << m.jsRef() << ");";
1496 GLDEBUG;
1497 }
1498
useProgram(WGLWidget::Program program)1499 void WClientGLWidget::useProgram(WGLWidget::Program program)
1500 {
1501 js_ << "ctx.useProgram(" << program.jsRef() << ");";
1502 GLDEBUG;
1503 }
1504
validateProgram(WGLWidget::Program program)1505 void WClientGLWidget::validateProgram(WGLWidget::Program program)
1506 {
1507 js_ << "ctx.validateProgram(" << program.jsRef() << ");";
1508 GLDEBUG;
1509 }
1510
vertexAttrib1f(WGLWidget::AttribLocation location,double x)1511 void WClientGLWidget::vertexAttrib1f(WGLWidget::AttribLocation location, double x)
1512 {
1513 char buf[30];
1514 js_ << "ctx.vertexAttrib1f(" << location.jsRef() << ",";
1515 js_ << makeFloat(x, buf) << ");";
1516 GLDEBUG;
1517 }
1518
vertexAttrib2f(WGLWidget::AttribLocation location,double x,double y)1519 void WClientGLWidget::vertexAttrib2f(WGLWidget::AttribLocation location,
1520 double x, double y)
1521 {
1522 char buf[30];
1523 js_ << "ctx.vertexAttrib2f(" << location.jsRef() << ",";
1524 js_ << makeFloat(x, buf) << ",";
1525 js_ << makeFloat(y, buf) << ");";
1526 GLDEBUG;
1527 }
1528
vertexAttrib3f(WGLWidget::AttribLocation location,double x,double y,double z)1529 void WClientGLWidget::vertexAttrib3f(WGLWidget::AttribLocation location,
1530 double x, double y, double z)
1531 {
1532 char buf[30];
1533 js_ << "ctx.vertexAttrib3f(" << location.jsRef() << ",";
1534 js_ << makeFloat(x, buf) << ",";
1535 js_ << makeFloat(y, buf) << ",";
1536 js_ << makeFloat(z, buf) << ");";
1537 GLDEBUG;
1538 }
1539
vertexAttrib4f(WGLWidget::AttribLocation location,double x,double y,double z,double w)1540 void WClientGLWidget::vertexAttrib4f(WGLWidget::AttribLocation location,
1541 double x, double y, double z, double w)
1542 {
1543 char buf[30];
1544 js_ << "ctx.vertexAttrib4f(" << location.jsRef() << ",";
1545 js_ << makeFloat(x, buf) << ",";
1546 js_ << makeFloat(y, buf) << ",";
1547 js_ << makeFloat(z, buf) << ",";
1548 js_ << makeFloat(w, buf) << ");";
1549 GLDEBUG;
1550 }
1551
vertexAttribPointer(WGLWidget::AttribLocation location,int size,WGLWidget::GLenum type,bool normalized,unsigned stride,unsigned offset)1552 void WClientGLWidget::vertexAttribPointer(WGLWidget::AttribLocation location,
1553 int size,
1554 WGLWidget::GLenum type,
1555 bool normalized,
1556 unsigned stride, unsigned offset)
1557 {
1558 js_ << "ctx.vertexAttribPointer(" << location.jsRef() << "," << size << "," << toString(type)
1559 << "," << (normalized?"true":"false") << "," << stride << "," << offset << ");";
1560 GLDEBUG;
1561 }
1562
viewport(int x,int y,unsigned width,unsigned height)1563 void WClientGLWidget::viewport(int x, int y, unsigned width, unsigned height)
1564 {
1565 js_ << "ctx.viewport(" << x << "," << y << "," << width << "," << height << ");";
1566 GLDEBUG;
1567 }
1568
initJavaScriptMatrix4(WGLWidget::JavaScriptMatrix4x4 & mat)1569 void WClientGLWidget::initJavaScriptMatrix4(WGLWidget::JavaScriptMatrix4x4 &mat)
1570 {
1571 if (!mat.hasContext())
1572 glInterface_->addJavaScriptMatrix4(mat);
1573 else if (mat.context_ != glInterface_)
1574 throw WException("JavaScriptMatrix4x4: associated WGLWidget is not equal to the WGLWidget it's being initialized in");
1575
1576 WGenericMatrix<double, 4, 4> m = mat.value();
1577 js_ << mat.jsRef() << "=";
1578 renderfv(js_, m, JsArrayType::Float32Array);
1579 js_ << ";";
1580
1581 mat.initialize();
1582 }
1583
setJavaScriptMatrix4(WGLWidget::JavaScriptMatrix4x4 & jsm,const WGenericMatrix<double,4,4> & m)1584 void WClientGLWidget::setJavaScriptMatrix4(WGLWidget::JavaScriptMatrix4x4 &jsm,
1585 const WGenericMatrix<double, 4, 4> &m)
1586 {
1587 js_ << WT_CLASS ".glMatrix.mat4.set(";
1588 WGenericMatrix<double, 4, 4> t(m.transposed());
1589 renderfv(js_, t, JsArrayType::Float32Array);
1590 js_ << ", " << jsm.jsRef() << ");";
1591 }
1592
initJavaScriptVector(WGLWidget::JavaScriptVector & vec)1593 void WClientGLWidget::initJavaScriptVector(WGLWidget::JavaScriptVector &vec)
1594 {
1595 if (!vec.hasContext())
1596 glInterface_->addJavaScriptVector(vec);
1597 else if (vec.context_ != glInterface_)
1598 throw WException("JavaScriptVector: associated WGLWidget is not equal to the WGLWidget it's being initialized in");
1599
1600 std::vector<float> v = vec.value();
1601 js_ << vec.jsRef() << "= new Float32Array([";
1602 for (unsigned i = 0; i < vec.length(); ++i) {
1603 std::string val;
1604 if (v[i] == std::numeric_limits<float>::infinity()) {
1605 val = "Infinity";
1606 } else if (v[i] == -std::numeric_limits<float>::infinity()) {
1607 val = "-Infinity";
1608 } else {
1609 val = std::to_string(v[i]);
1610 }
1611 if (i != 0)
1612 js_ << ",";
1613 js_ << val;
1614 }
1615 js_ << "]);";
1616
1617 vec.initialize();
1618 }
1619
setJavaScriptVector(WGLWidget::JavaScriptVector & jsv,const std::vector<float> & v)1620 void WClientGLWidget::setJavaScriptVector(WGLWidget::JavaScriptVector &jsv,
1621 const std::vector<float> &v)
1622 {
1623 if (jsv.length() != v.size())
1624 throw WException("Trying to set a JavaScriptVector with "
1625 "incompatible length!");
1626 for (unsigned i = 0; i < jsv.length(); ++i) {
1627 std::string val;
1628 if (v[i] == std::numeric_limits<float>::infinity()) {
1629 val = "Infinity";
1630 } else if (v[i] == -std::numeric_limits<float>::infinity()) {
1631 val = "-Infinity";
1632 } else {
1633 val = std::to_string(v[i]);
1634 }
1635 js_ << jsv.jsRef() << "[" << i << "] = " << val << ";";
1636 }
1637 }
1638
setClientSideMouseHandler(const std::string & handlerCode)1639 void WClientGLWidget::setClientSideMouseHandler(const std::string& handlerCode)
1640 {
1641 js_ << "obj.setMouseHandler(" << handlerCode << ");";
1642 }
1643
setClientSideLookAtHandler(const WGLWidget::JavaScriptMatrix4x4 & m,double centerX,double centerY,double centerZ,double uX,double uY,double uZ,double pitchRate,double yawRate)1644 void WClientGLWidget::setClientSideLookAtHandler(const WGLWidget::JavaScriptMatrix4x4 &m,
1645 double centerX, double centerY, double centerZ,
1646 double uX, double uY, double uZ,
1647 double pitchRate, double yawRate)
1648 {
1649 js_ << "obj.setMouseHandler(new obj.LookAtMouseHandler("
1650 << m.jsRef()
1651 << ",[" << centerX << "," << centerY << "," << centerZ << "],"
1652 << "[" << uX << "," << uY << "," << uZ << "],"
1653 << pitchRate << "," << yawRate << "));";
1654 }
1655
setClientSideWalkHandler(const WGLWidget::JavaScriptMatrix4x4 & m,double frontStep,double rotStep)1656 void WClientGLWidget::setClientSideWalkHandler(const WGLWidget::JavaScriptMatrix4x4 &m,
1657 double frontStep, double rotStep)
1658 {
1659 js_ << "obj.setMouseHandler(new obj.WalkMouseHandler("
1660 << m.jsRef() << ","
1661 << frontStep << "," << rotStep << "));";
1662 }
1663
arrayType()1664 JsArrayType WClientGLWidget::arrayType() const
1665 {
1666 return JsArrayType::Float32Array;
1667 }
1668
injectJS(const std::string & jsString)1669 void WClientGLWidget::injectJS(const std::string & jsString)
1670 {
1671 js_ << jsString;
1672 }
1673
restoreContext(const std::string & jsRef)1674 void WClientGLWidget::restoreContext(const std::string &jsRef)
1675 {
1676 std::stringstream tmp;
1677 tmp << "{var o = " << glObjJsRef(jsRef) << ";\n";
1678
1679 shaders_ = 0;
1680 programs_ = 0;
1681 attributes_ = 0;
1682 uniforms_ = 0;
1683 for (unsigned i = 0; i < buffers_; ++i) {
1684 tmp << "o.ctx.WtBuffer" << i << "=null;";
1685 }
1686 buffers_ = 0;
1687 arrayBuffers_ = 0;
1688
1689 framebuffers_ = 0;
1690 renderbuffers_ = 0;
1691 for (unsigned i = 0; i < textures_; ++i) {
1692 tmp << "o.ctx.WtTexture" << i << "=null;";
1693 }
1694 textures_ = 0;
1695 images_ = 0;
1696 canvas_ = 0;
1697
1698 initializeGL(jsRef, tmp);
1699 tmp << "o.initialized = false;}";
1700 WApplication::instance()->doJavaScript(tmp.str());
1701 }
1702
initializeGL(const std::string & jsRef,std::stringstream & ss)1703 void WClientGLWidget::initializeGL(const std::string &jsRef, std::stringstream &ss)
1704 {
1705 js_.str("");
1706 glInterface_->initializeGL();
1707 ss <<
1708 """o.initializeGL=function(){\n"
1709 """var obj=" << glObjJsRef(jsRef) << ";\n"
1710 """var ctx=obj.ctx; if(!ctx) return;\n" <<
1711 "" << js_.str() <<
1712 """obj.initialized = true;\n"
1713 // updates are queued until initialization is complete
1714 """var key;\n"
1715 """for(key in obj.updates) obj.updates[key]();\n"
1716 """obj.updates = new Array();\n"
1717 // Similar, resizeGL is not executed until initialized
1718 """obj.resizeGL();\n"
1719 "};\n";
1720 }
1721
render(const std::string & jsRef,WFlags<RenderFlag> flags)1722 void WClientGLWidget::render(const std::string& jsRef, WFlags<RenderFlag> flags)
1723 {
1724 if (flags.test(RenderFlag::Full)) {
1725 std::stringstream tmp;
1726 tmp <<
1727 "{\n"
1728 """var o = new " WT_CLASS ".WGLWidget(" << wApp->javaScriptClass() << "," << jsRef << ");\n"
1729 #ifndef WT_TARGET_JAVA
1730 """o.discoverContext(function(){" << webglNotAvailable_.createCall({})
1731 #else // WT_TARGET_JAVA
1732 """o.discoverContext(function(){" << webglNotAvailable_.createCall()
1733 #endif // WT_TARGET_JAVA
1734 << "}, "
1735 << (glInterface_->renderOptions_.test(GLRenderOption::AntiAliasing)
1736 ? "true" : "false") << ");\n";
1737
1738 initializeGL(jsRef, tmp);
1739 tmp << "}\n";
1740 WApplication::instance()->doJavaScript(tmp.str());
1741 }
1742
1743 if (updateGL_ || updateResizeGL_ || updatePaintGL_) {
1744 std::stringstream tmp;
1745 tmp <<
1746 "var o = " << glObjJsRef(jsRef) << ";\n"
1747 "if(o.ctx){\n";
1748 if (updateGL_) {
1749 js_.str("");
1750 glInterface_->updateGL();
1751 tmp << "var update =function(){\n"
1752 "var obj=" << glObjJsRef(jsRef) << ";\n"
1753 "var ctx=obj.ctx;if (!ctx) return;\n"
1754 << js_.str() << "\n};\n"
1755 // cannot execute updates before initializeGL is executed
1756 "o.updates.push(update);";
1757 }
1758 if (updateResizeGL_) {
1759 js_.str("");
1760 glInterface_->resizeGL(renderWidth_, renderHeight_);
1761 tmp << "o.resizeGL=function(){\n"
1762 "var obj=" << glObjJsRef(jsRef) << ";\n"
1763 "var ctx=obj.ctx;if (!ctx) return;\n"
1764 << js_.str() << "};";
1765 }
1766 if (updatePaintGL_) {
1767 js_.str("");
1768 glInterface_->paintGL();
1769 // TG: cannot overwrite paint before update is executed
1770 // therefore overwrite paintgl in a deferred function through the
1771 // tasks queue
1772 tmp << "var updatePaint = function(){\n";
1773 tmp << "var obj=" << glObjJsRef(jsRef) << ";\n";
1774
1775 tmp << "obj.paintGL=function(){\n"
1776 "var obj=" << glObjJsRef(jsRef) << ";\n"
1777 "var ctx=obj.ctx;if (!ctx) return;\n"
1778 << js_.str() << "};";
1779
1780 tmp << "};\n";
1781 tmp << "o.updates.push(updatePaint);";
1782
1783
1784 }
1785 js_.str("");
1786 // Make sure textures are loaded before we render
1787 tmp << "}\n";
1788
1789 // Preloading images and buffers
1790 const bool preloadingSomething = preloadImages_.size()>0 || preloadArrayBuffers_.size() >0;
1791
1792 if (preloadingSomething) {
1793 if (preloadImages_.size() > 0) {
1794 tmp <<
1795 "o.preloadingTextures++;"
1796 "new " << wApp->javaScriptClass() << "._p_.ImagePreloader([";
1797 for (unsigned i = 0; i < preloadImages_.size(); ++i) {
1798 if (i != 0)
1799 tmp << ',';
1800 tmp << '\'' << wApp->resolveRelativeUrl(preloadImages_[i].url) << '\'';
1801 }
1802 tmp <<
1803 "],function(images){\n"
1804 "var o=" << glObjJsRef(jsRef) << ";\n"
1805 "var ctx=null;\n"
1806 "if(o) ctx=o.ctx;\n"
1807 "if(ctx == null) return;\n";
1808 for (unsigned i = 0; i < preloadImages_.size(); ++i) {
1809 std::string texture = preloadImages_[i].jsRef;
1810 tmp << texture << "=ctx.createTexture();\n"
1811 << texture << ".image" << preloadImages_[i].id
1812 << "=images[" << i << "];\n";
1813 }
1814 tmp << "o.preloadingTextures--;\n"
1815 << "o.handlePreload();\n"
1816 << "});";
1817
1818 preloadImages_.clear();
1819 }
1820
1821 // now check for buffers to preload
1822 if (preloadArrayBuffers_.size() > 0) {
1823 tmp <<
1824 "o.preloadingBuffers++;"
1825 "new " << wApp->javaScriptClass() << "._p_.ArrayBufferPreloader([";
1826 for (unsigned i = 0; i < preloadArrayBuffers_.size(); ++i) {
1827 if (i != 0)
1828 tmp << ',';
1829 tmp << '\'' << preloadArrayBuffers_[i].url << '\'';
1830 }
1831 tmp <<
1832 "],function(bufferResources){\n"
1833 "var o=" << glObjJsRef(jsRef) << ";\n"
1834 "var ctx=null;\n"
1835 " if(o) ctx=o.ctx;\n"
1836 "if(ctx == null) return;\n";
1837 for (unsigned i = 0; i < preloadArrayBuffers_.size(); ++i) {
1838 std::string bufferResource = preloadArrayBuffers_[i].jsRef;
1839 // setup datatype
1840 tmp << bufferResource << " = ctx.createBuffer();";
1841 // set the data
1842 tmp << "if (bufferResources[" << i << "]==null){";
1843 tmp << bufferResource << ".data=[];\n";
1844 tmp << "}else{";
1845 tmp << bufferResource << ".data=bufferResources[" << i << "];\n";
1846 tmp << "}";
1847 }
1848 tmp << "o.preloadingBuffers--;"
1849 << "o.handlePreload();\n"
1850 << "});";
1851
1852 preloadArrayBuffers_.clear();
1853 }
1854 } else {
1855 // No textures or buffers to load - go and paint
1856 tmp << "o.handlePreload();";
1857 }
1858 WApplication::instance()->doJavaScript(tmp.str());
1859 updateGL_ = updatePaintGL_ = updateResizeGL_ = false;
1860 }
1861
1862 //repaintGL(GLClientSideRenderer::PAINT_GL | GLClientSideRenderer::RESIZE_GL);
1863 }
1864
glObjJsRef(const std::string & jsRef)1865 std::string WClientGLWidget::glObjJsRef(const std::string& jsRef)
1866 {
1867 return "(function(){"
1868 "var r = " + jsRef + ";"
1869 "var o = r ? r.wtObj : null;"
1870 "return o ? o : {ctx: null};"
1871 "})()";
1872 }
1873
1874 }
1875