1 #include "Wt/WApplication.h"
2 #include "Wt/WServerGLWidget.h"
3
4 #include "Wt/WClientGLWidget.h"
5 #include "Wt/WMemoryResource.h"
6 #include "Wt/WPainter.h"
7 #include "Wt/WRasterImage.h"
8 #include "Wt/WWebWidget.h"
9 #include "Wt/Http/Response.h"
10
11 #include <fstream>
12
13 #ifdef WT_WIN32
14 #define WIN32_GL
15 #define FRAMEBUFFER_RENDERING
16 #elif defined(__APPLE__)
17 #define APPLE_GL
18 #define FRAMEBUFFER_RENDERING
19 #else
20 #define X11_GL
21 #endif
22
23 #include <GL/glew.h>
24 #include <GL/gl.h>
25
26 #ifdef X11_GL
27 #include <X11/Xlib.h>
28 #include <X11/Xutil.h>
29 #include <GL/glx.h>
30
31 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
32 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
33
34 typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
35 #endif
36
37 #ifdef WIN32_GL
38 #include <GL/wglew.h>
39 #include <windows.h>
40 #endif
41
42 #ifdef APPLE_GL
43 #include <OpenGL/OpenGL.h>
44 #include <OpenGL/CGLCurrent.h>
45 #include <OpenGL/CGLRenderers.h>
46 #include <OpenGL/CGLTypes.h>
47 #include <OpenGL/OpenGL.h>
48 #endif
49
50 namespace {
51 GLenum serverGLenum(Wt::WGLWidget::GLenum e);
52 }
53
54 namespace Wt {
55
56 namespace {
57 class WGLImageResource final : public WMemoryResource {
58 public:
WGLImageResource()59 WGLImageResource() : WMemoryResource()
60 { }
61
handleRequest(const Http::Request & request,Http::Response & response)62 virtual void handleRequest(const Http::Request &request,
63 Http::Response &response) override
64 {
65 response.addHeader("Cache-Control", "max-age=60");
66 WMemoryResource::handleRequest(request, response);
67 }
68 };
69 }
70
71 class WServerGLWidgetImpl {
72 public:
73 WServerGLWidgetImpl(bool antialiasingEnabled);
74 ~WServerGLWidgetImpl();
75
76 void makeCurrent();
77 void unmakeCurrent();
78 void resize(int width, int height);
79 #ifdef FRAMEBUFFER_RENDERING
80 void initReadBuffer();
81 void setDrawBuffer();
82 void initializeRenderbuffers();
83 GLuint framebuffer() const;
84 GLuint renderbuffer() const;
85 GLuint depthbuffer() const;
86 #endif
87 private:
88 #ifdef WIN32_GL
89 HWND wnd_;
90 HDC hdc_;
91 HGLRC ctx_;
92 #endif
93 #ifdef X11_GL
94 Display *display_;
95 GLXContext ctx_;
96 // Window win_;
97 GLXPbuffer pbuffer_;
98 GLXFBConfig bestFbc_;
99 Colormap cmap_;
100 XVisualInfo *vi_;
101 XSetWindowAttributes swa_;
102 #endif
103 #ifdef APPLE_GL
104 CGLContextObj context_;
105 #endif
106 #ifdef FRAMEBUFFER_RENDERING
107 int width_, height_;
108 GLuint framebuffer_, renderbuffer_, depthbuffer_;
109 GLuint framebufferRead_, renderbufferRead_;
110 #endif
111 };
112
113 #ifdef X11_GL
WServerGLWidgetImpl(bool antialiasingEnabled)114 WServerGLWidgetImpl::WServerGLWidgetImpl(bool antialiasingEnabled):
115 display_(nullptr)
116 {
117 display_ = XOpenDisplay(nullptr);
118
119 if ( !display_ )
120 {
121 throw WException("WServerGLWidget.C: failed to open X display.\n");
122 }
123
124 int sampleBuffers;
125 int samples;
126 if (antialiasingEnabled) {
127 sampleBuffers = 1;
128 samples = 4;
129 } else {
130 sampleBuffers = 0;
131 samples = 0;
132 }
133
134 // Get a matching FB config
135 int visual_attribs[] =
136 {
137 GLX_X_RENDERABLE , True,
138 GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT,
139 GLX_RENDER_TYPE , GLX_RGBA_BIT,
140 GLX_X_VISUAL_TYPE , GLX_DIRECT_COLOR,
141 GLX_RED_SIZE , 8,
142 GLX_GREEN_SIZE , 8,
143 GLX_BLUE_SIZE , 8,
144 GLX_ALPHA_SIZE , 8,
145 GLX_DEPTH_SIZE , 24,
146 GLX_STENCIL_SIZE , 8,
147 GLX_DOUBLEBUFFER , True,
148 GLX_SAMPLE_BUFFERS , sampleBuffers,
149 GLX_SAMPLES , samples,
150 None
151 };
152
153 int fbcount;
154 GLXFBConfig *fbc = glXChooseFBConfig( display_, DefaultScreen( display_ ),
155 visual_attribs, &fbcount );
156 if ( !fbc )
157 {
158 XCloseDisplay( display_ );
159 throw WException("WServerGLWidget: Failed to retrieve framebuffer configuration.\n");
160 }
161
162 bestFbc_ = fbc[0];
163
164 // Be sure to free the FBConfig list allocated by glXChooseFBConfig()
165 XFree( fbc );
166
167 // NOTE: It is not necessary to create or make current to a context before
168 // calling glXGetProcAddressARB
169 glXCreateContextAttribsARBProc glXCreateContextAttribsARB = nullptr;
170 glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)
171 glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" );
172
173 int context_attribs[] =
174 {
175 GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
176 GLX_CONTEXT_MINOR_VERSION_ARB, 0,
177 None
178 };
179
180 ctx_ = glXCreateContextAttribsARB( display_, bestFbc_, nullptr,
181 True, context_attribs );
182
183 // Sync to ensure any errors generated are processed.
184 XSync( display_, False );
185 if ( ! ctx_ ) {
186 XCloseDisplay( display_ );
187 throw WException("WServerGLWidget: Failed to create an OpenGL context.\n");
188 }
189
190 int pbufferAttribs[] = {
191 GLX_PBUFFER_WIDTH, 600,
192 GLX_PBUFFER_HEIGHT, 600,
193 None
194 };
195 pbuffer_ = glXCreatePbuffer( display_, bestFbc_, pbufferAttribs );
196
197 // Sync to ensure any errors generated are processed.
198 XSync( display_, False );
199
200 if ( !pbuffer_ ) {
201 glXDestroyContext( display_, ctx_ );
202 XCloseDisplay( display_ );
203 throw WException("WServerGLWidget: Failed to create an OpenGL pBuffer.\n" );
204 }
205
206 glXMakeCurrent( display_, pbuffer_, ctx_ );
207 GLenum res = glewInit();
208 if (res != GLEW_OK) {
209 glXDestroyContext( display_, ctx_ );
210 XCloseDisplay( display_ );
211 glXMakeCurrent( display_, 0, nullptr );
212 throw WException("WServerGLWidget: problem with GLEW initialization.\n");
213 }
214 glEnable(GL_PROGRAM_POINT_SIZE);
215 glEnable(GL_POINT_SPRITE);
216 glXMakeCurrent( display_, 0, nullptr );
217 }
218
~WServerGLWidgetImpl()219 WServerGLWidgetImpl::~WServerGLWidgetImpl()
220 {
221 glXDestroyContext( display_, ctx_ );
222 XCloseDisplay( display_ );
223 }
224
makeCurrent()225 void WServerGLWidgetImpl::makeCurrent()
226 {
227 glXMakeCurrent(display_, pbuffer_, ctx_);
228 }
229
unmakeCurrent()230 void WServerGLWidgetImpl::unmakeCurrent()
231 {
232 glXMakeCurrent(display_, 0, nullptr);
233 }
234
resize(int width,int height)235 void WServerGLWidgetImpl::resize(int width, int height)
236 {
237 glXDestroyPbuffer(display_, pbuffer_);
238 int pbufferAttribs[] = {
239 GLX_PBUFFER_WIDTH, width,
240 GLX_PBUFFER_HEIGHT, height,
241 None
242 };
243 pbuffer_ = glXCreatePbuffer(display_, bestFbc_, pbufferAttribs);
244 // resize X-window
245 // XResizeWindow(display_, win_, (uint)renderWidth_, (uint)renderHeight_);
246 }
247 #endif
248
249 #ifdef APPLE_GL
WServerGLWidgetImpl(bool antialiasingEnabled)250 WServerGLWidgetImpl::WServerGLWidgetImpl(bool antialiasingEnabled):
251 width_(0),
252 height_(0),
253 framebuffer_(-1)
254 {
255 CGLPixelFormatAttribute attributes[4] = {
256 kCGLPFAAccelerated, // no software rendering
257 kCGLPFAOpenGLProfile, // core profile with the version stated below
258 (CGLPixelFormatAttribute) kCGLOGLPVersion_Legacy,
259 // (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
260 (CGLPixelFormatAttribute) 0
261 };
262 CGLPixelFormatObj pix;
263 CGLError errorCode;
264 GLint num; // stores the number of possible pixel formats
265 CGLError err;
266
267 err = CGLChoosePixelFormat(attributes, &pix, &num);
268 if (err != kCGLNoError) {
269 throw WException("WServerGLWidget cannot select proper pixel format: "
270 + std::to_string(err));
271 }
272
273 err = CGLCreateContext(pix, NULL, &context_);
274 CGLDestroyPixelFormat(pix);
275 if (err != kCGLNoError) {
276 throw WException("WServerGLWidget cannot create context"
277 + std::to_string(err));
278 }
279
280 makeCurrent();
281
282 // Experimental or glew doesn't work with core profile >= 3.2
283 glewExperimental = 1;
284 GLenum res = glewInit();
285 if (res == GLEW_OK && GLEW_ARB_framebuffer_object) {
286 initializeRenderbuffers();
287 } else {
288 unmakeCurrent();
289 CGLSetCurrentContext(NULL);
290 CGLDestroyContext(context_);
291 throw WException("WServerGLWidget cannot create offscreen framebuffers "
292 + std::to_string(err));
293 }
294 }
295
~WServerGLWidgetImpl()296 WServerGLWidgetImpl::~WServerGLWidgetImpl()
297 {
298 CGLSetCurrentContext(NULL);
299 CGLDestroyContext(context_);
300 }
301
makeCurrent()302 void WServerGLWidgetImpl::makeCurrent()
303 {
304 CGLError err = CGLSetCurrentContext(context_);
305 if (err != kCGLNoError) {
306 throw WException("WServerGLWidget cannot make context active"
307 + std::to_string(err));
308 }
309 }
310
unmakeCurrent()311 void WServerGLWidgetImpl::unmakeCurrent()
312 {
313 CGLSetCurrentContext(NULL);
314 }
315 #endif
316
317 #ifdef WIN32_GL
WServerGLWidgetImpl(bool antialiasingEnabled)318 WServerGLWidgetImpl::WServerGLWidgetImpl(bool antialiasingEnabled)
319 : framebuffer_(-1)
320 {
321 // Window properties
322 WNDCLASSEX wndClass;
323 wndClass.cbSize = sizeof(WNDCLASSEX);
324 wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
325 wndClass.lpfnWndProc = DefWindowProc;
326 wndClass.cbClsExtra = 0;
327 wndClass.cbWndExtra = 0;
328 wndClass.hInstance = 0;
329 wndClass.hIcon = 0;
330 wndClass.hCursor = LoadCursor(0, IDC_ARROW);
331 wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
332 wndClass.lpszMenuName = 0;
333 wndClass.lpszClassName = "WndClass";
334 wndClass.hIconSm = 0;
335 RegisterClassEx(&wndClass);
336
337 // Window decorations are substracted from the size of the drawable area,
338 // which is not what we want, so disable them completely.
339 DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP;
340 // Create the window. Position and size it.
341 wnd_ = CreateWindowEx(0,
342 "WndClass",
343 "",
344 style,
345 CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
346 0, 0, 0, 0);
347 // comment out line below to show server side render window
348 //ShowWindow(wnd_, SW_SHOW);
349 hdc_ = GetDC(wnd_);
350
351 PIXELFORMATDESCRIPTOR pfd;
352 memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
353 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
354 pfd.nVersion = 1;
355 pfd.dwFlags = /*PFD_DOUBLEBUFFER |*/ PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
356 pfd.iPixelType = PFD_TYPE_RGBA;
357 pfd.cColorBits = 32;
358 pfd.cDepthBits = 32;
359 pfd.iLayerType = PFD_MAIN_PLANE;
360 pfd.iPixelType = PFD_TYPE_RGBA;
361
362 int pixelFormat = ChoosePixelFormat(hdc_, &pfd);
363 if (pixelFormat == 0)
364 throw WException("WServerGLWidget: Failed to find suitable pixel format.\n" );
365
366 BOOL bResult = SetPixelFormat (hdc_, pixelFormat, &pfd);
367
368 if (!bResult)
369 throw WException("WServerGLWidget: Failed to set suitable pixel format.\n" );
370
371 HGLRC tempContext = wglCreateContext(hdc_);
372 wglMakeCurrent(hdc_, tempContext);
373
374 GLenum err = glewInit();
375
376 if (GLEW_OK != err)
377 throw WException("WServerGLWidget: GLEW failed to initialize.\n" );
378
379 int attribs[] = {
380 WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
381 WGL_CONTEXT_MINOR_VERSION_ARB, 1,
382 WGL_CONTEXT_FLAGS_ARB, 0,
383 0
384 };
385
386 int sampleBuffersARB = antialiasingEnabled ? GL_TRUE : GL_FALSE;
387
388 // check for anti-aliasing
389 if (wglewIsSupported("WGL_ARB_multisample") == 1) {
390 float fAttributes[] = {0,0};
391 int iAttributes[] = {
392 WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
393 WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
394 WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
395 WGL_COLOR_BITS_ARB,24,
396 WGL_ALPHA_BITS_ARB,8,
397 WGL_DEPTH_BITS_ARB,16,
398 WGL_STENCIL_BITS_ARB,0,
399 //WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
400 WGL_SAMPLE_BUFFERS_ARB,sampleBuffersARB,
401 WGL_SAMPLES_ARB, 2,
402 0,0};
403 int newPixelFormat;
404 UINT numFormats;
405 bool valid = wglChoosePixelFormatARB(hdc_, iAttributes, fAttributes, 1, &newPixelFormat, &numFormats);
406 if (valid && numFormats > 1) {
407 pixelFormat = newPixelFormat;
408
409 // D'oh! we have to re-create the window (cannot change pixel format)
410 // simply redo all the work
411 wglMakeCurrent(NULL, NULL);
412 wglDeleteContext(tempContext);
413 ReleaseDC(wnd_, hdc_);
414 DestroyWindow(wnd_);
415 wnd_ = CreateWindowEx(0,
416 "WndClass",
417 "",
418 style,
419 CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
420 0, 0, 0, 0);
421 // comment out line below to show server side render window
422 //ShowWindow(wnd_, SW_SHOW);
423 hdc_ = GetDC(wnd_);
424 BOOL bResult = SetPixelFormat (hdc_, pixelFormat, &pfd);
425 if (!bResult)
426 throw WException("WServerGLWidget: Failed to set multisample pixel format.\n" );
427 wglCreateContext(hdc_);
428 wglMakeCurrent(hdc_, tempContext);
429 }
430 }
431
432 if(wglewIsSupported("WGL_ARB_create_context") == 1) {
433 ctx_ = wglCreateContextAttribsARB(hdc_, 0, attribs);
434 wglMakeCurrent(NULL,NULL);
435 wglDeleteContext(tempContext);
436 wglMakeCurrent(hdc_, ctx_);
437 } else {
438 throw WException("WServerGLWidget: Failed to create a 3.x context.\n" );
439 }
440
441 glGenFramebuffers(1, &framebuffer_);
442 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
443 glGenRenderbuffers(1, &renderbuffer_);
444 glGenRenderbuffers(1, &depthbuffer_);
445 glGenFramebuffers(1, &framebufferRead_);
446 glBindFramebuffer(GL_FRAMEBUFFER, framebufferRead_);
447 glGenRenderbuffers(1, &renderbufferRead_);
448
449 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
450 unmakeCurrent();
451 resize(100, 100); // whatever
452 }
453
~WServerGLWidgetImpl()454 WServerGLWidgetImpl::~WServerGLWidgetImpl()
455 {
456 wglMakeCurrent(NULL, NULL);
457 if(ctx_) {
458 wglDeleteContext(ctx_);
459 ctx_ = 0;
460 }
461 ReleaseDC(wnd_, hdc_);
462 DestroyWindow(wnd_);
463 }
464
makeCurrent()465 void WServerGLWidgetImpl::makeCurrent()
466 {
467 if (!wglMakeCurrent(hdc_, ctx_))
468 throw WException("WServerGLWidget: makeCurrent() failed");
469 }
470
unmakeCurrent()471 void WServerGLWidgetImpl::unmakeCurrent()
472 {
473 if (!wglMakeCurrent(NULL,NULL))
474 throw WException("WServerGLWidget: unmakeCurrent() failed");
475
476 }
477 #endif
478
479 #ifdef FRAMEBUFFER_RENDERING
initializeRenderbuffers()480 void WServerGLWidgetImpl::initializeRenderbuffers()
481 {
482 glGenFramebuffers(1, &framebuffer_);
483 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
484 glGenRenderbuffers(1, &renderbuffer_);
485 glGenRenderbuffers(1, &depthbuffer_);
486 glGenFramebuffers(1, &framebufferRead_);
487 glBindFramebuffer(GL_FRAMEBUFFER, framebufferRead_);
488 glGenRenderbuffers(1, &renderbufferRead_);
489
490 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
491 unmakeCurrent();
492 resize(100, 100); // whatever
493 }
494
framebuffer()495 GLuint WServerGLWidgetImpl::framebuffer() const
496 {
497 return framebuffer_;
498 }
499
renderbuffer()500 GLuint WServerGLWidgetImpl::renderbuffer() const
501 {
502 return renderbuffer_;
503 }
504
depthbuffer()505 GLuint WServerGLWidgetImpl::depthbuffer() const
506 {
507 return depthbuffer_;
508 }
509
resize(int width,int height)510 void WServerGLWidgetImpl::resize(int width, int height)
511 {
512 if (width == width_ && height == height_)
513 return;
514 makeCurrent();
515 int status;
516 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_);
517 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, width, height);
518 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
519 GL_RENDERBUFFER, renderbuffer_);
520
521 glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer_);
522 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT, width, height);
523 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
524 GL_RENDERBUFFER, depthbuffer_);
525 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
526
527 glBindFramebuffer(GL_FRAMEBUFFER, framebufferRead_);
528 glBindRenderbuffer(GL_RENDERBUFFER, renderbufferRead_);
529 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
530 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
531 GL_RENDERBUFFER, renderbufferRead_);
532
533 glBindRenderbuffer(GL_RENDERBUFFER, 0);
534 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
535
536 unmakeCurrent();
537 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
538 throw WException("WServerGLWidget: resize failed\n");
539 width_ = width;
540 height_ = height;
541 }
542
initReadBuffer()543 void WServerGLWidgetImpl::initReadBuffer()
544 {
545 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer_);
546 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferRead_);
547 glBlitFramebuffer(0,0,width_,height_,0,0,width_,height_, GL_COLOR_BUFFER_BIT, GL_NEAREST);
548 glBindFramebufferEXT(GL_FRAMEBUFFER, framebufferRead_);
549 }
550
setDrawBuffer()551 void WServerGLWidgetImpl::setDrawBuffer()
552 {
553 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
554 }
555 #endif
556
WServerGLWidget(WGLWidget * glInterface)557 WServerGLWidget::WServerGLWidget(WGLWidget *glInterface)
558 : WAbstractGLImplementation(glInterface),
559 raster_(0),
560 memres_(new WGLImageResource())
561 {
562 try {
563 impl_ = new WServerGLWidgetImpl
564 (glInterface_->renderOptions_.test(GLRenderOption::AntiAliasing));
565 } catch (WException &e) {
566 delete memres_;
567 throw e;
568 }
569 }
570
~WServerGLWidget()571 WServerGLWidget::~WServerGLWidget()
572 {
573 delete raster_;
574 delete memres_;
575 delete impl_;
576 }
577
debugger()578 void WServerGLWidget::debugger()
579 {
580 // only functional in WClientGLWidget
581 }
582
activeTexture(WGLWidget::GLenum texture)583 void WServerGLWidget::activeTexture(WGLWidget::GLenum texture)
584 {
585 glActiveTexture(serverGLenum(texture));
586 SERVERGLDEBUG;
587 }
588
attachShader(WGLWidget::Program program,WGLWidget::Shader shader)589 void WServerGLWidget::attachShader(WGLWidget::Program program, WGLWidget::Shader shader)
590 {
591 glAttachShader(program.getId(), shader.getId());
592 SERVERGLDEBUG;
593 }
594
bindAttribLocation(WGLWidget::Program program,unsigned index,const std::string & name)595 void WServerGLWidget::bindAttribLocation(WGLWidget::Program program,
596 unsigned index,
597 const std::string &name)
598 {
599 glBindAttribLocation(program.getId(), index, name.c_str());
600 SERVERGLDEBUG;
601 }
602
bindBuffer(WGLWidget::GLenum target,WGLWidget::Buffer buffer)603 void WServerGLWidget::bindBuffer(WGLWidget::GLenum target, WGLWidget::Buffer buffer)
604 {
605 glBindBuffer(serverGLenum(target), buffer.getId());
606 SERVERGLDEBUG;
607 }
608
bindFramebuffer(WGLWidget::GLenum target,WGLWidget::Framebuffer buffer)609 void WServerGLWidget::bindFramebuffer(WGLWidget::GLenum target, WGLWidget::Framebuffer buffer)
610 {
611 if (buffer.isNull()) {
612 #ifdef FRAMEBUFFER_RENDERING
613 glBindFramebuffer(serverGLenum(target), impl_->framebuffer());
614 #else
615 glBindFramebuffer(serverGLenum(target), 0);
616 #endif
617 } else {
618 glBindFramebuffer(serverGLenum(target), buffer.getId());
619 }
620 SERVERGLDEBUG;
621 }
622
bindRenderbuffer(WGLWidget::GLenum target,WGLWidget::Renderbuffer buffer)623 void WServerGLWidget::bindRenderbuffer(WGLWidget::GLenum target, WGLWidget::Renderbuffer buffer)
624 {
625 if (buffer.isNull()) {
626 #ifdef FRAMEBUFFER_RENDERING
627 glBindRenderbuffer(serverGLenum(target), impl_->renderbuffer());
628 #else
629 glBindRenderbuffer(serverGLenum(target), 0);
630 #endif
631 } else {
632 glBindRenderbuffer(serverGLenum(target), buffer.getId());
633 }
634 SERVERGLDEBUG;
635 }
636
bindTexture(WGLWidget::GLenum target,WGLWidget::Texture texture)637 void WServerGLWidget::bindTexture(WGLWidget::GLenum target, WGLWidget::Texture texture)
638 {
639 glBindTexture(serverGLenum(target), texture.getId());
640 SERVERGLDEBUG;
641 }
642
blendColor(double red,double green,double blue,double alpha)643 void WServerGLWidget::blendColor(double red, double green, double blue, double alpha)
644 {
645 glBlendColor((GLfloat) red, (GLfloat) green, (GLfloat) blue, (GLfloat) alpha);
646 SERVERGLDEBUG;
647 }
648
blendEquation(WGLWidget::GLenum mode)649 void WServerGLWidget::blendEquation(WGLWidget::GLenum mode)
650 {
651 glBlendEquation(serverGLenum(mode));
652 SERVERGLDEBUG;
653 }
654
blendEquationSeparate(WGLWidget::GLenum modeRGB,WGLWidget::GLenum modeAlpha)655 void WServerGLWidget::blendEquationSeparate(WGLWidget::GLenum modeRGB,
656 WGLWidget::GLenum modeAlpha)
657 {
658 glBlendEquationSeparate(serverGLenum(modeRGB), serverGLenum(modeAlpha));
659 SERVERGLDEBUG;
660 }
661
blendFunc(WGLWidget::GLenum sfactor,WGLWidget::GLenum dfactor)662 void WServerGLWidget::blendFunc(WGLWidget::GLenum sfactor,
663 WGLWidget::GLenum dfactor)
664 {
665 glBlendFunc(serverGLenum(sfactor), serverGLenum(dfactor));
666 SERVERGLDEBUG;
667 }
668
blendFuncSeparate(WGLWidget::GLenum srcRGB,WGLWidget::GLenum dstRGB,WGLWidget::GLenum srcAlpha,WGLWidget::GLenum dstAlpha)669 void WServerGLWidget::blendFuncSeparate(WGLWidget::GLenum srcRGB,
670 WGLWidget::GLenum dstRGB,
671 WGLWidget::GLenum srcAlpha,
672 WGLWidget::GLenum dstAlpha)
673 {
674 glBlendFuncSeparate(serverGLenum(srcRGB), serverGLenum(dstRGB),
675 serverGLenum(srcAlpha), serverGLenum(dstAlpha));
676 SERVERGLDEBUG;
677 }
678
bufferData(WGLWidget::GLenum target,WGLWidget::ArrayBuffer res,unsigned bufferResourceOffset,unsigned bufferResourceSize,WGLWidget::GLenum usage)679 void WServerGLWidget::bufferData(WGLWidget::GLenum target,
680 WGLWidget::ArrayBuffer res,
681 unsigned bufferResourceOffset,
682 unsigned bufferResourceSize,
683 WGLWidget::GLenum usage)
684 {
685 throw WException("WServerGLWidget: this operation is not supported in server-side rendering");
686 }
687
bufferData(WGLWidget::GLenum target,WGLWidget::ArrayBuffer res,WGLWidget::GLenum usage)688 void WServerGLWidget::bufferData(WGLWidget::GLenum target,
689 WGLWidget::ArrayBuffer res,
690 WGLWidget::GLenum usage)
691 {
692 throw WException("WServerGLWidget: this operation is not supported in server-side rendering");
693 }
694
bufferSubData(Wt::WGLWidget::GLenum target,unsigned offset,WGLWidget::ArrayBuffer res)695 void WServerGLWidget::bufferSubData(Wt::WGLWidget::GLenum target,
696 unsigned offset,
697 WGLWidget::ArrayBuffer res)
698 {
699 throw WException("WServerGLWidget: this operation is not supported in server-side rendering");
700 }
701
bufferSubData(Wt::WGLWidget::GLenum target,unsigned offset,WGLWidget::ArrayBuffer res,unsigned bufferResourceOffset,unsigned bufferResourceSize)702 void WServerGLWidget::bufferSubData(Wt::WGLWidget::GLenum target,
703 unsigned offset,
704 WGLWidget::ArrayBuffer res,
705 unsigned bufferResourceOffset,
706 unsigned bufferResourceSize)
707 {
708 throw WException("WServerGLWidget: this operation is not supported in server-side rendering");
709 }
710
bufferData(WGLWidget::GLenum target,int size,WGLWidget::GLenum usage)711 void WServerGLWidget::bufferData(WGLWidget::GLenum target, int size,
712 WGLWidget::GLenum usage)
713 {
714 glBufferData(serverGLenum(target), (GLsizeiptr)size, 0, serverGLenum(usage));
715 SERVERGLDEBUG;
716 }
717
bufferDatafv(WGLWidget::GLenum target,const FloatBuffer & buffer,WGLWidget::GLenum usage,bool binary)718 void WServerGLWidget::bufferDatafv(WGLWidget::GLenum target, const FloatBuffer &buffer, WGLWidget::GLenum usage, bool binary)
719 {
720 glBufferData(serverGLenum(target), buffer.size()*4, &buffer[0],
721 serverGLenum(usage));
722 SERVERGLDEBUG;
723 }
724
bufferDataiv(WGLWidget::GLenum target,IntBuffer & buffer,WGLWidget::GLenum usage,WGLWidget::GLenum type)725 void WServerGLWidget::bufferDataiv(WGLWidget::GLenum target,
726 IntBuffer &buffer, WGLWidget::GLenum usage,
727 WGLWidget::GLenum type)
728 {
729 std::vector<short> shortbuffer;
730 for (unsigned i = 0; i < buffer.size(); i++) {
731 shortbuffer.push_back(buffer[i]);
732 }
733
734 glBufferData(serverGLenum(target), shortbuffer.size()*2, &shortbuffer[0],
735 serverGLenum(usage));
736 SERVERGLDEBUG;
737 }
738
bufferSubDatafv(WGLWidget::GLenum target,unsigned offset,const FloatBuffer & buffer,bool binary)739 void WServerGLWidget::bufferSubDatafv(WGLWidget::GLenum target, unsigned offset,
740 const FloatBuffer &buffer, bool binary)
741 {
742 glBufferSubData(serverGLenum(target), (GLintptr)offset, buffer.size()*4,
743 &buffer[0]);
744 }
745
bufferSubDataiv(WGLWidget::GLenum target,unsigned offset,IntBuffer & buffer,WGLWidget::GLenum type)746 void WServerGLWidget::bufferSubDataiv(WGLWidget::GLenum target,
747 unsigned offset, IntBuffer &buffer,
748 WGLWidget::GLenum type)
749 {
750 std::vector<short> shortbuffer;
751 for (unsigned i = 0; i < buffer.size(); i++) {
752 shortbuffer.push_back(buffer[i]);
753 }
754
755 glBufferSubData(serverGLenum(target), offset, buffer.size()*2,
756 &shortbuffer[0]);
757 SERVERGLDEBUG;
758 }
759
clear(WFlags<WGLWidget::GLenum> mask)760 void WServerGLWidget::clear(WFlags<WGLWidget::GLenum> mask)
761 {
762 GLbitfield glmask = 0;
763 if (mask.test(WGLWidget::COLOR_BUFFER_BIT))
764 glmask |= GL_COLOR_BUFFER_BIT;
765 if (mask.test(WGLWidget::DEPTH_BUFFER_BIT))
766 glmask |= GL_DEPTH_BUFFER_BIT;
767 if (mask.test(WGLWidget::STENCIL_BUFFER_BIT))
768 glmask |= GL_STENCIL_BUFFER_BIT;
769
770 glClear(glmask);
771 SERVERGLDEBUG;
772 }
773
clearColor(double r,double g,double b,double a)774 void WServerGLWidget::clearColor(double r, double g, double b, double a)
775 {
776 glClearColor((float)r, (float)g, (float)b, (float)a);
777 SERVERGLDEBUG;
778 }
779
clearDepth(double depth)780 void WServerGLWidget::clearDepth(double depth)
781 {
782 glClearDepth(depth);
783 SERVERGLDEBUG;
784 }
785
clearStencil(int s)786 void WServerGLWidget::clearStencil(int s)
787 {
788 glClearStencil(s);
789 SERVERGLDEBUG;
790 }
791
colorMask(bool red,bool green,bool blue,bool alpha)792 void WServerGLWidget::colorMask(bool red, bool green, bool blue, bool alpha)
793 {
794 glColorMask(red, green, blue, alpha);
795 SERVERGLDEBUG;
796 }
797
compileShader(WGLWidget::Shader shader)798 void WServerGLWidget::compileShader(WGLWidget::Shader shader)
799 {
800 glCompileShader(shader.getId());
801 SERVERGLDEBUG;
802 GLint params = 0;
803 glGetShaderiv(shader.getId(), GL_COMPILE_STATUS, ¶ms);
804 if (params != GL_TRUE) {
805 std::cerr << "Shader " << shader.getId() << " compilation failed" << std::endl;
806 char buffer[32*1024];
807 glGetShaderInfoLog(shader.getId(), sizeof(buffer), nullptr, buffer);
808 std::cerr << buffer << std::endl;
809 }
810 SERVERGLDEBUG;
811 }
812
copyTexImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalFormat,int x,int y,unsigned width,unsigned height,int border)813 void WServerGLWidget::copyTexImage2D(WGLWidget::GLenum target, int level,
814 WGLWidget::GLenum internalFormat,
815 int x, int y,
816 unsigned width, unsigned height,
817 int border)
818 {
819 glCopyTexImage2D(serverGLenum(target), level, serverGLenum(internalFormat),
820 x, y, width, height, border);
821 SERVERGLDEBUG;
822 }
823
copyTexSubImage2D(WGLWidget::GLenum target,int level,int xoffset,int yoffset,int x,int y,unsigned width,unsigned height)824 void WServerGLWidget::copyTexSubImage2D(WGLWidget::GLenum target, int level,
825 int xoffset, int yoffset,
826 int x, int y,
827 unsigned width, unsigned height)
828 {
829 glCopyTexSubImage2D(serverGLenum(target), level, xoffset, yoffset, x, y,
830 width, height);
831 SERVERGLDEBUG;
832 }
833
createBuffer()834 WGLWidget::Buffer WServerGLWidget::createBuffer()
835 {
836 GLuint id[1];
837 glGenBuffers(1, id);
838 SERVERGLDEBUG;
839 return WGLWidget::Buffer((int)id[0]);
840 }
841
createAndLoadArrayBuffer(const std::string & url)842 WGLWidget::ArrayBuffer WServerGLWidget::createAndLoadArrayBuffer(const std::string &url)
843 {
844 throw WException("WServerGLWidget: this operation is not supported in server-side rendering");
845 }
846
createFramebuffer()847 WGLWidget::Framebuffer WServerGLWidget::createFramebuffer()
848 {
849 GLuint id[1];
850 glGenFramebuffers(1, id);
851 SERVERGLDEBUG;
852 return WGLWidget::Framebuffer((int)id[0]);
853 }
854
createProgram()855 WGLWidget::Program WServerGLWidget::createProgram()
856 {
857 GLuint id = glCreateProgram();
858 SERVERGLDEBUG;
859 return WGLWidget::Program((int)id);
860 }
861
createRenderbuffer()862 WGLWidget::Renderbuffer WServerGLWidget::createRenderbuffer()
863 {
864 GLuint id[1];
865 glGenRenderbuffers(1, id);
866 SERVERGLDEBUG;
867 return WGLWidget::Renderbuffer((int)id[0]);
868 }
869
createShader(WGLWidget::GLenum shader)870 WGLWidget::Shader WServerGLWidget::createShader(WGLWidget::GLenum shader)
871 {
872 GLuint id = glCreateShader(serverGLenum(shader));
873 SERVERGLDEBUG;
874 return WGLWidget::Shader((int)id);
875 }
876
createTexture()877 WGLWidget::Texture WServerGLWidget::createTexture()
878 {
879 GLuint id[1];
880 glGenTextures(1, id);
881 SERVERGLDEBUG;
882 return WGLWidget::Texture((int)id[0]);
883 }
884
createTextureAndLoad(const std::string & url)885 WGLWidget::Texture WServerGLWidget::createTextureAndLoad(const std::string &url)
886 {
887 GLuint id[1];
888 glGenTextures(1, id);
889 SERVERGLDEBUG;
890 WGLWidget::Texture tex((int)id[0]);
891 tex.setUrl(url);
892 return tex;
893 }
894
895 std::unique_ptr<WPaintDevice> WServerGLWidget
createPaintDevice(const WLength & width,const WLength & height)896 ::createPaintDevice(const WLength& width, const WLength& height)
897 {
898 return std::unique_ptr<WRasterImage>(new WRasterImage("png", width, height));
899 }
900
cullFace(WGLWidget::GLenum mode)901 void WServerGLWidget::cullFace(WGLWidget::GLenum mode)
902 {
903 glCullFace(serverGLenum(mode));
904 SERVERGLDEBUG;
905 }
906
deleteBuffer(WGLWidget::Buffer buffer)907 void WServerGLWidget::deleteBuffer(WGLWidget::Buffer buffer)
908 {
909 unsigned int bufArray[1];
910 bufArray[0] = buffer.getId();
911 glDeleteBuffers(1, bufArray);
912 SERVERGLDEBUG;
913 }
914
deleteFramebuffer(WGLWidget::Framebuffer buffer)915 void WServerGLWidget::deleteFramebuffer(WGLWidget::Framebuffer buffer)
916 {
917 unsigned int bufArray[1];
918 bufArray[0] = buffer.getId();
919 glDeleteFramebuffers(1, bufArray);
920 SERVERGLDEBUG;
921 }
922
deleteProgram(WGLWidget::Program program)923 void WServerGLWidget::deleteProgram(WGLWidget::Program program)
924 {
925 glDeleteProgram(program.getId());
926 SERVERGLDEBUG;
927 }
928
deleteRenderbuffer(WGLWidget::Renderbuffer buffer)929 void WServerGLWidget::deleteRenderbuffer(WGLWidget::Renderbuffer buffer)
930 {
931 unsigned int bufArray[1];
932 bufArray[0] = buffer.getId();
933 glDeleteRenderbuffers(1, bufArray);
934 SERVERGLDEBUG;
935 }
936
deleteShader(WGLWidget::Shader shader)937 void WServerGLWidget::deleteShader(WGLWidget::Shader shader)
938 {
939 glDeleteShader(shader.getId());
940 SERVERGLDEBUG;
941 }
942
deleteTexture(WGLWidget::Texture texture)943 void WServerGLWidget::deleteTexture(WGLWidget::Texture texture)
944 {
945 unsigned int texArray[1];
946 texArray[0] = texture.getId();
947 glDeleteTextures(1, texArray);
948 SERVERGLDEBUG;
949 }
950
depthFunc(WGLWidget::GLenum func)951 void WServerGLWidget::depthFunc(WGLWidget::GLenum func)
952 {
953 glDepthFunc(serverGLenum(func));
954 SERVERGLDEBUG;
955 }
956
depthMask(bool flag)957 void WServerGLWidget::depthMask(bool flag)
958 {
959 glDepthMask(flag);
960 SERVERGLDEBUG;
961 }
962
depthRange(double zNear,double zFar)963 void WServerGLWidget::depthRange(double zNear, double zFar)
964 {
965 glDepthRange(zNear, zFar);
966 SERVERGLDEBUG;
967 }
968
detachShader(WGLWidget::Program program,WGLWidget::Shader shader)969 void WServerGLWidget::detachShader(WGLWidget::Program program, WGLWidget::Shader shader)
970 {
971 glDetachShader(program.getId(), shader.getId());
972 SERVERGLDEBUG;
973 }
974
disable(WGLWidget::GLenum cap)975 void WServerGLWidget::disable(WGLWidget::GLenum cap)
976 {
977 glDisable(serverGLenum(cap));
978 SERVERGLDEBUG;
979 }
980
disableVertexAttribArray(WGLWidget::AttribLocation index)981 void WServerGLWidget::disableVertexAttribArray(WGLWidget::AttribLocation index)
982 {
983 glDisableVertexAttribArray(index.getId());
984 SERVERGLDEBUG;
985 }
986
drawArrays(WGLWidget::GLenum mode,int first,unsigned count)987 void WServerGLWidget::drawArrays(WGLWidget::GLenum mode, int first, unsigned count)
988 {
989 glDrawArrays(serverGLenum(mode), first, count);
990 SERVERGLDEBUG;
991 }
992
drawElements(WGLWidget::GLenum mode,unsigned count,WGLWidget::GLenum type,unsigned offset)993 void WServerGLWidget::drawElements(WGLWidget::GLenum mode, unsigned count,
994 WGLWidget::GLenum type, unsigned offset)
995 {
996 glDrawElements(serverGLenum(mode), count, serverGLenum(type), nullptr);
997 SERVERGLDEBUG;
998 }
999
enable(WGLWidget::GLenum cap)1000 void WServerGLWidget::enable(WGLWidget::GLenum cap)
1001 {
1002 glEnable(serverGLenum(cap));
1003 SERVERGLDEBUG;
1004 }
1005
enableVertexAttribArray(WGLWidget::AttribLocation index)1006 void WServerGLWidget::enableVertexAttribArray(WGLWidget::AttribLocation index)
1007 {
1008 glEnableVertexAttribArray(index.getId());
1009 SERVERGLDEBUG;
1010 }
1011
finish()1012 void WServerGLWidget::finish()
1013 {
1014 glFinish();
1015 SERVERGLDEBUG;
1016 }
flush()1017 void WServerGLWidget::flush()
1018 {
1019 glFlush();
1020 SERVERGLDEBUG;
1021 }
1022
framebufferRenderbuffer(WGLWidget::GLenum target,WGLWidget::GLenum attachment,WGLWidget::GLenum renderbuffertarget,WGLWidget::Renderbuffer renderbuffer)1023 void WServerGLWidget::framebufferRenderbuffer(WGLWidget::GLenum target,
1024 WGLWidget::GLenum attachment,
1025 WGLWidget::GLenum renderbuffertarget,
1026 WGLWidget::Renderbuffer renderbuffer)
1027 {
1028 glFramebufferRenderbuffer(serverGLenum(target), serverGLenum(attachment),
1029 serverGLenum(renderbuffertarget),
1030 renderbuffer.getId());
1031 SERVERGLDEBUG;
1032 }
1033
framebufferTexture2D(WGLWidget::GLenum target,WGLWidget::GLenum attachment,WGLWidget::GLenum textarget,WGLWidget::Texture texture,int level)1034 void WServerGLWidget::framebufferTexture2D(WGLWidget::GLenum target,
1035 WGLWidget::GLenum attachment,
1036 WGLWidget::GLenum textarget,
1037 WGLWidget::Texture texture,
1038 int level)
1039 {
1040 glFramebufferTexture2D(serverGLenum(target), serverGLenum(attachment),
1041 serverGLenum(textarget), texture.getId(), level);
1042 SERVERGLDEBUG;
1043 }
1044
frontFace(WGLWidget::GLenum mode)1045 void WServerGLWidget::frontFace(WGLWidget::GLenum mode)
1046 {
1047 glFrontFace(serverGLenum(mode));
1048 SERVERGLDEBUG;
1049 }
1050
generateMipmap(WGLWidget::GLenum target)1051 void WServerGLWidget::generateMipmap(WGLWidget::GLenum target)
1052 {
1053 glGenerateMipmap(serverGLenum(target));
1054 SERVERGLDEBUG;
1055 }
1056
getAttribLocation(WGLWidget::Program program,const std::string & attrib)1057 WGLWidget::AttribLocation WServerGLWidget::getAttribLocation(WGLWidget::Program program, const std::string &attrib)
1058 {
1059 GLint id = glGetAttribLocation(program.getId(), attrib.c_str());
1060 SERVERGLDEBUG;
1061 return WGLWidget::AttribLocation((int)id);
1062 }
1063
getUniformLocation(WGLWidget::Program program,const std::string & location)1064 WGLWidget::UniformLocation WServerGLWidget::getUniformLocation(WGLWidget::Program program, const std::string &location)
1065 {
1066 GLint id = glGetUniformLocation(program.getId(), location.c_str());
1067 SERVERGLDEBUG;
1068 return WGLWidget::UniformLocation((int)id);
1069 }
1070
hint(WGLWidget::GLenum target,WGLWidget::GLenum mode)1071 void WServerGLWidget::hint(WGLWidget::GLenum target, WGLWidget::GLenum mode)
1072 {
1073 glHint(serverGLenum(target), serverGLenum(mode));
1074 SERVERGLDEBUG;
1075 }
1076
lineWidth(double width)1077 void WServerGLWidget::lineWidth(double width)
1078 {
1079 glLineWidth((GLfloat)width);
1080 SERVERGLDEBUG;
1081 }
1082
linkProgram(WGLWidget::Program program)1083 void WServerGLWidget::linkProgram(WGLWidget::Program program)
1084 {
1085 glLinkProgram(program.getId());
1086 SERVERGLDEBUG;
1087 }
1088
pixelStorei(WGLWidget::GLenum pname,int param)1089 void WServerGLWidget::pixelStorei(WGLWidget::GLenum pname, int param)
1090 {
1091 if (pname == WGLWidget::UNPACK_FLIP_Y_WEBGL ||
1092 pname == WGLWidget::UNPACK_PREMULTIPLY_ALPHA_WEBGL ||
1093 pname == WGLWidget::UNPACK_COLORSPACE_CONVERSION_WEBGL)
1094 return;
1095
1096 glPixelStorei(serverGLenum(pname), param);
1097 SERVERGLDEBUG;
1098 }
1099
polygonOffset(double factor,double units)1100 void WServerGLWidget::polygonOffset(double factor, double units)
1101 {
1102 glPolygonOffset((GLfloat)factor, (GLfloat)units);
1103 SERVERGLDEBUG;
1104 }
1105
renderbufferStorage(WGLWidget::GLenum target,WGLWidget::GLenum internalformat,unsigned width,unsigned height)1106 void WServerGLWidget::renderbufferStorage(WGLWidget::GLenum target, WGLWidget::GLenum internalformat,
1107 unsigned width, unsigned height)
1108 {
1109 glRenderbufferStorage(serverGLenum(target), serverGLenum(internalformat),
1110 width, height);
1111 SERVERGLDEBUG;
1112 }
1113
sampleCoverage(double value,bool invert)1114 void WServerGLWidget::sampleCoverage(double value, bool invert)
1115 {
1116 glSampleCoverage((GLfloat) value, invert);
1117 SERVERGLDEBUG;
1118 }
1119
scissor(int x,int y,unsigned width,unsigned height)1120 void WServerGLWidget::scissor(int x, int y, unsigned width, unsigned height)
1121 {
1122 glScissor(x, y, width, height);
1123 SERVERGLDEBUG;
1124 }
1125
shaderSource(WGLWidget::Shader shader,const std::string & src)1126 void WServerGLWidget::shaderSource(WGLWidget::Shader shader,
1127 const std::string &src)
1128 {
1129 const char* csrc = src.c_str();
1130 const GLchar** string = &csrc;
1131
1132 int psize = src.length();
1133 const GLint* length = &psize;
1134
1135 glShaderSource(shader.getId(), 1, string, length);
1136 SERVERGLDEBUG;
1137 }
1138
stencilFunc(WGLWidget::GLenum func,int ref,unsigned mask)1139 void WServerGLWidget::stencilFunc(WGLWidget::GLenum func, int ref,
1140 unsigned mask)
1141 {
1142 glStencilFunc(serverGLenum(func), ref, mask);
1143 SERVERGLDEBUG;
1144 }
1145
stencilFuncSeparate(WGLWidget::GLenum face,WGLWidget::GLenum func,int ref,unsigned mask)1146 void WServerGLWidget::stencilFuncSeparate(WGLWidget::GLenum face,
1147 WGLWidget::GLenum func, int ref,
1148 unsigned mask)
1149 {
1150 glStencilFuncSeparate(serverGLenum(face), serverGLenum(func), ref, mask);
1151 SERVERGLDEBUG;
1152 }
1153
stencilMask(unsigned mask)1154 void WServerGLWidget::stencilMask(unsigned mask)
1155 {
1156 glStencilMask(mask);
1157 SERVERGLDEBUG;
1158 }
1159
stencilMaskSeparate(WGLWidget::GLenum face,unsigned mask)1160 void WServerGLWidget::stencilMaskSeparate(WGLWidget::GLenum face, unsigned mask)
1161 {
1162 glStencilMaskSeparate(serverGLenum(face), mask);
1163 SERVERGLDEBUG;
1164 }
1165
stencilOp(WGLWidget::GLenum fail,WGLWidget::GLenum zfail,WGLWidget::GLenum zpass)1166 void WServerGLWidget::stencilOp(WGLWidget::GLenum fail, WGLWidget::GLenum zfail,
1167 WGLWidget::GLenum zpass)
1168 {
1169 glStencilOp(serverGLenum(fail), serverGLenum(zfail), serverGLenum(zpass));
1170 SERVERGLDEBUG;
1171 }
1172
stencilOpSeparate(WGLWidget::GLenum face,WGLWidget::GLenum fail,WGLWidget::GLenum zfail,WGLWidget::GLenum zpass)1173 void WServerGLWidget::stencilOpSeparate(WGLWidget::GLenum face,
1174 WGLWidget::GLenum fail,
1175 WGLWidget::GLenum zfail,
1176 WGLWidget::GLenum zpass)
1177 {
1178 glStencilOpSeparate(serverGLenum(face),
1179 serverGLenum(fail),
1180 serverGLenum(zfail),
1181 serverGLenum(zpass));
1182 SERVERGLDEBUG;
1183 }
1184
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,unsigned width,unsigned height,int border,WGLWidget::GLenum format)1185 void WServerGLWidget::texImage2D(WGLWidget::GLenum target,
1186 int level, WGLWidget::GLenum internalformat,
1187 unsigned width, unsigned height, int border,
1188 WGLWidget::GLenum format)
1189 {
1190 glTexImage2D(serverGLenum(target), level, serverGLenum(internalformat),
1191 width, height, border, serverGLenum(format), GL_UNSIGNED_BYTE,
1192 nullptr);
1193 SERVERGLDEBUG;
1194 }
1195
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,WImage * image)1196 void WServerGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1197 WGLWidget::GLenum internalformat,
1198 WGLWidget::GLenum format,
1199 WGLWidget::GLenum type,
1200 WImage *image)
1201 {
1202 throw WException("WServerGLWidget: this operation is not supported in server-side rendering");
1203 }
1204
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,WVideo * video)1205 void WServerGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1206 WGLWidget::GLenum internalformat,
1207 WGLWidget::GLenum format,
1208 WGLWidget::GLenum type,
1209 WVideo *video)
1210 {
1211 throw WException("WServerGLWidget: this operation is not supported in server-side rendering");
1212 }
1213
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,std::string imgFilename)1214 void WServerGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1215 WGLWidget::GLenum internalformat,
1216 WGLWidget::GLenum format,
1217 WGLWidget::GLenum type,
1218 std::string imgFilename)
1219 {
1220 WPainter::Image image(WApplication::instance()->docRoot().append("/")
1221 .append(imgFilename), imgFilename);
1222 WRasterImage raster("png", image.width(), image.height());
1223 WPainter decoder(&raster);
1224 decoder.drawImage(WPointF(), image);
1225
1226 int width = (int)raster.width().value();
1227 int height = (int)raster.height().value();
1228
1229 std::vector<unsigned char> imgdata(width*height*4); // 4 bytes per pixel
1230 raster.getPixels(&imgdata[0]);
1231
1232 // flip image over Y axis
1233 uint32_t *word = (uint32_t *)&imgdata[0];
1234 for (int r = 0; r < height/2; r++) {
1235 for (int c = 0; c < width; c++) {
1236 uint32_t tmp = word[r*width + c];
1237 word[r*width + c] = word[(height - r - 1)*width + c];
1238 word[(height - r - 1)*width + c] = tmp;
1239 }
1240 }
1241
1242 glTexImage2D(serverGLenum(target), level, GL_RGBA, width, height, 0, GL_RGBA,
1243 GL_UNSIGNED_BYTE, &imgdata[0]);
1244 SERVERGLDEBUG;
1245 }
1246
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,WPaintDevice * paintdevice)1247 void WServerGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1248 WGLWidget::GLenum internalformat,
1249 WGLWidget::GLenum format,
1250 WGLWidget::GLenum type,
1251 WPaintDevice *paintdevice)
1252 {
1253 WRasterImage *rpd = dynamic_cast<WRasterImage*>(paintdevice);
1254 if (!rpd)
1255 return;
1256
1257 int width = (int)rpd->width().value();
1258 int height = (int)rpd->height().value();
1259
1260 std::vector<unsigned char> imgdata(width*height*4);
1261 rpd->getPixels(&imgdata[0]);
1262
1263 // flip image over Y axis
1264 uint32_t *word = (uint32_t *)&imgdata[0];
1265 for (int r = 0; r < height/2; r++) {
1266 for (int c = 0; c < width; c++) {
1267 uint32_t tmp = word[r*width + c];
1268 word[r*width + c] = word[(height - r - 1)*width + c];
1269 word[(height - r - 1)*width + c] = tmp;
1270 }
1271 }
1272
1273 glTexImage2D(serverGLenum(target), level, GL_RGBA, width, height, 0, GL_RGBA,
1274 GL_UNSIGNED_BYTE, &imgdata[0]);
1275 SERVERGLDEBUG;
1276 }
1277
texImage2D(WGLWidget::GLenum target,int level,WGLWidget::GLenum internalformat,WGLWidget::GLenum format,WGLWidget::GLenum type,WGLWidget::Texture texture)1278 void WServerGLWidget::texImage2D(WGLWidget::GLenum target, int level,
1279 WGLWidget::GLenum internalformat,
1280 WGLWidget::GLenum format,
1281 WGLWidget::GLenum type,
1282 WGLWidget::Texture texture)
1283 {
1284 texImage2D(target, level, internalformat, format, type, texture.url());
1285 }
1286
texParameteri(WGLWidget::GLenum target,WGLWidget::GLenum pname,WGLWidget::GLenum param)1287 void WServerGLWidget::texParameteri(WGLWidget::GLenum target,
1288 WGLWidget::GLenum pname,
1289 WGLWidget::GLenum param)
1290 {
1291 glTexParameteri(serverGLenum(target), serverGLenum(pname), serverGLenum(param));
1292 SERVERGLDEBUG;
1293 }
1294
uniform1f(const WGLWidget::UniformLocation & location,double x)1295 void WServerGLWidget::uniform1f(const WGLWidget::UniformLocation &location, double x)
1296 {
1297 glUniform1f(location.getId(), (GLfloat)x);
1298 SERVERGLDEBUG;
1299 }
1300
uniform1fv(const WGLWidget::UniformLocation & location,const WT_ARRAY float * value)1301 void WServerGLWidget::uniform1fv(const WGLWidget::UniformLocation &location,
1302 const WT_ARRAY float *value)
1303 {
1304 glUniform1fv(location.getId(), 1, value);
1305 SERVERGLDEBUG;
1306 }
1307
uniform1fv(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptVector & v)1308 void WServerGLWidget::uniform1fv(const WGLWidget::UniformLocation &location,
1309 const WGLWidget::JavaScriptVector &v)
1310 {
1311 glUniform1fv(location.getId(), 1, &v.value()[0]);
1312 SERVERGLDEBUG;
1313 }
1314
uniform1i(const WGLWidget::UniformLocation & location,int x)1315 void WServerGLWidget::uniform1i(const WGLWidget::UniformLocation &location,
1316 int x)
1317 {
1318 glUniform1i(location.getId(), x);
1319 SERVERGLDEBUG;
1320 }
1321
uniform1iv(const WGLWidget::UniformLocation & location,const WT_ARRAY int * value)1322 void WServerGLWidget::uniform1iv(const WGLWidget::UniformLocation &location,
1323 const WT_ARRAY int *value)
1324 {
1325 glUniform1iv(location.getId(), 1, value);
1326 SERVERGLDEBUG;
1327 }
1328
uniform2f(const WGLWidget::UniformLocation & location,double x,double y)1329 void WServerGLWidget::uniform2f(const WGLWidget::UniformLocation &location,
1330 double x, double y)
1331 {
1332 glUniform2f(location.getId(), (GLfloat)x, (GLfloat)y);
1333 SERVERGLDEBUG;
1334 }
1335
uniform2fv(const WGLWidget::UniformLocation & location,const WT_ARRAY float * value)1336 void WServerGLWidget::uniform2fv(const WGLWidget::UniformLocation &location,
1337 const WT_ARRAY float *value)
1338 {
1339 glUniform2fv(location.getId(), 1, value);
1340 SERVERGLDEBUG;
1341 }
1342
uniform2fv(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptVector & v)1343 void WServerGLWidget::uniform2fv(const WGLWidget::UniformLocation &location,
1344 const WGLWidget::JavaScriptVector &v)
1345 {
1346 glUniform2fv(location.getId(), 1, &v.value()[0]);
1347 SERVERGLDEBUG;
1348 }
1349
uniform2i(const WGLWidget::UniformLocation & location,int x,int y)1350 void WServerGLWidget::uniform2i(const WGLWidget::UniformLocation &location,
1351 int x, int y)
1352 {
1353 glUniform2i(location.getId(), x, y);
1354 SERVERGLDEBUG;
1355 }
1356
uniform2iv(const WGLWidget::UniformLocation & location,const WT_ARRAY int * value)1357 void WServerGLWidget::uniform2iv(const WGLWidget::UniformLocation &location,
1358 const WT_ARRAY int *value)
1359 {
1360 glUniform2iv(location.getId(), 1, value);
1361 SERVERGLDEBUG;
1362 }
1363
uniform3f(const WGLWidget::UniformLocation & location,double x,double y,double z)1364 void WServerGLWidget::uniform3f(const WGLWidget::UniformLocation &location,
1365 double x, double y, double z)
1366 {
1367 glUniform3f(location.getId(), (GLfloat)x, (GLfloat)y, (GLfloat)z);
1368 SERVERGLDEBUG;
1369 }
1370
uniform3fv(const WGLWidget::UniformLocation & location,const WT_ARRAY float * value)1371 void WServerGLWidget::uniform3fv(const WGLWidget::UniformLocation &location,
1372 const WT_ARRAY float *value)
1373 {
1374 glUniform3fv(location.getId(), 1, value);
1375 SERVERGLDEBUG;
1376 }
1377
uniform3fv(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptVector & v)1378 void WServerGLWidget::uniform3fv(const WGLWidget::UniformLocation &location,
1379 const WGLWidget::JavaScriptVector &v)
1380 {
1381 glUniform3fv(location.getId(), 1, &v.value()[0]);
1382 SERVERGLDEBUG;
1383 }
1384
uniform3i(const WGLWidget::UniformLocation & location,int x,int y,int z)1385 void WServerGLWidget::uniform3i(const WGLWidget::UniformLocation &location,
1386 int x, int y, int z)
1387 {
1388 glUniform3i(location.getId(), x, y, z);
1389 SERVERGLDEBUG;
1390 }
1391
uniform3iv(const WGLWidget::UniformLocation & location,const WT_ARRAY int * value)1392 void WServerGLWidget::uniform3iv(const WGLWidget::UniformLocation &location,
1393 const WT_ARRAY int *value)
1394 {
1395 glUniform3iv(location.getId(), 1, value);
1396 SERVERGLDEBUG;
1397 }
1398
uniform4f(const WGLWidget::UniformLocation & location,double x,double y,double z,double w)1399 void WServerGLWidget::uniform4f(const WGLWidget::UniformLocation &location,
1400 double x, double y, double z, double w)
1401 {
1402 glUniform4f(location.getId(), (GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)w);
1403 SERVERGLDEBUG;
1404 }
1405
uniform4fv(const WGLWidget::UniformLocation & location,const WT_ARRAY float * value)1406 void WServerGLWidget::uniform4fv(const WGLWidget::UniformLocation &location,
1407 const WT_ARRAY float *value)
1408 {
1409 glUniform4fv(location.getId(), 1, value);
1410 SERVERGLDEBUG;
1411 }
1412
uniform4fv(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptVector & v)1413 void WServerGLWidget::uniform4fv(const WGLWidget::UniformLocation &location,
1414 const WGLWidget::JavaScriptVector &v)
1415 {
1416 glUniform4fv(location.getId(), 1, &v.value()[0]);
1417 SERVERGLDEBUG;
1418 }
1419
uniform4i(const WGLWidget::UniformLocation & location,int x,int y,int z,int w)1420 void WServerGLWidget::uniform4i(const WGLWidget::UniformLocation &location,
1421 int x, int y, int z, int w)
1422 {
1423 glUniform4i(location.getId(), x, y, z, w);
1424 SERVERGLDEBUG;
1425 }
1426
uniform4iv(const WGLWidget::UniformLocation & location,const WT_ARRAY int * value)1427 void WServerGLWidget::uniform4iv(const WGLWidget::UniformLocation &location,
1428 const WT_ARRAY int *value)
1429 {
1430 glUniform4iv(location.getId(), 1, value);
1431 SERVERGLDEBUG;
1432 }
1433
uniformMatrix2fv(const WGLWidget::UniformLocation & location,bool transpose,const WT_ARRAY double * value)1434 void WServerGLWidget::uniformMatrix2fv(const WGLWidget::UniformLocation &location,
1435 bool transpose,
1436 const WT_ARRAY double *value)
1437 {
1438 float mat[4];
1439 for (int i=0; i<4; i++){
1440 mat[i] = (GLfloat)value[i];
1441 }
1442
1443 glUniformMatrix2fv(location.getId(), 1, transpose, mat);
1444 SERVERGLDEBUG;
1445 }
1446
uniformMatrix2(const WGLWidget::UniformLocation & location,const WGenericMatrix<double,2,2> & m)1447 void WServerGLWidget::uniformMatrix2(const WGLWidget::UniformLocation &location,
1448 const WGenericMatrix<double, 2, 2> &m)
1449 {
1450 float mat[4];
1451 for (int i=0; i<2; i++){
1452 for (int j=0; j<2; j++) {
1453 mat[i*2+j] = (GLfloat)m(j, i);
1454 }
1455 }
1456
1457 glUniformMatrix2fv(location.getId(), 1, false, mat);
1458 SERVERGLDEBUG;
1459 }
1460
uniformMatrix3fv(const WGLWidget::UniformLocation & location,bool transpose,const WT_ARRAY double * value)1461 void WServerGLWidget::uniformMatrix3fv(const WGLWidget::UniformLocation &location,
1462 bool transpose,
1463 const WT_ARRAY double *value)
1464 {
1465 float mat[9];
1466 for (int i=0; i<9; i++){
1467 mat[i] = (GLfloat)value[i];
1468 }
1469
1470 glUniformMatrix2fv(location.getId(), 1, transpose, mat);
1471 SERVERGLDEBUG;
1472 }
1473
uniformMatrix3(const WGLWidget::UniformLocation & location,const WGenericMatrix<double,3,3> & m)1474 void WServerGLWidget::uniformMatrix3(const WGLWidget::UniformLocation &location,
1475 const WGenericMatrix<double, 3, 3> &m)
1476 {
1477 float mat[9];
1478 for (int i=0; i<3; i++){
1479 for (int j=0; j<3; j++) {
1480 mat[i*3+j] = (GLfloat)m(j, i);
1481 }
1482 }
1483
1484 glUniformMatrix2fv(location.getId(), 1, false, mat);
1485 SERVERGLDEBUG;
1486 }
1487
uniformMatrix4fv(const WGLWidget::UniformLocation & location,bool transpose,const WT_ARRAY double * value)1488 void WServerGLWidget::uniformMatrix4fv(const WGLWidget::UniformLocation &location,
1489 bool transpose,
1490 const WT_ARRAY double *value)
1491 {
1492 float mat[16];
1493 for (int i=0; i<16; i++){
1494 mat[i] = (GLfloat)value[i];
1495 }
1496
1497 glUniformMatrix2fv(location.getId(), 1, transpose, mat);
1498 SERVERGLDEBUG;
1499 }
1500
uniformMatrix4(const WGLWidget::UniformLocation & location,const WGenericMatrix<double,4,4> & m)1501 void WServerGLWidget::uniformMatrix4(const WGLWidget::UniformLocation &location,
1502 const WGenericMatrix<double, 4, 4> &m)
1503 {
1504 float data[16];
1505 for (int i=0; i<4; i++) {
1506 for (int j=0; j<4; j++) {
1507 data[i*4+j] = (float)m(j,i);
1508 }
1509 }
1510
1511 glUniformMatrix4fv(location.getId(), 1, false, data);
1512 SERVERGLDEBUG;
1513 }
1514
uniformMatrix4(const WGLWidget::UniformLocation & location,const WGLWidget::JavaScriptMatrix4x4 & jsm)1515 void WServerGLWidget::uniformMatrix4(const WGLWidget::UniformLocation &location,
1516 const WGLWidget::JavaScriptMatrix4x4 &jsm)
1517 {
1518 WMatrix4x4 mat = jsm.value();
1519
1520 float data[16];
1521 for (int i=0; i<4; i++) {
1522 for (int j=0; j<4; j++) {
1523 data[i*4+j] = (float)mat(j, i);
1524 }
1525 }
1526
1527 glUniformMatrix4fv(location.getId(), 1, false, data);
1528 SERVERGLDEBUG;
1529 }
1530
useProgram(WGLWidget::Program program)1531 void WServerGLWidget::useProgram(WGLWidget::Program program)
1532 {
1533 glUseProgram(program.getId());
1534 SERVERGLDEBUG;
1535 }
1536
validateProgram(WGLWidget::Program program)1537 void WServerGLWidget::validateProgram(WGLWidget::Program program)
1538 {
1539 glValidateProgram(program.getId());
1540 SERVERGLDEBUG;
1541 }
1542
vertexAttrib1f(WGLWidget::AttribLocation location,double x)1543 void WServerGLWidget::vertexAttrib1f(WGLWidget::AttribLocation location,
1544 double x)
1545 {
1546 glVertexAttrib1f(location.getId(), (GLfloat) x);
1547 SERVERGLDEBUG;
1548 }
1549
vertexAttrib2f(WGLWidget::AttribLocation location,double x,double y)1550 void WServerGLWidget::vertexAttrib2f(WGLWidget::AttribLocation location,
1551 double x, double y)
1552 {
1553 glVertexAttrib2f(location.getId(), (GLfloat)x, (GLfloat)y);
1554 SERVERGLDEBUG;
1555 }
1556
vertexAttrib3f(WGLWidget::AttribLocation location,double x,double y,double z)1557 void WServerGLWidget::vertexAttrib3f(WGLWidget::AttribLocation location,
1558 double x, double y, double z)
1559 {
1560 glVertexAttrib3f(location.getId(), (GLfloat)x, (GLfloat)y, (GLfloat)z);
1561 SERVERGLDEBUG;
1562 }
1563
vertexAttrib4f(WGLWidget::AttribLocation location,double x,double y,double z,double w)1564 void WServerGLWidget::vertexAttrib4f(WGLWidget::AttribLocation location,
1565 double x, double y, double z, double w)
1566 {
1567 glVertexAttrib4f(location.getId(), (GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)w);
1568 SERVERGLDEBUG;
1569 }
1570
vertexAttribPointer(WGLWidget::AttribLocation location,int size,WGLWidget::GLenum type,bool normalized,unsigned stride,unsigned offset)1571 void WServerGLWidget::vertexAttribPointer(WGLWidget::AttribLocation location,
1572 int size, WGLWidget::GLenum type,
1573 bool normalized, unsigned stride,
1574 unsigned offset)
1575 {
1576 glVertexAttribPointer(location.getId(), size, serverGLenum(type),
1577 normalized, stride, nullptr);
1578 SERVERGLDEBUG;
1579 }
1580
viewport(int x,int y,unsigned width,unsigned height)1581 void WServerGLWidget::viewport(int x, int y, unsigned width, unsigned height)
1582 {
1583 glViewport(x, y, width, height);
1584 SERVERGLDEBUG;
1585 }
1586
clearBinaryResources()1587 void WServerGLWidget::clearBinaryResources()
1588 {
1589 // only in WClientGLWidget
1590 }
1591
initJavaScriptMatrix4(WGLWidget::JavaScriptMatrix4x4 & mat)1592 void WServerGLWidget::initJavaScriptMatrix4(WGLWidget::JavaScriptMatrix4x4 &mat)
1593 {
1594 if (!mat.hasContext())
1595 glInterface_->addJavaScriptMatrix4(mat);
1596 else if (mat.context_ != glInterface_)
1597 throw WException("JavaScriptMatrix4x4: associated WGLWidget is not equal to the WGLWidget it's being initialized in");
1598 if (mat.initialized())
1599 throw WException("JavaScriptMatrix4x4: matrix already initialized");
1600
1601 WGenericMatrix<double, 4, 4> m = mat.value();
1602 js_ << mat.jsRef() << "=";
1603 WClientGLWidget::renderfv(js_, m, JsArrayType::Array);
1604 js_ << ";";
1605
1606 mat.initialize();
1607 }
1608
setJavaScriptMatrix4(WGLWidget::JavaScriptMatrix4x4 & jsm,const WGenericMatrix<double,4,4> & m)1609 void WServerGLWidget::setJavaScriptMatrix4(WGLWidget::JavaScriptMatrix4x4 &jsm,
1610 const WGenericMatrix<double, 4, 4> &m)
1611 {
1612 // transpose it for javascript
1613 WMatrix4x4 transposed;
1614 for (int i=0; i<4; i++) {
1615 for (int j=0; j<4; j++) {
1616 transposed(i, j) = m(j, i);
1617 }
1618 }
1619
1620 // set it in javascript
1621 js_ << WT_CLASS ".glMatrix.mat4.set(";
1622 WClientGLWidget::renderfv(js_, transposed, JsArrayType::Array);
1623 js_ << ", " << jsm.jsRef() << ");";
1624 }
1625
initJavaScriptVector(WGLWidget::JavaScriptVector & vec)1626 void WServerGLWidget::initJavaScriptVector(WGLWidget::JavaScriptVector &vec)
1627 {
1628 if (!vec.hasContext())
1629 glInterface_->addJavaScriptVector(vec);
1630 else if (vec.context_ != glInterface_)
1631 throw WException("JavaScriptVector: associated WGLWidget is not equal to the WGLWidget it's being initialized in");
1632 if (vec.initialized())
1633 throw WException("JavaScriptVector: vector already initialized");
1634
1635 std::vector<float> v = vec.value();
1636 js_ << vec.jsRef() << "= [";
1637 for (unsigned i = 0; i < vec.length(); ++i) {
1638 if (i != 0)
1639 js_ << ",";
1640 std::string val;
1641 if (v[i] == std::numeric_limits<float>::infinity()) {
1642 val = "Infinity";
1643 } else if (v[i] == -std::numeric_limits<float>::infinity()) {
1644 val = "-Infinity";
1645 } else {
1646 val = std::to_string(v[i]);
1647 }
1648 js_ << val;
1649 }
1650 js_ << "];";
1651
1652 vec.initialize();
1653 }
1654
setJavaScriptVector(WGLWidget::JavaScriptVector & jsv,const std::vector<float> & v)1655 void WServerGLWidget::setJavaScriptVector(WGLWidget::JavaScriptVector &jsv,
1656 const std::vector<float> &v)
1657 {
1658 if (jsv.length() != v.size())
1659 throw WException("Trying to set a JavaScriptVector with incompatible length!");
1660 for (unsigned i = 0; i < jsv.length(); ++i) {
1661 std::string val;
1662 if (v[i] == std::numeric_limits<float>::infinity()) {
1663 val = "Number.POSITIVE_INFINITY";
1664 } else if (v[i] == -std::numeric_limits<float>::infinity()) {
1665 val = "Number.NEGATIVE_INFINITY";
1666 } else {
1667 val = std::to_string(v[i]);
1668 }
1669 js_ << jsv.jsRef() << "[" << i << "] = " << val << ";";
1670 }
1671 }
1672
setClientSideMouseHandler(const std::string & handlerCode)1673 void WServerGLWidget::setClientSideMouseHandler(const std::string& handlerCode)
1674 {
1675 js_ << "obj.setMouseHandler(" << handlerCode << ");";
1676 }
1677
setClientSideLookAtHandler(const WGLWidget::JavaScriptMatrix4x4 & m,double centerX,double centerY,double centerZ,double uX,double uY,double uZ,double pitchRate,double yawRate)1678 void WServerGLWidget::setClientSideLookAtHandler(const WGLWidget::JavaScriptMatrix4x4 &m,
1679 double centerX, double centerY, double centerZ,
1680 double uX, double uY, double uZ,
1681 double pitchRate, double yawRate)
1682 {
1683 js_ << "obj.setMouseHandler(new obj.LookAtMouseHandler("
1684 << m.jsRef() << ",[" << centerX << "," << centerY << "," << centerZ << "],["
1685 << uX << "," << uY << "," << uZ << "],"
1686 << pitchRate << "," << yawRate << "));";
1687 }
1688
setClientSideWalkHandler(const WGLWidget::JavaScriptMatrix4x4 & m,double frontStep,double rotStep)1689 void WServerGLWidget::setClientSideWalkHandler(const WGLWidget::JavaScriptMatrix4x4 &m, double frontStep, double rotStep)
1690 {
1691 js_ << "obj.setMouseHandler(new obj.WalkMouseHandler("
1692 << m.jsRef() << "," << frontStep << "," << rotStep << "));\n";
1693 }
1694
arrayType()1695 JsArrayType WServerGLWidget::arrayType() const
1696 {
1697 return JsArrayType::Array;
1698 }
1699
glObjJsRef(const std::string & jsRef)1700 std::string WServerGLWidget::glObjJsRef(const std::string& jsRef)
1701 {
1702 return "(function(){"
1703 "var r = " + jsRef + ";"
1704 "var o = r ? r.wtObj : null;"
1705 "return o ? o : {ctx: null};"
1706 "})()";
1707 }
1708
render(const std::string & jsRef,WFlags<RenderFlag> flags)1709 void WServerGLWidget::render(const std::string& jsRef, WFlags<RenderFlag> flags)
1710 {
1711 //boost::timer::auto_cpu_timer t;
1712 if (updateResizeGL_ && sizeChanged_) {
1713 impl_->resize(renderWidth_, renderHeight_);
1714 delete raster_;
1715 raster_ = nullptr; // will be re-initialized later
1716
1717 }
1718
1719 impl_->makeCurrent();
1720 glEnable(GL_MULTISAMPLE_ARB);
1721
1722 if (flags.test(RenderFlag::Full)) {
1723 std::stringstream ss;
1724 ss << "{\nvar obj = new " WT_CLASS ".WGLWidget("
1725 << WApplication::instance()->javaScriptClass() << ","
1726 << jsRef << ");\n";
1727
1728 js_.str("");
1729 glInterface_->initializeGL();
1730 ss << js_.str().c_str();
1731 ss << "obj.paintGL = function(){\n"
1732 << Wt::WApplication::instance()->javaScriptClass() << ".emit(" << jsRef << ", " << WWebWidget::jsStringLiteral(std::string("repaintSignal")) << ");"
1733 << "}";
1734 ss << "}";
1735
1736 glInterface_->doJavaScript(ss.str());
1737 updatePaintGL_ = true;
1738 }
1739 if (updateGL_) {
1740 js_.str("");
1741 js_ << "var obj=" << glObjJsRef(jsRef) << ";\n";
1742 glInterface_->updateGL();
1743 glInterface_->doJavaScript(js_.str());
1744 updateGL_ = false;
1745 }
1746 if (updateResizeGL_) {
1747 js_.str("");
1748 js_ << "var obj=" << glObjJsRef(jsRef) << ";\n";
1749 glInterface_->resizeGL(renderWidth_, renderHeight_);
1750 glInterface_->doJavaScript(js_.str());
1751 updateResizeGL_ = false;
1752 }
1753 if (updatePaintGL_) {
1754 js_.str("");
1755 js_ << "var obj=" << glObjJsRef(jsRef) << ";\n";
1756 glInterface_->paintGL();
1757 glInterface_->doJavaScript(js_.str());
1758 updatePaintGL_ = false;
1759 }
1760
1761 glFinish();
1762 glFlush();
1763
1764 //impl_->swapBuffers();
1765
1766 {
1767 //boost::timer::auto_cpu_timer t;
1768
1769 // paint a picture with the framebuffer 0
1770 std::vector<unsigned char> pixelData(renderWidth_ * renderHeight_ * 4);
1771 glPixelStorei(GL_PACK_ALIGNMENT, 1);
1772 SERVERGLDEBUG;
1773 #ifdef FRAMEBUFFER_RENDERING
1774 impl_->initReadBuffer();
1775 #endif
1776 glReadPixels(0, 0, renderWidth_, renderHeight_, GL_RGBA,
1777 GL_UNSIGNED_BYTE, &pixelData[0]);
1778 SERVERGLDEBUG;
1779 #ifdef FRAMEBUFFER_RENDERING
1780 impl_->setDrawBuffer();
1781 #endif
1782
1783 if (!raster_)
1784 raster_ = new WRasterImage("png", renderWidth_, renderHeight_);
1785 int idx = 0;
1786
1787 WColor pixel;
1788 for (int i=0; i < renderHeight_; i++) {
1789 for (int j=0; j < renderWidth_; j++) {
1790 pixel.setRgb((int)pixelData[idx+0],
1791 (int)pixelData[idx+1],
1792 (int)pixelData[idx+2],
1793 (int)pixelData[idx+3]);
1794 idx += 4;
1795 raster_->setPixel(j, renderHeight_-1-i, pixel);
1796 }
1797 }
1798 std::stringstream sstream;
1799 raster_->write(sstream);
1800 std::string tmp = sstream.str();
1801 memres_->setData(reinterpret_cast<const unsigned char*>(tmp.c_str()), tmp.size());
1802 }
1803 memres_->generateUrl();
1804 impl_->unmakeCurrent();
1805
1806 std::stringstream ss;
1807 ss << jsRef << ".wtObj.loadImage(" << WWebWidget::jsStringLiteral(memres_->url()) << ");";
1808 glInterface_->doJavaScript(ss.str());
1809 }
1810
injectJS(const std::string & jsString)1811 void WServerGLWidget::injectJS(const std::string & jsString)
1812 { }
1813
restoreContext(const std::string & jsRef)1814 void WServerGLWidget::restoreContext(const std::string &jsRef)
1815 { }
1816
1817 }
1818
1819 namespace {
1820
1821 using namespace Wt;
serverGLenum(WGLWidget::GLenum e)1822 GLenum serverGLenum(WGLWidget::GLenum e)
1823 {
1824 switch(e) {
1825 case WGLWidget::DEPTH_BUFFER_BIT:
1826 return GL_DEPTH_BUFFER_BIT;
1827 case WGLWidget::STENCIL_BUFFER_BIT:
1828 return GL_STENCIL_BUFFER_BIT;
1829 case WGLWidget::COLOR_BUFFER_BIT:
1830 return GL_COLOR_BUFFER_BIT;
1831 case WGLWidget::POINTS:
1832 return GL_POINTS;
1833 case WGLWidget::LINES:
1834 return GL_LINES;
1835 case WGLWidget::LINE_LOOP:
1836 return GL_LINE_LOOP;
1837 case WGLWidget::LINE_STRIP:
1838 return GL_LINE_STRIP;
1839 case WGLWidget::TRIANGLES:
1840 return GL_TRIANGLES;
1841 case WGLWidget::TRIANGLE_STRIP:
1842 return GL_TRIANGLE_STRIP;
1843 case WGLWidget::TRIANGLE_FAN:
1844 return GL_TRIANGLE_FAN;
1845 // case WGLWidget::ZERO:
1846 // return GL_ZERO;
1847 // case WGLWidget::ONE:
1848 // return GL_ONE;
1849 case WGLWidget::SRC_COLOR:
1850 return GL_SRC_COLOR;
1851 case WGLWidget::ONE_MINUS_SRC_COLOR:
1852 return GL_ONE_MINUS_SRC_COLOR;
1853 case WGLWidget::SRC_ALPHA:
1854 return GL_SRC_ALPHA;
1855 case WGLWidget::ONE_MINUS_SRC_ALPHA:
1856 return GL_ONE_MINUS_SRC_ALPHA;
1857 case WGLWidget::DST_ALPHA:
1858 return GL_DST_ALPHA;
1859 case WGLWidget::ONE_MINUS_DST_ALPHA:
1860 return GL_ONE_MINUS_DST_ALPHA;
1861 case WGLWidget::DST_COLOR:
1862 return GL_DST_COLOR;
1863 case WGLWidget::ONE_MINUS_DST_COLOR:
1864 return GL_ONE_MINUS_DST_COLOR;
1865 case WGLWidget::SRC_ALPHA_SATURATE:
1866 return GL_SRC_ALPHA_SATURATE;
1867 case WGLWidget::FUNC_ADD:
1868 return GL_FUNC_ADD;
1869 case WGLWidget::BLEND_EQUATION:
1870 return GL_BLEND_EQUATION;
1871 // case WGLWidget::BLEND_EQUATION_RGB:
1872 // return GL_BLEND_EQUATION_RGB;
1873 case WGLWidget::BLEND_EQUATION_ALPHA:
1874 return GL_BLEND_EQUATION_ALPHA;
1875 case WGLWidget::FUNC_SUBTRACT:
1876 return GL_FUNC_SUBTRACT;
1877 case WGLWidget::FUNC_REVERSE_SUBTRACT:
1878 return GL_FUNC_REVERSE_SUBTRACT;
1879 case WGLWidget::BLEND_DST_RGB:
1880 return GL_BLEND_DST_RGB;
1881 case WGLWidget::BLEND_SRC_RGB:
1882 return GL_BLEND_SRC_RGB;
1883 case WGLWidget::BLEND_DST_ALPHA:
1884 return GL_BLEND_DST_ALPHA;
1885 case WGLWidget::BLEND_SRC_ALPHA:
1886 return GL_BLEND_SRC_ALPHA;
1887 case WGLWidget::CONSTANT_COLOR:
1888 return GL_CONSTANT_COLOR;
1889 case WGLWidget::ONE_MINUS_CONSTANT_COLOR:
1890 return GL_ONE_MINUS_CONSTANT_COLOR;
1891 case WGLWidget::CONSTANT_ALPHA:
1892 return GL_CONSTANT_ALPHA;
1893 case WGLWidget::ONE_MINUS_CONSTANT_ALPHA:
1894 return GL_ONE_MINUS_CONSTANT_ALPHA;
1895 case WGLWidget::BLEND_COLOR:
1896 return GL_BLEND_COLOR;
1897 case WGLWidget::ARRAY_BUFFER:
1898 return GL_ARRAY_BUFFER;
1899 case WGLWidget::ELEMENT_ARRAY_BUFFER:
1900 return GL_ELEMENT_ARRAY_BUFFER;
1901 case WGLWidget::ARRAY_BUFFER_BINDING:
1902 return GL_ARRAY_BUFFER_BINDING;
1903 case WGLWidget::ELEMENT_ARRAY_BUFFER_BINDING:
1904 return GL_ELEMENT_ARRAY_BUFFER_BINDING;
1905 case WGLWidget::STREAM_DRAW:
1906 return GL_STREAM_DRAW;
1907 case WGLWidget::STATIC_DRAW:
1908 return GL_STATIC_DRAW;
1909 case WGLWidget::DYNAMIC_DRAW:
1910 return GL_DYNAMIC_DRAW;
1911 case WGLWidget::BUFFER_SIZE:
1912 return GL_BUFFER_SIZE;
1913 case WGLWidget::BUFFER_USAGE:
1914 return GL_BUFFER_USAGE;
1915 case WGLWidget::CURRENT_VERTEX_ATTRIB:
1916 return GL_CURRENT_VERTEX_ATTRIB;
1917 case WGLWidget::FRONT:
1918 return GL_FRONT;
1919 case WGLWidget::BACK:
1920 return GL_BACK;
1921 case WGLWidget::FRONT_AND_BACK:
1922 return GL_FRONT_AND_BACK;
1923 case WGLWidget::CULL_FACE:
1924 return GL_CULL_FACE;
1925 case WGLWidget::BLEND:
1926 return GL_BLEND;
1927 case WGLWidget::DITHER:
1928 return GL_DITHER;
1929 case WGLWidget::STENCIL_TEST:
1930 return GL_STENCIL_TEST;
1931 case WGLWidget::DEPTH_TEST:
1932 return GL_DEPTH_TEST;
1933 case WGLWidget::SCISSOR_TEST:
1934 return GL_SCISSOR_TEST;
1935 case WGLWidget::POLYGON_OFFSET_FILL:
1936 return GL_POLYGON_OFFSET_FILL;
1937 case WGLWidget::SAMPLE_ALPHA_TO_COVERAGE:
1938 return GL_SAMPLE_ALPHA_TO_COVERAGE;
1939 case WGLWidget::SAMPLE_COVERAGE:
1940 return GL_SAMPLE_COVERAGE;
1941 // case WGLWidget::NO_ERROR:
1942 // return GL_NO_ERROR;
1943 case WGLWidget::INVALID_ENUM:
1944 return GL_INVALID_ENUM;
1945 case WGLWidget::INVALID_VALUE:
1946 return GL_INVALID_VALUE;
1947 case WGLWidget::INVALID_OPERATION:
1948 return GL_INVALID_OPERATION;
1949 case WGLWidget::OUT_OF_MEMORY:
1950 return GL_OUT_OF_MEMORY;
1951 case WGLWidget::CW:
1952 return GL_CW;
1953 case WGLWidget::CCW:
1954 return GL_CCW;
1955 case WGLWidget::LINE_WIDTH:
1956 return GL_LINE_WIDTH;
1957 case WGLWidget::ALIASED_POINT_SIZE_RANGE:
1958 return GL_ALIASED_POINT_SIZE_RANGE;
1959 case WGLWidget::ALIASED_LINE_WIDTH_RANGE:
1960 return GL_ALIASED_LINE_WIDTH_RANGE;
1961 case WGLWidget::CULL_FACE_MODE:
1962 return GL_CULL_FACE_MODE;
1963 case WGLWidget::FRONT_FACE:
1964 return GL_FRONT_FACE;
1965 case WGLWidget::DEPTH_RANGE:
1966 return GL_DEPTH_RANGE;
1967 case WGLWidget::DEPTH_WRITEMASK:
1968 return GL_DEPTH_WRITEMASK;
1969 case WGLWidget::DEPTH_CLEAR_VALUE:
1970 return GL_DEPTH_CLEAR_VALUE;
1971 case WGLWidget::DEPTH_FUNC:
1972 return GL_DEPTH_FUNC;
1973 case WGLWidget::STENCIL_CLEAR_VALUE:
1974 return GL_STENCIL_CLEAR_VALUE;
1975 case WGLWidget::STENCIL_FUNC:
1976 return GL_STENCIL_FUNC;
1977 case WGLWidget::STENCIL_FAIL:
1978 return GL_STENCIL_FAIL;
1979 case WGLWidget::STENCIL_PASS_DEPTH_FAIL:
1980 return GL_STENCIL_PASS_DEPTH_FAIL;
1981 case WGLWidget::STENCIL_PASS_DEPTH_PASS:
1982 return GL_STENCIL_PASS_DEPTH_PASS;
1983 case WGLWidget::STENCIL_REF:
1984 return GL_STENCIL_REF;
1985 case WGLWidget::STENCIL_VALUE_MASK:
1986 return GL_STENCIL_VALUE_MASK;
1987 case WGLWidget::STENCIL_WRITEMASK:
1988 return GL_STENCIL_WRITEMASK;
1989 case WGLWidget::STENCIL_BACK_FUNC:
1990 return GL_STENCIL_BACK_FUNC;
1991 case WGLWidget::STENCIL_BACK_FAIL:
1992 return GL_STENCIL_BACK_FAIL;
1993 case WGLWidget::STENCIL_BACK_PASS_DEPTH_FAIL:
1994 return GL_STENCIL_BACK_PASS_DEPTH_FAIL;
1995 case WGLWidget::STENCIL_BACK_PASS_DEPTH_PASS:
1996 return GL_STENCIL_BACK_PASS_DEPTH_PASS;
1997 case WGLWidget::STENCIL_BACK_REF:
1998 return GL_STENCIL_BACK_REF;
1999 case WGLWidget::STENCIL_BACK_VALUE_MASK:
2000 return GL_STENCIL_BACK_VALUE_MASK;
2001 case WGLWidget::STENCIL_BACK_WRITEMASK:
2002 return GL_STENCIL_BACK_WRITEMASK;
2003 case WGLWidget::VIEWPORT:
2004 return GL_VIEWPORT;
2005 case WGLWidget::SCISSOR_BOX:
2006 return GL_SCISSOR_BOX;
2007 case WGLWidget::COLOR_CLEAR_VALUE:
2008 return GL_COLOR_CLEAR_VALUE;
2009 case WGLWidget::COLOR_WRITEMASK:
2010 return GL_COLOR_WRITEMASK;
2011 case WGLWidget::UNPACK_ALIGNMENT:
2012 return GL_UNPACK_ALIGNMENT;
2013 case WGLWidget::PACK_ALIGNMENT:
2014 return GL_PACK_ALIGNMENT;
2015 case WGLWidget::MAX_TEXTURE_SIZE:
2016 return GL_MAX_TEXTURE_SIZE;
2017 case WGLWidget::MAX_VIEWPORT_DIMS:
2018 return GL_MAX_VIEWPORT_DIMS;
2019 case WGLWidget::SUBPIXEL_BITS:
2020 return GL_SUBPIXEL_BITS;
2021 case WGLWidget::RED_BITS:
2022 return GL_RED_BITS;
2023 case WGLWidget::GREEN_BITS:
2024 return GL_GREEN_BITS;
2025 case WGLWidget::BLUE_BITS:
2026 return GL_BLUE_BITS;
2027 case WGLWidget::ALPHA_BITS:
2028 return GL_ALPHA_BITS;
2029 case WGLWidget::DEPTH_BITS:
2030 return GL_DEPTH_BITS;
2031 case WGLWidget::STENCIL_BITS:
2032 return GL_STENCIL_BITS;
2033 case WGLWidget::POLYGON_OFFSET_UNITS:
2034 return GL_POLYGON_OFFSET_UNITS;
2035 case WGLWidget::POLYGON_OFFSET_FACTOR:
2036 return GL_POLYGON_OFFSET_FACTOR;
2037 case WGLWidget::TEXTURE_BINDING_2D:
2038 return GL_TEXTURE_BINDING_2D;
2039 case WGLWidget::SAMPLE_BUFFERS:
2040 return GL_SAMPLE_BUFFERS;
2041 case WGLWidget::SAMPLES:
2042 return GL_SAMPLES;
2043 case WGLWidget::SAMPLE_COVERAGE_VALUE:
2044 return GL_SAMPLE_COVERAGE_VALUE;
2045 case WGLWidget::SAMPLE_COVERAGE_INVERT:
2046 return GL_SAMPLE_COVERAGE_INVERT;
2047 case WGLWidget::NUM_COMPRESSED_TEXTURE_FORMATS:
2048 return GL_NUM_COMPRESSED_TEXTURE_FORMATS;
2049 case WGLWidget::COMPRESSED_TEXTURE_FORMATS:
2050 return GL_COMPRESSED_TEXTURE_FORMATS;
2051 case WGLWidget::DONT_CARE:
2052 return GL_DONT_CARE;
2053 case WGLWidget::FASTEST:
2054 return GL_FASTEST;
2055 case WGLWidget::NICEST:
2056 return GL_NICEST;
2057 case WGLWidget::GENERATE_MIPMAP_HINT:
2058 return GL_GENERATE_MIPMAP_HINT;
2059 case WGLWidget::BYTE:
2060 return GL_BYTE;
2061 case WGLWidget::UNSIGNED_BYTE:
2062 return GL_UNSIGNED_BYTE;
2063 case WGLWidget::SHORT:
2064 return GL_SHORT;
2065 case WGLWidget::UNSIGNED_SHORT:
2066 return GL_UNSIGNED_SHORT;
2067 case WGLWidget::INT:
2068 return GL_INT;
2069 case WGLWidget::UNSIGNED_INT:
2070 return GL_UNSIGNED_INT;
2071 case WGLWidget::FLOAT:
2072 return GL_FLOAT;
2073 case WGLWidget::DEPTH_COMPONENT:
2074 return GL_DEPTH_COMPONENT;
2075 case WGLWidget::ALPHA:
2076 return GL_ALPHA;
2077 case WGLWidget::RGB:
2078 return GL_RGB;
2079 case WGLWidget::RGBA:
2080 return GL_RGBA;
2081 case WGLWidget::LUMINANCE:
2082 return GL_LUMINANCE;
2083 case WGLWidget::LUMINANCE_ALPHA:
2084 return GL_LUMINANCE_ALPHA;
2085 case WGLWidget::UNSIGNED_SHORT_4_4_4_4:
2086 return GL_UNSIGNED_SHORT_4_4_4_4;
2087 case WGLWidget::UNSIGNED_SHORT_5_5_5_1:
2088 return GL_UNSIGNED_SHORT_5_5_5_1;
2089 case WGLWidget::UNSIGNED_SHORT_5_6_5:
2090 return GL_UNSIGNED_SHORT_5_6_5;
2091 case WGLWidget::FRAGMENT_SHADER:
2092 return GL_FRAGMENT_SHADER;
2093 case WGLWidget::VERTEX_SHADER:
2094 return GL_VERTEX_SHADER;
2095 case WGLWidget::MAX_VERTEX_ATTRIBS:
2096 return GL_MAX_VERTEX_ATTRIBS;
2097 case WGLWidget::MAX_VERTEX_UNIFORM_VECTORS:
2098 return GL_MAX_VERTEX_UNIFORM_VECTORS;
2099 case WGLWidget::MAX_VARYING_VECTORS:
2100 return GL_MAX_VARYING_VECTORS;
2101 case WGLWidget::MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2102 return GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS;
2103 case WGLWidget::MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2104 return GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;
2105 case WGLWidget::MAX_TEXTURE_IMAGE_UNITS:
2106 return GL_MAX_TEXTURE_IMAGE_UNITS;
2107 case WGLWidget::MAX_FRAGMENT_UNIFORM_VECTORS:
2108 return GL_MAX_FRAGMENT_UNIFORM_VECTORS;
2109 case WGLWidget::SHADER_TYPE:
2110 return GL_SHADER_TYPE;
2111 case WGLWidget::DELETE_STATUS:
2112 return GL_DELETE_STATUS;
2113 case WGLWidget::LINK_STATUS:
2114 return GL_LINK_STATUS;
2115 case WGLWidget::VALIDATE_STATUS:
2116 return GL_VALIDATE_STATUS;
2117 case WGLWidget::ATTACHED_SHADERS:
2118 return GL_ATTACHED_SHADERS;
2119 case WGLWidget::ACTIVE_UNIFORMS:
2120 return GL_ACTIVE_UNIFORMS;
2121 case WGLWidget::ACTIVE_UNIFORM_MAX_LENGTH:
2122 return GL_ACTIVE_UNIFORM_MAX_LENGTH;
2123 case WGLWidget::ACTIVE_ATTRIBUTES:
2124 return GL_ACTIVE_ATTRIBUTES;
2125 case WGLWidget::ACTIVE_ATTRIBUTE_MAX_LENGTH:
2126 return GL_ACTIVE_ATTRIBUTE_MAX_LENGTH;
2127 case WGLWidget::SHADING_LANGUAGE_VERSION:
2128 return GL_SHADING_LANGUAGE_VERSION;
2129 case WGLWidget::CURRENT_PROGRAM:
2130 return GL_CURRENT_PROGRAM;
2131 case WGLWidget::NEVER:
2132 return GL_NEVER;
2133 case WGLWidget::LESS:
2134 return GL_LESS;
2135 case WGLWidget::EQUAL:
2136 return GL_EQUAL;
2137 case WGLWidget::LEQUAL:
2138 return GL_LEQUAL;
2139 case WGLWidget::GREATER:
2140 return GL_GREATER;
2141 case WGLWidget::NOTEQUAL:
2142 return GL_NOTEQUAL;
2143 case WGLWidget::GEQUAL:
2144 return GL_GEQUAL;
2145 case WGLWidget::ALWAYS:
2146 return GL_ALWAYS;
2147 case WGLWidget::KEEP:
2148 return GL_KEEP;
2149 case WGLWidget::REPLACE:
2150 return GL_REPLACE;
2151 case WGLWidget::INCR:
2152 return GL_INCR;
2153 case WGLWidget::DECR:
2154 return GL_DECR;
2155 case WGLWidget::INVERT:
2156 return GL_INVERT;
2157 case WGLWidget::INCR_WRAP:
2158 return GL_INCR_WRAP;
2159 case WGLWidget::DECR_WRAP:
2160 return GL_DECR_WRAP;
2161 case WGLWidget::VENDOR:
2162 return GL_VENDOR;
2163 case WGLWidget::RENDERER:
2164 return GL_RENDERER;
2165 case WGLWidget::VERSION:
2166 return GL_VERSION;
2167 case WGLWidget::NEAREST:
2168 return GL_NEAREST;
2169 case WGLWidget::LINEAR:
2170 return GL_LINEAR;
2171 case WGLWidget::NEAREST_MIPMAP_NEAREST:
2172 return GL_NEAREST_MIPMAP_NEAREST;
2173 case WGLWidget::LINEAR_MIPMAP_NEAREST:
2174 return GL_LINEAR_MIPMAP_NEAREST;
2175 case WGLWidget::NEAREST_MIPMAP_LINEAR:
2176 return GL_NEAREST_MIPMAP_LINEAR;
2177 case WGLWidget::LINEAR_MIPMAP_LINEAR:
2178 return GL_LINEAR_MIPMAP_LINEAR;
2179 case WGLWidget::TEXTURE_MAG_FILTER:
2180 return GL_TEXTURE_MAG_FILTER;
2181 case WGLWidget::TEXTURE_MIN_FILTER:
2182 return GL_TEXTURE_MIN_FILTER;
2183 case WGLWidget::TEXTURE_WRAP_S:
2184 return GL_TEXTURE_WRAP_S;
2185 case WGLWidget::TEXTURE_WRAP_T:
2186 return GL_TEXTURE_WRAP_T;
2187 case WGLWidget::TEXTURE_2D:
2188 return GL_TEXTURE_2D;
2189 case WGLWidget::TEXTURE:
2190 return GL_TEXTURE;
2191 case WGLWidget::TEXTURE_CUBE_MAP:
2192 return GL_TEXTURE_CUBE_MAP;
2193 case WGLWidget::TEXTURE_BINDING_CUBE_MAP:
2194 return GL_TEXTURE_BINDING_CUBE_MAP;
2195 case WGLWidget::TEXTURE_CUBE_MAP_POSITIVE_X:
2196 return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
2197 case WGLWidget::TEXTURE_CUBE_MAP_NEGATIVE_X:
2198 return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
2199 case WGLWidget::TEXTURE_CUBE_MAP_POSITIVE_Y:
2200 return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
2201 case WGLWidget::TEXTURE_CUBE_MAP_NEGATIVE_Y:
2202 return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
2203 case WGLWidget::TEXTURE_CUBE_MAP_POSITIVE_Z:
2204 return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
2205 case WGLWidget::TEXTURE_CUBE_MAP_NEGATIVE_Z:
2206 return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
2207 case WGLWidget::MAX_CUBE_MAP_TEXTURE_SIZE:
2208 return GL_MAX_CUBE_MAP_TEXTURE_SIZE;
2209 case WGLWidget::TEXTURE0:
2210 return GL_TEXTURE0;
2211 case WGLWidget::TEXTURE1:
2212 return GL_TEXTURE1;
2213 case WGLWidget::TEXTURE2:
2214 return GL_TEXTURE2;
2215 case WGLWidget::TEXTURE3:
2216 return GL_TEXTURE3;
2217 case WGLWidget::TEXTURE4:
2218 return GL_TEXTURE4;
2219 case WGLWidget::TEXTURE5:
2220 return GL_TEXTURE5;
2221 case WGLWidget::TEXTURE6:
2222 return GL_TEXTURE6;
2223 case WGLWidget::TEXTURE7:
2224 return GL_TEXTURE7;
2225 case WGLWidget::TEXTURE8:
2226 return GL_TEXTURE8;
2227 case WGLWidget::TEXTURE9:
2228 return GL_TEXTURE9;
2229 case WGLWidget::TEXTURE10:
2230 return GL_TEXTURE10;
2231 case WGLWidget::TEXTURE11:
2232 return GL_TEXTURE11;
2233 case WGLWidget::TEXTURE12:
2234 return GL_TEXTURE12;
2235 case WGLWidget::TEXTURE13:
2236 return GL_TEXTURE13;
2237 case WGLWidget::TEXTURE14:
2238 return GL_TEXTURE14;
2239 case WGLWidget::TEXTURE15:
2240 return GL_TEXTURE15;
2241 case WGLWidget::TEXTURE16:
2242 return GL_TEXTURE16;
2243 case WGLWidget::TEXTURE17:
2244 return GL_TEXTURE17;
2245 case WGLWidget::TEXTURE18:
2246 return GL_TEXTURE18;
2247 case WGLWidget::TEXTURE19:
2248 return GL_TEXTURE19;
2249 case WGLWidget::TEXTURE20:
2250 return GL_TEXTURE20;
2251 case WGLWidget::TEXTURE21:
2252 return GL_TEXTURE21;
2253 case WGLWidget::TEXTURE22:
2254 return GL_TEXTURE22;
2255 case WGLWidget::TEXTURE23:
2256 return GL_TEXTURE23;
2257 case WGLWidget::TEXTURE24:
2258 return GL_TEXTURE24;
2259 case WGLWidget::TEXTURE25:
2260 return GL_TEXTURE25;
2261 case WGLWidget::TEXTURE26:
2262 return GL_TEXTURE26;
2263 case WGLWidget::TEXTURE27:
2264 return GL_TEXTURE27;
2265 case WGLWidget::TEXTURE28:
2266 return GL_TEXTURE28;
2267 case WGLWidget::TEXTURE29:
2268 return GL_TEXTURE29;
2269 case WGLWidget::TEXTURE30:
2270 return GL_TEXTURE30;
2271 case WGLWidget::TEXTURE31:
2272 return GL_TEXTURE31;
2273 case WGLWidget::ACTIVE_TEXTURE:
2274 return GL_ACTIVE_TEXTURE;
2275 case WGLWidget::REPEAT:
2276 return GL_REPEAT;
2277 case WGLWidget::CLAMP_TO_EDGE:
2278 return GL_CLAMP_TO_EDGE;
2279 case WGLWidget::MIRRORED_REPEAT:
2280 return GL_MIRRORED_REPEAT;
2281 case WGLWidget::FLOAT_VEC2:
2282 return GL_FLOAT_VEC2;
2283 case WGLWidget::FLOAT_VEC3:
2284 return GL_FLOAT_VEC3;
2285 case WGLWidget::FLOAT_VEC4:
2286 return GL_FLOAT_VEC4;
2287 case WGLWidget::INT_VEC2:
2288 return GL_INT_VEC2;
2289 case WGLWidget::INT_VEC3:
2290 return GL_INT_VEC3;
2291 case WGLWidget::INT_VEC4:
2292 return GL_INT_VEC4;
2293 case WGLWidget::BOOL:
2294 return GL_BOOL;
2295 case WGLWidget::BOOL_VEC2:
2296 return GL_BOOL_VEC2;
2297 case WGLWidget::BOOL_VEC3:
2298 return GL_BOOL_VEC3;
2299 case WGLWidget::BOOL_VEC4:
2300 return GL_BOOL_VEC4;
2301 case WGLWidget::FLOAT_MAT2:
2302 return GL_FLOAT_MAT2;
2303 case WGLWidget::FLOAT_MAT3:
2304 return GL_FLOAT_MAT3;
2305 case WGLWidget::FLOAT_MAT4:
2306 return GL_FLOAT_MAT4;
2307 case WGLWidget::SAMPLER_2D:
2308 return GL_SAMPLER_2D;
2309 case WGLWidget::SAMPLER_CUBE:
2310 return GL_SAMPLER_CUBE;
2311 case WGLWidget::VERTEX_ATTRIB_ARRAY_ENABLED:
2312 return GL_VERTEX_ATTRIB_ARRAY_ENABLED;
2313 case WGLWidget::VERTEX_ATTRIB_ARRAY_SIZE:
2314 return GL_VERTEX_ATTRIB_ARRAY_SIZE;
2315 case WGLWidget::VERTEX_ATTRIB_ARRAY_STRIDE:
2316 return GL_VERTEX_ATTRIB_ARRAY_STRIDE;
2317 case WGLWidget::VERTEX_ATTRIB_ARRAY_TYPE:
2318 return GL_VERTEX_ATTRIB_ARRAY_TYPE;
2319 case WGLWidget::VERTEX_ATTRIB_ARRAY_NORMALIZED:
2320 return GL_VERTEX_ATTRIB_ARRAY_NORMALIZED;
2321 case WGLWidget::VERTEX_ATTRIB_ARRAY_POINTER:
2322 return GL_VERTEX_ATTRIB_ARRAY_POINTER;
2323 case WGLWidget::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
2324 return GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING;
2325 case WGLWidget::COMPILE_STATUS:
2326 return GL_COMPILE_STATUS;
2327 case WGLWidget::INFO_LOG_LENGTH:
2328 return GL_INFO_LOG_LENGTH;
2329 case WGLWidget::SHADER_SOURCE_LENGTH:
2330 return GL_SHADER_SOURCE_LENGTH;
2331 case WGLWidget::LOW_FLOAT:
2332 return GL_LOW_FLOAT;
2333 case WGLWidget::MEDIUM_FLOAT:
2334 return GL_MEDIUM_FLOAT;
2335 case WGLWidget::HIGH_FLOAT:
2336 return GL_HIGH_FLOAT;
2337 case WGLWidget::LOW_INT:
2338 return GL_LOW_INT;
2339 case WGLWidget::MEDIUM_INT:
2340 return GL_MEDIUM_INT;
2341 case WGLWidget::HIGH_INT:
2342 return GL_HIGH_INT;
2343 case WGLWidget::FRAMEBUFFER:
2344 return GL_FRAMEBUFFER;
2345 case WGLWidget::RENDERBUFFER:
2346 return GL_RENDERBUFFER;
2347 case WGLWidget::RGBA4:
2348 return GL_RGBA4;
2349 case WGLWidget::RGB5_A1:
2350 return GL_RGB5_A1;
2351 case WGLWidget::RGB565:
2352 return GL_RGB565;
2353 case WGLWidget::DEPTH_COMPONENT16:
2354 return GL_DEPTH_COMPONENT16;
2355 case WGLWidget::STENCIL_INDEX:
2356 return GL_STENCIL_INDEX;
2357 case WGLWidget::STENCIL_INDEX8:
2358 return GL_STENCIL_INDEX8;
2359 case WGLWidget::DEPTH_STENCIL:
2360 return GL_DEPTH_STENCIL;
2361 case WGLWidget::RENDERBUFFER_WIDTH:
2362 return GL_RENDERBUFFER_WIDTH;
2363 case WGLWidget::RENDERBUFFER_HEIGHT:
2364 return GL_RENDERBUFFER_HEIGHT;
2365 case WGLWidget::RENDERBUFFER_INTERNAL_FORMAT:
2366 return GL_RENDERBUFFER_INTERNAL_FORMAT;
2367 case WGLWidget::RENDERBUFFER_RED_SIZE:
2368 return GL_RENDERBUFFER_RED_SIZE;
2369 case WGLWidget::RENDERBUFFER_GREEN_SIZE:
2370 return GL_RENDERBUFFER_GREEN_SIZE;
2371 case WGLWidget::RENDERBUFFER_BLUE_SIZE:
2372 return GL_RENDERBUFFER_BLUE_SIZE;
2373 case WGLWidget::RENDERBUFFER_ALPHA_SIZE:
2374 return GL_RENDERBUFFER_ALPHA_SIZE;
2375 case WGLWidget::RENDERBUFFER_DEPTH_SIZE:
2376 return GL_RENDERBUFFER_DEPTH_SIZE;
2377 case WGLWidget::RENDERBUFFER_STENCIL_SIZE:
2378 return GL_RENDERBUFFER_STENCIL_SIZE;
2379 case WGLWidget::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2380 return GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE;
2381 case WGLWidget::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2382 return GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME;
2383 case WGLWidget::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2384 return GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL;
2385 case WGLWidget::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2386 return GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE;
2387 case WGLWidget::COLOR_ATTACHMENT0:
2388 return GL_COLOR_ATTACHMENT0;
2389 case WGLWidget::DEPTH_ATTACHMENT:
2390 return GL_DEPTH_ATTACHMENT;
2391 case WGLWidget::STENCIL_ATTACHMENT:
2392 return GL_STENCIL_ATTACHMENT;
2393 case WGLWidget::DEPTH_STENCIL_ATTACHMENT:
2394 return GL_DEPTH_STENCIL_ATTACHMENT;
2395 // case WGLWidget::NONE:
2396 // return GL_NONE;
2397 case WGLWidget::FRAMEBUFFER_COMPLETE:
2398 return GL_FRAMEBUFFER_COMPLETE;
2399 case WGLWidget::FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
2400 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
2401 case WGLWidget::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
2402 return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
2403 // case WGLWidget::FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
2404 // return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
2405 case WGLWidget::FRAMEBUFFER_UNSUPPORTED:
2406 return GL_FRAMEBUFFER_UNSUPPORTED;
2407 case WGLWidget::FRAMEBUFFER_BINDING:
2408 return GL_FRAMEBUFFER_BINDING;
2409 case WGLWidget::RENDERBUFFER_BINDING:
2410 return GL_RENDERBUFFER_BINDING;
2411 case WGLWidget::MAX_RENDERBUFFER_SIZE:
2412 return GL_MAX_RENDERBUFFER_SIZE;
2413 case WGLWidget::INVALID_FRAMEBUFFER_OPERATION:
2414 return GL_INVALID_FRAMEBUFFER_OPERATION;
2415 default:
2416 return -1;
2417 }
2418 }
2419
2420 }
2421