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, &params);
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