Skip to content
1 change: 1 addition & 0 deletions include/Inventor/actions/SoActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#endif
#include <Inventor/actions/SoWriteAction.h>
#include <Inventor/actions/SoAudioRenderAction.h>
#include <Inventor/actions/SoIRRenderAction.h>
#include <Inventor/collision/SoIntersectionDetectionAction.h>
#include <Inventor/actions/SoSimplifyAction.h>
#include <Inventor/actions/SoToVRMLAction.h>
Expand Down
127 changes: 127 additions & 0 deletions include/Inventor/actions/SoIRRenderAction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// include/Inventor/actions/SoIRRenderAction.h

#ifndef COIN_SOIRRENDERACTION_H
#define COIN_SOIRRENDERACTION_H

#include <Inventor/actions/SoAction.h>
#include <Inventor/actions/SoSubAction.h>
#include <Inventor/SbViewportRegion.h>
#include <Inventor/lists/SbList.h>

#include <Inventor/rendering/SoRenderIR.h>

#include <cstddef>
class SoPrimitiveVertex;
class SoPath;
class SoPathList;
class SoNode;
class SoIRRenderActionP;

/*!
\class SoIRRenderAction SoIRRenderAction.h
\brief Render action that traverses a scene graph into a backend-neutral draw list.

\ingroup coin_actions

SoIRRenderAction is the traversal front-end for Coin's render-backend path.
Unlike SoGLRenderAction, it does not issue OpenGL commands directly during
traversal. Instead it records geometry, material state, and render state
into a SoDrawList that can later be consumed by a concrete backend.

The action owns transient per-frame storage for generated geometry.

A frame begins with beginFrame() (also performed by the normal apply
entry points), records commands through addCommand(), and ends when the
caller replaces or clears the action's frame. Geometry and other borrowed
command data must not be retained beyond that frame lifetime.

\ingroup coin_retained_rendering
*/
class COIN_DLL_API SoIRRenderAction : public SoAction {
typedef SoAction inherited;
SO_ACTION_HEADER(SoIRRenderAction);

public:
/*!
\class SoIRRenderAction::PrimitiveCollector
\brief Callback interface for receiving primitives generated during traversal.

Shapes that fall back to generatePrimitives() can stream their output
through a PrimitiveCollector instead of building temporary Coin-specific
callback structures. The active collector is managed as a stack so helper
code can install a collector for a limited traversal scope.
*/
class PrimitiveCollector {
public:
virtual ~PrimitiveCollector() {}
virtual void onTriangle(const SoPrimitiveVertex * v1,
const SoPrimitiveVertex * v2,
const SoPrimitiveVertex * v3) = 0;
virtual void onLine(const SoPrimitiveVertex * v1,
const SoPrimitiveVertex * v2) = 0;
virtual void onPoint(const SoPrimitiveVertex * v) = 0;
};

static void initClass(void);

SoIRRenderAction(const SbViewportRegion & vp);
virtual ~SoIRRenderAction();

//! Clear the current draw list and begin a new retained frame.
void beginFrame();

void setViewportRegion(const SbViewportRegion & vp);
const SbViewportRegion & getViewportRegion(void) const { return this->vpRegion; }

// Standard entry points, mirroring SoGLRenderAction
virtual void apply(SoNode * root) override;
virtual void apply(SoPath * path) override;
virtual void apply(const SoPathList & pathlist, SbBool obeysrules = FALSE) override;

//! Append a retained command produced during the current traversal.
void addCommand(const SoRenderCommand & command);

//! Mark the current frame as unsupported by the retained renderer.
void markUnsupported(const SoNode * node, const char * reason);
//! Return whether traversal encountered semantics not represented by IR.
SbBool hasUnsupportedRendering() const { return this->unsupportedRendering; }
//! Return the first node that made this frame unsupported, if any.
const SoNode * getUnsupportedNode() const { return this->unsupportedNode; }
//! Return a static or otherwise frame-stable explanation for the status.
const char * getUnsupportedReason() const { return this->unsupportedReason; }

//! Return the generated draw list for the current frame.
const SoDrawList & getDrawList(void) const { return this->drawlist; }
//! Mutable access to the generated draw list for the current frame.
SoDrawList & getMutableDrawList() { return this->drawlist; }

/*!
\brief Allocate per-frame geometry storage owned by the action.

The returned memory remains valid until the frame resources are cleared or
the geometry pool is rewound to an earlier save point.
*/
void * allocateGeometryStorage(size_t bytes, size_t alignment = alignof(float));

//! Push a primitive collector for subsequent fallback primitive generation.
void pushPrimitiveCollector(PrimitiveCollector * collector);
//! Pop the current primitive collector. The caller must pop in stack order.
void popPrimitiveCollector(PrimitiveCollector * collector);
//! Return the currently active primitive collector, or NULL.
PrimitiveCollector * getActivePrimitiveCollector(void) const;

protected:
virtual void beginTraversal(SoNode * node) override;

private:
void resetFrameResources();

SbViewportRegion vpRegion;
SoDrawList drawlist;
SoIRRenderActionP * pimpl;
bool unsupportedRendering = false;
const SoNode * unsupportedNode = nullptr;
const char * unsupportedReason = nullptr;
};

#endif // COIN_SOIRRENDERACTION_H
3 changes: 3 additions & 0 deletions include/Inventor/nodes/SoNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class SoRayPickAction;
class SoSearchAction;
class SoWriteAction;
class SoAudioRenderAction;
class SoIRRenderAction;
class SbDict;

class COIN_DLL_API SoNode : public SoFieldContainer {
Expand Down Expand Up @@ -95,6 +96,7 @@ class COIN_DLL_API SoNode : public SoFieldContainer {
virtual SbBool affectsState(void) const;

virtual void doAction(SoAction * action);
virtual void IRRender(SoIRRenderAction * action);
virtual void GLRender(SoGLRenderAction * action);
virtual void GLRenderBelowPath(SoGLRenderAction * action);
virtual void GLRenderInPath(SoGLRenderAction * action);
Expand Down Expand Up @@ -137,6 +139,7 @@ class COIN_DLL_API SoNode : public SoFieldContainer {
static int getActionMethodIndex(const SoType type);

static void getBoundingBoxS(SoAction * action, SoNode * node);
static void IRRenderS(SoAction * action, SoNode * node);
static void GLRenderS(SoAction * action, SoNode * node);
static void callbackS(SoAction * action, SoNode * node);
static void getMatrixS(SoAction * action, SoNode * node);
Expand Down
2 changes: 2 additions & 0 deletions include/Inventor/nodes/SoShaderProgram.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <Inventor/fields/SoMFNode.h>

class SoState;
class SoIRRenderAction;
#if COIN_HAVE_LEGACY_GL_RENDERER
class SoGLRenderAction;
#endif
Expand All @@ -62,6 +63,7 @@ class COIN_DLL_API SoShaderProgram : public SoNode {
void * closure);

SoEXTENDER public:
void IRRender(SoIRRenderAction * action) override;
#if COIN_HAVE_LEGACY_GL_RENDERER
void GLRender(SoGLRenderAction * action) override;
#endif
Expand Down
2 changes: 2 additions & 0 deletions include/Inventor/nodes/SoShape.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class SoCoordinateElement;
class SbVec2f;
class SoMaterialBundle;
class SoBoundingBoxCache;
class SoIRRenderAction;

class COIN_DLL_API SoShape : public SoNode {
typedef SoNode inherited;
Expand All @@ -70,6 +71,7 @@ class COIN_DLL_API SoShape : public SoNode {
#if COIN_HAVE_LEGACY_GL_RENDERER
void GLRender(SoGLRenderAction * action) override;
#endif
void IRRender(SoIRRenderAction * action) override;
void rayPick(SoRayPickAction * action) override;
void callback(SoCallbackAction * action) override;
virtual void computeBBox(SoAction * action, SbBox3f & box,
Expand Down
Loading
Loading