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