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