1 // This may look like C code, but it's really -*- C++ -*- 2 /* 3 * Copyright (C) 2010 Emweb bv, Herent, Belgium. 4 * 5 * See the LICENSE file for terms of use. 6 */ 7 #ifndef WGLWIDGET_H_ 8 #define WGLWIDGET_H_ 9 10 #include <Wt/WException.h> 11 #include <Wt/WInteractWidget.h> 12 #include <Wt/WJavaScriptSlot.h> 13 #include <Wt/WGenericMatrix.h> 14 #include <Wt/WMatrix4x4.h> 15 16 #ifndef WT_TARGET_JAVA 17 namespace Wt { 18 typedef std::vector<float> FloatBuffer; 19 typedef std::vector<int> IntBuffer; 20 } 21 #else 22 #include <java/buffer> 23 #endif 24 25 namespace Wt { 26 27 // define to enable WebGL debug code 28 #define WT_WGLWIDGET_DEBUG 29 30 #ifdef WT_TARGET_JAVA 31 #define __FUNCTION__ "(unknown)" 32 #endif 33 34 #ifdef WT_WGLWIDGET_DEBUG 35 #define GLDEBUG do {if (debugging_) {js_ << "\n{var err = ctx.getError(); if(err != ctx.NO_ERROR && err != ctx.CONTEXT_LOST_WEBGL) {alert('error " << __FUNCTION__ << ": ' + err); debugger;}}\n";}} while(false) 36 //if (glGetError() != GL_NO_ERROR){} 37 #define SERVERGLDEBUG do {if (debugging_) {int err = glGetError(); if (err != GL_NO_ERROR){std::cerr << "gl error occured in " << __FUNCTION__ << ": " << err << std::endl;}} } while(false) 38 //#define GLDEBUG do {js_ << "\n{var err = ctx.getError(); if(err != ctx.NO_ERROR) {debugger;}}\n";} while(false) 39 #else 40 #define GLDEBUG 41 #endif 42 43 class WAbstractGLImplementation; 44 class WPaintDevice; 45 46 #if !defined(WT_TARGET_JAVA) 47 #define WT_WGL_TEMPLATE(...) template < __VA_ARGS__ > 48 #else 49 #define WT_WGL_TEMPLATE(...) 50 #endif 51 52 class WHTML5Video; 53 class WImage; 54 55 enum class JsArrayType { 56 Array, 57 Float32Array 58 }; 59 60 /*! \brief Enumeration for render options 61 * 62 * \sa setRenderOptions() 63 */ 64 enum class GLRenderOption { 65 ClientSide = 0x1, //!< Enables client-side rendering 66 ServerSide = 0x2, //!< Enables server-side rendering 67 AntiAliasing = 0x4 //!< Enables anti-aliasing 68 }; 69 70 /*! \brief Specifies what GL function needs to be updated 71 */ 72 enum class GLClientSideRenderer { 73 PAINT_GL = 0x1, //!< refresh paintGL() 74 RESIZE_GL = 0x2, //!< refresh resizeGL() 75 UPDATE_GL = 0x4 //!< refresh updateGL() 76 }; 77 78 /*! \class WGLWidget Wt/WGLWidget.h Wt/WGLWidget.h 79 * \brief GL support class 80 * 81 * The WGLWidget class is an interface to the HTML5 WebGL infrastructure 82 * for client-side rendering, and OpenGL for server-side rendering. 83 * Its API is based on the WebGL API. To fully understand WebGL, it is 84 * recommended to read the WebGL standard in addition to this documentation. 85 * 86 * The most recent version of the WebGL specification can be found here: 87 * http://www.khronos.org/registry/webgl/specs/latest/1.0/ 88 * 89 * The goal of the WGLWidget class is to provide a method to render 3D 90 * structures in the browser, where rendering and rerendering is normally 91 * done at the client side in JavaScript without interaction from the server, 92 * in order to obtain a smooth user interaction. Unless the scene requires 93 * server-side updates, there is no communication with the server. 94 * 95 * The rendering interface resembles to OpenGL ES, the same standard as 96 * WebGL is based on. This is a stripped down version of the normal OpenGL 97 * as we usually find them on desktops. Many stateful OpenGL features are 98 * not present in OpenGL ES: no modelview and camera transformation stacks, 99 * no default lighting models, no support for other rendering methods than 100 * through VBOs, ... Therefore much existing example code for OpenGL 101 * applications and shaders will not work on WebGL without modifications. 102 * The 'learning webgl' web site at http://learningwebgl.com/ is a good 103 * starting point to get familiar with WebGL. 104 * 105 * To use a %WGLWidget, you must derive from it and reimplement 106 * the painter methods. Usually, you will always need to implement 107 * initializeGL() and paintGL(). Optionally, you may choose to implement 108 * resizeGL() (if your widget does not have a fixed size), and updateGL(). 109 * If you need to modify the painting methods, a repaint is triggered by 110 * calling the repaintGL() method. The default behaviour for any of these 111 * four painting functions is to do nothing. 112 * 113 * The four painter methods (initializeGL(), resizeGL(), paintGL() and 114 * updateGL()) all record JavaScript which is sent to the 115 * browser. The JavaScript code of paintGL() is cached client-side, and 116 * may be executed many times, e.g. to repaint a scene from different 117 * viewpoints. The JavaScript code of initializeGL(), resizeGL() and 118 * updateGL() are intended for OpenGL state updates, and is therefore 119 * only executed once on the client and is then discarded. 120 * 121 * There are four painting methods that you may implement in a 122 * specialization of this class. The purpose of these functions is 123 * to register what JavaScript code has to be executed to render a 124 * scene. Through invocations of the WebGL functions documented below, 125 * %Wt records the JavaScript calls that have to be invoked in the 126 * browser. 127 * <ul> 128 * <li><b>initializeGL()</b>: this function is executed after the GL 129 * context has been initialized. It is also executed when the 130 * \c webglcontextrestored signal is fired. You can distinguish between 131 * the first initialization and restoration of context using restoringContext(). 132 * This is the ideal location to compose shader programs, send VBO's to 133 * the client, extract uniform and attribute locations, ... Due to 134 * the presence of VBO's, this function may generate a large amount 135 * of data to the client. 136 * <li><b>resizeGL()</b>: this function is executed whenever the canvas 137 * dimensions change. A change in canvas size will require you to 138 * invoke the viewport() function again, as well as recalculate the 139 * projection matrices (especially when the aspect ratio has changed). 140 * The resizeGL() function is therefore the ideal location to set those 141 * properties. 142 * The resizeGL() function is invoked automatically on every resize, 143 * and after the first initializeGL() invocation. Additional invocations 144 * may be triggered by calling repaint() with the RESIZE_GL flag. 145 * <li><b>paintGL()</b>: this is the main scene drawing function. Through 146 * its execution, %Wt records what has to be done to render a scene, 147 * and it is executed every time that the scene is to be redrawn. You 148 * can use the VBO's and shaders prepared in the initializeGL() phase. 149 * Usually, this function sets uniforms and attributes, links 150 * attributes to VBO's, applies textures, and draws primitives. 151 * You may also create local programs, buffers, ... Remember that this 152 * function is executed a lot of times, so every buffer/program created 153 * in this function should also be destroyed to avoid memory leaks. 154 * This function is transmitted once to the client, and is executed 155 * when the scene needs to be redrawn. Redraws may be triggered from 156 * mouse events, timer triggers, events on e.g. a video element, or 157 * whatever other event. 158 * The paintGL() function can be updated through invoking repaintGL() 159 * with the PAINT_GL flag. 160 * <li><b>updateGL()</b>: VBO's, programs, uniforms, GL properties, 161 * or anything else set during intializeGL() are not necessarily 162 * immutable. If you want to change, add, remove or reconfigure those 163 * properties, the execution of an updateGL() function can be triggered 164 * by invoking repaintGL() with the UPDATE_GL flag. This signals that 165 * updateGL() needs to be evaluated - just once. It is possible that 166 * the paintGL() function also requires updates as consequence of the 167 * changes in the updateGL() function; in this case, you should also set 168 * the PAINT_GL flag of repaintGL(). 169 * </ul> 170 * 171 * The GL functions are intended to be used exclusively from within the 172 * invocation of the four callback functions mentioned above. In order to 173 * manually trigger the execution of these function, use the repaintGL(). 174 * 175 * A WGLWidget must be given a size explicitly, or must be put inside a 176 * layout manager that manages its width and height. The behaviour of a 177 * WGLWidget that was not given a size is undefined. 178 * 179 * <h3>Binary buffer transfers</h3> 180 * 181 * In bufferDatafv(), there is an additional boolean argument where you 182 * can indicate that you want the data to be transferred to the client in 183 * binary form. A WMemoryResource is created for each of these buffers. If 184 * you know all previous resources are not required in the client anymore, 185 * you can free memory with the method clearBinaryResources() (the memory 186 * is also managed, so this is not neccesary). If you want to manage these 187 * resources entirely by yourself, the following method can be used. 188 * 189 * Using createAndLoadArrayBuffer(), you can load an array buffer in 190 * binary format from an URL. This will cause the client to fetch the 191 * given URL, and make the contents of the file available in an 192 * ArrayBuffer, which can then be used by BufferData() to bind them 193 * to an OpenGL buffer. This is ideal to load VBO buffers in a faster 194 * way, as it avoids converting floats to text strings on the server 195 * and then back to floats on the client. You can combine this with 196 * the use of WResource (e.g. WMemoryResource) to send an std::vector of 197 * vertices to the client. Note that using ArrayBuffer is not possible when 198 * you want a fall-back in the form of server-side rendering. 199 * 200 * <h3>Client side matrices and vectors.</h3> 201 * 202 * The WGLWidget provides the WGLWidget::JavaScriptMatrix4x4 class as 203 * a mechanism to use client-side modifiable matrices in the render 204 * functions. These matrices can be used identically to the 205 * 'constant', with the advantage that there is no need to have a 206 * roundtrip to the server to redraw the scene when they are changed. 207 * As such, they are ideal for mouse-based camera manipulations, timer 208 * triggered animations, or object manipulations. 209 * 210 * There's also support for client-side modifiable vectors, with 211 * WGLWidget::JavaScriptVector. 212 */ 213 class WT_API WGLWidget: public WInteractWidget 214 { 215 #ifdef WT_TARGET_JAVA 216 typedef float FloatArray; 217 typedef int IntArray; 218 typedef double MatrixType; 219 #endif 220 221 public: 222 /*! \brief Typedef for enum Wt::GLRenderOption */ 223 typedef GLRenderOption RenderOption; 224 /*! \brief Typedef for enum Wt::GLClientSideRenderer */ 225 typedef GLClientSideRenderer ClientSideRenderer; 226 227 228 //! Abstract base class for all GL objects 229 class WT_API GlObject { 230 public: GlObject()231 GlObject(): id_(-1) {} GlObject(int id)232 GlObject(int id) : 233 id_(id) {} ~GlObject()234 virtual ~GlObject() {} 235 236 virtual std::string jsRef() const = 0; 237 getId()238 int getId() const { return id_; } 239 clear()240 void clear() { id_ = -1; } 241 isNull()242 bool isNull() const { return id_ == -1; } 243 244 private: 245 int id_; 246 }; 247 248 //! Reference to a WebGLShader class 249 class WT_API Shader : public GlObject { 250 public: Shader()251 Shader() {} 252 Shader(int i)253 explicit Shader(int i) : 254 GlObject(i) {} 255 jsRef()256 virtual std::string jsRef() const override 257 { 258 if (isNull()) 259 throw WException("Shader: is null"); 260 return std::string("ctx.WtShader") + std::to_string(getId()); 261 } 262 }; 263 264 //! Reference to a WebGLProgram class 265 class WT_API Program : public GlObject { 266 public: Program()267 Program() {} Program(int i)268 explicit Program(int i) : 269 GlObject(i) {} 270 jsRef()271 virtual std::string jsRef() const override 272 { 273 if (isNull()) 274 throw WException("Program: is null"); 275 return std::string("ctx.WtProgram") + std::to_string(getId()); 276 } 277 }; 278 279 //! Reference to a shader attribute location 280 class WT_API AttribLocation : public GlObject { 281 public: AttribLocation()282 AttribLocation() {} AttribLocation(int i)283 explicit AttribLocation(int i) : 284 GlObject(i) {} 285 jsRef()286 virtual std::string jsRef() const override 287 { 288 if (isNull()) 289 throw WException("AttribLocation: is null"); 290 return std::string("ctx.WtAttrib") + std::to_string(getId()); 291 } 292 }; 293 294 //! Reference to a WebGLBuffer class 295 class WT_API Buffer : public GlObject { 296 public: Buffer()297 Buffer() {} Buffer(int i)298 explicit Buffer(int i) : 299 GlObject(i) {} 300 jsRef()301 virtual std::string jsRef() const override 302 { 303 if (isNull()) 304 throw WException("Buffer: is null"); 305 return std::string("ctx.WtBuffer") + std::to_string(getId()); 306 } 307 }; 308 309 //! Reference to a WebGLUniformLocation class 310 class WT_API UniformLocation : public GlObject { 311 public: UniformLocation()312 UniformLocation() {} UniformLocation(int i)313 explicit UniformLocation(int i) : 314 GlObject(i) {} 315 jsRef()316 virtual std::string jsRef() const override 317 { 318 if (isNull()) 319 throw WException("UniformLocation: is null"); 320 return std::string("ctx.WtUniform") + std::to_string(getId()); 321 } 322 }; 323 324 //! Reference to a WebGLTexture class 325 class WT_API Texture: public GlObject { 326 public: Texture()327 Texture() 328 : url_("") 329 {} Texture(int i)330 explicit Texture(int i) : 331 GlObject(i) {} 332 jsRef()333 virtual std::string jsRef() const override 334 { 335 if (isNull()) { 336 // throw WException("Texture: is null"); 337 return "null"; 338 } 339 return std::string("ctx.WtTexture") + std::to_string(getId()); 340 } 341 setUrl(std::string url)342 void setUrl(std::string url) { 343 url_ = url; 344 } 345 url()346 const std::string& url() const { 347 return url_; 348 } 349 350 private: 351 std::string url_; 352 }; 353 354 //! Reference to a WebGLFramebuffer class 355 class WT_API Framebuffer : public GlObject { 356 public: Framebuffer()357 Framebuffer() {} Framebuffer(int i)358 Framebuffer(int i) : 359 GlObject(i) {} 360 jsRef()361 virtual std::string jsRef() const override 362 { 363 if (isNull()) { 364 //throw WException("FrameBuffer: is null"); 365 return "null"; 366 } 367 return "ctx.WtFramebuffer" + std::to_string(getId()); 368 } 369 }; 370 371 //! Reference to a WebGLRenderbuffer class 372 class WT_API Renderbuffer : public GlObject { 373 public: Renderbuffer()374 Renderbuffer() {} Renderbuffer(int i)375 Renderbuffer(int i) : 376 GlObject(i) {} 377 jsRef()378 virtual std::string jsRef() const override 379 { 380 if (isNull()) { 381 //throw WException("RenderBuffer: is null"); 382 return "null"; 383 } 384 return "ctx.WtRenderbuffer" + std::to_string(getId()); 385 } 386 }; 387 388 /*! 389 * \brief Reference to a javascript %ArrayBuffer class 390 */ 391 class WT_API ArrayBuffer : public GlObject { 392 public: ArrayBuffer()393 ArrayBuffer() {} ArrayBuffer(int i)394 ArrayBuffer(int i) : 395 GlObject(i) {} 396 jsRef()397 virtual std::string jsRef() const override 398 { 399 if (isNull()) 400 throw WException("ArrayBuffer: is null"); 401 return "ctx.WtBufferResource" + std::to_string(getId()); 402 } 403 }; 404 405 /*! \brief A client-side JavaScript vector 406 * 407 * Using a JavaScriptVector, GL parameters can be modified without 408 * communication with the server. The value of the JavaScriptMatrix4x4 409 * is updated server-side whenever an event is sent to the server. 410 * 411 * The JavaScriptVector is represented in JavaScript as an array, either 412 * as a Float32Array or as a plain JavaScript array. 413 */ 414 class WT_API JavaScriptVector { 415 public: 416 /** \brief Create a temporarily invalid JavaScriptVector. 417 * 418 * Should be added to a %WGLWidget with 419 * WGLWidget::addJavaScriptVector(), and initialized with 420 * WGLWidget::initJavaScriptVector(). 421 */ 422 JavaScriptVector(unsigned length); 423 424 #ifndef WT_TARGET_JAVA 425 JavaScriptVector(const JavaScriptVector &other); 426 427 JavaScriptVector &operator=(const JavaScriptVector &rhs); 428 #endif 429 id()430 int id() const { return id_; } 431 432 /** \brief Returns whether this %JavaScriptVector has been initialized. 433 */ initialized()434 bool initialized() const { return initialized_; } 435 436 /** \brief Returns whether this %JavaScriptVector has been assigned 437 * to a WGLWidget. 438 */ hasContext()439 bool hasContext() const { return context_ != nullptr; } 440 441 /** \brief Returns the length (number of items) of this JavaScriptVector. 442 */ length()443 unsigned length() const { return length_; } 444 445 /** \brief Returns the JavaScript reference to this JavaScriptVector. 446 * 447 * In order to get a valid JavaScript reference, this vector 448 * should have been added to a WGLWidget. 449 */ jsRef()450 std::string jsRef() const 451 { 452 if (!hasContext()) 453 throw WException("JavaScriptVector: does not belong to a " 454 "WGLWidget yet"); 455 return jsRef_; 456 } 457 458 /** \brief Returns the current server-side value. 459 * 460 * Client-side changes to the JavaScriptVector are automatically 461 * synchronized. 462 */ 463 std::vector<float> value() const; 464 465 #ifdef WT_TARGET_JAVA 466 JavaScriptVector clone() const; 467 #endif 468 private: 469 void assignToContext(int id, const WGLWidget* context); initialize()470 void initialize() { initialized_ = true; } 471 int id_; 472 unsigned length_; 473 std::string jsRef_; 474 const WGLWidget* context_; 475 bool initialized_; 476 477 friend class WGLWidget; 478 friend class WServerGLWidget; 479 friend class WClientGLWidget; 480 }; 481 482 /*! \brief A client-side JavaScript matrix 483 * 484 * A JavaScriptMatrix has methods that make it possible to do client-side 485 * calculations on matrices. 486 * 487 * Using a JavaScriptMatrix4x4, GL parameters can be modified without 488 * communication with the server. The value of the JavaScriptMatrix4x4 489 * is updated server-side whenever an event is sent to the server. 490 * 491 * Important: only the jsRef() of the return value from a call to 492 * WGLWidget::createJavaScriptMatrix() is a variable name that can be used 493 * in custom JavaScript to modify a matrix from external scripts. 494 * The jsRef() of return values of operations refer to unnamed temporary 495 * objects - rvalues in C++-lingo. 496 * 497 * The JavaScriptMatrix4x4 is represented in JavaScript as an array of 16 498 * elements. This array represents the values of the matrix in column-major 499 * order. It is either a Float32Array or a plain JavaScript array. 500 */ 501 class WT_API JavaScriptMatrix4x4 { 502 public: 503 /** \brief Creates a temporarily invalid JavaScriptMatrix4x4. 504 * 505 * Should be added to a %WGLWidget with 506 * WGLWidget::addJavaScriptMatrix4, and initialized with 507 * WGLWidget::initJavaScriptMatrix4. 508 */ 509 JavaScriptMatrix4x4(); 510 511 #ifndef WT_TARGET_JAVA 512 JavaScriptMatrix4x4(const JavaScriptMatrix4x4 &other); 513 514 JavaScriptMatrix4x4 &operator=(const JavaScriptMatrix4x4 &rhs); 515 #endif 516 id()517 int id() const { return id_; } 518 519 /** \brief Returns whether this JavaScriptMatrix4x4 has been initialized. 520 */ initialized()521 bool initialized() const { return initialized_; } 522 523 /** \brief Returns whether this JavaScriptMatrix4x4 has been assigned 524 * to a WGLWidget. 525 */ hasContext()526 bool hasContext() const { return context_ != nullptr; } 527 528 /** \brief Returns the JavaScript reference to this JavaScriptMatrix4x4. 529 * 530 * In order to get a valid JavaScript reference, this matrix should 531 * have been added to a WGLWidget. 532 */ jsRef()533 std::string jsRef() const 534 { 535 if (!hasContext()) 536 throw WException("JavaScriptMatrix4x4: does not belong to a WGLWidget yet"); 537 return jsRef_; 538 } 539 540 /** \brief Returns the current server-side value. 541 * 542 * Client-side changes to the JavaScriptMatrix4x4 are automatically 543 * synchronized. 544 */ 545 WMatrix4x4 value() const; 546 547 JavaScriptMatrix4x4 inverted() const; 548 JavaScriptMatrix4x4 transposed() const; 549 550 #if !defined(WT_TARGET_JAVA) 551 JavaScriptMatrix4x4 operator*(const WGenericMatrix<double, 4, 4> &m) const; 552 #else 553 JavaScriptMatrix4x4 multiply(const WGenericMatrix<MatrixType, 4, 4> &m) const; 554 #endif 555 556 #ifdef WT_TARGET_JAVA 557 JavaScriptMatrix4x4 clone() const; 558 #endif 559 560 private: 561 void assignToContext(int i, const WGLWidget* context); initialize()562 void initialize() { initialized_ = true; } hasOperations()563 bool hasOperations() const { return operations_.size() > 0;} 564 565 // void invert(); 566 // void transpose(); 567 // void mul(const WGenericMatrix<double, 4, 4> &m); 568 569 int id_; 570 std::string jsRef_; 571 const WGLWidget* context_; 572 573 enum class op {TRANSPOSE, INVERT, MULTIPLY}; 574 std::vector<op> operations_; 575 std::vector< WGenericMatrix<double, 4, 4> > matrices_; 576 577 bool initialized_; 578 579 friend class WGLWidget; 580 friend class WServerGLWidget; 581 friend class WClientGLWidget; 582 }; 583 584 /*! \brief Construct a GL widget. 585 * 586 * Before the first rendering, you must apply a size to the WGLWidget. 587 */ 588 WGLWidget(); 589 590 /*! \brief Destructor 591 */ 592 ~WGLWidget(); 593 594 /*! \brief Sets the rendering option. 595 * 596 * Use this method to configure whether client-side and/or 597 * server-side rendering can be used, and whether anti-aliasing 598 * should be enabled. The actual choice is also based 599 * on availability (respectively client-side or server-side). 600 * 601 * The default value is to try both ClientSide or ServerSide rendering, 602 * and to enable anti-aliasing if available. 603 * 604 * \note Options must be set before the widget is being rendered. 605 */ 606 void setRenderOptions(WFlags<GLRenderOption> options); 607 608 protected: 609 610 /*! \brief Initialize the GL state when the widget is first shown. 611 * 612 * initializeGL() is called when the widget is first rendered, and 613 * when the webglcontextrestored signal is fired. You can distinguish 614 * between the first initialization and context restoration using 615 * restoringContext(). 616 * It usually creates most of the GL related state: shaders, VBOs, 617 * uniform locations, ... 618 * 619 * If this state is to be updated during the lifetime of the widget, 620 * you should specialize the updateGL() to accomodate for this. 621 */ 622 virtual void initializeGL(); 623 624 /*! \brief Act on resize events 625 * 626 * Usually, this method only contains functions to set the viewport 627 * and the projection matrix (as this is aspect ration dependent). 628 * 629 * resizeGL() is rendered after initializeGL, and whenever widget is 630 * resized. After this method finishes, the widget is repainted with 631 * the cached client-side paint function. 632 */ 633 virtual void resizeGL(int width, int height); 634 635 /*! \brief Update the client-side painting function. 636 * 637 * This method is invoked client-side when a repaint is required, 638 * i.e. when the repaintSlot() (a JavaScript-side JSlot) is triggered. 639 * Typical examples are: after mouse-based camera movements, after 640 * a timed update of a camera or an object's position, after 641 * a resize event (resizeGL() will also be called then), after 642 * an animation event, ... In many cases, this function will be 643 * executed client-side many many times. 644 * 645 * Using the GL functions from this class, you construct a scene. 646 * The implementation tracks all JavaScript calls that need to be 647 * performed to draw the scenes, and will replay them verbatim on 648 * every trigger of the repaintSlot(). There are a few mechanisms 649 * that may be employed to change what is rendered without updating 650 * the paintGL() cache: 651 * <ul> 652 * <li>Client-side matrices may be used to change camera viewpoints, 653 * manipilate separate object's model transformation matrices, ... 654 * </li> 655 * <li>Shader sources can be updated without requiring the paint 656 * function to be renewed</li> 657 * </ul> 658 * 659 * Updating the paintGL() cache is usually not too expensive; the VBOs, 660 * which are large in many cases, are already at the client side, while 661 * the paintGL() code only draws the VBOs. Of course, if you have to 662 * draw many separate objects, the paintGL() JS code may become large 663 * and updating is more expensive. 664 * 665 * In order to update the paintGL() cache, call repaintGL() with 666 * the PAINT_GL parameter, which will cause the invocation of this 667 * method. 668 */ 669 virtual void paintGL(); 670 671 /*! \brief Update state set in initializeGL() 672 * 673 * Invoked when repaint is called with the UPDATE_GL call. 674 * 675 * This is intended to be executed when you want to change programs, 676 * 'constant' uniforms, or even VBO's, ... without resending already 677 * initialized data. It is a mechanism to make changes to what you've 678 * set in intializeGL(). For every server-side invocation of this method, 679 * the result will be rendered client-side exactly once. 680 */ 681 virtual void updateGL(); 682 683 public: 684 685 /*! \brief Request invocation of resizeGL, paintGL and/or updateGL. 686 * 687 * If invoked with PAINT_GL, the client-side cached paint function 688 * is updated. If invoked with RESIZE_GL or UPDATE_GL, the code 689 * will be executed once. 690 * 691 * If invoked with multiple flags set, the order of execution will be 692 * updateGL(), resizeGL(), paintGL(). 693 */ 694 void repaintGL(WFlags<GLClientSideRenderer> which); 695 696 /*! \brief Returns whether a lost context is in the process of being restored. 697 * 698 * You can check for this in initializeGL(), to handle the first 699 * initialization and restoration of context differently. 700 */ restoringContext()701 bool restoringContext() const { return restoringContext_; } 702 703 void resize(const WLength &width, const WLength &height) override; 704 705 /*! \brief The enormous GLenum 706 * 707 * This enum contains all numeric constants defined by the WebGL 708 * standard, see: 709 * http://www.khronos.org/registry/webgl/specs/latest/1.0/#WEBGLRENDERINGCONTEXT 710 */ 711 enum GLenum { 712 /* ClearBufferMask */ 713 DEPTH_BUFFER_BIT = 0x00000100, 714 STENCIL_BUFFER_BIT = 0x00000400, 715 COLOR_BUFFER_BIT = 0x00004000, 716 717 /* BeginMode */ 718 POINTS = 0x0000, 719 LINES = 0x0001, 720 LINE_LOOP = 0x0002, 721 LINE_STRIP = 0x0003, 722 TRIANGLES = 0x0004, 723 TRIANGLE_STRIP = 0x0005, 724 TRIANGLE_FAN = 0x0006, 725 726 /* AlphaFunction (not supported in ES20) */ 727 /* NEVER */ 728 /* LESS */ 729 /* EQUAL */ 730 /* LEQUAL */ 731 /* GREATER */ 732 /* NOTEQUAL */ 733 /* GEQUAL */ 734 /* ALWAYS */ 735 736 /* BlendingFactorDest */ 737 ZERO = 0x0, 738 ONE = 0x1, 739 SRC_COLOR = 0x0300, 740 ONE_MINUS_SRC_COLOR = 0x0301, 741 SRC_ALPHA = 0x0302, 742 ONE_MINUS_SRC_ALPHA = 0x0303, 743 DST_ALPHA = 0x0304, 744 ONE_MINUS_DST_ALPHA = 0x0305, 745 746 /* BlendingFactorSrc */ 747 /* ZERO */ 748 /* ONE */ 749 DST_COLOR = 0x0306, 750 ONE_MINUS_DST_COLOR = 0x0307, 751 SRC_ALPHA_SATURATE = 0x0308, 752 /* SRC_ALPHA */ 753 /* ONE_MINUS_SRC_ALPHA */ 754 /* DST_ALPHA */ 755 /* ONE_MINUS_DST_ALPHA */ 756 757 /* BlendEquationSeparate */ 758 FUNC_ADD = 0x8006, 759 BLEND_EQUATION = 0x8009, 760 BLEND_EQUATION_RGB = 0x8009, /* same as BLEND_EQUATION */ 761 BLEND_EQUATION_ALPHA = 0x883D, 762 763 /* BlendSubtract */ 764 FUNC_SUBTRACT = 0x800A, 765 FUNC_REVERSE_SUBTRACT = 0x800B, 766 767 /* Separate Blend Functions */ 768 BLEND_DST_RGB = 0x80C8, 769 BLEND_SRC_RGB = 0x80C9, 770 BLEND_DST_ALPHA = 0x80CA, 771 BLEND_SRC_ALPHA = 0x80CB, 772 CONSTANT_COLOR = 0x8001, 773 ONE_MINUS_CONSTANT_COLOR = 0x8002, 774 CONSTANT_ALPHA = 0x8003, 775 ONE_MINUS_CONSTANT_ALPHA = 0x8004, 776 BLEND_COLOR = 0x8005, 777 778 /* Buffer Objects */ 779 ARRAY_BUFFER = 0x8892, 780 ELEMENT_ARRAY_BUFFER = 0x8893, 781 ARRAY_BUFFER_BINDING = 0x8894, 782 ELEMENT_ARRAY_BUFFER_BINDING = 0x8895, 783 784 STREAM_DRAW = 0x88E0, 785 STATIC_DRAW = 0x88E4, 786 DYNAMIC_DRAW = 0x88E8, 787 788 BUFFER_SIZE = 0x8764, 789 BUFFER_USAGE = 0x8765, 790 791 CURRENT_VERTEX_ATTRIB = 0x8626, 792 793 /* CullFaceMode */ 794 FRONT = 0x0404, 795 BACK = 0x0405, 796 FRONT_AND_BACK = 0x0408, 797 798 /* DepthFunction */ 799 /* NEVER */ 800 /* LESS */ 801 /* EQUAL */ 802 /* LEQUAL */ 803 /* GREATER */ 804 /* NOTEQUAL */ 805 /* GEQUAL */ 806 /* ALWAYS */ 807 808 /* EnableCap */ 809 /* TEXTURE_2D */ 810 CULL_FACE = 0x0B44, 811 BLEND = 0x0BE2, 812 DITHER = 0x0BD0, 813 STENCIL_TEST = 0x0B90, 814 DEPTH_TEST = 0x0B71, 815 SCISSOR_TEST = 0x0C11, 816 POLYGON_OFFSET_FILL = 0x8037, 817 SAMPLE_ALPHA_TO_COVERAGE = 0x809E, 818 SAMPLE_COVERAGE = 0x80A0, 819 820 /* ErrorCode */ 821 NO_ERROR = 0x0, 822 INVALID_ENUM = 0x0500, 823 INVALID_VALUE = 0x0501, 824 INVALID_OPERATION = 0x0502, 825 OUT_OF_MEMORY = 0x0505, 826 827 /* FrontFaceDirection */ 828 CW = 0x0900, 829 CCW = 0x0901, 830 831 /* GetPName */ 832 LINE_WIDTH = 0x0B21, 833 ALIASED_POINT_SIZE_RANGE = 0x846D, 834 ALIASED_LINE_WIDTH_RANGE = 0x846E, 835 CULL_FACE_MODE = 0x0B45, 836 FRONT_FACE = 0x0B46, 837 DEPTH_RANGE = 0x0B70, 838 DEPTH_WRITEMASK = 0x0B72, 839 DEPTH_CLEAR_VALUE = 0x0B73, 840 DEPTH_FUNC = 0x0B74, 841 STENCIL_CLEAR_VALUE = 0x0B91, 842 STENCIL_FUNC = 0x0B92, 843 STENCIL_FAIL = 0x0B94, 844 STENCIL_PASS_DEPTH_FAIL = 0x0B95, 845 STENCIL_PASS_DEPTH_PASS = 0x0B96, 846 STENCIL_REF = 0x0B97, 847 STENCIL_VALUE_MASK = 0x0B93, 848 STENCIL_WRITEMASK = 0x0B98, 849 STENCIL_BACK_FUNC = 0x8800, 850 STENCIL_BACK_FAIL = 0x8801, 851 STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802, 852 STENCIL_BACK_PASS_DEPTH_PASS = 0x8803, 853 STENCIL_BACK_REF = 0x8CA3, 854 STENCIL_BACK_VALUE_MASK = 0x8CA4, 855 STENCIL_BACK_WRITEMASK = 0x8CA5, 856 VIEWPORT = 0x0BA2, 857 SCISSOR_BOX = 0x0C10, 858 /* SCISSOR_TEST */ 859 COLOR_CLEAR_VALUE = 0x0C22, 860 COLOR_WRITEMASK = 0x0C23, 861 UNPACK_ALIGNMENT = 0x0CF5, 862 PACK_ALIGNMENT = 0x0D05, 863 MAX_TEXTURE_SIZE = 0x0D33, 864 MAX_VIEWPORT_DIMS = 0x0D3A, 865 SUBPIXEL_BITS = 0x0D50, 866 RED_BITS = 0x0D52, 867 GREEN_BITS = 0x0D53, 868 BLUE_BITS = 0x0D54, 869 ALPHA_BITS = 0x0D55, 870 DEPTH_BITS = 0x0D56, 871 STENCIL_BITS = 0x0D57, 872 POLYGON_OFFSET_UNITS = 0x2A00, 873 /* POLYGON_OFFSET_FILL */ 874 POLYGON_OFFSET_FACTOR = 0x8038, 875 TEXTURE_BINDING_2D = 0x8069, 876 SAMPLE_BUFFERS = 0x80A8, 877 SAMPLES = 0x80A9, 878 SAMPLE_COVERAGE_VALUE = 0x80AA, 879 SAMPLE_COVERAGE_INVERT = 0x80AB, 880 881 /* GetTextureParameter */ 882 /* TEXTURE_MAG_FILTER */ 883 /* TEXTURE_MIN_FILTER */ 884 /* TEXTURE_WRAP_S */ 885 /* TEXTURE_WRAP_T */ 886 887 NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2, 888 COMPRESSED_TEXTURE_FORMATS = 0x86A3, 889 890 /* HintMode */ 891 DONT_CARE = 0x1100, 892 FASTEST = 0x1101, 893 NICEST = 0x1102, 894 895 /* HintTarget */ 896 GENERATE_MIPMAP_HINT = 0x8192, 897 898 /* DataType */ 899 BYTE = 0x1400, 900 UNSIGNED_BYTE = 0x1401, 901 SHORT = 0x1402, 902 UNSIGNED_SHORT = 0x1403, 903 INT = 0x1404, 904 UNSIGNED_INT = 0x1405, 905 FLOAT = 0x1406, 906 907 /* PixelFormat */ 908 DEPTH_COMPONENT = 0x1902, 909 ALPHA = 0x1906, 910 RGB = 0x1907, 911 RGBA = 0x1908, 912 LUMINANCE = 0x1909, 913 LUMINANCE_ALPHA = 0x190A, 914 915 /* PixelType */ 916 /* UNSIGNED_BYTE */ 917 UNSIGNED_SHORT_4_4_4_4 = 0x8033, 918 UNSIGNED_SHORT_5_5_5_1 = 0x8034, 919 UNSIGNED_SHORT_5_6_5 = 0x8363, 920 921 /* Shaders */ 922 FRAGMENT_SHADER = 0x8B30, 923 VERTEX_SHADER = 0x8B31, 924 MAX_VERTEX_ATTRIBS = 0x8869, 925 MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB, 926 MAX_VARYING_VECTORS = 0x8DFC, 927 MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D, 928 MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C, 929 MAX_TEXTURE_IMAGE_UNITS = 0x8872, 930 MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD, 931 SHADER_TYPE = 0x8B4F, 932 DELETE_STATUS = 0x8B80, 933 LINK_STATUS = 0x8B82, 934 VALIDATE_STATUS = 0x8B83, 935 ATTACHED_SHADERS = 0x8B85, 936 ACTIVE_UNIFORMS = 0x8B86, 937 ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87, 938 ACTIVE_ATTRIBUTES = 0x8B89, 939 ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A, 940 SHADING_LANGUAGE_VERSION = 0x8B8C, 941 CURRENT_PROGRAM = 0x8B8D, 942 943 /* StencilFunction */ 944 NEVER = 0x0200, 945 LESS = 0x0201, 946 EQUAL = 0x0202, 947 LEQUAL = 0x0203, 948 GREATER = 0x0204, 949 NOTEQUAL = 0x0205, 950 GEQUAL = 0x0206, 951 ALWAYS = 0x0207, 952 953 /* StencilOp */ 954 /* ZERO */ 955 KEEP = 0x1E00, 956 REPLACE = 0x1E01, 957 INCR = 0x1E02, 958 DECR = 0x1E03, 959 INVERT = 0x150A, 960 INCR_WRAP = 0x8507, 961 DECR_WRAP = 0x8508, 962 963 /* StringName */ 964 VENDOR = 0x1F00, 965 RENDERER = 0x1F01, 966 VERSION = 0x1F02, 967 968 /* TextureMagFilter */ 969 NEAREST = 0x2600, 970 LINEAR = 0x2601, 971 972 /* TextureMinFilter */ 973 /* NEAREST */ 974 /* LINEAR */ 975 NEAREST_MIPMAP_NEAREST = 0x2700, 976 LINEAR_MIPMAP_NEAREST = 0x2701, 977 NEAREST_MIPMAP_LINEAR = 0x2702, 978 LINEAR_MIPMAP_LINEAR = 0x2703, 979 980 /* TextureParameterName */ 981 TEXTURE_MAG_FILTER = 0x2800, 982 TEXTURE_MIN_FILTER = 0x2801, 983 TEXTURE_WRAP_S = 0x2802, 984 TEXTURE_WRAP_T = 0x2803, 985 986 /* TextureTarget */ 987 TEXTURE_2D = 0x0DE1, 988 TEXTURE = 0x1702, 989 990 TEXTURE_CUBE_MAP = 0x8513, 991 TEXTURE_BINDING_CUBE_MAP = 0x8514, 992 TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515, 993 TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516, 994 TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517, 995 TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518, 996 TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519, 997 TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A, 998 MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C, 999 1000 /* TextureUnit */ 1001 TEXTURE0 = 0x84C0, 1002 TEXTURE1 = 0x84C1, 1003 TEXTURE2 = 0x84C2, 1004 TEXTURE3 = 0x84C3, 1005 TEXTURE4 = 0x84C4, 1006 TEXTURE5 = 0x84C5, 1007 TEXTURE6 = 0x84C6, 1008 TEXTURE7 = 0x84C7, 1009 TEXTURE8 = 0x84C8, 1010 TEXTURE9 = 0x84C9, 1011 TEXTURE10 = 0x84CA, 1012 TEXTURE11 = 0x84CB, 1013 TEXTURE12 = 0x84CC, 1014 TEXTURE13 = 0x84CD, 1015 TEXTURE14 = 0x84CE, 1016 TEXTURE15 = 0x84CF, 1017 TEXTURE16 = 0x84D0, 1018 TEXTURE17 = 0x84D1, 1019 TEXTURE18 = 0x84D2, 1020 TEXTURE19 = 0x84D3, 1021 TEXTURE20 = 0x84D4, 1022 TEXTURE21 = 0x84D5, 1023 TEXTURE22 = 0x84D6, 1024 TEXTURE23 = 0x84D7, 1025 TEXTURE24 = 0x84D8, 1026 TEXTURE25 = 0x84D9, 1027 TEXTURE26 = 0x84DA, 1028 TEXTURE27 = 0x84DB, 1029 TEXTURE28 = 0x84DC, 1030 TEXTURE29 = 0x84DD, 1031 TEXTURE30 = 0x84DE, 1032 TEXTURE31 = 0x84DF, 1033 ACTIVE_TEXTURE = 0x84E0, 1034 1035 /* TextureWrapMode */ 1036 REPEAT = 0x2901, 1037 CLAMP_TO_EDGE = 0x812F, 1038 MIRRORED_REPEAT = 0x8370, 1039 1040 /* Uniform Types */ 1041 FLOAT_VEC2 = 0x8B50, 1042 FLOAT_VEC3 = 0x8B51, 1043 FLOAT_VEC4 = 0x8B52, 1044 INT_VEC2 = 0x8B53, 1045 INT_VEC3 = 0x8B54, 1046 INT_VEC4 = 0x8B55, 1047 BOOL = 0x8B56, 1048 BOOL_VEC2 = 0x8B57, 1049 BOOL_VEC3 = 0x8B58, 1050 BOOL_VEC4 = 0x8B59, 1051 FLOAT_MAT2 = 0x8B5A, 1052 FLOAT_MAT3 = 0x8B5B, 1053 FLOAT_MAT4 = 0x8B5C, 1054 SAMPLER_2D = 0x8B5E, 1055 SAMPLER_CUBE = 0x8B60, 1056 1057 /* Vertex Arrays */ 1058 VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622, 1059 VERTEX_ATTRIB_ARRAY_SIZE = 0x8623, 1060 VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624, 1061 VERTEX_ATTRIB_ARRAY_TYPE = 0x8625, 1062 VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A, 1063 VERTEX_ATTRIB_ARRAY_POINTER = 0x8645, 1064 VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F, 1065 1066 /* Shader Source */ 1067 COMPILE_STATUS = 0x8B81, 1068 INFO_LOG_LENGTH = 0x8B84, 1069 SHADER_SOURCE_LENGTH = 0x8B88, 1070 1071 /* Shader Precision-Specified Types */ 1072 LOW_FLOAT = 0x8DF0, 1073 MEDIUM_FLOAT = 0x8DF1, 1074 HIGH_FLOAT = 0x8DF2, 1075 LOW_INT = 0x8DF3, 1076 MEDIUM_INT = 0x8DF4, 1077 HIGH_INT = 0x8DF5, 1078 1079 /* Framebuffer Object. */ 1080 FRAMEBUFFER = 0x8D40, 1081 RENDERBUFFER = 0x8D41, 1082 1083 RGBA4 = 0x8056, 1084 RGB5_A1 = 0x8057, 1085 RGB565 = 0x8D62, 1086 DEPTH_COMPONENT16 = 0x81A5, 1087 STENCIL_INDEX = 0x1901, 1088 STENCIL_INDEX8 = 0x8D48, 1089 DEPTH_STENCIL = 0x84F9, 1090 1091 RENDERBUFFER_WIDTH = 0x8D42, 1092 RENDERBUFFER_HEIGHT = 0x8D43, 1093 RENDERBUFFER_INTERNAL_FORMAT = 0x8D44, 1094 RENDERBUFFER_RED_SIZE = 0x8D50, 1095 RENDERBUFFER_GREEN_SIZE = 0x8D51, 1096 RENDERBUFFER_BLUE_SIZE = 0x8D52, 1097 RENDERBUFFER_ALPHA_SIZE = 0x8D53, 1098 RENDERBUFFER_DEPTH_SIZE = 0x8D54, 1099 RENDERBUFFER_STENCIL_SIZE = 0x8D55, 1100 1101 FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0, 1102 FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1, 1103 FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2, 1104 FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3, 1105 1106 COLOR_ATTACHMENT0 = 0x8CE0, 1107 DEPTH_ATTACHMENT = 0x8D00, 1108 STENCIL_ATTACHMENT = 0x8D20, 1109 DEPTH_STENCIL_ATTACHMENT = 0x821A, 1110 1111 NONE = 0x0, 1112 1113 FRAMEBUFFER_COMPLETE = 0x8CD5, 1114 FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6, 1115 FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7, 1116 FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9, 1117 FRAMEBUFFER_UNSUPPORTED = 0x8CDD, 1118 1119 FRAMEBUFFER_BINDING = 0x8CA6, 1120 RENDERBUFFER_BINDING = 0x8CA7, 1121 MAX_RENDERBUFFER_SIZE = 0x84E8, 1122 1123 INVALID_FRAMEBUFFER_OPERATION = 0x0506, 1124 1125 /* WebGL-specific enums */ 1126 UNPACK_FLIP_Y_WEBGL = 0x9240, 1127 UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241, 1128 CONTEXT_LOST_WEBGL = 0x9242, 1129 UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243, 1130 BROWSER_DEFAULT_WEBGL = 0x9244, 1131 }; 1132 1133 void debugger(); 1134 1135 /*! @name GL methods 1136 * The GL methods are mostly 1-on-1 translated to the identical 1137 * JavaScript call in WebGL. You can use the GL methods in your resizeGL(), 1138 * paintGL() and updateGL() specializations. Wt takes care that data, 1139 * arguments, ... are transfered to the client side and that the equivalent 1140 * JavaScript WebGL funtion is executed when using client-side rendering. 1141 * When using server-side rendering, the appropriate OpenGL functions 1142 * are called. 1143 * @{ 1144 */ 1145 1146 1147 /*! \brief GL function to activate an existing texture 1148 * 1149 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glActiveTexture.xml"> 1150 * glActiveTexture() OpenGL ES manpage</a> 1151 */ 1152 void activeTexture(GLenum texture); 1153 1154 /*! \brief GL function to attach a shader to a program 1155 * 1156 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glAttachShader.xml"> 1157 * glAttachShader() OpenGL ES manpage</a> 1158 */ 1159 void attachShader(Program program, Shader shader); 1160 1161 /*! \brief GL function to bind an attribute to a given location 1162 * 1163 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBindAttribLocation.xml"> 1164 * glBindAttribLocation() OpenGL ES manpage</a> 1165 */ 1166 void bindAttribLocation(Program program, unsigned index, 1167 const std::string &name); 1168 1169 /*! \brief GL function to bind a buffer to a target 1170 * 1171 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBindBuffer.xml"> 1172 * glBindBuffer() OpenGL ES manpage</a> 1173 */ 1174 void bindBuffer(GLenum target, Buffer buffer); 1175 1176 /*! \brief GL function to bind a frame buffer to a target 1177 * 1178 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBindFramebuffer.xml"> 1179 * glBindFramebuffer() OpenGL ES manpage</a> 1180 */ 1181 void bindFramebuffer(GLenum target, Framebuffer framebuffer); 1182 1183 /*! \brief GL function to bind a render buffer to a target 1184 * 1185 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBindRenderbuffer.xml"> 1186 * glBindRenderbuffer() OpenGL ES manpage</a> 1187 */ 1188 void bindRenderbuffer(GLenum target, Renderbuffer renderbuffer); 1189 1190 /*! \brief GL function to bind a texture to a target 1191 * 1192 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBindTexture.xml"> 1193 * glBindTexture() OpenGL ES manpage</a> 1194 */ 1195 void bindTexture(GLenum target, Texture texture); 1196 1197 /*! \brief GL function to set the blending color 1198 * 1199 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBlendColor.xml"> 1200 * glBlendColor() OpenGL ES manpage</a> 1201 */ 1202 void blendColor(double red, double green, double blue, double alpha); 1203 1204 /*! \brief GL function to set the blending equation 1205 * 1206 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBlendEquation.xml"> 1207 * glBlendEquation() OpenGL ES manpage</a> 1208 */ 1209 void blendEquation(GLenum mode); 1210 1211 /*! \brief GL function that sets separate blending functions for RGB and alpha 1212 * 1213 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBlendEquationSeparate.xml"> 1214 * glBlendEquationSeparate() OpenGL ES manpage</a> 1215 */ 1216 void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); 1217 1218 /*! \brief GL function to configure the blending function 1219 * 1220 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBlendFunc.xml"> 1221 * glBlendFunc() OpenGL ES manpage</a> 1222 */ 1223 void blendFunc(GLenum sfactor, GLenum dfactor); 1224 1225 /*! \brief GL function that configures the blending function 1226 * 1227 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBlendFuncSeparate.xml"> 1228 * glBlendFuncSeparate() OpenGL ES manpage</a> 1229 */ 1230 void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, 1231 GLenum srcAlpha, GLenum dstAlpha); 1232 1233 /*! \brief glBufferData - create and initialize a buffer object's data store 1234 * 1235 * Set the size of the currently bound WebGLBuffer object for the passed target. 1236 * The buffer is initialized to 0. 1237 * 1238 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferData.xml"> 1239 * glBufferData() OpenGL ES manpage</a> 1240 */ 1241 void bufferData(GLenum target, int size, GLenum usage); 1242 1243 /*! \brief glBufferData - create and initialize a buffer object's data store 1244 * from an ArrayBuffer 1245 * 1246 * Set the size and contents of the currently bound WebGLBuffer object to 1247 * be a copy of the given ArrayBuffer. 1248 * 1249 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferData.xml"> 1250 * glBufferData() OpenGL ES manpage</a> 1251 * 1252 * Note: an ArrayBuffer refers to a javascript object, which cannot be 1253 * used for server-side rendering. If a server-side fallback will be used, 1254 * then bufferDatafv() should be used with the additional boolean argument to 1255 * indicate binary transfer of the data in case of client-side rendering. 1256 * 1257 * \sa createAndLoadArrayBuffer 1258 */ 1259 void bufferData(GLenum target, ArrayBuffer res, GLenum usage); 1260 1261 /*! \brief glBufferData - create and initialize a buffer object's data store 1262 * from an ArrayBuffer 1263 * 1264 * Set the size of the currently bound WebGLBuffer object to 1265 * arrayBufferSize, and copy the contents of the ArrayBuffer to 1266 * the buffer, starting at the given offset. 1267 * 1268 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferData.xml"> 1269 * glBufferData() OpenGL ES manpage</a> 1270 * 1271 * Note: not functional for a server-side fall-back (see bufferData(GLenum target, ArrayBuffer res, GLenum usage) for more info) 1272 * 1273 * \sa createAndLoadArrayBuffer 1274 */ 1275 void bufferData(GLenum target, ArrayBuffer res, unsigned arrayBufferOffset, 1276 unsigned arrayBufferSize, GLenum usage); 1277 1278 /*! \brief Initialize a buffer object's data store from an ArrayBuffer 1279 * 1280 * Load the data of the currently bound WebGLBuffer object from 1281 * the given ArrayBuffer. The first byte of the resource data will 1282 * be written at the given offset of the currently bound buffer. 1283 * 1284 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferSubData.xml"> 1285 * glBufferSubData() OpenGL ES manpage</a> 1286 * 1287 * Note: not functional for a server-side fall-back (see bufferData(GLenum target, ArrayBuffer res, GLenum usage) for more info) 1288 * 1289 * \sa createAndLoadArrayBuffer 1290 */ 1291 void bufferSubData(GLenum target, unsigned offset, ArrayBuffer res); 1292 1293 /*! \brief Initialize a buffer object's data store from an ArrayBuffer 1294 * 1295 * Load the data of the currently bound WebGLBuffer object from 1296 * the given ArrayBuffer. The byte at position arrayBufferOffset 1297 * will be written to the currently bound buffer at position offset. 1298 * 1299 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferSubData.xml"> 1300 * glBufferSubData() OpenGL ES manpage</a> 1301 * 1302 * Note: not functional for a server-side fall-back (see bufferData(GLenum target, ArrayBuffer res, GLenum usage) for more info) 1303 * 1304 * \sa createAndLoadArrayBuffer 1305 */ 1306 void bufferSubData(GLenum target, unsigned offset, ArrayBuffer res, 1307 unsigned arrayBufferOffset, unsigned size); 1308 1309 #if !defined(WT_TARGET_JAVA) 1310 /*! \brief GL function that loads float or double data in a VBO 1311 * 1312 * Unlike the C version, we can't accept a void * here. We must be able 1313 * to interpret the buffer's data in order to transmit it to the JS side. 1314 * 1315 * Later we may also want versions with strides and offsets to cope with 1316 * more complex buffer layouts that we typically see on desktop WebGL apps; 1317 * suggestions to improve this are welcome 1318 * 1319 * Note: prefer bufferDatafv(GLenum target, const std::vector<float> &buffer, GLenum usage, bool binary) 1320 * 1321 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferData.xml"> 1322 * glBufferData() OpenGL ES manpage</a> 1323 */ 1324 template<typename Iterator> 1325 void bufferDatafv(GLenum target, const Iterator begin, const Iterator end, GLenum usage, bool binary = false) { 1326 std::vector<float> data; 1327 data.reserve(end-begin); 1328 for (Iterator i = begin; i != end; ++i) { 1329 data.push_back((float)*i); 1330 } 1331 1332 bufferDatafv(target, data, usage, binary); 1333 } 1334 1335 /*! \brief GL function that loads integer data in a VBO 1336 * 1337 * Note: prefer bufferDataiv(GLenum target, std::vector<int> &buffer, GLenum usage, GLenum type) 1338 * 1339 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferData.xml"> 1340 * glBufferData() OpenGL ES manpage</a> 1341 */ 1342 template<typename Iterator> bufferDataiv(GLenum target,const Iterator begin,const Iterator end,GLenum usage,GLenum type)1343 void bufferDataiv(GLenum target, const Iterator begin, const Iterator end, 1344 GLenum usage, GLenum type) 1345 { 1346 std::vector<int> data; 1347 data.reserve(end-begin); 1348 for (Iterator i = begin; i != end; i++) 1349 data.push_back(*i); 1350 1351 bufferDataiv(target, data, usage, type); 1352 } 1353 1354 /*! \brief GL function that updates an existing VBO with new float or double 1355 * data 1356 * 1357 * Note: prefer bufferSubDatafv(GLenum target, unsigned offset, const std::vector<float> &buffer, bool binary) 1358 * 1359 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferSubData.xml"> 1360 * glBufferSubData() OpenGL ES manpage</a> 1361 */ 1362 template<typename Iterator> 1363 void bufferSubDatafv(GLenum target, unsigned offset, const Iterator begin, const Iterator end, bool binary = false) 1364 { 1365 std::vector<float> data; 1366 data.reserve(end-begin); 1367 for (Iterator i = begin; i != end; ++i) 1368 data.push_back(*i); 1369 1370 bufferSubDatafv(target, offset, data, binary); 1371 } 1372 1373 /*! \brief GL function that updates an existing VBO with new integer data 1374 * 1375 * Note: prefer void bufferSubDataiv(GLenum target, unsigned offset, std::vector<int> &buffer, GLenum type) 1376 * 1377 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glBufferSubData.xml"> 1378 * glBufferSubData() OpenGL ES manpage</a> 1379 */ 1380 template<typename Iterator> bufferSubDataiv(GLenum target,unsigned offset,const Iterator begin,Iterator end,GLenum type)1381 void bufferSubDataiv(GLenum target, unsigned offset, const Iterator begin, Iterator end, GLenum type) 1382 { 1383 std::vector<int> data; 1384 data.reserve(end-begin); 1385 for (Iterator i = begin; i != end; i++) 1386 data.push_back(*i); 1387 1388 bufferSubDataiv(target, offset, data, type); 1389 } 1390 #endif 1391 1392 /*! \brief GL function that loads float or double data in a VBO 1393 * 1394 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/glBufferData.xml"> 1395 * glBufferData() OpenGL ES manpage</a> 1396 */ 1397 #ifdef WT_TARGET_JAVA 1398 void bufferDatafv(GLenum target, const FloatBuffer &buffer, GLenum usage, bool binary = false); 1399 void bufferDatafv(GLenum target, const FloatNotByteBuffer &buffer, GLenum usage); 1400 #else 1401 void bufferDatafv(GLenum target, const std::vector<float> &buffer, GLenum usage, bool binary = false); 1402 #endif 1403 1404 /*! \brief remove all binary buffer resources 1405 * 1406 * Removes all WMemoryResources that were allocated when calling 1407 * bufferDatafv with binary=true. This is not required, since the resources 1408 * are also managed, but if you are sure they will not be used anymore in 1409 * the client, this can help free some memory. 1410 */ 1411 void clearBinaryResources(); 1412 1413 /*! \brief GL function that updates an existing VBO with new integer data 1414 * 1415 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/glBufferData.xml"> 1416 * glBufferData() OpenGL ES manpage</a> 1417 */ 1418 #ifdef WT_TARGET_JAVA 1419 void bufferDataiv(GLenum target, IntBuffer &buffer, GLenum usage, 1420 GLenum type); 1421 #else 1422 void bufferDataiv(GLenum target, std::vector<int> &buffer, GLenum usage, 1423 GLenum type); 1424 #endif 1425 1426 /*! \brief GL function that updates an existing VBO with new float data 1427 * 1428 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/glBufferSubData.xml"> 1429 * glBufferSubData() OpenGL ES manpage</a> 1430 */ 1431 #ifdef WT_TARGET_JAVA 1432 void bufferSubDatafv(GLenum target, unsigned offset, 1433 const FloatBuffer &buffer, bool binary = false); 1434 1435 void bufferSubDatafv(GLenum target, unsigned offset, 1436 const FloatNotByteBuffer &buffer); 1437 #else 1438 void bufferSubDatafv(GLenum target, unsigned offset, 1439 const std::vector<float> &buffer, bool binary = false); 1440 #endif 1441 1442 /*! \brief GL function that loads integer data in a VBO 1443 * 1444 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/glBufferSubData.xml"> 1445 * glBufferSubData() OpenGL ES manpage</a> 1446 */ 1447 #ifdef WT_TARGET_JAVA 1448 void bufferSubDataiv(GLenum target, 1449 unsigned offset, IntBuffer &buffer, 1450 GLenum type); 1451 #else 1452 void bufferSubDataiv(GLenum target, 1453 unsigned offset, std::vector<int> &buffer, 1454 GLenum type); 1455 #endif 1456 1457 //GLenum checkFramebufferStatus(GLenum target); 1458 1459 /*! \brief GL function that clears the given buffers 1460 * 1461 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glClear.xml"> 1462 * glClear() OpenGL ES manpage</a> 1463 */ 1464 void clear(WFlags<GLenum> mask); 1465 1466 /*! \brief GL function that sets the clear color of the color buffer 1467 * 1468 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glClearColor.xml"> 1469 * glClearColor() OpenGL ES manpage</a> 1470 */ 1471 void clearColor(double r, double g, double b, double a); 1472 1473 /*! \brief GL function that configures the depth to be set when the 1474 * depth buffer is cleared 1475 * 1476 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glClearDepthf.xml"> 1477 * glClearDepthf() OpenGL ES manpage</a> 1478 */ 1479 void clearDepth(double depth); 1480 1481 /*! \brief GL function 1482 * 1483 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glClearStencil.xml"> 1484 * glClearStencil() OpenGL ES manpage</a> 1485 */ 1486 void clearStencil(int s); 1487 1488 /*! \brief GL function 1489 * 1490 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glColorMask.xml"> 1491 * glColorMask() OpenGL ES manpage</a> 1492 */ 1493 void colorMask(bool red, bool green, bool blue, bool alpha); 1494 1495 /*! \brief GL function to compile a shader 1496 * 1497 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glCompileShader.xml"> 1498 * glCompileShader() OpenGL ES manpage</a> 1499 */ 1500 void compileShader(Shader shader); 1501 1502 /*! \brief GL function to copy a texture image 1503 * 1504 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glCopyTexImage2D.xml"> 1505 * glCopyTexImage2D() OpenGL ES manpage</a> 1506 */ 1507 void copyTexImage2D(GLenum target, int level, 1508 GLenum internalformat, 1509 int x, int y, 1510 unsigned width, unsigned height, 1511 int border); 1512 1513 /*! \brief GL function that copies a part of a texture image 1514 * 1515 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glCopyTexSubImage2D.xml"> 1516 * glCopyTexSubImage2D() OpenGL ES manpage</a> 1517 */ 1518 void copyTexSubImage2D(GLenum target, int level, 1519 int xoffset, int yoffset, 1520 int x, int y, 1521 unsigned width, unsigned height); 1522 1523 /*! \brief GL function that creates an empty VBO 1524 * 1525 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGenBuffers.xml"> 1526 * glGenBuffers() OpenGL ES manpage</a> 1527 */ 1528 Buffer createBuffer(); 1529 1530 /*! \brief GL function that creates a frame buffer object 1531 * 1532 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGenFramebuffers.xml"> 1533 * glGenFramebuffers() OpenGL ES manpage</a> 1534 */ 1535 Framebuffer createFramebuffer(); 1536 1537 /*! \brief GL function that creates an empty program 1538 * 1539 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glCreateProgram.xml"> 1540 * glCreateProgram() OpenGL ES manpage</a> 1541 */ 1542 Program createProgram(); 1543 1544 /*! \brief GL function that creates a render buffer object 1545 * 1546 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGenRenderbuffers.xml"> 1547 * glGenRenderbuffers() OpenGL ES manpage</a> 1548 */ 1549 Renderbuffer createRenderbuffer(); 1550 1551 /*! \brief GL function that creates an empty shader 1552 * 1553 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glCreateShader.xml"> 1554 * glCreateShader() OpenGL ES manpage</a> 1555 */ 1556 Shader createShader(GLenum shader); 1557 1558 /*! \brief GL function that creates an empty texture 1559 * 1560 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGenTextures.xml"> 1561 * glGenTextures() OpenGL ES manpage</a> 1562 */ 1563 Texture createTexture(); 1564 1565 /*! \brief GL function that creates an image texture 1566 * 1567 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGenTextures.xml"> 1568 * glGenTextures() OpenGL ES manpage</a> 1569 */ 1570 Texture createTextureAndLoad(const std::string &url); 1571 1572 /*! \brief returns an paintdevice that can be used to paint a GL texture 1573 * 1574 * If the client has a webGL enabled browser this function returns a 1575 * WCanvasPaintDevice. 1576 * 1577 * \if cpp 1578 * If server-side rendering is used as fallback then 1579 * this function returns a WRasterImage. 1580 * \endif 1581 * \if java 1582 * If server-side rendering is used as fallback then 1583 * this function returns a {@link WRasterPaintDevice}. 1584 * \endif 1585 */ 1586 std::unique_ptr<WPaintDevice> createPaintDevice(const WLength& width, 1587 const WLength& height); 1588 1589 /*! \brief GL function that configures the backface culling mode 1590 * 1591 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glCullFace.xml"> 1592 * glCullFace() OpenGL ES manpage</a> 1593 */ 1594 void cullFace(GLenum mode); 1595 1596 /*! \brief GL function that deletes a VBO 1597 * 1598 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteBuffers.xml"> 1599 * glDeleteBuffers() OpenGL ES manpage</a> 1600 */ 1601 void deleteBuffer(Buffer buffer); 1602 1603 /*! \brief GL function that deletes a frame buffer 1604 * 1605 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteFramebuffers.xml"> 1606 * glDeleteFramebuffers() OpenGL ES manpage</a> 1607 */ 1608 void deleteFramebuffer(Framebuffer framebuffer); 1609 1610 /*! \brief GL function that deletes a program 1611 * 1612 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteProgram.xml"> 1613 * glDeleteProgram() OpenGL ES manpage</a> 1614 */ 1615 void deleteProgram(Program program); 1616 1617 /*! \brief GL function that deletes a render buffer 1618 * 1619 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteRenderbuffers.xml"> 1620 * glDeleteRenderbuffers() OpenGL ES manpage</a> 1621 */ 1622 void deleteRenderbuffer(Renderbuffer renderbuffer); 1623 1624 /*! \brief GL function that depetes a shader 1625 * 1626 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteShader.xml"> 1627 * glDeleteShader() OpenGL ES manpage</a> 1628 */ 1629 void deleteShader(Shader shader); 1630 1631 /*! \brief GL function that deletes a texture 1632 * 1633 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDeleteTextures.xml"> 1634 * glDeleteTextures() OpenGL ES manpage</a> 1635 */ 1636 void deleteTexture(Texture texture); 1637 1638 /*! \brief GL function to set the depth test function 1639 * 1640 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDepthFunc.xml"> 1641 * glDepthFunc() OpenGL ES manpage</a> 1642 */ 1643 void depthFunc(GLenum func); 1644 1645 /*! \brief GL function that enables or disables writing to the depth buffer 1646 * 1647 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDepthMask.xml"> 1648 * glDepthMask() OpenGL ES manpage</a> 1649 */ 1650 void depthMask(bool flag); 1651 1652 /*! \brief GL function that specifies to what range the normalized [-1,1] z 1653 * values should match. 1654 * 1655 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDepthRangef.xml"> 1656 * glDepthRangef() OpenGL ES manpage</a> 1657 */ 1658 void depthRange(double zNear, double zFar); 1659 1660 /*! \brief GL function that detaches a shader from a program 1661 * 1662 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDetachShader.xml"> 1663 * glDetachShader() OpenGL ES manpage</a> 1664 */ 1665 void detachShader(Program program, Shader shader); 1666 1667 /*! \brief GL function to disable features 1668 * 1669 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDisable.xml"> 1670 * glDisable() OpenGL ES manpage</a> 1671 */ 1672 void disable(GLenum cap); 1673 1674 /*! \brief GL function to disable the vertex attribute array 1675 * 1676 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDisableVertexAttribArray.xml"> 1677 * glDisableVertexAttribArray() OpenGL ES manpage</a> 1678 */ 1679 void disableVertexAttribArray(AttribLocation index); 1680 1681 /*! \brief GL function to draw a VBO 1682 * 1683 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDrawArrays.xml"> 1684 * glDrawArrays() OpenGL ES manpage</a> 1685 */ 1686 void drawArrays(GLenum mode, int first, unsigned count); 1687 1688 /*! \brief GL function to draw indexed VBOs 1689 * 1690 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glDrawElements.xml"> 1691 * glDrawElements() OpenGL ES manpage</a> 1692 */ 1693 void drawElements(GLenum mode, unsigned count, GLenum type, unsigned offset); 1694 1695 /*! \brief GL function to enable features 1696 * 1697 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glEnable.xml"> 1698 * glEnable() OpenGL ES manpage</a> 1699 */ 1700 void enable(GLenum cap); 1701 1702 /*! \brief GL function to enable the vertex attribute array 1703 * 1704 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glEnableVertexAttribArray.xml"> 1705 * glEnableVertexAttribArray() OpenGL ES manpage</a> 1706 */ 1707 void enableVertexAttribArray(AttribLocation index); 1708 1709 /*! \brief GL function to wait until given commands are executed 1710 * 1711 * This call is transfered to JS, but the server will never wait on 1712 * this call. 1713 * 1714 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glFinish.xml"> 1715 * glFinish() OpenGL ES manpage</a> 1716 */ 1717 void finish(); 1718 1719 /*! \brief GL function to force execution of GL commands in finite time. 1720 * 1721 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glFlush.xml"> 1722 * glFlush() OpenGL ES manpage</a> 1723 */ 1724 void flush(); 1725 1726 /*! \brief GL function to attach the given renderbuffer to the currently 1727 * bound frame buffer. 1728 * 1729 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glFramebufferRenderbuffer.xml"> 1730 * glFramebufferRenderbuffer() OpenGL ES manpage</a> 1731 */ 1732 void framebufferRenderbuffer(GLenum target, GLenum attachment, 1733 GLenum renderbuffertarget, 1734 Renderbuffer renderbuffer); 1735 1736 /*! \brief GL function to render directly into a texture image. 1737 * 1738 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glFramebufferTexture2D.xml"> 1739 * glFramebufferTexture2D() OpenGL ES manpage</a> 1740 */ 1741 void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, 1742 Texture texture, int level); 1743 1744 /*! \brief GL function that specifies which side of a triangle is the 1745 * front side 1746 * 1747 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glFrontFace.xml"> 1748 * glFrontFace() OpenGL ES manpage</a> 1749 */ 1750 void frontFace(GLenum mode); 1751 1752 /*! \brief GL function that generates a set of mipmaps for a texture 1753 * object. 1754 * 1755 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGenerateMipmap.xml"> 1756 * glGenerateMipmap() OpenGL ES manpage</a> 1757 */ 1758 void generateMipmap(GLenum target); 1759 1760 //WebGLActiveInfo getActiveAttrib(WebGLProgram program, GLuint index); 1761 //WebGLActiveInfo getActiveUniform(WebGLProgram program, GLuint index); 1762 //WebGLShader[ ] getAttachedShaders(WebGLProgram program); 1763 1764 /*! \brief GL function to retrieve an attribute's location in a Program 1765 * 1766 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGetAttribLocation.xml"> 1767 * glGetAttribLocation() OpenGL ES manpage</a> 1768 */ 1769 AttribLocation getAttribLocation(Program program, const std::string &attrib); 1770 1771 //any getParameter(GLenum pname); 1772 //any getBufferParameter(GLenum target, GLenum pname); 1773 1774 //GLenum getError(); 1775 1776 //any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, 1777 // GLenum pname); 1778 //any getProgramParameter(WebGLProgram program, GLenum pname); 1779 //DOMString getProgramInfoLog(WebGLProgram program); 1780 //any getRenderbufferParameter(GLenum target, GLenum pname); 1781 //any getShaderParameter(WebGLShader shader, GLenum pname); 1782 //DOMString getShaderInfoLog(WebGLShader shader); 1783 1784 //DOMString getShaderSource(WebGLShader shader); 1785 1786 //any getTexParameter(GLenum target, GLenum pname); 1787 1788 //any getUniform(WebGLProgram program, WebGLUniformLocation location); 1789 1790 /*! \brief GL function to retrieve a Uniform's location in a Program. 1791 * 1792 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glGetUniformLocation.xml"> 1793 * glGetUniformLocation() OpenGL ES manpage</a> 1794 */ 1795 UniformLocation getUniformLocation(Program program, const std::string &location); 1796 1797 //any getVertexAttrib(GLuint index, GLenum pname); 1798 1799 //GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname); 1800 1801 /*! \brief GL function to give hints to the render pipeline 1802 * 1803 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glHint.xml"> 1804 * glHint() OpenGL ES manpage</a> 1805 */ 1806 void hint(GLenum target, GLenum mode); 1807 1808 //GLboolean isBuffer(WebGLBuffer buffer); 1809 //GLboolean isEnabled(GLenum cap); 1810 //GLboolean isFramebuffer(WebGLFramebuffer framebuffer); 1811 //GLboolean isProgram(WebGLProgram program); 1812 //GLboolean isRenderbuffer(WebGLRenderbuffer renderbuffer); 1813 //GLboolean isShader(WebGLShader shader); 1814 //GLboolean isTexture(WebGLTexture texture); 1815 1816 /*! \brief GL function to set the line width 1817 * 1818 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glLineWidth.xml"> 1819 * glLineWidth() OpenGL ES manpage</a> 1820 */ 1821 void lineWidth(double width); 1822 1823 /*! \brief GL function to link a program 1824 * 1825 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glLinkProgram.xml"> 1826 * glLinkProgram() OpenGL ES manpage</a> 1827 */ 1828 void linkProgram(Program program); 1829 1830 /*! \brief GL function to set the pixel storage mode 1831 * 1832 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glPixelStorei.xml"> 1833 * glPixelStorei() OpenGL ES manpage</a> 1834 */ 1835 void pixelStorei(GLenum pname, int param); 1836 1837 /*! \brief GL function to apply modifications to Z values 1838 * 1839 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glPolygonOffset.xml"> 1840 * glPolygonOffset() OpenGL ES manpage</a> 1841 */ 1842 void polygonOffset(double factor, double units); 1843 1844 //void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 1845 // GLenum format, GLenum type, ArrayBufferView pixels); 1846 1847 /*! \brief GL function to allocate the appropriate amount of memory for 1848 * a render buffer 1849 * 1850 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glRenderbufferStorage.xml"> 1851 * glSampleCoverage() OpenGL ES manpage</a> 1852 */ 1853 void renderbufferStorage(GLenum target, GLenum internalformat, 1854 unsigned width, unsigned height); 1855 1856 /*! \brief GL function to set multisample parameters 1857 * 1858 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glSampleCoverage.xml"> 1859 * glSampleCoverage() OpenGL ES manpage</a> 1860 */ 1861 void sampleCoverage(double value, bool invert); 1862 1863 /*! \brief GL function to define the scissor box 1864 * 1865 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glScissor.xml"> 1866 * glScissor() OpenGL ES manpage</a> 1867 */ 1868 void scissor(int x, int y, unsigned width, unsigned height); 1869 1870 /*! \brief GL function to set a shader's source code 1871 * 1872 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glShaderSource.xml"> 1873 * glShaderSource() OpenGL ES manpage</a> 1874 */ 1875 void shaderSource(Shader shader, const std::string &src); 1876 1877 /*! \brief GL function to set stencil test parameters 1878 * 1879 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glStencilFunc.xml"> 1880 * glStencilFunc() OpenGL ES manpage</a> 1881 */ 1882 void stencilFunc(GLenum func, int ref, unsigned mask); 1883 1884 /*! \brief GL function to set stencil test parameters for front and/or 1885 * back stencils 1886 * 1887 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glStencilFuncSeparate.xml"> 1888 * glStencilFuncSeparate() OpenGL ES manpage</a> 1889 */ 1890 void stencilFuncSeparate(GLenum face, GLenum func, int ref, unsigned mask); 1891 1892 /*! \brief GL function to control which bits are to be written in the stencil 1893 * buffer 1894 * 1895 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glStencilMask.xml"> 1896 * glStencilMask() OpenGL ES manpage</a> 1897 */ 1898 void stencilMask(unsigned mask); 1899 1900 /*! \brief GL function to control which bits are written to the front and/or 1901 * back stencil buffers 1902 * 1903 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glStencilMaskSeparate.xml"> 1904 * glStencilMaskSeparate() OpenGL ES manpage</a> 1905 */ 1906 void stencilMaskSeparate(GLenum face, unsigned mask); 1907 1908 /*! \brief GL function to set stencil test actions 1909 * 1910 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glStencilOp.xml"> 1911 * glStencilOp() OpenGL ES manpage</a> 1912 */ 1913 void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); 1914 1915 /*! \brief GL function to set front and/or back stencil test actions 1916 * separately 1917 * 1918 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glStencilOpSeparate.xml"> 1919 * glStencilOpSeparate() OpenGL ES manpage</a> 1920 */ 1921 void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); 1922 1923 //void texImage2D(TextureTargetEnum target, int level, PixelFormatEnum internalformat, 1924 // GLsizei width, GLsizei height, GLint border, PixelFormatEnum format, 1925 // GLenum type, ArrayBufferView pixels); 1926 /*! \brief GL function to reserve space for a 2D texture, without specifying its 1927 * contents. 1928 * 1929 * This corresponds to calling the WebGL function 1930 * void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, 1931 * GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView pixels) 1932 * with null as last parameters. The value of 'type' is then of no importance and is 1933 * therefore omitted from this function. 1934 * 1935 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glTexImage2D.xml"> 1936 * glTexImage2D() OpenGL ES manpage</a> 1937 */ 1938 void texImage2D(GLenum target, int level, GLenum internalformat, 1939 unsigned width, unsigned height, int border, GLenum format); 1940 1941 //void texImage2D(TextureTargetEnum target, int level, PixelFormatEnum internalformat, 1942 // PixelFormatEnum format, GLenum type, ImageData pixels); 1943 1944 /*! \brief GL function to load a 2D texture from a WImage 1945 * 1946 * Note: WImage must be loaded before this function is executed. 1947 * 1948 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glTexImage2D.xml"> 1949 * glTexImage2D() OpenGL ES manpage</a> 1950 */ 1951 void texImage2D(GLenum target, int level, GLenum internalformat, 1952 GLenum format, GLenum type, WImage *image); 1953 1954 //void texImage2D(TextureTargetEnum target, int level, PixelFormatEnum internalformat, 1955 // PixelFormatEnum format, GLenum type, HTMLCanvasElement canvas); 1956 1957 /*! \brief GL function to load a 2D texture from a WVideo 1958 * 1959 * Note: the video must be loaded prior to calling this function. The 1960 * current frame is used as texture image. 1961 * 1962 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glTexImage2D.xml"> 1963 * glTexImage2D() OpenGL ES manpage</a> 1964 */ 1965 void texImage2D(GLenum target, int level, GLenum internalformat, 1966 GLenum format, GLenum type, WVideo *video); 1967 1968 /*! \brief GL function to load a 2D texture from a file 1969 * 1970 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glTexImage2D.xml"> 1971 * glTexImage2D() OpenGL ES manpage</a> 1972 */ 1973 void texImage2D(GLenum target, int level, GLenum internalformat, 1974 GLenum format, GLenum type, std::string filename); 1975 1976 /*! \brief GL function to load a 2D texture from a WPaintDevice 1977 * 1978 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glTexImage2D.xml"> 1979 * glTexImage2D() OpenGL ES manpage</a> 1980 * 1981 * \sa createPaintDevice() 1982 */ 1983 void texImage2D(GLenum target, int level, GLenum internalformat, 1984 GLenum format, GLenum type, 1985 WPaintDevice *paintdevice); 1986 1987 /*! \brief GL function to load a 2D texture loaded with createTextureAndLoad() 1988 * 1989 * This function must only be used for textures created with 1990 * createTextureAndLoad() 1991 * 1992 * Note: the WGLWidget implementation will delay rendering until 1993 * all textures created with createTextureAndLoad() are loaded in the 1994 * browser. 1995 * 1996 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glTexImage2D.xml"> 1997 * glTexImage2D() OpenGL ES manpage</a> 1998 */ 1999 void texImage2D(GLenum target, int level, GLenum internalformat, 2000 GLenum format, GLenum type, Texture texture); 2001 2002 //void texParameterf(TextureTargetEnum target, 2003 // TextureParameterNameEnum pname, double param); 2004 2005 /*! \brief GL function to set texture parameters 2006 * 2007 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glTexParameter.xml"> 2008 * glTexParameter() OpenGL ES manpage</a> 2009 */ 2010 void texParameteri(GLenum target, GLenum pname, GLenum param); 2011 2012 //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 2013 // GLsizei width, GLsizei height, 2014 // GLenum format, GLenum type, ArrayBufferView pixels); 2015 //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 2016 // GLenum format, GLenum type, ImageData pixels); 2017 //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 2018 // GLenum format, GLenum type, HTMLImageElement image); 2019 //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 2020 // GLenum format, GLenum type, HTMLCanvasElement canvas); 2021 //void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 2022 // GLenum format, GLenum type, HTMLVideoElement video); 2023 2024 2025 /*! \brief GL function to set the value of a uniform variable of the current 2026 * program 2027 * 2028 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2029 * glUniform() OpenGL ES manpage</a> 2030 */ 2031 void uniform1f(const UniformLocation &location, double x); 2032 2033 /*! \brief GL function to set the value of a uniform variable of the current 2034 * program 2035 * 2036 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2037 * glUniform() OpenGL ES manpage</a> 2038 */ WT_WGL_TEMPLATE(typename FloatArray)2039 WT_WGL_TEMPLATE(typename FloatArray) 2040 void uniform1fv(const UniformLocation &location, 2041 const WT_ARRAY FloatArray *value) 2042 #ifndef WT_TARGET_JAVA 2043 { 2044 float out[1]; 2045 for (int i=0; i<1; i++) { 2046 out[i] = (float)value[i]; 2047 } 2048 2049 uniform1fv(location, out); 2050 } 2051 2052 /// \cond 2053 void uniform1fv(const UniformLocation &location, 2054 const WT_ARRAY float *value); 2055 /// \endcond 2056 #else 2057 ; 2058 #endif 2059 2060 /*! \brief GL function to set the value of a uniform variable of the current 2061 * program 2062 * 2063 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2064 * glUniform() OpenGL ES manpage</a> 2065 */ 2066 void uniform1fv(const UniformLocation &location, 2067 const JavaScriptVector &v); 2068 2069 /*! \brief GL function to set the value of a uniform variable of the current 2070 * program 2071 * 2072 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2073 * glUniform() OpenGL ES manpage</a> 2074 */ 2075 void uniform1i(const UniformLocation &location, int x); 2076 2077 /*! \brief GL function to set the value of a uniform variable of the current 2078 * program 2079 * 2080 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2081 * glUniform() OpenGL ES manpage</a> 2082 */ WT_WGL_TEMPLATE(typename IntArray)2083 WT_WGL_TEMPLATE(typename IntArray) 2084 void uniform1iv(const UniformLocation &location, 2085 const WT_ARRAY IntArray *value) 2086 #ifndef WT_TARGET_JAVA 2087 { 2088 int out[1]; 2089 for (int i=0; i<1; i++) { 2090 out[i] = (int)value[i]; 2091 } 2092 2093 uniform1iv(location, out); 2094 } 2095 2096 /// \cond 2097 void uniform1iv(const UniformLocation &location, 2098 const WT_ARRAY int *value); 2099 /// \endcond 2100 #else 2101 ; 2102 #endif 2103 2104 /*! \brief GL function to set the value of a uniform variable of the current 2105 * program 2106 * 2107 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2108 * glUniform() OpenGL ES manpage</a> 2109 */ 2110 void uniform2f(const UniformLocation &location, double x, double y); 2111 2112 /*! \brief GL function to set the value of a uniform variable of the current 2113 * program 2114 * 2115 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2116 * glUniform() OpenGL ES manpage</a> 2117 */ WT_WGL_TEMPLATE(typename FloatArray)2118 WT_WGL_TEMPLATE(typename FloatArray) 2119 void uniform2fv(const UniformLocation &location, 2120 const WT_ARRAY FloatArray *value) 2121 #ifndef WT_TARGET_JAVA 2122 { 2123 float out[2]; 2124 for (int i=0; i<2; i++) { 2125 out[i] = (float)value[i]; 2126 } 2127 2128 uniform2fv(location, out); 2129 } 2130 2131 /// \cond 2132 void uniform2fv(const UniformLocation &location, 2133 const WT_ARRAY float *value); 2134 /// \endcond 2135 #else 2136 ; 2137 #endif 2138 2139 /*! \brief GL function to set the value of a uniform variable of the current 2140 * program 2141 * 2142 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2143 * glUniform() OpenGL ES manpage</a> 2144 */ 2145 void uniform2fv(const UniformLocation &location, 2146 const JavaScriptVector &v); 2147 2148 /*! \brief GL function to set the value of a uniform variable of the current 2149 * program 2150 * 2151 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2152 * glUniform() OpenGL ES manpage</a> 2153 */ 2154 void uniform2i(const UniformLocation &location, int x, int y); 2155 2156 /*! \brief GL function to set the value of a uniform variable of the current 2157 * program 2158 * 2159 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2160 * glUniform() OpenGL ES manpage</a> 2161 */ WT_WGL_TEMPLATE(typename IntArray)2162 WT_WGL_TEMPLATE(typename IntArray) 2163 void uniform2iv(const UniformLocation &location, 2164 const WT_ARRAY IntArray *value) 2165 #ifndef WT_TARGET_JAVA 2166 { 2167 int out[2]; 2168 for (int i=0; i<2; i++) { 2169 out[i] = (int)value[i]; 2170 } 2171 2172 uniform2iv(location, out); 2173 } 2174 2175 /// \cond 2176 void uniform2iv(const UniformLocation &location, 2177 const WT_ARRAY int *value); 2178 /// \endcond 2179 #else 2180 ; 2181 #endif 2182 2183 /*! \brief GL function to set the value of a uniform variable of the current 2184 * program 2185 * 2186 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2187 * glUniform() OpenGL ES manpage</a> 2188 */ 2189 void uniform3f(const UniformLocation &location, 2190 double x, double y, double z); 2191 2192 /*! \brief GL function to set the value of a uniform variable of the current 2193 * program 2194 * 2195 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2196 * glUniform() OpenGL ES manpage</a> 2197 */ WT_WGL_TEMPLATE(typename FloatArray)2198 WT_WGL_TEMPLATE(typename FloatArray) 2199 void uniform3fv(const UniformLocation &location, 2200 const WT_ARRAY FloatArray *value) 2201 #ifndef WT_TARGET_JAVA 2202 { 2203 float out[3]; 2204 for (int i=0; i<3; i++) { 2205 out[i] = (float)value[i]; 2206 } 2207 2208 uniform3fv(location, out); 2209 } 2210 2211 /// \cond 2212 void uniform3fv(const UniformLocation &location, 2213 const WT_ARRAY float *value); 2214 /// \endcond 2215 #else 2216 ; 2217 #endif 2218 2219 /*! \brief GL function to set the value of a uniform variable of the current 2220 * program 2221 * 2222 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2223 * glUniform() OpenGL ES manpage</a> 2224 */ 2225 void uniform3fv(const UniformLocation &location, 2226 const JavaScriptVector &v); 2227 2228 /*! \brief GL function to set the value of a uniform variable of the current 2229 * program 2230 * 2231 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2232 * glUniform() OpenGL ES manpage</a> 2233 */ 2234 void uniform3i(const UniformLocation &location, int x, int y, int z); 2235 2236 /*! \brief GL function to set the value of a uniform variable of the current 2237 * program 2238 * 2239 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2240 * glUniform() OpenGL ES manpage</a> 2241 */ WT_WGL_TEMPLATE(typename IntArray)2242 WT_WGL_TEMPLATE(typename IntArray) 2243 void uniform3iv(const UniformLocation &location, 2244 const WT_ARRAY IntArray *value) 2245 #ifndef WT_TARGET_JAVA 2246 { 2247 int out[3]; 2248 for (int i=0; i<3; i++) { 2249 out[i] = (int)value[i]; 2250 } 2251 2252 uniform3iv(location, out); 2253 } 2254 2255 /// \cond 2256 void uniform3iv(const UniformLocation &location, 2257 const WT_ARRAY int *value); 2258 /// \endcond 2259 #else 2260 ; 2261 #endif 2262 2263 /*! \brief GL function to set the value of a uniform variable of the current 2264 * program 2265 * 2266 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2267 * glUniform() OpenGL ES manpage</a> 2268 */ 2269 void uniform4f(const UniformLocation &location, 2270 double x, double y, double z, double w); 2271 2272 /*! \brief GL function to set the value of a uniform variable of the current 2273 * program 2274 * 2275 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2276 * glUniform() OpenGL ES manpage</a> 2277 */ WT_WGL_TEMPLATE(typename FloatArray)2278 WT_WGL_TEMPLATE(typename FloatArray) 2279 void uniform4fv(const UniformLocation &location, 2280 const WT_ARRAY FloatArray *value) 2281 #ifndef WT_TARGET_JAVA 2282 { 2283 float out[4]; 2284 for (int i=0; i<4; i++) { 2285 out[i] = (float)value[i]; 2286 } 2287 2288 uniform4fv(location, out); 2289 } 2290 2291 /// \cond 2292 void uniform4fv(const UniformLocation &location, 2293 const WT_ARRAY float *value); 2294 /// \endcond 2295 #else 2296 ; 2297 #endif 2298 2299 /*! \brief GL function to set the value of a uniform variable of the current 2300 * program 2301 * 2302 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2303 * glUniform() OpenGL ES manpage</a> 2304 */ 2305 void uniform4fv(const UniformLocation &location, 2306 const JavaScriptVector &v); 2307 2308 /*! \brief GL function to set the value of a uniform variable of the current 2309 * program 2310 * 2311 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2312 * glUniform() OpenGL ES manpage</a> 2313 */ 2314 void uniform4i(const UniformLocation &location, int x, int y, int z, int w); 2315 2316 /*! \brief GL function to set the value of a uniform variable of the current 2317 * program 2318 * 2319 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2320 * glUniform() OpenGL ES manpage</a> 2321 */ WT_WGL_TEMPLATE(typename IntArray)2322 WT_WGL_TEMPLATE(typename IntArray) 2323 void uniform4iv(const UniformLocation &location, 2324 const WT_ARRAY IntArray *value) 2325 #ifndef WT_TARGET_JAVA 2326 { 2327 int out[4]; 2328 for (int i=0; i<4; i++) { 2329 out[i] = (int)value[i]; 2330 } 2331 2332 uniform4iv(location, out); 2333 } 2334 2335 /// \cond 2336 void uniform4iv(const UniformLocation &location, 2337 const WT_ARRAY int *value); 2338 /// \endcond 2339 #else 2340 ; 2341 #endif 2342 2343 /*! \brief GL function to set the value of a uniform matrix of the current 2344 * program 2345 * 2346 * Attention: The OpenGL ES specification states that transpose MUST be 2347 * false. 2348 * 2349 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2350 * glUniform() OpenGL ES manpage</a> 2351 */ WT_WGL_TEMPLATE(typename MatrixType)2352 WT_WGL_TEMPLATE(typename MatrixType) 2353 void uniformMatrix2fv(const UniformLocation &location, 2354 bool transpose, 2355 const WT_ARRAY MatrixType *value) 2356 #ifndef WT_TARGET_JAVA 2357 { 2358 double out[4]; 2359 for (int i=0; i<4; i++) { 2360 out[i] = (double)value[i]; 2361 } 2362 uniformMatrix2fv(location, transpose, out); 2363 } 2364 2365 /// \cond 2366 void uniformMatrix2fv(const UniformLocation &location, 2367 bool transpose, 2368 const WT_ARRAY double *value); 2369 /// \endcond 2370 #else 2371 ; 2372 #endif 2373 2374 /*! \brief GL function to set the value of a uniform matrix of the current 2375 * program 2376 * 2377 * This function renders the matrix in the proper row/column order. 2378 * 2379 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2380 * glUniform() OpenGL ES manpage</a> 2381 */ WT_WGL_TEMPLATE(typename MatrixType)2382 WT_WGL_TEMPLATE(typename MatrixType) 2383 void uniformMatrix2(const UniformLocation &location, 2384 const WGenericMatrix<MatrixType, 2, 2> &m) 2385 #ifndef WT_TARGET_JAVA 2386 { 2387 WGenericMatrix<double, 2, 2> out; 2388 for (int i=0; i<2; i++) { 2389 for (int j=0; j<2; j++) { 2390 out.at(i, j) = (double)m.at(i, j); 2391 } 2392 } 2393 uniformMatrix2(location, out); 2394 } 2395 2396 /// \cond 2397 void uniformMatrix2(const UniformLocation &location, 2398 const WGenericMatrix<double, 2, 2> &m); 2399 /// \endcond 2400 #else 2401 ; 2402 #endif 2403 2404 /*! \brief GL function to set the value of a uniform matrix of the current 2405 * program 2406 * 2407 * Attention: The OpenGL ES specification states that transpose MUST be 2408 * false. 2409 * 2410 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2411 * glUniform() OpenGL ES manpage</a> 2412 */ WT_WGL_TEMPLATE(typename MatrixType)2413 WT_WGL_TEMPLATE(typename MatrixType) 2414 void uniformMatrix3fv(const UniformLocation &location, bool transpose, 2415 const WT_ARRAY MatrixType *value) 2416 #ifndef WT_TARGET_JAVA 2417 { 2418 double out[9]; 2419 for (int i=0; i<9; i++) { 2420 out[i] = (double)value[i]; 2421 } 2422 uniformMatrix3fv(location, transpose, out); 2423 } 2424 2425 /// \cond 2426 void uniformMatrix3fv(const UniformLocation &location, bool transpose, 2427 const WT_ARRAY double *value); 2428 /// \endcond 2429 #else 2430 ; 2431 #endif 2432 2433 /*! \brief GL function to set the value of a uniform matrix of the current 2434 * program 2435 * 2436 * This function renders the matrix in the proper row/column order. 2437 * 2438 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2439 * glUniform() OpenGL ES manpage</a> 2440 */ WT_WGL_TEMPLATE(typename MatrixType)2441 WT_WGL_TEMPLATE(typename MatrixType) 2442 void uniformMatrix3(const UniformLocation &location, 2443 const WGenericMatrix<MatrixType, 3, 3> &m) 2444 #ifndef WT_TARGET_JAVA 2445 { 2446 WGenericMatrix<double, 3, 3> out; 2447 for (int i=0; i<3; i++) { 2448 for (int j=0; j<3; j++) { 2449 out.at(i, j) = (double)m.at(i, j); 2450 } 2451 } 2452 uniformMatrix3(location, out); 2453 } 2454 2455 /// \cond 2456 void uniformMatrix3(const UniformLocation &location, 2457 const WGenericMatrix<double, 3, 3> &m); 2458 /// \endcond 2459 #else 2460 ; 2461 #endif 2462 2463 /*! \brief GL function to set the value of a uniform matrix of the current 2464 * program 2465 * 2466 * Attention: The OpenGL ES specification states that transpose MUST be 2467 * false. 2468 * 2469 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2470 * glUniform() OpenGL ES manpage</a> 2471 */ WT_WGL_TEMPLATE(typename MatrixType)2472 WT_WGL_TEMPLATE(typename MatrixType) 2473 void uniformMatrix4fv(const UniformLocation &location, bool transpose, 2474 const WT_ARRAY MatrixType *value) 2475 #ifndef WT_TARGET_JAVA 2476 { 2477 double out[16]; 2478 for (int i=0; i<16; i++) { 2479 out[i] = (double)value[i]; 2480 } 2481 uniformMatrix4fv(location, transpose, out); 2482 } 2483 2484 /// \cond 2485 void uniformMatrix4fv(const UniformLocation &location, bool transpose, 2486 const WT_ARRAY double *value); 2487 /// \endcond 2488 #else 2489 ; 2490 #endif 2491 2492 /*! \brief GL function to set the value of a uniform matrix of the current 2493 * program 2494 * 2495 * This function renders the matrix in the proper row/column order. 2496 * 2497 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2498 * glUniform() OpenGL ES manpage</a> 2499 */ WT_WGL_TEMPLATE(typename MatrixType)2500 WT_WGL_TEMPLATE(typename MatrixType) 2501 void uniformMatrix4(const UniformLocation &location, 2502 const WGenericMatrix<MatrixType, 4, 4> &m) 2503 #ifndef WT_TARGET_JAVA 2504 { 2505 WGenericMatrix<double, 4, 4> out; 2506 for (int i=0; i<4; i++) { 2507 for (int j=0; j<4; j++) { 2508 out.at(i, j) = (double)m.at(i, j); 2509 } 2510 } 2511 uniformMatrix4(location, out); 2512 } 2513 2514 /// \cond 2515 void uniformMatrix4(const UniformLocation &location, 2516 const WGenericMatrix<double, 4, 4> &m); 2517 /// \endcond 2518 #else 2519 ; 2520 #endif 2521 2522 /*! \brief GL function to set the value of a uniform matrix of the current 2523 * program 2524 * 2525 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUniform.xml"> 2526 * glUniform() OpenGL ES manpage</a> 2527 */ 2528 void uniformMatrix4(const UniformLocation &location, 2529 const JavaScriptMatrix4x4 &m); 2530 2531 2532 /*! \brief GL function to set the current active shader program 2533 * 2534 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glUseProgram.xml"> 2535 * glUseProgram() OpenGL ES manpage</a> 2536 */ 2537 void useProgram(Program program); 2538 2539 /*! \brief GL function to validate a program 2540 * 2541 * implementation note: there is currently not yet a method to read 2542 * out the validation result. 2543 * 2544 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glValidateProgram.xml"> 2545 * glValidateProgram() OpenGL ES manpage</a> 2546 */ 2547 void validateProgram(Program program); 2548 2549 /*! \brief GL function to set the value of an attribute of the current program 2550 * 2551 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttrib.xml"> 2552 * glVertexAttrib() OpenGL ES manpage</a> 2553 */ 2554 void vertexAttrib1f(AttribLocation location, double x); 2555 2556 #ifndef WT_TARGET_JAVA 2557 /*! \brief GL function to set the value of an attribute of the current program 2558 * 2559 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttrib.xml"> 2560 * glVertexAttrib() OpenGL ES manpage</a> 2561 */ WT_WGL_TEMPLATE(typename FloatArray)2562 WT_WGL_TEMPLATE(typename FloatArray) 2563 void vertexAttrib1fv(AttribLocation location, 2564 const WT_ARRAY FloatArray *values) { 2565 vertexAttrib1f(location, values[0]); 2566 } 2567 #endif 2568 2569 /*! \brief GL function to set the value of an attribute of the current program 2570 * 2571 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttrib.xml"> 2572 * glVertexAttrib() OpenGL ES manpage</a> 2573 */ 2574 void vertexAttrib2f(AttribLocation location, double x, double y); 2575 2576 /*! \brief GL function to set the value of an attribute of the current program 2577 * 2578 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttrib.xml"> 2579 * glVertexAttrib() OpenGL ES manpage</a> 2580 */ WT_WGL_TEMPLATE(typename FloatArray)2581 WT_WGL_TEMPLATE(typename FloatArray) 2582 void vertexAttrib2fv(AttribLocation location, 2583 const WT_ARRAY FloatArray *values) { 2584 vertexAttrib2f(location, values[0], values[1]); 2585 } 2586 2587 /*! \brief GL function to set the value of an attribute of the current program 2588 * 2589 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttrib.xml"> 2590 * glVertexAttrib() OpenGL ES manpage</a> 2591 */ 2592 void vertexAttrib3f(AttribLocation location, double x, double y, double z); 2593 2594 /*! \brief GL function to set the value of an attribute of the current program 2595 * 2596 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttrib.xml"> 2597 * glVertexAttrib() OpenGL ES manpage</a> 2598 */ WT_WGL_TEMPLATE(typename FloatArray)2599 WT_WGL_TEMPLATE(typename FloatArray) 2600 void vertexAttrib3fv(AttribLocation location, 2601 const WT_ARRAY FloatArray *values) { 2602 vertexAttrib3f(location, values[0], values[1], values[2]); 2603 } 2604 2605 /*! \brief GL function to set the value of an attribute of the current program 2606 * 2607 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttrib.xml"> 2608 * glVertexAttrib() OpenGL ES manpage</a> 2609 */ 2610 void vertexAttrib4f(AttribLocation location, 2611 double x, double y, double z, double w); 2612 2613 /*! \brief GL function to set the value of an attribute of the current program 2614 * 2615 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttrib.xml"> 2616 * glVertexAttrib() OpenGL ES manpage</a> 2617 */ WT_WGL_TEMPLATE(typename FloatArray)2618 WT_WGL_TEMPLATE(typename FloatArray) 2619 void vertexAttrib4fv(AttribLocation location, 2620 const WT_ARRAY FloatArray *values) { 2621 vertexAttrib4f(location, values[0], values[1], values[2], values[3]); 2622 } 2623 2624 /*! \brief GL function to bind a VBO to an attribute 2625 * 2626 * This function links the given attribute to the VBO currently bound 2627 * to the ARRAY_BUFFER target. 2628 * 2629 * The size parameter specifies the number of components per attribute (1 2630 * to 4). The type parameter is also used to determine the size of each 2631 * component. 2632 * 2633 * The size of a float is 8 bytes. 2634 * 2635 * In WGLWidget, the size of an int is 4 bytes. 2636 * 2637 * The stride is in bytes. 2638 * 2639 * The maximum stride is 255. 2640 * 2641 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glVertexAttribPointer.xml"> 2642 * glVertexAttribPointer() OpenGL ES manpage</a> 2643 */ 2644 void vertexAttribPointer(AttribLocation location, int size, 2645 GLenum type, bool normalized, unsigned stride, unsigned offset); 2646 2647 /*! \brief GL function to set the viewport 2648 * 2649 * <a href="http://www.khronos.org/opengles/sdk/2.0/docs/man/xhtml/glViewport.xml"> 2650 * glViewport() OpenGL ES manpage</a> 2651 */ 2652 void viewport(int x, int y, unsigned width, unsigned height); 2653 2654 //!@} 2655 2656 /*! @name Client-side vectors and matrices 2657 * 2658 * These methods can be used to modify 2659 * vectors and matrices client-side, to change 2660 * the GL uniforms without a roundtrip to the server. 2661 * @{ 2662 */ 2663 2664 /*! \brief Create a matrix that can be manipulated in client-side 2665 * JavaScript 2666 * 2667 * This is a shorthand for creating a JavaScriptMatrix4x4, 2668 * then adding it to a WGLWidget with addJavaScriptMatrix4, 2669 * and initializing it with initJavaScriptMatrix4. 2670 * 2671 * This method should only be called in initializeGL(), 2672 * updateGL() or resizeGL(). 2673 */ 2674 JavaScriptMatrix4x4 createJavaScriptMatrix4(); 2675 2676 /*! \brief Register a matrix with this WGLWidget. 2677 * 2678 * You can call this outside of resizeGL(), paintGL(), updateGL() 2679 * or initializeGL() methods. After a JavaScriptMatrix4x4 is 2680 * added to a WGLWidget, its jsRef() becomes valid, and can be 2681 * used in a JSlot, for example. 2682 */ 2683 void addJavaScriptMatrix4(JavaScriptMatrix4x4 &m); 2684 2685 /*! \brief Initialize the client-side JavaScript for the 2686 * given JavaScriptMatrix4x4 2687 * 2688 * If the given matrix is not associated with a widget yet, 2689 * it will be added to this widget. 2690 * 2691 * If the given matrix has already been added to a WGLWidget, 2692 * then this WGLWidget should be the same as the one you call 2693 * initJavaScriptMatrix4 on. 2694 * 2695 * This method should only be called in initializeGL(), 2696 * updateGL() or resizeGL(). 2697 */ 2698 void initJavaScriptMatrix4(JavaScriptMatrix4x4 &m); 2699 2700 /*! \brief Set the value of a client-side JavaScript matrix created by 2701 * createJavaScriptMatrix4x4() 2702 * 2703 * This method should only be called in initializeGL(), 2704 * updateGL() or resizeGL(). 2705 */ WT_WGL_TEMPLATE(typename MatrixType)2706 WT_WGL_TEMPLATE(typename MatrixType) 2707 void setJavaScriptMatrix4(JavaScriptMatrix4x4 &jsm, 2708 const WGenericMatrix<MatrixType, 4, 4> &m) 2709 #ifndef WT_TARGET_JAVA 2710 { 2711 WGenericMatrix<double, 4, 4> out; 2712 for (int i=0; i<4; i++) { 2713 for (int j=0; j<4; j++) { 2714 out.at(i, j) = (double)m.at(i, j); 2715 } 2716 } 2717 setJavaScriptMatrix4(jsm, out); 2718 } 2719 2720 /// \cond 2721 void setJavaScriptMatrix4(JavaScriptMatrix4x4 &jsm, 2722 const WGenericMatrix<double, 4, 4> &m); 2723 /// \endcond 2724 #else 2725 ; 2726 #endif 2727 2728 /*! \brief Create a vector of a certain length that can be manipulated 2729 * in client-side JavaScript 2730 * 2731 * This is a shorthand for creating a JavaScriptVector, 2732 * then adding it to a WGLWidget with addJavaScriptVector, 2733 * and initializing it with initJavaScriptVector. 2734 * 2735 * This method should only be called in initializeGL(), 2736 * updateGL() or resizeGL(). 2737 */ 2738 JavaScriptVector createJavaScriptVector(unsigned length); 2739 2740 /*! \brief Register a vector with this WGLWidget. 2741 * 2742 * You can call this outside of resizeGL(), paintGL(), updateGL() 2743 * or initializeGL() methods. After a JavaScriptVector is 2744 * added to a WGLWidget, its jsRef() becomes valid, and can be 2745 * used in a JSlot, for example. 2746 */ 2747 void addJavaScriptVector(JavaScriptVector &v); 2748 2749 /*! \brief Initialize the client-side JavaScript for the 2750 * given JavaScriptVector 2751 * 2752 * If the given vector is not associated with a widget yet, 2753 * it will be added to this widget. 2754 * 2755 * If the given vector has already been added to a WGLWidget, 2756 * then this WGLWidget should be the same as the one you call 2757 * initJavaScriptVector on. 2758 * 2759 * This method should only be called in initializeGL(), 2760 * updateGL() or resizeGL(). 2761 */ 2762 void initJavaScriptVector(JavaScriptVector &v); 2763 2764 /*! \brief Set the value of a client-side JavaScript vector created by 2765 * createJavaScriptVector() 2766 * 2767 * This method should only be called in initializeGL(), 2768 * updateGL() or resizeGL(). 2769 */ 2770 void setJavaScriptVector(JavaScriptVector &jsv, 2771 const std::vector<float> &v); 2772 2773 //!@} 2774 2775 /*! \brief Set a custom mouse handler based on the given JavaScript code. 2776 * 2777 * The handler code should be JavaScript code that produces an object when evaluated. 2778 * 2779 * A mouse handler is an object that can implement one or more of the following functions: 2780 * 2781 * - <b>setTarget(target)</b>: This is called immediately when the mouse handler is added with an 2782 * object that uniquely identifies the WGLWidget, and a paintGL() method. 2783 * - <b>mouseDown(o, event)</b>: To handle the \c mousedown event. \c o is the \c <canvas> (client-side rendering) 2784 * or \c <img> (server-side rendering) element corresponding to this WGLWidget. \c event is 2785 * the \c MouseEvent. 2786 * - <b>mouseUp(o, event)</b>: To handle the \c mouseup event. \c o is the \c <canvas> (client-side rendering) 2787 * or \c <img> (server-side rendering) element corresponding to this WGLWidget. \c event is 2788 * the \c MouseEvent. 2789 * - <b>mouseDrag(o, event)</b>: Called when the mouse is dragged. \c o is the \c <canvas> (client-side rendering) 2790 * or \c <img> (server-side rendering) element corresponding to this WGLWidget. \c event is 2791 * the \c MouseEvent. 2792 * - <b>mouseMove(o, event)</b>: Called when the mouse is moved. \c o is the \c <canvas> (client-side rendering) 2793 * or \c <img> (server-side rendering) element corresponding to this WGLWidget. \c event is 2794 * the \c MouseEvent. 2795 * - <b>mouseWheel(o, event)</b>: Called when the mouse wheel is used. \c o is the \c <canvas> (client-side rendering) 2796 * or \c <img> (server-side rendering) element corresponding to this WGLWidget. \c event is 2797 * the \c MouseEvent. 2798 * - <b>touchStart(o, event)</b>: To handle the \c touchstart event. \c o is the \c <canvas> (client-side rendering) 2799 * or \c <img> (server-side rendering) element corresponding to this WGLWidget. \c event is 2800 * the \c TouchEvent. 2801 * - <b>touchEnd(o, event)</b>: To handle the \c touchend event. \c o is this \c <canvas> (client-side rendering) 2802 * or \c <img> (server-side rendering) element corresponding to this WGLWidget. \c event is 2803 * the \c TouchEvent. 2804 * - <b>touchMoved(o, event)</b>: To handle the \c touchmove event. \c o is this \c <canvas> (client-side rendering) 2805 * or \c <img> (server-side rendering) element corresponding to this WGLWidget. \c event is 2806 * the \c TouchEvent. 2807 * 2808 * 2809 * For example, if we wanted to scale some object when we scroll, we could create 2810 * a JavaScriptMatrix4x4 called \p transform_: 2811 * 2812 * \if cpp 2813 * \code 2814 private: 2815 JavaScriptMatrix4x4 transform_; 2816 \endcode 2817 * \endif 2818 * 2819 * \if java 2820 * \code 2821 private JavaScriptMatrix4x4 transform_; 2822 \endcode 2823 * \endif 2824 * 2825 * We can add this in the constructor: 2826 * 2827 * \if cpp 2828 * \code 2829 addJavaScriptMatrix4(transform_); 2830 \endcode 2831 * \endif 2832 * 2833 * \if java 2834 * \code 2835 transform_ = new JavaScriptMatrix4x4(); 2836 addJavaScriptMatrix4(transform_); 2837 \endcode 2838 * \endif 2839 * 2840 * Then, in initializeGL(), we can initialize it and set the value: 2841 * 2842 * \if cpp 2843 * \code 2844 initJavaScriptMatrix4(transform_); 2845 setJavaScriptMatrix4(transform_, WMatrix4x4()); // Set to identity matrix 2846 \endcode 2847 * \endif 2848 * 2849 * \if java 2850 * \code 2851 initJavaScriptMatrix4(transform_); 2852 setJavaScriptMatrix4(transform_, new WMatrix4x4()); // Set to identity matrix 2853 \endcode 2854 * \endif 2855 * 2856 * Then, still in initializeGL(), we can set a mouse handler as such: 2857 * 2858 * \if cpp 2859 * \code 2860 setClientSideMouseHandler(std::string("(function(){") + 2861 "var MouseHandler = function(transform) {" 2862 "var target = null;" 2863 "this.setTarget = function(newTarget) {" 2864 "target = newTarget;" 2865 "};" 2866 "this.mouseWheel = function(o, event) {" 2867 "var fix = jQuery.event.fix(event);" 2868 "fix.preventDefault();" 2869 "fix.stopPropagation();" 2870 "var d = wheelDelta(event);" 2871 "var s = Math.pow(1.2, d);" 2872 "transform[0] *= s;" // Scale X 2873 "transform[5] *= s;" // Scale Y 2874 "transform[10] *= s;" // Scale Z 2875 "target.paintGL();" // Repaint 2876 "};" 2877 "function wheelDelta(e) {" 2878 "var delta = 0;" 2879 "if (e.wheelDelta) {" 2880 "delta = e.wheelDelta > 0 ? 1 : -1;" 2881 "} else if (e.detail) {" 2882 "delta = e.detail < 0 ? 1 : -1;" 2883 "}" 2884 "return delta;" 2885 "}" 2886 "};" 2887 "return new MouseHandler(" + transform_.jsRef() + ");" 2888 "})()"); 2889 \endcode 2890 * \endif 2891 * 2892 * \if java 2893 * \code 2894 setClientSideMouseHandler("(function(){") + 2895 "var MouseHandler = function(transform) {" + 2896 "var target = null;" + 2897 "this.setTarget = function(newTarget) {" + 2898 "target = newTarget;" + 2899 "};" + 2900 "this.mouseWheel = function(o, event) {" + 2901 "var fix = jQuery.event.fix(event);" + 2902 "fix.preventDefault();" + 2903 "fix.stopPropagation();" + 2904 "var d = wheelDelta(event);" + 2905 "var s = Math.pow(1.2, d);" + 2906 "transform[0] *= s;" + // Scale X 2907 "transform[5] *= s;" + // Scale Y 2908 "transform[10] *= s;" + // Scale Z 2909 "target.paintGL();" + // Repaint 2910 "};" + 2911 "function wheelDelta(e) {" + 2912 "var delta = 0;" + 2913 "if (e.wheelDelta) {" + 2914 "delta = e.wheelDelta > 0 ? 1 : -1;" + 2915 "} else if (e.detail) {" + 2916 "delta = e.detail < 0 ? 1 : -1;" + 2917 "}" + 2918 "return delta;" + 2919 "}" + 2920 "};" + 2921 "return new MouseHandler(" + transform_.jsRef() + ");" + 2922 "})()"); 2923 \endcode 2924 * \endif 2925 * 2926 * All that's left to do then is to use this transform somewhere as a uniform variable, 2927 * see getUniformLocation() and uniformMatrix4(). 2928 */ 2929 void setClientSideMouseHandler(const std::string& handlerCode); 2930 2931 /*! \brief Add a mouse handler to the widget that looks at a given point 2932 * 2933 * This will allow a user to change client-side matrix m with the 2934 * mouse. M is a model transformation matrix, representing the viewpoint of 2935 * the camera. 2936 * 2937 * Through mouse operations, the camera can be changed by the user, but 2938 * (lX, lY, lZ) will always be at the center of the display, (uX, uY, uZ) 2939 * is considered to be the up direction, and the distance of the camera to 2940 * (lX, lY, lZ) will never change. 2941 * 2942 * Pressing the left mouse button and moving the mouse left/right will 2943 * rotate the camera around the up (uX, uY, uZ) direction. Moving up/down 2944 * will tilt the camera (causing it to move up/down to keep the lookpoint 2945 * centered). The scroll wheel simulates zooming by scaling the scene. 2946 * 2947 * pitchRate and yawRate control how much the camera will move per mouse 2948 * pixel. 2949 * 2950 * Usually this method is called after setting a camera transformation 2951 * with a client-side matrix in initializeGL(). However, this function 2952 * may also be called from outside the intializeGL()/paintGL()/updateGL() 2953 * methods (but not before m was initialized). 2954 */ 2955 void setClientSideLookAtHandler(const JavaScriptMatrix4x4 &m, 2956 double lX, double lY, double lZ, 2957 double uX, double uY, double uZ, 2958 double pitchRate, double yawRate); 2959 2960 /*! \brief Add a mouse handler to the widget that allows 'walking' in 2961 * the scene 2962 * 2963 * This will allow a user to change client-side matrix m with the 2964 * mouse. M is a model transformation matrix, representing the viewpoint of 2965 * the camera. 2966 * 2967 * Through mouse operations, the camera can be changed by the user, as if 2968 * he is walking around on a plane. 2969 * 2970 * Pressing the left mouse button and moving the mouse left/right will 2971 * rotate the camera around Y axis. Moving the mouse up/down will move 2972 * the camera in the Z direction (walking forward/backward). 2973 * centered). 2974 * 2975 * frontStep and rotStep control how much the camera will move per mouse 2976 * pixel. 2977 */ 2978 void setClientSideWalkHandler(const JavaScriptMatrix4x4 &m, 2979 double frontStep, double rotStep); 2980 2981 /*! \brief Sets the content to be displayed when WebGL is not available. 2982 * 2983 * If %Wt cannot create a working WebGL context, this content will be 2984 * shown to the user. This may be a text explanation, or a pre-rendered 2985 * image, or a video, a flash movie, ... 2986 * 2987 * The default is a widget that explains to the user that he has no 2988 * WebGL support. 2989 */ 2990 void setAlternativeContent(std::unique_ptr<WWidget> alternative); 2991 2992 /*! \brief A JavaScript slot that repaints the widget when triggered. 2993 * 2994 * This is useful for client-side initiated repaints. You may e.g. use this 2995 * if you write your own client-side mouse handler, or if you updated 2996 * a texture, or if you're playing a video texture. 2997 */ repaintSlot()2998 JSlot &repaintSlot() { return repaintSlot_; } 2999 3000 /*! \brief enable client-side error messages (read detailed doc!) 3001 * 3002 * This option will add client-side code to check the result of every 3003 * WebGL call, and will popup an error dialog if a WebGL call returned 3004 * an error. The JavaScript then invokes the client-side debugger. This 3005 * code is intended to test your application, and should not be used in 3006 * production. 3007 */ 3008 void enableClientErrorChecks(bool enable = true); 3009 3010 /*! \brief Inject JavaScript into the current js-stream. 3011 * 3012 * Careful: this method directly puts the given jsString into 3013 * the JavaScript stream, whatever state it current has. 3014 * For example, if called in initGL(), it will put the jsString 3015 * into the client-side initGL() code. 3016 */ 3017 void injectJS(const std::string & jsString); 3018 3019 void webglNotAvailable(); 3020 3021 protected: 3022 virtual DomElementType domElementType() const override; 3023 virtual DomElement *createDomElement(WApplication *app) override; 3024 virtual void getDomChanges(std::vector<DomElement *>& result, WApplication *app) override; 3025 virtual void updateDom(DomElement &element, bool all) override; 3026 3027 virtual void render(WFlags<RenderFlag> flags) override; 3028 virtual std::string renderRemoveJs(bool recursive) override; 3029 3030 virtual void layoutSizeChanged(int width, int height) override; 3031 3032 virtual void setFormData(const FormData& formData) override; 3033 3034 virtual void contextRestored(); 3035 3036 private: 3037 3038 WFlags<GLRenderOption> renderOptions_; 3039 std::unique_ptr<WAbstractGLImplementation> pImpl_; 3040 struct jsMatrixMap { 3041 int id; 3042 WMatrix4x4 serverSideCopy; 3043 jsMatrixMapjsMatrixMap3044 jsMatrixMap(int matId, const WMatrix4x4& ssCopy) 3045 : id(matId), serverSideCopy(ssCopy) 3046 {} 3047 }; 3048 struct jsVectorMap { 3049 int id; 3050 std::vector<float> serverSideCopy; 3051 jsVectorMapjsVectorMap3052 jsVectorMap(int vecId, const std::vector<float> &ssCopy) 3053 : id(vecId), serverSideCopy(ssCopy) 3054 {} 3055 }; 3056 std::vector<jsMatrixMap> jsMatrixList_; 3057 std::vector<jsVectorMap> jsVectorList_; 3058 unsigned jsValues_; 3059 std::stringstream js_; 3060 JSignal<> repaintSignal_; 3061 3062 std::string glObjJsRef() const; 3063 3064 std::unique_ptr<WWidget> alternative_; 3065 3066 // If client detects that a WebGL context cannot be created, it fires this 3067 // signal, and the handler sets wegGlNotAvailable_ to true. If this happens, 3068 // the client side will have deleted the canvas widget. 3069 JSignal<> webglNotAvailable_; 3070 bool webGlNotAvailable_; 3071 3072 JSignal<> contextRestored_; 3073 bool restoringContext_; 3074 3075 bool valueChanged_; 3076 3077 JSlot mouseWentDownSlot_; 3078 JSlot mouseWentUpSlot_; 3079 JSlot mouseDraggedSlot_; 3080 JSlot mouseMovedSlot_; 3081 JSlot mouseWheelSlot_; 3082 JSlot touchStarted_; 3083 JSlot touchEnded_; 3084 JSlot touchMoved_; 3085 JSlot repaintSlot_; 3086 3087 void defineJavaScript(); 3088 3089 #ifdef WT_TARGET_JAVA 3090 static void renderfv(std::ostream &os, WGenericMatrix<MatrixType, 4, 4> t, 3091 JsArrayType type); 3092 #endif 3093 3094 friend class WGLWidget::JavaScriptMatrix4x4; 3095 friend class WClientGLWidget; 3096 friend class WServerGLWidget; 3097 }; 3098 3099 W_DECLARE_OPERATORS_FOR_FLAGS(WGLWidget::GLenum) 3100 W_DECLARE_OPERATORS_FOR_FLAGS(GLClientSideRenderer) 3101 W_DECLARE_OPERATORS_FOR_FLAGS(GLRenderOption) 3102 } 3103 3104 #undef WT_WGL_TEMPLATE 3105 3106 #endif 3107