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