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