HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_OGLRender.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RE_OGLRender.h ( RE Library, C++)
7  *
8  * COMMENTS:
9  * Interface class for Open GL. Comamnds are grouped, in this order,
10  * under these tags:
11  *
12  * - RENDERING ENVIRONMENT (gl version, extensions, driver)
13  * - MONITOR SCREEN (monitor setup)
14  * - DISPLAY MODE & WINDOWS (windows, visuals)
15  * - ERROR REPORTING (gl errors)
16  * - FRAMEBUFFER OBJECTS
17  * - BUFFER CONTROL
18  * - FRUSTUM & CLIPPING
19  * - TRANSFORMATION
20  * - COLOR
21  * - LINE & POINT STYLES
22  * - STENCIL, LOGIC & DEPTH
23  * - BLENDING & SMOOTHING
24  * - DISPLAY LISTS
25  * - MATERIALS
26  * - GLSL SHADERS
27  * - TEXTURING
28  * - LIGHTING & SHADING
29  * - PICKING
30  * - RASTER OPERATIONS
31  * - SIMPLE PRIMITIVES (rect, circles, arcs)
32  * - FONT RENDERING
33  * - SURFACES (nurbs)
34  * - OBSOLETE DRAWING METHODS (begin/end stuff, vertex calls)
35  */
36 #ifndef __RE_OGLRender__
37 #define __RE_OGLRender__
38 
39 #include "RE_API.h"
40 
41 #include <SYS/SYS_Floor.h>
42 #include <SYS/SYS_Types.h>
43 
44 #include <UT/UT_Array.h>
45 #include <UT/UT_ArrayMap.h>
46 #include <UT/UT_Assert.h>
47 #include <UT/UT_Color.h>
48 #include <UT/UT_IntArray.h>
49 #include <UT/UT_Pixel.h>
50 #include <UT/UT_Rect.h>
51 #include <UT/UT_SpinLock.h>
52 #include <UT/UT_Thread.h>
54 #include <UT/UT_UniquePtr.h>
55 #include <UT/UT_Vector2.h>
56 #include <UT/UT_VectorTypes.h>
57 
58 #include <PXL/PXL_Common.h>
59 
60 #include "RE_Extension.h"
61 #include "RE_Material.h"
62 #include "RE_OGL.h"
63 #include "RE_OGLExt.h"
64 #include "RE_OGLState.h"
65 #include "RE_RenderFlush.h"
66 #include "RE_Texture.h"
67 #include "RE_TextureTypes.h"
68 #include "RE_Uniform.h"
69 
70 #include <utility>
71 
72 template <typename ITEM_T> class UT_StringMap;
73 class UT_WorkBuffer;
74 class UT_StopWatch;
75 class UT_StringHolder;
76 class IMG_Raster;
77 class TIL_Raster;
78 class PXL_Raster;
79 class PXL_Lookup;
80 
81 class RE_Cursor;
83 class RE_FontBuffers;
84 class RE_Geometry;
85 #if defined(EXPERIMENTAL_QOPENGLWIDGET)
86 class RE_GLDrawable;
87 #endif
88 class RE_OcclusionQuery;
89 class RE_OGLFramebuffer;
90 class RE_OGLTexture;
93 class RE_Render;
94 class RE_Server;
95 class RE_Shader;
96 class RE_ShaderHandle;
97 class RE_Visual;
98 class RE_Window;
99 class RE_WindowList;
100 
101 #define OPEN_GL
102 
103 // These values are the keys in the table returned by getDriverInfoDict().
104 #define RE_DRIVER_INFO_VENDOR "OpenGL Vendor"
105 #define RE_DRIVER_INFO_RENDERER "OpenGL Renderer"
106 #define RE_DRIVER_INFO_VERSION "OpenGL Version"
107 #define RE_DRIVER_INFO_SHADING_LANGUAGE "OpenGL Shading Language"
108 #define RE_DRIVER_INFO_DETECTED "Detected"
109 
110 // --------------------------------------------------------------------------
111 
113 {
114 public:
115  ~RE_OGLRender() override;
116 
117  const char *className() const;
118  int getContextID() const { return myUniqueID; }
119 
120  static void initialize();
121  bool isInitialized() const { return !firstInitialize; }
122 
123 #if defined(EXPERIMENTAL_QOPENGLWIDGET)
124  /// Initializes the OpenGL state in the render.
125  /// This method assumes that the render's context is already current.
126  /// If you need to make the render's context current first, then consider
127  /// creating an RE_RenderAutoLock instead.
128  void initGLState();
129 #endif
130 
131  // For RE_OGLRender methods to pass an RE_Render * to various objects
133  { return reinterpret_cast<RE_Render*>(this); }
134  const RE_Render *getRender() const
135  { return reinterpret_cast<const RE_Render*>(this); }
136 
137  // RENDERING ENVIRONMENT ------------------------------------------------
138  // You can use these methods to query support for a specific OpenGL
139  // version on the machine Houdini is running on.
140  static bool hasGL11();
141  static bool hasGL12();
142  static bool hasGL13();
143  static bool hasGL14();
144  static bool hasGL15();
145  static bool hasGL20();
146  static bool hasGL21();
147 
148  static bool hasGL3(int minor);
149  static bool hasGL4(int minor);
150 
151  static int glMajorVersion();
152  static int glMinorVersion();
153 
154  // Determines the version of GLSL. Currently it's either 1.xx or 0.0 (unsup)
155  int glslMajorVersion(); // 1
156  int glslMinorVersion(); // 0, 10, 20, 30, 40 or 50
157  int glslMaxOutputComponents(RE_ShaderType stage);
158  int glslMaxUniformComponents(RE_ShaderType stage);
159 
160  bool hasGLExtension(RE_Extension e) const;
161 
162  // Low-level hardware and driver verisons. Use these only to work
163  // around driver issues. All other features should use the GL version,
164  // or RE_OGLExt.
165 
166  // Returns the hardware doing the rendering.
167  static RE_GraphicsDevice getGraphicsDevice();
168 
169  // By default, we early exit without OpenGL 3.3, use this to disable
170  // for just querying GL info.
171  static void setPerformBadDriverCheck(bool onoff);
172 
173  // The driver version. NVidia uses XX.XX, while ATI uses X.XX.XX
174  static bool hasDriverVersion();
175  static int getDriverMajorVersion();
176  static int getDriverMinorVersion();
177  static int getDriverBuildMajorVersion();
178  static int getDriverBuildMinorVersion();
179  static void getDriverInfo(UT_WorkBuffer &info);
180  static const UT_StringMap<UT_StringHolder> &getDriverInfoDict();
181  static bool getUsingCoreProfile();
182  static void setUsingCoreProfile(bool using_core_profile);
183 
184  // Access to the RE_OGLExt methods. Should not be used outside of RE; use
185  // hasGLExtension() instead.
186  RE_OGLExt *getExt() const;
187 
188  // clear out all VBOs and textures in the graphics cache.
189  static void clearGraphicsCache();
190 
191  // Queries to return the total free memory, and optionally the largest
192  // available chunk of memory on the GPU. Extension RE_EXT_MEMORY_QUERY
193  // is required.
194  int64 getFreeTextureMemoryKB(int64 *largest_chunk = nullptr);
195  int64 getFreeBufferMemoryKB(int64 *largest_chunk = nullptr);
196  int64 getFreeFramebufferMemoryKB(int64 *largest_chunk = nullptr);
197 
198  // Returns the amount of free memory on the GPU when Houdini first started.
199  static int64 getInitialFreeMemoryKB();
200 
201  // Call in the case of a fatal startup error due to insufficient driver
202  // support.
203  static void exitWithBadDriver();
204 
205  // MONITOR SCREEN ---------------------------------------------------------
206 
207  static int resX();
208  static int resY();
209 
210  static void updateScreenSize();
211 
212  // Multi-monitor support. Primary monitor is screen 0.
213  //
214  // returns true if all the screens are the same size
215  static bool areScreensUniform();
216  // returns a work area for the screen(s) occupied by 'area', for use when
217  // multiple screens aren't uniform in size.
218  static UT_DimRect getWorkAreaForScreen(UT_DimRect area);
219 
220  // this method positions rect entirely on one screen, shifting if
221  // required. If screen_hint is not -1, the screen containing that
222  // coord will be used. It returns the screen chosen.
223  //
224  static int positionOnScreen(UT_DimRect &area,
225  int screen_hint=-1);
226 
227  // returns true if the area fits entirely within one of the work areas.
228  static bool positionOkay(const UT_DimRect &area);
229 
230  static int dpi(); // system dpi * UI scale
231  static fpreal uiScale(); // UI scale factor (HOUDINI_UISCALE)
232  static void scaleUI(fpreal scale);
233  static float pixelsToInches(int n);
234  static int inchesToPixels(float i);
235  static int scaledSize(int size);
236  static fpreal scaledSize(fpreal size);
237 
238  // does a quick check to determine if the computer entered a suspend (sleep)
239  // mode, where many GPU computed textures and buffers will need to be
240  // recomputed.
241  void checkForSuspendResume();
242  static void addSuspendResumeCB(void (*cb)(void*), void *data);
243  static void removeSuspendResumeCB(void (*cb)(void*), void *data);
244 
245  // DISPLAY MODE & WINDOWS ----------------------------------------------
246 
247  RE_DisplayMode getMode() const;
248  RE_VisualType getVisualType() const;
249 
250  void enableMultisample(bool enable);
251  bool isMultisampleEnabled() const;
252 
253  void enableAlphaToCoverage(bool enable);
254  bool isAlphaToCoverage() const;
255 
256  void getMaxViewportSize(int &w, int &h) const;
257  int getMaxColorSamples() const;
258  int getMaxDepthSamples() const;
259 
260  static RE_Visual *getVisualForMode(RE_DisplayMode newmode);
261  static RE_Server *getServer();
262  static RE_Cursor *getCursor(const char *name);
263 
264  void setWindow(RE_Window *, bool attach = true);
265 
266  bool makeCurrent(bool ignore_errors = false);
267 #if defined(EXPERIMENTAL_QOPENGLWIDGET)
268  bool isCurrent() const;
269 #else
270  bool isCurrent() const
271  { return theCurrentRender.get() == this; }
272 #endif
273  static void resetCurrent();
274 #if defined(EXPERIMENTAL_QOPENGLWIDGET)
275  bool contextIsValid() const;
276  RE_OGLContext getContext() const;
277 #else
278  bool contextIsValid() const { return (bool)myContext; }
279  RE_OGLContext getContext() const { return myContext; }
280 #endif
281 
282  // When using Pbuffers instead of FBOs, we have to set them up as the
283  // render target. You cannot push more than 1 buffer at a time.
284 #if defined(EXPERIMENTAL_QOPENGLWIDGET)
285  bool pushOffscreenBuffer(RE_GLDrawable *type);
286 #else
287  bool pushOffscreenBuffer(OGLDrawable type);
288 #endif
289  void popOffscreenBuffer();
290 
291  // This is the context of the main window, which should persist always.
292  void setMainContext(RE_Window *w);
293  static RE_Window *getMainContext();
294 
295  static RE_OGLRender *getCurrentRender();
296  static RE_WindowList *getWindowList();
297  const RE_Window *getCurrentWindow() const;
298  RE_Window *getCurrentWindow();
299 
300  // These methods prepares for another thread to access OpenGL.
301  // They are called from the same thread that will be accessing OpenGL.
302  // If they're called from the main thread, they do nothing.
303  //
304  // These methods work by giving each thread its own OpenGL context.
305  // Because other threads do not know when the main thread changes the
306  // OpenGL context or drawable, they must call the prepare...() method
307  // to explicitly set their context, before they main RE/OGL calls.
308  //
309  // These methods do not provide support for concurrent access to RE
310  // from multiple threads: only one thread at a time may make RE calls.
311  // The main thread must be blocked while the other thread makes the
312  // calls. That other thread must call lock...() while the main thread
313  // is blocked, make its RE calls, call unlock...(), and only then may it
314  // unblock the main thread.
315  //
316  // These methods are called by HOMF_HOMGLAutoLock so HOMF methods can
317  // call code that eventually makes OpenGL calls, even when the Python
318  // interpreter is running in a separate thread.
319  void lockContextForRender();
320  void unlockContextAfterRender();
321  bool tryLockContextForRender();
322  bool isContextLocked() const;
323 
324 #if defined(EXPERIMENTAL_QOPENGLWIDGET)
325  /// These methods are similar to lockContextForRender() and
326  /// unlockContextAfterRender() but they do not set or unset the current
327  /// OpenGL context.
328  /// {
329  void lockContext();
330  void unlockContext();
331  /// }
332 
333 #endif
334  void bumpRenderCount() { myRenderCount ++; }
335  void resetRenderCount() { myRenderCount = 0; }
336  int64 getRenderCount() const { return myRenderCount; }
337 
338  // ERROR REPORTING --------------------------------------------------
339  int getGLError();
340  int getNextGLError();
341  void clearGLErrors();
342  const char *getGLErrorString( int error );
343  void printGLError(const char *header,
344  bool assert = false );
345  void printAllGLErrors( const char *header,
346  bool assert = false );
347 
348  void dumpNewState(bool show_all = false,
349  bool show_shader_blocks = true);
350  void dumpViewportState(bool show_all = false);
351  void dumpTextureState() const;
352  void dumpVertexAttributes() const;
353  void dumpFragmentTests(bool show_all = false) const;
354  void dumpRasterizeState(bool show_all = false) const;
355  void dumpTextureCacheState(int stack_level =-1) const;
356 
357  void getLimits(UT_WorkBuffer &os);
358 
359  // RE_EXT_DEBUG_OUTPUT2 (GL_KHR_debug) required with env HOUDINI_OGL_DEBUG>0
360  bool isDebugLabelSupported() const;
361 
362  // HOUDINI_OGL_DEBUG > 0 and RE_EXT_DEBUG_OUTPUT2 is supported.
363  bool isDebugging() const;
364 
365  int pushDebug(bool enable);
366  void popDebug(int *nest = nullptr);
367 
368  int pushDebugGroup(const char *name, int id=1987);
369  void popDebugGroup(int *nest = nullptr);
370 
371  void addComment(const char *name,
373  int id =1987);
374 
375 
376  // FRAMEBUFFER OBJECTS -------------------------------------------------
377 
378  // There are two bindings for framebuffers, read and draw. If
379  // RE_EXT_FRAME_BUFFER_OBJECT_ARB is not supported, these will be the same.
380  int pushDrawFramebuffer(); // no change to FBO state
381  int pushDrawFramebuffer(RE_OGLFramebuffer *fb);
382  void setDrawFramebuffer(RE_OGLFramebuffer *fb);
383  RE_OGLFramebuffer *getDrawFramebuffer();
384  void popDrawFramebuffer(int *nest = nullptr);
385 
386  int pushReadFramebuffer(); // no change to FBO state
387  int pushReadFramebuffer(RE_OGLFramebuffer *fb);
388  void setReadFramebuffer(RE_OGLFramebuffer *fb);
389  RE_OGLFramebuffer *getReadFramebuffer();
390  void popReadFramebuffer(int *nest = nullptr);
391 
392  void updateFramebuffer();
393  // Only called by RE_OGLFramebuffer; updates the current FBO state.
394  void updateCurrentFramebuffer(RE_OGLFramebuffer *fb,
395  bool for_draw);
396 
397  void registerFBO(RE_OGLFramebuffer *fb, int fb_id);
398  void unregisterFBO(int id);
399  RE_OGLFramebuffer *getFBO(int id) const;
400 
401  // Sample state
402  void useSampleMask(bool use);
403  bool usingSampleMask() const;
404  int getMaxIntegerSamples() const;
405  int getSampleMask(int mask_number);
406  void setSampleMask(int mask_number, int mask);
407  static int getMatteMaskForSampleCount(int samples);
408 
409  // BUFFER CONTROL -------------------------------------------------------
410 
411  // If possible, call clearCZ() instead of clear() followed by clearZ(),
412  // since a single clearCZ() is much faster on all post-Indy machines.
413  void clearC(float *color = nullptr);
414  void clearZ(float z = 1.0);
415  void clearCZ(float z = 1.0);
416  void clearS();
417 
418  // Using these methods, you can disable updates to the colour and/or depth
419  // bits of the frame buffer. Be careful with these, since the associated
420  // calculations will still be performed (eg. even if color buffer updates
421  // are disabled, useless lighting calculations are still done if
422  // GL_LIGHTING is enabled). Same with GL_DEPTH_TEST. So you can easily
423  // write inefficient code.
424  void enableColorBufferWriting();
425  void disableColorBufferWriting();
426  bool getColorBufferWriting();
427  void updateColorBufferWriting();
428 
429  void setColorMask(bool red, bool green, bool blue, bool alpha);
430  void getColorMask(bool &red, bool &green, bool &blue, bool &alpha);
431 
432  bool swapbuffers();
433 
434  // By default, the buffer is not changed (RE_BUFFER_UNINIT)
435  int pushDrawBuffer( RE_RenderBuf buf = RE_BUFFER_UNINIT);
436  void popDrawBuffer(int *nest = 0);
437  void setDrawBuffer( RE_RenderBuf buf );
438  RE_RenderBuf getDrawBuffer();
439  bool getDrawBufferIsBlendable();
440 
441  int pushReadBuffer( RE_RenderBuf buf = RE_BUFFER_UNINIT);
442  void popReadBuffer(int *nest = 0);
443  void setReadBuffer( RE_RenderBuf buf );
444  RE_RenderBuf getReadBuffer();
445 
446  // set by the current window, UI_Window::setContext(). returns if the
447  // front buffer has been written to since last swap (for marquee drawing)
448  //
449  bool isFrontBufferDirty() const;
450  void setFrontBufferDirty(bool d);
451 
452  void flush(int wait=0);
453 
454  /// Ensure all writes are complete to the specified resource(s).
455  /// GL4.2, RE_EXT_BUFFER_STORE or RE_EXT_SHADER_LOAD_STORE must be
456  /// supported, or this will return false, doing nothing.
457  bool memoryBarrier(RE_MemoryBarrierBitfield barriers);
458 
459  // FRUSTUM & CLIPPING ------------------------------------------------
460 
461  // masked rendering (scissor)
462  void viewport2DI(const UT_DimRect &rect);
463  void screenMask2DI(const UT_DimRect &rect);
464  void disableScreenMask();
465  void intersectMask2DI(const UT_DimRect &rect);
466  UT_DimRect getScreenMask2DI();
467  UT_DimRect getViewport2DI();
468  bool getScreenMask();
469 
470  // Clip distance enables
471  int getOGLMaxClipPlanes();
472  void enableClipDistance(int clip_plane, bool enable);
473  bool clipDistanceEnabled(int clip_plane) const;
474 
475  // Active Occlusion query (only 1 active at a time)
476  void setActiveOcclusionQuery(RE_OcclusionQuery *q);
477  RE_OcclusionQuery *getActiveOcclusionQuery() const;
478 
479  // Backface culling
480  int pushBackfaceCulling();
481  int pushBackfaceCulling(bool backface);
482  void popBackfaceCulling(int *nested = 0);
483 
484  bool isBackface() const;
485  void setBackface(bool removeBackface);
486  bool getReverseWinding();
487  void setReverseWinding(bool reverse_winding);
488  RE_FaceMode getCullFace() const;
489  void setCullFace(RE_FaceMode m);
490 
491  // polygon/line offset
492  bool isPointOffset();
493  bool isLineOffset();
494  bool isPolygonOffset();
495  void pointOffset( bool onoff );
496  void lineOffset( bool onoff );
497  void polygonOffset( bool onoff );
498  void setOffsetAmount( float variable, float constant );
499  void getOffsetAmount(float *variable, float *constant) const;
500 
501 
502 
503  // Start collecting vertex/geometry shader attribute output into buffers.
504  // There must be a shader active, and this shader must have one or more
505  // transform feedback buffers enabled. 'mode' must be one of RE_PRIM_POINTS,
506  // RE_PRIM_LINES, or RE_PRIM_TRIANGLES, and only those types can be
507  // rendered. 'rasterize_too' controls whether primitives continue on to the
508  // fragment shader to be rasterized or stop at the transform feedback stage.
509  // 'stream_bitfield' allows multiple vertex streams to be captured when GL4
510  // is present (bit N = vertex stream N).
511  bool beginTransformFeedback(RE_PrimType mode,
512  bool rasterize_too,
513  int stream_bitfield = 0x1);
514 
515  // only call end if begin returned true.
516  void endTransformFeedback();
517 
518  // returns the number of primitives collected in the transform feedback
519  // buffers. Must be called after endTransformFeedback().
520  int getNumFeedbackPrimitives(int stream = 0);
521 
522  // Returns true if the feedback buffers overflowed. Must be called after
523  // endTransformFeedback()
524  bool hasFeedbackBufferOverflow(int stream = 0);
525 
526  // Transform feedback state queries.
527  bool isTransformFeedbackEnabled() const;
528  RE_PrimType getFeedbackMode() const;
529  bool isRasterizeEnabled() const;
530 
531  // Line & Point sizes
532  int pushLineWidth(float w);
533  void popLineWidth(int *nest = nullptr);
534  float getLineWidth() const;
535  float getMaxSmoothLineWidth();
536 
537  int pushPointSize(float size, bool program_point_size = false);
538  void popPointSize(int *nest = nullptr);
539  void setPointSize(float size);
540 
541  // If enabled, point size is taken from vertex or geometry shader's
542  // gl_PointSize output
543  void setProgramPointSize(bool enable);
544  bool getProgramPointSize() const;
545 
546  // STENCIL, LOGIC & DEPTH ------------------------------------------------
547 
548  // The depth state consists of the depth test bit, depth compare function
549  // depth clamp, and the depth buffer writemask. Note that pushBlendState()
550  // can affect the depth buffer writemask, so it is important that if they
551  // are nested, the order of the pops is reversed from the pushes.
552  int pushDepthState();
553  void popDepthState(int *nest = nullptr);
554 
555  // In order to enable depth buffer writes, a depth buffer must be present
556  // in the current window or framebuffer.
557  void enableDepthBufferWriting();
558  void disableDepthBufferWriting();
559  bool getDepthBufferWriting();
560  void updateDepthBufferWriting();
561 
562  // Depth testing must be enabled for depth buffer writes to have any effect.
563  void enableDepthTest();
564  void disableDepthTest();
565  bool getDepthTest();
566  void updateDepthTest();
567 
568  // The depth function only has an effect if depth testing is enabled.
569  void setZFunction(RE_ZFunction func);
570  RE_ZFunction getZFunction() const;
571  void updateZFunction() const;
572 
573  // Depth clamping causes objects outside of [near,far] to clamp their Z to
574  // near or far. By default it is off.
575  void enableDepthClamp(bool b);
576  bool getDepthClamp();
577  void updateDepthClamp();
578 
579  void setDepthRange(double nr, double fr);
580  void getDepthRange(double &nr, double &fr) const;
581 
582  // Stencil state
583  int pushStencilState();
584  void popStencilState(int *nest = nullptr);
585  bool isStencil();
586  void setStencil(bool enable);
587  void setSClearValue(int clearValue);
588  void setSWriteMask(int writeMask);
589  void setSFunction(RE_SFunction func, int ref, int mask);
590  void setSOperation(RE_SOperation sfail,
593  void updateStencilState();
594  void resetSFunction();
595  void resetSWriteMask();
596  void resetSClearValue();
597  void resetSOperation();
598 
599  // Logic state
600  void enableLogicOp();
601  void disableLogicOp();
602  void invertPixels();
603  void xorPixels();
604  void orPixels();
605 
606  // BLENDING and SMOOTHING -----------------------------------------------
607  int pushBlendState();
608  void popBlendState(int *nesting = 0);
609 
610  bool isBlending() const;
611  void blend(int onoff);
612  void setBlendFunction(RE_BlendSourceFactor sourceFactor,
613  RE_BlendDestFactor destFactor);
614  bool setAlphaBlendFunction(RE_BlendSourceFactor sourceFactor,
615  RE_BlendDestFactor destFactor,
616  bool force = false);
617  void getBlendFunction(RE_BlendSourceFactor* sourceFactor,
618  RE_BlendDestFactor* destFactor);
619  void getAlphaBlendFunction(RE_BlendSourceFactor *sourceFactor,
620  RE_BlendDestFactor *destFactor);
621  void setBlendEquation(RE_BlendEquation eq);
622  RE_BlendEquation getBlendEquation();
623 
624  // blendAlpha uses (Sa, 1-Sa). blendAlphaPremult uses (1, 1-Sa) (assumes
625  // color is premultiplied)
626  void blendAlpha(int onoff = 1);
627  void blendAlphaPremult(bool onoff = true);
628 
629  int pushSmoothLines();
630  void popSmoothLines(int *nesting = 0);
631  void forceSmooth();
632  void smoothBlendLines(RE_SmoothMode mode);
633  void smoothBlendLinesNoFlagChange(bool by_smooth);
634  RE_SmoothMode getSmoothLines();
635 
636  int getBlendSmoothLevel() const;
637 
638  static void allowSmoothLines(int yn);
639  static int allowsSmoothLines();
640 
641  static int getGLBlendSource(RE_BlendSourceFactor sourceFactor);
642  static int getGLBlendDest(RE_BlendDestFactor destFactor);
643 
644  // MATERIALS -------------------------------------------------------------
645 
646  // The layer here is indexed from 0, while the layers in the GU_Details
647  // are indexed from 1.
648  void setMaterial(const RE_MaterialPtr &mat,
649  int layer=0, bool texture=true,
651  RE_Shader *override_mat_shader = nullptr,
652  bool allow_partial_render = false);
653  int pushMaterial(const RE_MaterialPtr &mat,
654  int layer=0, bool texture=true,
656  RE_Shader *override_mat_shader = nullptr,
657  bool allow_partial_render = false);
658  int pushMaterial();
659  void popMaterial(int *nest = nullptr);
660 
661 
662  // material used as a default material
663  const RE_MaterialPtr &getDefaultMaterial();
664 
665  // GLSL SHADERS ---------------------------------------------------------
666 
667  int pushShader(); // no change to state
668  int pushShader(RE_Shader *s);
669  int pushShader(RE_ShaderHandle &sh);
670 
671  void bindShader(RE_Shader *s);
672  void bindShader(RE_ShaderHandle &sh);
673 
674  RE_Shader *getShader();
675  void popShader(int *nest = nullptr);
676 
677  void updateShader(RE_Shader *s); // only called by RE_Shader.
678 
679  int pushShaderTransformFeedback(RE_Shader *sh,
681  bool rasterize = true,
682  int stream_bitfield = 0x1);
683  int pushShaderTransformFeedback(RE_ShaderHandle &sh,
685  bool rasterize = true,
686  int stream_bitfield = 0x1);
687  void popShaderTransformFeedback(int *nest = nullptr);
688 
689  // When on, the GL shader will never be set back to nullptr by popShader();
690  // however, an RE_Geometry::draw() command when the shader should be nullptr
691  // will enter fixed function mode. This is basically a 'lazy pop' mode.
692  // immediate mode begin/end should not be used with this shading mode.
693  void setShaderOnlyMode(bool enable);
694  void requestFixedFunction();
695 
696  /// Set the tesselation default outer level parameters (with no tess control
697  /// shader) for the tesselator. Requires RE_EXT_TESS_SHADER or GL4.
698  void setPatchOuterLevel(const UT_Vector4F &outer);
699 
700  /// Set the tesselation default inner level parameters (with no tess control
701  /// shader) for the tesselator. Requires RE_EXT_TESS_SHADER or GL4.
702  void setPatchInnerLevel(const UT_Vector2F &inner);
703 
704  /// Set the number of vertices per patch for tesselation. Requires
705  /// RE_EXT_TESS_SHADER or GL4.
706  void setPatchVertices(int num_verts);
707 
708  // for multisampled buffers on GL4+ hardware, the fragment shader can be
709  // run to produce more than one color sample. The rate is a fraction between
710  // 0.0 and 1.0, which will guarentee at least ceil(rate*samples) color
711  // samples are produced in multisampled buffers. Note this can degrade
712  // performance substantially for some heavy fragment shaders.
713  // If RE_EXT_SAMPLE_SHADING is unsupported, this has no effect and
714  // setShaderSampleRate() will return false.
715  bool setShaderSampleRate(fpreal rate);
716  fpreal getShaderSampleRate() const;
717 
718  bool isSampleShading() const;
719 
720  // Assign a new uniform value to built-in uniform. If nullptr is passed,
721  // the value is unchanged but the current value copied to the uniform stack.
722  void pushUniform(RE_UniformBuiltIn bindex,
723  RE_Uniform *var = nullptr);
724  // Assign raw values to a built-in uniform. The array must be at least of
725  // size getUniform(builtin_var_type)->getByteSize().
726  void pushUniformData(RE_UniformBuiltIn bindex,
727  const void *data);
728  void pushUniformInt(RE_UniformBuiltIn bindex, int i);
729  void pushUniformColor(RE_UniformBuiltIn bindex,
730  const UT_Color &clr, fpreal32 alpha = 1.0f);
731  void pushUniformSampler(RE_UniformBuiltIn bindex,
732  RE_Texture *tex);
733  void pushUniformMatrix(RE_UniformBuiltIn bindex,
734  const UT_Matrix4D &mat);
735  void assignUniformData(RE_UniformBuiltIn bindex,
736  const void *data);
737  void assignUniformInt(RE_UniformBuiltIn bindex, int i);
738  void assignUniformSampler(RE_UniformBuiltIn bindex,
739  RE_Texture *tex);
740  void assignUniformColor(RE_UniformBuiltIn bindex,
741  const UT_Color &clr, fpreal32 alpha = 1.0f);
742  void assignUniformMatrix(RE_UniformBuiltIn bindex,
743  const UT_Matrix4D &mat);
744  void popUniform(RE_UniformBuiltIn bindex);
746  { popUniform(bindex); }
747 
748  RE_Uniform *getUniform(RE_UniformBuiltIn builtin_var_type) const;
749 
750  // Prints all builtins that have been assigned, or only those which the
751  // current shader has bound (if bound_only is true).
752  void printBuiltInUniforms(bool bound_only);
753 
754  // Print a single builtin's current value.
755  void printBuiltInUniform(RE_UniformBuiltIn b);
756 
757  // Bind all builtin uniforms to the shader. Returns the # of uniforms bound
758  int bindBuiltInUniforms(RE_Shader *s);
759 
760  // Bind the specified uniform to the shader. returns true if a uniform was
761  // present to bind.
762  bool bindBuiltInUniform(RE_Shader *s,
763  RE_UniformBuiltIn uniform);
764 
766  { return myBuiltInUniformSerial; }
767  void bumpBuiltInUniformSerial() { myBuiltInUniformSerial++; }
768 
769  // Assigns a generic uniform, which will be bound to any shaders with this
770  // name. These will override any uniform values when the shader is bound, or
771  // values on the current shader when the uniform is pushed. The name and
772  // uniform type must match exactly for an override to occur.
773  // If more than one uniform of the same name and type is pushed, the last
774  // one pushed takes precedent. Popping it will restore the previous uniform.
775  void pushUniform(RE_Uniform &uniform);
776  void popUniform(RE_Uniform &uniform);
777 
778 
779  // Push the object matrix and update the object and object-view uniforms.
780  // If inverse_too is true, compute and push the inverse object matrix.
781  void pushObjectMatrix(const UT_Matrix4D &obj,
782  bool inverse_too = false);
783  void popObjectMatrix();
784 
785 
786 
787  // Sets a GLSL hint to compute derivatives - fast = false, nice = true
788  void setFragmentDerivativeHint(bool nicest);
789  bool getFragmentDerivativeHint();
790 
791  // Maximum number of vertex attributes supported for vertex shader input
792  int getMaxVertexAttribs() const { return myMaxVertexAttribs; }
793 
794  // Set a vertex attribute at input 'loc' to 'vsize' constant values.
795  // 'vsize' must be between 1 and 4.
796  void setConstAttribF32(int loc, int vsize, const fpreal32 *data);
797 
798  // Set a vertex attribute to constant values. Downcasts to FP32 in GL call.
799  void setConstAttribF32(int loc, int vsize, const fpreal64 *data);
800 
801  // Set a vertex attribute to constant values. Sets as proper FP64.
802  void setConstAttribF64(int loc, int vsize, const fpreal64 *data);
803 
804  // Set a vertex attribute to constant values.
805  void setConstAttribI32(int loc, int vsize, const int32 *data);
806 
807  // Set a vertex attribute to constant values.
808  void setConstAttribU32(int loc, int vsize, const uint32 *data);
809 
810  // Notify the context that 'list' is now the current VAO.
811  bool setCurrentVAO(RE_OGLVertexArrayList *list);
812 
813  // Query the current VAO.
814  RE_OGLVertexArrayList *getCurrentVAO();
815 
816  // Query the default VAO for this context.
817  RE_OGLVertexArrayList *getDefaultVAO() { return myDefaultVAO; }
818 
819  // Don't call this.
820  void setDefaultVAO(RE_OGLVertexArrayList *vao) { myDefaultVAO = vao;}
821 
822  // Notify the context that 'list' is being deleted, and any referenece
823  // should be cleared.
824  void resetCurrentVAO(RE_OGLVertexArrayList *deleted_list);
825 
826  // Returns a list of the currently bound uniform blocks to this context.
827  UT_IntArray &getBoundUniformBlocks() { return myState.myBoundUniformBlocks;}
828 
829  // TEXTURING -------------------------------------------------------------
830 
831  // Bind the given texture to the specified, or active, texture unit. The
832  // texturing mode can be optionally set at the same time (if not set to
833  // UNKNOWN). If texturing for the texture's type is not enabled on the
834  // texturing unit, it is enabled.
835  void bindTexture(const RE_OGLTexture *tex,
836  int unit = RE_ACTIVE_UNIT,
838  void verifyTextureIsNotBound(RE_OGLTexture *texture);
839 
840  // Bind texture buffer 'id' to 'unit' and return the previously bound
841  // texture at 'unit'. This is only used by low-level RE methods.
842  RE_TextureID bindTextureBuffer(int id, int unit);
843 
844  RE_TextureID bindTextureRaw2D(int id, int unit);
845  int bindTextureRaw(int id, int unit);
846 
847  // Bind an array of textures starting at 'first'. Requires
848  // RE_EXT_MULTI_BIND. Returns false if this is not supported.
849  bool bindTextures(int first, const UT_IntArray &tex_ids);
850 
851  // Unbind all instances of texture 'tex'. This can be an expensive call.
852  void unbindTexture(const RE_OGLTexture *tex);
853 
854  // Query & set the active texture units. Note these are 0 based,
855  // not GL_TEXTURE0 based.
856  void setActiveTexture(int textureunit);
857  int getActiveTexture() const;
858 
859  // Save the texture state for the specified texture unit, or all of
860  // them (RE_ALL_UNITS). If the entire state is pushed, the active texture
861  // unit is saved as well. RE_ALL_UNITS is relatively expensive, so use
862  // with care. push returns a nesting index which can be passed to pop to
863  // ensure proper nesting of push/pop calls.
864  int pushTextureState(int textureunit = RE_ALL_UNITS);
865  void popTextureState(int *nest = nullptr);
866 
867  // The type and texture object currently bound to the given,
868  // or current (-1), texture unit
869  RE_TextureDimension getBoundTextureType(int texunit = RE_ACTIVE_UNIT) const;
870  const RE_OGLTexture *getBoundTexture(int texunit = RE_ACTIVE_UNIT) const;
871 
872  // Returns the first texture unit with no bound unit, starting the search
873  // at starting_unit. -1 is returned if no free units are available.
874  int findFirstFreeTextureUnit(int starting_unit = 0) const;
875 
876  // Reads in initial values for all the textures.
877  void updateTextureState() const;
878 
879  // Query the maximum number of texture units we support.
881  { return myMaxTextureShaderUnits; }
883  { return myMaxTextureVertexUnits; }
885  { return myMaxTextureGeometryUnits; }
887  { return myMaxTextureFragmentUnits; }
889  { return myMaxTextureAnisotropy; }
890 
891  // Query the maximum size of a texture that is supported (either width or
892  // height)
893  int getMaxTextureSize() const
894  { return myMaxTextureSize; }
896  { return myMaxTexture3DSize; }
898  { return myMaxTextureRectSize; }
899 
900  // Query the maximum number of frame buffer color attachments.
901  int getMaxColorBuffers() const
902  { return myMaxColorBuffers; }
903  // Query the max number of draw buffers.
904  int getMaxDrawBuffers() const
905  { return myMaxDrawBuffers; }
906 
907  // This will disable for all texture units.
908  void disableAllTextures();
909  void removeTextureRefs(RE_OGLTexture *tex);
910 
911  // Bind a texture as an image (requires RE_EXT_IMAGE_LOAD_STORE or GL4.2)
912  bool bindImageTexture(int image_unit,
913  RE_Texture *image,
914  RE_BufferAccess image_access,
915  bool layered,
916  int layer);
917  void unbindImageTexture(int image_unit);
918 
919  //
920 
921  // These methods ensure that the pixel store options are set so that the
922  //
923  int pushReadAlignment(const void *data, int scansize);
924  void popReadAlignment(int *nest = nullptr);
925 
926  int pushWriteAlignment(const void *data, int scansize);
927  void popWriteAlignment(int *nest = nullptr);
928 
929  // Enables seamless cubemap filtering for all cubemaps, if supported.
930  void useSeamlessMaps(bool enable);
931  bool usingSeamlessMaps();
932 
933  // Returns an 8b RGBA 64x64 texture with 0-1 random values in all comps.
934  RE_OGLTexture *getRandomTexture(unsigned int seed, bool interp,
935  int size = 64);
936 
937  // Returns an 8b RGBA size^3 3D texture with 0-1 random values
938  RE_OGLTexture *getRandomTexture3D(unsigned int seed, bool interp,
939  int size = 32);
940  // Returns an 8b RGBA size^2 2D texture array of size 'num_layers'
941  RE_OGLTexture *getRandomTextureArray(unsigned int seed, bool interp,
942  int num_layers, int size = 64 );
943 
944  // returns an int32 single channel texture that returns a random sample
945  // mask. The texture is size x (nsamples+1) in size, with each row having
946  // 'N' bits randomly enabled, where N is the row # (0..nsamples). This can
947  // be used for gl_SampleMask
948  RE_OGLTexture *getRandomSampleMaskTexture(unsigned int seed, int nsamples,
949  int size = 64);
950 
951  // Texture Image drawing ------------------------------------------------
952 
953  // makes a texture out of the raster, and stores the id in the raster.
954  void convertRasterToTexture(PXL_Raster *raster,
955  int convert16bit = 0,
956  bool isinteger = false);
957  void convertLUTToTexture(PXL_Lookup *lookup);
958  bool setupShaderForLUT(RE_Shader *shader,
959  PXL_Lookup *lookup,
960  float gamma,
961  bool add_shader);
962  bool is3DLUTSupported() const;
963 
964  void buildRasterTextureGeometry(
965  fpreal32 x0, fpreal32 y0, fpreal32 z,
966  fpreal32 x1, fpreal32 y1,
967  fpreal32 u0, fpreal32 v0,
969  int rotation, // Must be in the range [-360, 360] in 90 degree increments
970  RE_Geometry &geo);
971  void displayRasterTexture(float x, float y, float z,
972  const PXL_Raster *raster,
973  const RE_RasterOpts *opts = 0);
974  void displayRasterTexture(float x, float y, float z,
975  float w, float h,
976  const IMG_Raster *raster,
977  const RE_RasterOpts *opts = 0);
978  void displayRasterTexture(float x, float y, float z,
979  int w, int h,
980  UT_RGBA *r, int stride,
981  float zoomx=-1.0f,
982  float zoomy=-1.0f,
983  int dither=1,
984  float alpha_mult=1.0f);
985 
986  // The saveRaster method saves the front buffer to a raster. The
987  // raster should be the same size as the w and h parms. As well,
988  // currently, we only support 8 bit channels in the raster. A zoom of -1
989  // uses the current zoom (default).
990  void saveRaster(int x, int y, int w, int h,
991  IMG_Raster *r, bool use_backbuf = true);
992  UT_UniquePtr<TIL_Raster> saveRaster(int x, int y, int w, int h,
993  PXL_DataFormat format, bool alphatoo,
994  bool use_backbuf = true);
995 
996 
997  // The following method is used to align text in the viewport where the
998  // current xform makes attempting to use textMove* impractical for this
999  // purpose.
1000  // NOTE: Clipping is performed using the actual raster position (set
1001  // through textMove*) and not the offset position.
1002  // NOTE: Only works for bitmap fonts, not texture fonts.
1003  void setViewportFontOffset(int x, int y);
1004  int getViewportFontOffsetX() const;
1005  int getViewportFontOffsetY() const;
1006 
1007  RE_FontBuffers *fetchFontBufferFromPool(int size);
1008  void returnFontBufferToPool(RE_FontBuffers *buf);
1009 
1010  // DRAWING METHODS -------------------------------------------------------
1011 
1012  // Begin a conditional render based on an occlusion query's samples result.
1013  // If the query returns zero samples, all drawing is ignored until
1014  // the conditional render is ended. Otherwise, rendering is done as normal.
1015  // Conditional rendering cannot be nested.
1016  //
1017  // 'render_wait' specifies whether the render should wait for the results
1018  // of the occlusion query, if they are not available.
1019  // 'region_support' allows the conditional render to happen at a fine
1020  // grain level, which is implementation specific.
1021 
1022  // beginConditionalRender() will return false if the the query_object has
1023  // not be run yet, if a conditional render is already in progress, or if
1024  // RE_EXT_CONDITIONAL_RENDER is not supported. Do not call
1025  // endConditionalRender() in this case.
1026  bool beginConditionalRender(RE_OcclusionQuery *query_obj,
1027  bool render_wait,
1028  bool region_support);
1029  void endConditionalRender();
1030 
1031  // enables a primitive restart index, which begins a new primitive when
1032  // using an element buffer.
1033  void enablePrimitiveRestart(bool enable);
1034  void setPrimitiveRestartIndex(unsigned int index);
1035 
1036  // A few higher level functions for simple tasks rendering to the
1037  // viewport. These encapsulate a lot of boilerplate code.
1038  void drawViewportPoint(const fpreal32 p[3],
1039  fpreal32 size);
1040  void preDrawViewportString(UT_Matrix4D &view,
1041  UT_Matrix4D &proj,
1042  UT_DimRect &viewport);
1043  void drawViewportString(const fpreal32 p[3],
1044  const char *str,
1045  const UT_Color *clr = nullptr,
1046  const UT_Matrix4D *view = nullptr,
1047  const UT_Matrix4D *proj = nullptr,
1048  const UT_DimRect *viewport = nullptr);
1049  void postDrawViewportString();
1050 
1051  // Called by various RE classes; do not call directly.
1052  static void destroyShaderObject(unsigned int progid, bool unreg,
1053  bool shader);
1054  static void destroyTextureObject(unsigned int texid, RE_OGLTexture *tex);
1055  static void destroyRenderbufferObject(unsigned int rb);
1056  static void destroyBufferObject(unsigned int buf);
1057  static void destroySync(void *sync);
1058 
1059  static void clearCachedUniformBuffer(int id);
1060 
1061  // Context specific objects
1062  void destroyVertexArrayObject(unsigned int vao);
1063  void destroyQuery(unsigned int query);
1064  void destroyFramebufferObject(unsigned int fbo);
1065 
1066  void fetchDriverInfo(UT_WorkBuffer &info, bool full_info);
1067 
1068  // unbind common objects that might get stomped on by HDK calls:
1069  // shader, VAO, textures
1070  void unbindPipeline();
1071 
1072  // Invalidates all cached state. Useful when GL calls outside of RE are
1073  // used which change the GL state away from the cached state, and it is too
1074  // difficult to track the state, which is often the case with HDK plugins.
1075  void invalidateCachedState();
1076 
1077  // If GL calls outside of RE are used and change the state without restoring
1078  // it, call this method to update RE_OGLRender to the new state. This method
1079  // is somewhat expensive (causing a GPU/CPU sync) and should not be called
1080  // frequently or performance will suffer.
1081  void resync() { updateGLState(); }
1082 
1083  // Optimization to do additional buffer management for small buffers.
1084  // It must be turned on before updating any buffers, and then turned off
1085  // again before drawing those same buffers (enable, update, disable, draw).
1086  void enableSubBufferDrawing(bool enable);
1087  bool subBufferDrawingEnabled() const { return mySubBufferDrawing; }
1088 
1089 // Private methods ----------------------------------------------------------
1090 protected:
1091 
1092  /// Protected constructor to avoid having it created standalone. Strong
1093  /// assumptions are made that RE_OGLRender objects are always an instance
1094  /// of an RE_Render subclass.
1095  RE_OGLRender(int do_foreground, const char *appname = 0);
1096 
1097  // use macros for state change functions. Member variables are in
1098  // RE_OGLState.
1099 #define RE_FLAG_STATE(RE_NAME,GL_FLAG) \
1100  void enable##RE_NAME () { if( myState.my##RE_NAME##State != 1 ) { ::glEnable( GL_FLAG ); myState.my##RE_NAME##State = 1; } } \
1101  void disable##RE_NAME () { if( myState.my##RE_NAME##State != 0 ) { ::glDisable( GL_FLAG ); myState.my##RE_NAME##State = 0; } } \
1102  bool get##RE_NAME () { if(myState.my##RE_NAME##State == 3) update##RE_NAME(); return (myState.my##RE_NAME##State ==1); } \
1103  void update##RE_NAME () { myState.my##RE_NAME##State = ::glIsEnabled( GL_FLAG ); } \
1104  void invalidate##RE_NAME() { myState.my##RE_NAME##State = 3; }
1105 
1106  RE_FLAG_STATE(Scissor,GL_SCISSOR_TEST);
1107  RE_FLAG_STATE(LineSmoothing,GL_LINE_SMOOTH);
1108  RE_FLAG_STATE(Stencil,GL_STENCIL_TEST);
1109 #undef RE_FLAG_STATE
1110 
1111 #define RE_FLAG_11_STATE(RE_NAME,GL_FLAG) \
1112  void enable##RE_NAME () { if( (myState.my##RE_NAME##State) != 1 && hasGL11() ) {::glEnable( GLenum(GL_FLAG) ); myState.my##RE_NAME##State = 1; } } \
1113  void disable##RE_NAME () { if( myState.my##RE_NAME##State && hasGL11() ) { ::glDisable( GLenum(GL_FLAG) ); myState.my##RE_NAME##State = 0; } } \
1114  bool get##RE_NAME () { if(myState.my##RE_NAME##State == 3) update##RE_NAME(); return (myState.my##RE_NAME##State==1) ; } \
1115  void update##RE_NAME () { if( hasGL11() ) { myState.my##RE_NAME##State = ::glIsEnabled( GLenum(GL_FLAG) ); } else { myState.my##RE_NAME##State = 0; } } \
1116  void invalidate##RE_NAME() { if(hasGL11()) myState.my##RE_NAME##State=3; }
1117 
1121 #undef RE_FLAG_11_STATE
1122 
1123  void updateOffsetAmount();
1124 
1125  static bool initGLVersionInfo();
1126 #if !defined(EXPERIMENTAL_QOPENGLWIDGET)
1127  virtual void initGLState();
1128 #endif
1129  virtual void initGLExtensions();
1130  virtual void updateGLState();// load the following state variables
1131  virtual void updateStacks();
1132  void switchTexture(int textureunit, const RE_OGLTexture *texture);
1133 
1134  static void determineTwinView();
1135  bool switchContextForRender(bool ignore_errors);
1136 
1137 #ifdef WIN32
1138 private:
1139 #endif
1140 
1141  void updateBlendSmoothState();
1142  int privPushBlendSmoothState(bool smooth_too);
1143  void privPopBlendSmoothState(bool smooth_too, int *idx);
1144 
1145  void setupDebugging();
1146 
1147  void freePendingObjects();
1148 
1149  UT_DimRect adjustFramebufferViewport(const UT_DimRect &rect, bool to_fbo);
1150 
1151  void assignPushedUniforms();
1152 
1153  void fetchDriverInfoDict(UT_StringMap<UT_StringHolder> &dict);
1154 
1155 protected:
1156  // get the viewportState from GL
1157  void updateViewport();
1158 
1159  static RE_ZFunction oglToREzfunc( int oglZFunc );
1160  static int reToOGLzfunc( RE_ZFunction reZFunc );
1161  static RE_SFunction oglToREsfunc( int oglSFunc );
1162  static int reToOGLsfunc( RE_SFunction reSFunc );
1163  static RE_SOperation oglToREsoperation( int oglSOperation );
1164  static int reToOGLsoperation( RE_SOperation reSOperation );
1165 
1166  static const char *bufferName(GLint e);
1167  static const char *faceName(GLint e);
1168  static const char *hintName(GLint e);
1169  static const char *cullName(GLint e);
1170 
1171  // ---------------------------------------------------------------------
1172  // Cached OpenGL State
1173 
1175 
1176  // ------------------------------------------------------------------------
1177  // State independent data
1178 
1180 
1185 
1187 
1188 #if defined(EXPERIMENTAL_QOPENGLWIDGET)
1189  RE_GLDrawable *myDrawable;
1190  bool myDrawableInitialized;
1191  RE_GLDrawable *myPushedDrawable;
1192 #else
1197 #endif
1198 
1201 
1213 
1216 
1222 
1225 
1227 
1228  // Bound built-in uniform list for RE_Uniform.
1231  int myBuiltInStackIndex[RE_UNIFORM_BUILT_IN__count];
1232 
1234 
1235  int myViewportFontOffsetX, myViewportFontOffsetY;
1236 
1238 
1240  bool myMaterialTextureStack[RE_MAX_TEXTURE_STATE_STACK];
1241  int myMaterialLayerStack[RE_MAX_TEXTURE_STATE_STACK];
1244 
1254 
1258 
1262 
1265 
1267 
1273 
1275 
1276  // Static data ----------------------------------------------------------
1277  static int majorGLVersion;
1278  static int minorGLVersion;
1281 
1283  static int theXRes;
1284  static int theYRes;
1285  static int theDotsPerInch;
1288 
1292 
1293  // Card and driver info
1295  static int theDriverMajor;
1296  static int theDriverMinor;
1299  static bool theUsingCoreProfile;
1300 
1301  // These objects are per-context.
1305 
1307 
1309  {
1310  public:
1312  : is_cached(false), type(RE_GPU_FLOAT32), vector_size(4)
1313  { value[0] = 0.0; value[1] = 0.0; value[2] = 0.0; value[3] = 0.0; }
1317  fpreal64 value[4];// This is just a scratch buffer for comparing
1318  };
1319 
1323 
1325 
1326  // Suspend check on Linux
1327  void suspendTestPatternRender();
1328  bool suspendTestPatternCheck();
1329 
1336 
1337 protected:
1340 
1341  // which thread this context was created in.
1342  ut_thread_id_t myNativeThread;
1344 
1345  friend class RE_RenderFlush;
1346 #if defined(EXPERIMENTAL_QOPENGLWIDGET)
1347 
1348 private:
1349 
1350  void lockContextInternal_(bool set_current_context);
1351  void unlockContextInternal_(bool clear_current_context);
1352 #endif
1353 };
1354 
1356 {
1357 public:
1359  : myR(r),
1360  myLockedFlag(false)
1361  {
1362  if(!myR->isContextLocked())
1363  {
1364  myR->lockContextForRender();
1365  myLockedFlag = true;
1366  }
1367  }
1368 
1370  {
1371  if(myLockedFlag)
1372  {
1373  myR->unlockContextAfterRender();
1374  }
1375  }
1376 
1377 private:
1378  RE_OGLRender *myR;
1379  bool myLockedFlag;
1380 };
1381 
1382 
1383 // Inlines ---------------------------------------------------------------
1384 
1385 inline bool
1387  ((majorGLVersion >= 1) &&
1388  (minorGLVersion >= 1))); };
1389 inline bool
1391  ((majorGLVersion >= 1) &&
1392  (minorGLVersion >= 2))); };
1393 inline bool
1395  ((majorGLVersion >= 1) &&
1396  (minorGLVersion >= 3))); };
1397 inline bool
1399  ((majorGLVersion >= 1) &&
1400  (minorGLVersion >= 4))); };
1401 inline bool
1403  ((majorGLVersion >= 1) &&
1404  (minorGLVersion >= 5))); };
1405 inline bool
1407  ((majorGLVersion >= 2) &&
1408  (minorGLVersion >= 0))); };
1409 inline bool
1411  ((majorGLVersion >= 2) &&
1412  (minorGLVersion >= 1))); };
1413 
1414 inline bool
1415 RE_OGLRender::hasGL3(int minor) { return ((majorGLVersion > 3) ||
1416  ((majorGLVersion == 3) &&
1417  (minorGLVersion >= minor))); };
1418 
1419 inline bool
1420 RE_OGLRender::hasGL4(int minor) { return ((majorGLVersion > 4) ||
1421  ((majorGLVersion == 4) &&
1422  (minorGLVersion >= minor))); };
1423 
1426 
1429 
1430 inline RE_GraphicsDevice
1432 
1434 {
1435  return !(theDriverMajor == 0
1436  && theDriverMinor == 0
1437  && theDriverBuildMajor == 0
1438  && theDriverBuildMinor == 0);
1439 }
1444 
1445 inline RE_OGLExt *RE_OGLRender::getExt() const { return myExt; }
1447 {
1448  UT_ASSERT_P( myExt );
1449  return myExt->hasExtension( e );
1450 }
1451 
1452 inline int RE_OGLRender::resX() { return theXRes; }
1453 inline int RE_OGLRender::resY() { return theYRes; }
1454 inline int RE_OGLRender::dpi()
1455 {
1456  return SYSrint(theDotsPerInch * uiScale());
1457 }
1458 
1460 {
1461  if(theUIScale <= 0.0)
1462  return 1.0;
1463 
1464  return theUIScale;
1465 }
1466 
1467 inline float
1469 {
1470  return (float)n / dpi();
1471 }
1472 
1473 inline int
1475 {
1476  return (int)SYSrint(i*(float)dpi());
1477 }
1478 
1479 inline int
1481 {
1482  if (size == 0)
1483  return size;
1484 
1485  // Add 0.5 for rounding.
1486  fpreal scaled_size = scaledSize((fpreal)size) + 0.5;
1487 
1488  if (scaled_size < 1.0)
1489  return 1;
1490 
1491  return (int)scaled_size;
1492 }
1493 
1494 inline fpreal
1496 {
1497 #if defined(MBSD)
1498  // Native Qt widgets are automatically scaled by the OS using the display's
1499  // backing scale factor. Scaling again will make native Qt UI look
1500  // comically out-of-place.
1501  return size;
1502 #else
1503  if (size == 0)
1504  return size;
1505 
1506  fpreal ui_scale = uiScale();
1507  if (ui_scale == 1.0)
1508  return size;
1509 
1510  fpreal scaled_size = ui_scale * size;
1511  return scaled_size;
1512 #endif
1513 }
1514 
1515 inline RE_Window *
1517 
1518 inline RE_OGLRender *
1520 
1521 inline RE_WindowList *
1523 
1524 inline const RE_Window *
1526 
1527 inline RE_Window *
1529 
1530 inline bool
1532 { return myFrontBufferDirty;}
1533 
1534 inline void
1536 { myFrontBufferDirty = d; }
1537 
1538 inline int
1540 
1541 inline bool
1542 RE_OGLRender::isPointOffset() { return getPointOffset(); }
1543 
1544 inline bool
1545 RE_OGLRender::isLineOffset() { return getLineOffset(); }
1546 
1547 inline bool
1548 RE_OGLRender::isPolygonOffset() { return getFillOffset(); }
1549 
1550 inline void
1552 {
1553  if( onoff )
1554  enablePointOffset();
1555  else
1556  disablePointOffset();
1557 }
1558 
1559 inline void
1561 {
1562  if( onoff )
1563  enableLineOffset();
1564  else
1565  disableLineOffset();
1566 }
1567 
1568 inline void
1570 {
1571  if( onoff )
1572  enableFillOffset();
1573  else
1574  disableFillOffset();
1575 }
1576 
1577 inline void
1578 RE_OGLRender::getOffsetAmount(float *variable, float *constant) const
1579 {
1580  *variable = myState._offset_variable;
1581  *constant = myState._offset_constant;
1582 }
1583 
1584 inline bool
1586 {
1588 }
1589 inline int
1591 {
1592  return myState.myBlendSmoothLevel;
1593 }
1594 
1597 
1598 inline int
1600 { return myViewportFontOffsetX; }
1601 
1602 inline int
1604 { return myViewportFontOffsetY; }
1605 
1606 
1607 inline bool
1609 {
1611 }
1612 
1613 inline RE_PrimType
1615 {
1616  return myTransformFeedbackType;
1617 }
1618 
1619 inline bool
1621 {
1622  return myRasterizeEnabled;
1623 }
1624 
1625 inline RE_Uniform *
1627 {
1628  return myBuiltInUniforms[builtin_var_type];
1629 }
1630 
1631 inline bool
1633 {
1634  return myDebugLabelSupported;
1635 }
1636 
1637 inline bool
1639 {
1640  return myDebuggingSupported;
1641 }
1642 
1643 #endif
GLuint GLuint stream
Definition: glcorearb.h:1832
int getMaxDrawBuffers() const
Definition: RE_OGLRender.h:904
UT_IntArray myPendingDeleteFBOs
RE_OGLExt * getExt() const
GLenum query
Definition: glad.h:2772
GLint first
Definition: glcorearb.h:405
static int scaledSize(int size)
static int getDriverMajorVersion()
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
RE_PrimType getFeedbackMode() const
bool isRasterizeEnabled() const
bool myMultisampleEnable
int myDebugGroupStackSize
RV_API RV_VKImagePtr getRandomTextureArray(RV_Render *r, unsigned int seed, bool interp, int num_layers, int size=64)
Returns an 8b RGBA size^2 2D texture array of size 'num_layers'.
bool isInitialized() const
Definition: RE_OGLRender.h:121
int GLint
Definition: cl.hpp:165
UT_Vector2F myLineWidthRange
int int32
Definition: SYS_Types.h:39
bool isFrontBufferDirty() const
void setPointSize(fpreal32 size)
OGLDrawable myPushedDrawable
static int inchesToPixels(float i)
void rasterize(const PointDataTreeOrGridT &points, TransferT &transfer, const FilterT &filter=NullFilter(), InterrupterT *interrupter=nullptr)
Perform potentially complex rasterization from a user defined transfer scheme.
#define RE_API
Definition: RE_API.h:10
bool mySampleShading
#define RE_FLAG_11_STATE(RE_NAME, GL_FLAG)
int myFragmentDerivativeHint
int getMaxTexture3DSize() const
Definition: RE_OGLRender.h:895
static RE_GraphicsDevice theDevice
static int theDriverBuildMinor
RE_FaceMode
Definition: RE_Types.h:464
RE_TextureMode
RE_OGLFramebuffer * mySuspendTestFBO
RE_PrimType myTransformFeedbackType
RE_GraphicsDevice
Definition: RE_Types.h:641
#define RE_ALL_UNITS
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
#define GL_POLYGON_OFFSET_POINT
Definition: glcorearb.h:311
bool myDebugLabelSupported
int64 myBuiltInUniformSerial
A collection of vertex arrays defining a geometry object. This class acts as a wrapper around multipl...
Definition: RE_Geometry.h:53
bool isBlending() const
GLdouble s
Definition: glad.h:3009
int getContextID() const
Definition: RE_OGLRender.h:118
static bool hasGL20()
void resetRenderCount()
Definition: RE_OGLRender.h:335
int64 myRenderCount
bool isPolygonOffset()
GLenum sfail
Definition: glcorearb.h:782
RE_Severity
Definition: RE_Types.h:630
static UT_Array< std::pair< RE_Visual *, RE_DisplayMode > > theVisuals
GLenum GLenum GLsizei void * image
Definition: glad.h:5132
GLint y
Definition: glcorearb.h:103
static bool hasGL12()
static int allowsSmoothLines()
UT_IntArray myPendingDeleteQueries
void pointOffset(bool onoff)
RE_TextureDimension
GLdouble GLdouble GLdouble q
Definition: glad.h:2445
UT_IntArray myClipDistance
bool subBufferDrawingEnabled() const
int myMaxTextureAnisotropy
UT_RecursiveSpinLock myOpenGLLock
float fpreal32
Definition: SYS_Types.h:200
GLdouble u1
Definition: glad.h:2676
#define GL_STENCIL_TEST
Definition: glcorearb.h:267
GLenum GLenum GLenum dppass
Definition: glcorearb.h:782
int getViewportFontOffsetX() const
bool isPointOffset()
static int glMinorVersion()
static fpreal uiScale()
static RE_GraphicsDevice getGraphicsDevice()
#define GL_POLYGON_OFFSET_FILL
Definition: glcorearb.h:313
void lineOffset(bool onoff)
static int minorGLVersion
int myMaxVertexAttribs
GLenum GLuint GLint GLint layer
Definition: glcorearb.h:1299
int myMaxTextureRectSize
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
< returns > If no error
Definition: snippets.dox:2
static RE_WindowList * theWindowList
int myMaxTexture3DSize
static bool hasGL14()
double fpreal64
Definition: SYS_Types.h:201
RE_ShaderType
Definition: RE_Types.h:228
bool isCurrent() const
Definition: RE_OGLRender.h:270
static bool hasGL13()
vint4 blend(const vint4 &a, const vint4 &b, const vbool4 &mask)
Definition: simd.h:4784
int myMaxDebugGroupStackSize
RE_OGLTexture * mySuspendTestTexture
void getOffsetAmount(float *variable, float *constant) const
GA_API const UT_StringHolder scale
RE_GPUType
Definition: RE_Types.h:44
static fpreal theUIScale
GLdouble n
Definition: glcorearb.h:2008
UT_IntArray myPendingDeleteVertexArrays
int getMaxColorBuffers() const
Definition: RE_OGLRender.h:901
int getOGLMaxClipPlanes()
RE_Window * currentWindow
GLfloat f
Definition: glcorearb.h:1926
RE_Uniform * getUniform(RE_UniformBuiltIn builtin_var_type) const
bool myDebuggingSupported
static int getDriverMinorVersion()
int myMaxTextureGeometryUnits
int getBlendSmoothLevel() const
UT_IntArray & getBoundUniformBlocks()
Definition: RE_OGLRender.h:827
RE_OcclusionQuery * myActiveQuery
static int theXRes
int getMaxShaderTextureUnits() const
Definition: RE_OGLRender.h:880
#define RE_ACTIVE_UNIT
void pushLineWidth()
int getMaxVertexTextureUnits() const
Definition: RE_OGLRender.h:882
void bumpBuiltInUniformSerial()
Definition: RE_OGLRender.h:767
GLint ref
Definition: glcorearb.h:124
static RE_Window * theMainContextWindow
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
static int theDriverMajor
RE_Geometry * mySuspendBox
unsigned int RE_TextureID
GLuint GLint GLboolean layered
Definition: glcorearb.h:2222
UT_StopWatch * mySuspendCheckTimer
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
GLfloat green
Definition: glcorearb.h:112
bool contextIsValid() const
Definition: RE_OGLRender.h:278
GLint GLenum GLboolean GLsizei stride
Definition: glcorearb.h:872
GLdouble y1
Definition: glad.h:2349
bool myActiveConditionalRender
GLint GLuint mask
Definition: glcorearb.h:124
RE_SmoothMode
Definition: RE_Types.h:458
static RE_Server * theServer
UT_ArrayMap< int, RE_OGLFramebuffer * > myFBOTable
int getViewportFontOffsetY() const
HUSD_API const char * raster()
RE_BlendEquation
Definition: RE_Types.h:532
long long int64
Definition: SYS_Types.h:116
static RE_Window * getMainContext()
static int getDriverBuildMinorVersion()
png_const_structrp png_const_inforp int * unit
Definition: png.h:2161
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
#define RE_MAX_TEXTURE_STATE_STACK
SIM_API const UT_StringHolder rotation
RE_UniformBuiltIn
Definition: RE_Uniform.h:28
UT_Array< RE_FeedbackPrimitivesWrittenQuery * > myTransformFeedbackWrittenQuery
static int resY()
int myViewportFontOffsetY
RE_MemoryBarrierBitfield
Definition: RE_Types.h:549
int glslMinorVersion()
GLuint const GLchar * name
Definition: glcorearb.h:786
OPENVDB_API void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
Definition: logging.h:294
RE_DisplayMode
Definition: RE_Types.h:573
RE_ZFunction
Definition: RE_Types.h:471
PXL_DataFormat
Definition: PXL_Common.h:20
static UT_ThreadSpecificValue< RE_OGLRender * > theCurrentRender
void polygonOffset(bool onoff)
int myMaxTextureFragmentUnits
int myMaxTransformFeedbackComponents
static void allowSmoothLines(int yn)
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
short currentDisplayMode
RE_OGLFramebuffer * mySuspendResultFBO
bool myContextInitialized
OGLDrawable myDrawable
int myMaxTextureVertexUnits
fpreal32 SYSrint(fpreal32 val)
Definition: SYS_Floor.h:163
#define RE_FLAG_STATE(RE_NAME, GL_FLAG)
RE_OGLExt * myExt
bool hasExtension(RE_Extension ext)
Definition: RE_OGLExt.h:35
RE_OGLTexture * mySuspendResultTexture
GLsizei samples
Definition: glcorearb.h:1298
int getMaxTextureSize() const
Definition: RE_OGLRender.h:893
RE_OGLVertexArrayList * getDefaultVAO()
Definition: RE_OGLRender.h:817
bool hasGLExtension(RE_Extension e) const
GLenum mode
Definition: glcorearb.h:99
GLfloat v0
Definition: glcorearb.h:816
int getMaxFragmentTextureUnits() const
Definition: RE_OGLRender.h:886
RE_OGLContext getContext() const
Definition: RE_OGLRender.h:279
bool isDebugging() const
int myVertexMaxStreams
static int theDotsPerInch
void bumpRenderCount()
Definition: RE_OGLRender.h:334
int myViewportFontOffsetX
int myShaderOnlyModeCount
*tasks wait()
static int theDriverBuildMajor
RE_OGLState myState
GLenum GLenum dpfail
Definition: glcorearb.h:782
const RE_Render * getRender() const
Definition: RE_OGLRender.h:134
static int getDriverBuildMajorVersion()
static bool theSmoothLinesAllowed
GLsizeiptr size
Definition: glcorearb.h:664
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
RE_RenderAutoLock(RE_OGLRender *r)
GLuint shader
Definition: glcorearb.h:785
GLenum func
Definition: glcorearb.h:783
static RE_WindowList * getWindowList()
RE_BufferAccess
Definition: RE_Types.h:314
void pushPointSize(fpreal32 size)
Point options that can change per-point.
bool isTransformFeedbackEnabled() const
int glslMajorVersion()
#define GL_LINE_SMOOTH
Definition: glcorearb.h:253
SIM_API const UT_StringHolder force
RE_Render * getRender()
Definition: RE_OGLRender.h:132
GLuint color
Definition: glcorearb.h:1261
UT_Array< RE_Uniform * > myPushedUniforms
int64 getBuiltInUniformSerial() const
Definition: RE_OGLRender.h:765
static bool hasGL15()
bool myIsAllowingOtherThreads
fpreal64 fpreal
Definition: SYS_Types.h:277
void popLineWidth()
static int theDriverMinor
const RE_Window * getCurrentWindow() const
static bool hasGL4(int minor)
bool isDebugLabelSupported() const
RE_SOperation
Definition: RE_Types.h:495
int myMaxTextureShaderUnits
GLuint index
Definition: glcorearb.h:786
RE_OGLContext myContext
fpreal myShaderSampleRate
RE_VisualType
Definition: RE_Types.h:623
GLfloat GLfloat v1
Definition: glcorearb.h:817
int getTextureAnisotropyLimit() const
Definition: RE_OGLRender.h:888
GLint maxClipPlanes
RE_BlendSourceFactor
Definition: RE_Types.h:507
static bool hasGL11()
ut_thread_id_t myNativeThread
int myMaxTransformFeedbackBuffers
static float pixelsToInches(int n)
static int dpi()
unsigned int uint32
Definition: SYS_Types.h:40
static bool hasDriverVersion()
UT_IntArray myDebugStack
bool myMaterialLighting
Definition: core.h:982
RV_API RV_VKImagePtr getRandomTexture(RV_Render *r, unsigned int seed, bool interp, int size=64)
Returns an 8b RGBA 64x64 texture with 0-1 random values in all comps.
int64 getRenderCount() const
Definition: RE_OGLRender.h:336
GLuint texture
Definition: glcorearb.h:415
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
Definition: core.h:1131
int myBlendSmoothLevel
Definition: RE_OGLState.h:120
RE_RenderBuf
Definition: RE_Types.h:430
bool myTransformFeedbackEnabled
int getMaxVertexAttribs() const
Definition: RE_OGLRender.h:792
static bool theUsingCoreProfile
RE_Window * mySavedMainThreadCurrentWindow
static bool hasGL3(int minor)
RE_OGLVertexArrayList * myCurrentVAO
bool myRasterizeEnabled
bool isLineOffset()
GLboolean r
Definition: glcorearb.h:1222
bool mySubBufferDrawing
float _offset_variable
Definition: RE_OGLState.h:65
re_BlendSmoothState myBlendSmoothStack[RE_SMOOTH_STACK_SIZE]
Definition: RE_OGLState.h:121
GLfloat GLfloat blue
Definition: glcorearb.h:112
int getMaxGeometryTextureUnits() const
Definition: RE_OGLRender.h:884
void popUniformData(RE_UniformBuiltIn bindex)
Definition: RE_OGLRender.h:745
void setDefaultVAO(RE_OGLVertexArrayList *vao)
Definition: RE_OGLRender.h:820
RE_ShaderTarget
Definition: RE_Types.h:269
static UT_ThreadSpecificValue< RE_OGLRender * > theLastRender
static int resX()
void popPointSize()
int getMaxTextureRectangleSize()
Definition: RE_OGLRender.h:897
static bool hasGL21()
QOpenGLContext * RE_OGLContext
Definition: RE_Types.h:952
#define GL_SCISSOR_TEST
Definition: glcorearb.h:286
RE_Uniform * myBuiltInUniforms[RE_UNIFORM_BUILT_IN__count]
void setFrontBufferDirty(bool d)
UT_Array< RE_PrimitivesGeneratedQuery * > myTransformFeedbackPrimitiveQuery
UT_Array< re_ConstVertexAttrib > myConstVertexAttribs
static int theYRes
RE_Shader * myShaderOnlyActiveShader
type
Definition: core.h:1059
RE_PrimType
Definition: RE_Types.h:193
RE_SFunction
Definition: RE_Types.h:483
png_structrp int png_fixed_point red
Definition: png.h:1083
float _offset_constant
Definition: RE_OGLState.h:66
RV_API RV_VKImagePtr getRandomTexture3D(RV_Render *r, unsigned int seed, bool interp, int size=32)
Returns an 8b RGBA size^3 3D texture with 0-1 random values.
bool myFrontBufferDirty
#define RE_BUFFER_STACK_SIZE
Definition: RE_Types.h:938
RE_OGLVertexArrayList * myDefaultVAO
RE_Extension
Definition: RE_Extension.h:4
RE_OGLContext pushedGraphicsContext
bool firstInitialize
bool myMultisampleAlphaToCoverage
Definition: RE_Uniform.h:389
Definition: format.h:895
int myOpenGLContextLockCount
static int majorGLVersion
#define GL_POLYGON_OFFSET_LINE
Definition: glcorearb.h:312
GA_API const UT_StringHolder area
static RE_OGLRender * getCurrentRender()
Simple interface to building a shader from a .prog file.
RE_BlendDestFactor
Definition: RE_Types.h:520
static int glMajorVersion()