#include "gpuCacheDrawOverride.h"
#include "gpuCacheConfig.h"
#include "gpuCacheShapeNode.h"
#include "gpuCacheDrawTraversal.h"
#include "gpuCacheFrustum.h"
#include "gpuCacheGLFT.h"
#include <maya/MAnimControl.h>
#include <maya/MDrawContext.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MGlobal.h>
#include <maya/MHWGeometryUtilities.h>
#include <maya/MStateManager.h>
#include <maya/MUserData.h>
#include <maya/MGL.h>
#include <maya/MFnCamera.h>
#include <maya/MSelectionList.h>
#include <maya/MPointArray.h>
#include <algorithm>
namespace {
using namespace GPUCache;
enum DepthOffsetType {
kNoDepthOffset,
kApplyDepthOffset,
kNbDepthOffsetType
};
enum ColorType {
kSubNodeColor,
kDefaultColor,
kBlackColor,
kXrayColor,
kXrayBlackColor,
kNbColorType
};
enum NormalsType {
kFrontNormals,
kBackNormals,
kNbNormalsType
};
enum FrontFaceType {
kFrontClockwise,
kFrontCounterClockwise,
kNbFrontFaceType
};
enum TwoSidedLightingType {
kTwoSidedLighting,
kOneSidedLighting,
kNbTwoSidedLightingType
};
{
if (!blendState) {
}
}
const DepthOffsetType depthOffsetType)
{
if (depthOffsetType == kApplyDepthOffset) {
}
}
void setShadedRasterState(
const DepthOffsetType depthOffsetType,
const FrontFaceType frontFaceType)
{
{NULL, NULL};
{NULL, NULL};
{NULL, NULL};
if (!cullNoneRasterizerState[kNoDepthOffset]) {
for (int dot = 0; dot < kNbDepthOffsetType; ++dot) {
cullNoneRasterizerState[dot] = createShadedRasterState(
stateMgr, MRasterizerState::kCullNone, DepthOffsetType(dot));
cullFrontRasterizerState[dot] = createShadedRasterState(
stateMgr, MRasterizerState::kCullFront, DepthOffsetType(dot));
cullBackRasterizerState[dot] = createShadedRasterState(
stateMgr, MRasterizerState::kCullBack, DepthOffsetType(dot));
}
}
switch (cullMode) {
case MRasterizerState::kCullNone:
cullNoneRasterizerState[depthOffsetType]);
break;
case MRasterizerState::kCullFront:
cullFrontRasterizerState[depthOffsetType]);
break;
case MRasterizerState::kCullBack:
cullBackRasterizerState[depthOffsetType]);
break;
default: assert(0);
}
gGLFT->glFrontFace(frontFaceType == kFrontClockwise ? MGL_CW : MGL_CCW);
}
void setShadedSolidDepthState(
{
if (!depthState) {
}
}
void setShadedTwoSidedLightingState(
const TwoSidedLightingType twoSidedLightingType)
{
gGLFT->glLightModeli(MGL_LIGHT_MODEL_TWO_SIDE,
twoSidedLightingType == kTwoSidedLighting ? 1 : 0);
}
void setShadedAlphaDepthState(
{
if (!depthState) {
}
}
void setWireframeState(
{
{
if (!blendState) {
}
}
{
if (!rasterizerState) {
}
}
{
if (!depthState) {
}
}
}
class TopLevelCullVisitor : public SubNodeVisitor
{
public:
TopLevelCullVisitor(const Frustum& frustrum, double seconds)
: fFrustum(frustrum),
fSeconds(seconds),
fIsCulled(true)
{}
bool isCulled() const { return fIsCulled; }
void visit(const XformData& xform,
const SubNode& subNode) override
{
const std::shared_ptr<const XformSample>& sample =
xform.getSample(fSeconds);
if (!sample) return;
fIsCulled =
fFrustum.test(sample->boundingBox()) == Frustum::kOutside;
}
void visit(const ShapeData& shape,
const SubNode& subNode) override
{
const std::shared_ptr<const ShapeSample>& sample =
shape.getSample(fSeconds);
if (!sample) return;
fIsCulled =
fFrustum.test(sample->boundingBox()) == Frustum::kOutside;
}
private:
const Frustum& fFrustum;
const double fSeconds;
bool fIsCulled;
};
class DrawShadedState : public DrawTraversalState
{
public:
DrawShadedState(
const Frustum& frustrum,
const double seconds,
const TransparentPruneType transparentPrune,
const DepthOffsetType depthOffsetType,
const ColorType colorType,
const MColor& defaultDiffuseColor,
const NormalsType normalsType)
: DrawTraversalState(frustrum, seconds, transparentPrune),
fStateMgr(stateMgr),
fCullMode(cullMode),
fDepthOffsetType(depthOffsetType),
fColorType(colorType),
fDefaultDiffuseColor(defaultDiffuseColor),
fNormalsType(normalsType)
{}
DepthOffsetType depthOffsetType() const { return fDepthOffsetType; }
ColorType colorType() const { return fColorType; }
const MColor& defaultDiffuseColor()
const {
return fDefaultDiffuseColor; }
NormalsType normalsType() const { return fNormalsType; }
private:
const DepthOffsetType fDepthOffsetType;
const ColorType fColorType;
const MColor fDefaultDiffuseColor;
const NormalsType fNormalsType;
};
class DrawShadedTraversal
: public DrawTraversal<DrawShadedTraversal, DrawShadedState>
{
public:
typedef DrawTraversal<DrawShadedTraversal, DrawShadedState> BaseClass;
DrawShadedTraversal(
DrawShadedState& state,
bool isReflection,
Frustum::ClippingResult parentClippingResult)
: BaseClass(state, xform, isReflection, parentClippingResult)
{}
void draw(const std::shared_ptr<const ShapeSample>& sample)
{
if (!sample->visibility()) return;
gGLFT->glLoadMatrixd(xform().matrix[0]);
if (sample->isBoundingBoxPlaceHolder()) {
state().vboProxy().drawBoundingBox(sample, true);
GlobalReaderCache::theCache().hintShapeReadOrder(subNode());
return;
}
assert(sample->positions());
assert(sample->normals());
switch (state().colorType()) {
case kSubNodeColor:
diffuseColor = sample->diffuseColor();
break;
case kDefaultColor:
diffuseColor = state().defaultDiffuseColor();
break;
case kBlackColor:
diffuseColor =
MColor(0.0f, 0.0f, 0.0f, sample->diffuseColor()[3]);
break;
case kXrayColor:
diffuseColor =
MColor(sample->diffuseColor()[0],
sample->diffuseColor()[1],
sample->diffuseColor()[2],
sample->diffuseColor()[3] * 0.3f);
break;
case kXrayBlackColor:
diffuseColor =
MColor(0.0f, 0.0f, 0.0f, sample->diffuseColor()[3] * 0.3f);
break;
default:
assert(0);
}
if (diffuseColor[3] <= 0.0 ||
(diffuseColor[3] >= 1.0 &&
state().transparentPrune() == DrawShadedState::kPruneOpaque) ||
(diffuseColor[3] < 1.0 &&
state().transparentPrune() == DrawShadedState::kPruneTransparent)) {
return;
}
gGLFT->glColor4f(diffuseColor[0]*diffuseColor[3],
diffuseColor[1]*diffuseColor[3],
diffuseColor[2]*diffuseColor[3],
diffuseColor[3]);
setShadedRasterState(state().stateManager(),
state().cullMode(),
state().depthOffsetType(),
isReflection() ?
kFrontClockwise : kFrontCounterClockwise);
for (size_t groupId = 0; groupId < sample->numIndexGroups(); ++groupId ) {
state().vboProxy().drawTriangles(
sample, groupId,
state().normalsType() == kFrontNormals ?
VBOProxy::kFrontNormals : VBOProxy::kBackNormals,
VBOProxy::kNoUVs);
}
}
};
class DrawWireframeState : public DrawTraversalState
{
public:
DrawWireframeState(
const Frustum& frustrum,
const double seconds)
: DrawTraversalState(frustrum, seconds, kPruneNone)
{}
};
class DrawWireframeTraversal
: public DrawTraversal<DrawWireframeTraversal, DrawWireframeState>
{
public:
typedef DrawTraversal<DrawWireframeTraversal, DrawWireframeState> BaseClass;
DrawWireframeTraversal(
DrawWireframeState& state,
bool isReflection,
Frustum::ClippingResult parentClippingResult)
: BaseClass(state, xform, isReflection, parentClippingResult)
{}
void draw(const std::shared_ptr<const ShapeSample>& sample)
{
if (!sample->visibility()) return;
gGLFT->glLoadMatrixd(xform().matrix[0]);
if (sample->isBoundingBoxPlaceHolder()) {
state().vboProxy().drawBoundingBox(sample);
GlobalReaderCache::theCache().hintShapeReadOrder(subNode());
return;
}
assert(sample->positions());
assert(sample->normals());
state().vboProxy().drawWireframe(sample);
}
};
}
namespace GPUCache {
class DrawOverride::UserData :
public MUserData
{
public:
UserData(const ShapeNode* node)
: fShapeNode(node)
{}
void set(const double& seconds,
bool isSelected)
{
fSeconds = seconds;
fWireframeColor[0] = wireframeColor[0];
fWireframeColor[1] = wireframeColor[1];
fWireframeColor[2] = wireframeColor[2];
fIsSelected = isSelected;
}
private:
void drawShadedSampleGL(
const Frustum& frustum,
const DepthOffsetType depthOffsetType,
const ColorType colorType,
const MColor& defaultDiffuseColor,
const NormalsType normalsType,
const DrawShadedState::TransparentPruneType transparentPrune,
const SubNode::Ptr& rootNode) const;
void drawWireframeSampleGL(const Frustum& frustum,
const SubNode::Ptr& rootNode) const;
void drawBoundingBoxSampleGL(
const MMatrix& xform,
const SubNode::Ptr& rootNode) const;
~UserData() override {}
const ShapeNode* fShapeNode = nullptr;
double fSeconds{0.0};
GLfloat fWireframeColor[3] = {1.f, 1.f, 1.f};
bool fIsSelected{false};
};
void DrawOverride::UserData::drawShadedSampleGL(
const Frustum& frustum,
const DepthOffsetType depthOffsetType,
const ColorType colorType,
const MColor& defaultDiffuseColor,
const NormalsType normalsType,
const DrawShadedState::TransparentPruneType transparentPrune,
const SubNode::Ptr& rootNode) const
{
DrawShadedState state(
frustum, fSeconds, transparentPrune, stateMgr,
cullMode, depthOffsetType, colorType,
defaultDiffuseColor, normalsType);
DrawShadedTraversal visitor(
state, xform, xform.
det3x3() < 0.0, Frustum::kUnknown);
rootNode->accept(visitor);
}
void DrawOverride::UserData::drawWireframeSampleGL(
const Frustum& frustum,
const SubNode::Ptr& rootNode) const
{
DrawWireframeState state(frustum, fSeconds);
DrawWireframeTraversal visitor(state, xform, false, Frustum::kUnknown);
rootNode->accept(visitor);
}
void DrawOverride::UserData::drawBoundingBoxSampleGL(
const SubNode::Ptr& rootNode) const
{
const SubNodeData::Ptr subNodeData = rootNode->getData();
if (!subNodeData) return;
const XformData::Ptr xformData =
std::dynamic_pointer_cast<const XformData>(subNodeData);
if (xformData) {
const std::shared_ptr<const XformSample>& sample =
xformData->getSample(fSeconds);
if (!sample || !sample->visibility()) return;
boundingBox = sample->boundingBox();
}
else {
const ShapeData::Ptr shapeData =
std::dynamic_pointer_cast<const ShapeData>(subNodeData);
if (shapeData) {
const std::shared_ptr<const ShapeSample>& sample =
shapeData->getSample(fSeconds);
if (!sample || !sample->visibility()) return;
boundingBox = sample->boundingBox();
}
}
gGLFT->glLoadMatrixd(xform.
matrix[0]);
VBOProxy vboProxy;
vboProxy.drawBoundingBox(boundingBox);
}
bool DrawOverride::UserData::setupLightingGL(
{
const unsigned int nbLights =
std::min(context.
numberOfActiveLights(MDrawContext::LightFilter::kFilteredToLightLimit, &status), 8u);
if (nbLights > 0) {
gGLFT->glLoadMatrixd(worldToView.
matrix[0]);
gGLFT->glEnable(MGL_LIGHTING);
gGLFT->glColorMaterial(MGL_FRONT_AND_BACK, MGL_AMBIENT_AND_DIFFUSE);
gGLFT->glEnable(MGL_COLOR_MATERIAL) ;
gGLFT->glEnable(MGL_NORMALIZE) ;
{
const MGLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
const MGLfloat specular[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
gGLFT->glMaterialfv(MGL_FRONT_AND_BACK, MGL_AMBIENT, ambient);
gGLFT->glMaterialfv(MGL_FRONT_AND_BACK, MGL_SPECULAR, specular);
gGLFT->glLightModelfv(MGL_LIGHT_MODEL_AMBIENT, ambient);
if (Config::emulateTwoSidedLighting()) {
gGLFT->glLightModeli(MGL_LIGHT_MODEL_TWO_SIDE, 0);
}
else {
gGLFT->glLightModeli(MGL_LIGHT_MODEL_TWO_SIDE, 1);
}
}
for (unsigned int i=0; i<nbLights; ++i) {
float intensity;
bool hasDirection;
bool hasPosition;
i, positions, direction, intensity, color,
hasDirection, hasPosition);
if (hasDirection) {
if (hasPosition) {
position[0] = positions[0][0];
position[1] = positions[0][1];
position[2] = positions[0][2];
const MGLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
const MGLfloat diffuse[4] = { intensity * color[0],
intensity * color[1],
intensity * color[2],
1.0f };
const MGLfloat pos[4] = { position[0],
position[1],
position[2],
1.0f };
const MGLfloat dir[3] = { direction[0],
direction[1],
direction[2]};
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_AMBIENT, ambient);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_DIFFUSE, diffuse);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_POSITION, pos);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_SPOT_DIRECTION, dir);
gGLFT->glLightf(MGL_LIGHT0+i, MGL_SPOT_EXPONENT, 0.0);
gGLFT->glLightf(MGL_LIGHT0+i, MGL_SPOT_CUTOFF, 20.0);
}
else {
const MGLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
const MGLfloat diffuse[4] = { intensity * color[0],
intensity * color[1],
intensity * color[2],
1.0f };
const MGLfloat pos[4] = { -direction[0],
-direction[1],
-direction[2],
0.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_AMBIENT, ambient);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_DIFFUSE, diffuse);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_POSITION, pos);
gGLFT->glLightf(MGL_LIGHT0+i, MGL_SPOT_CUTOFF, 180.0);
}
}
else if (hasPosition) {
position[0] = positions[0][0];
position[1] = positions[0][1];
position[2] = positions[0][2];
const MGLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
const MGLfloat diffuse[4] = { intensity * color[0],
intensity * color[1],
intensity * color[2],
1.0f };
const MGLfloat pos[4] = { position[0],
position[1],
position[2],
1.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_AMBIENT, ambient);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_DIFFUSE, diffuse);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_POSITION, pos);
gGLFT->glLightf(MGL_LIGHT0+i, MGL_SPOT_CUTOFF, 180.0);
}
else {
const MGLfloat ambient[4] = { intensity * color[0],
intensity * color[1],
intensity * color[2],
1.0f };
const MGLfloat diffuse[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
const MGLfloat pos[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_AMBIENT, ambient);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_DIFFUSE, diffuse);
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_POSITION, pos);
gGLFT->glLightf(MGL_LIGHT0+i, MGL_SPOT_CUTOFF, 180.0);
}
gGLFT->glEnable(MGL_LIGHT0+i);
}
}
return nbLights > 0;
}
void DrawOverride::UserData::unsetLightingGL(
{
const unsigned int nbLights =
std::min(context.
numberOfActiveLights(MDrawContext::LightFilter::kFilteredToLightLimit, &status), 8u);
if (nbLights > 0) {
for (unsigned int i=0; i<nbLights; ++i) {
gGLFT->glDisable(MGL_LIGHT0+i);
const MGLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_AMBIENT, ambient);
if (i==0) {
const MGLfloat diffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_DIFFUSE, diffuse);
const MGLfloat spec[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_SPECULAR, spec);
}
else {
const MGLfloat diffuse[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_DIFFUSE, diffuse);
const MGLfloat spec[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_SPECULAR, spec);
}
const MGLfloat pos[4] = { 0.0f, 0.0f, 1.0f, 0.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_POSITION, pos);
const MGLfloat dir[3] = { 0.0f, 0.0f, -1.0f };
gGLFT->glLightfv(MGL_LIGHT0+i, MGL_SPOT_DIRECTION, dir);
gGLFT->glLightf(MGL_LIGHT0+i, MGL_SPOT_EXPONENT, 0.0);
gGLFT->glLightf(MGL_LIGHT0+i, MGL_SPOT_CUTOFF, 180.0);
}
gGLFT->glDisable(MGL_LIGHTING);
gGLFT->glDisable(MGL_COLOR_MATERIAL) ;
gGLFT->glDisable(MGL_NORMALIZE) ;
const MGLfloat ambient[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
const MGLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
gGLFT->glMaterialfv(MGL_FRONT_AND_BACK, MGL_AMBIENT, ambient);
gGLFT->glMaterialfv(MGL_FRONT_AND_BACK, MGL_SPECULAR, specular);
gGLFT->glLightModelfv(MGL_LIGHT_MODEL_AMBIENT, ambient);
gGLFT->glLightModeli(MGL_LIGHT_MODEL_TWO_SIDE, 0);
}
}
void DrawOverride::UserData::draw(
{
const SubNode::Ptr& rootNode =
fShapeNode->getCachedGeometry();
if (!rootNode) return;
MRenderer* theRenderer = MRenderer::theRenderer();
if (!theRenderer) return;
if (!stateMgr) return;
if (displayStyle == 0) return;
static const bool debugPassInformation = false;
if (debugPassInformation)
{
printf(
"gpuCache override in pass[%s], semantic[", passId.
asChar());
for (
unsigned int i=0; i<passSem.
length(); i++)
printf(" %s", passSem[i].asChar());
printf("\n");
}
if (displayStyle & MFrameContext::kXray) {
if (rasterState && rasterState->
desc().
cullMode == MRasterizerState::kCullFront) {
return;
}
}
const MMatrix worldViewProjInvMatrix =
context.
getMatrix(MFrameContext::kWorldViewProjInverseMtx, &status);
Frustum frustum( worldViewProjInvMatrix);
{
TopLevelCullVisitor visitor(frustum, fSeconds);
rootNode->accept(visitor);
if (visitor.isCulled()) return;
}
context.
getMatrix(MFrameContext::kWorldViewMtx, &status);
context.
getMatrix(MFrameContext::kProjectionMtx, &status);
if (selectInfo)
{
int view_x, view_y, view_w, view_h;
unsigned int sel_x, sel_y, sel_w, sel_h;
selectInfo->
selectRect(sel_x, sel_y, sel_w, sel_h);
double center_x = sel_x + sel_w * 0.5;
double center_y = sel_y + sel_h * 0.5;
pickMatrix[0][0] = view_w / double(sel_w);
pickMatrix[1][1] = view_h / double(sel_h);
pickMatrix[3][0] = (view_w - 2.0 * (center_x - view_x)) / double(sel_w);
pickMatrix[3][1] = (view_h - 2.0 * (center_y - view_y)) / double(sel_h);
projection *= pickMatrix;
}
{
gGLFT->glMatrixMode(MGL_PROJECTION);
gGLFT->glPushMatrix();
gGLFT->glLoadMatrixd(projection.
matrix[0]);
gGLFT->glMatrixMode(MGL_MODELVIEW);
gGLFT->glPushMatrix();
if (displayStyle & MFrameContext::kBoundingBox)
{
setWireframeState(stateMgr);
gGLFT->glColor3fv(fWireframeColor);
gGLFT->glEnable(MGL_LINE_STIPPLE);
gGLFT->glLineStipple(1, Config::kLineStippleShortDashed);
drawBoundingBoxSampleGL(xform, rootNode);
gGLFT->glDisable(MGL_LINE_STIPPLE);
}
const bool needWireframe =
!(displayStyle & MFrameContext::kBoundingBox) &&
(displayStyle & MFrameContext::kWireFrame || fIsSelected);
const bool wireframeOnShaded = needWireframe &&
(displayStyle & MFrameContext::kGouraudShaded);
const bool disableWireframeOnShaded = wireframeOnShaded &&
(DisplayPref::wireframeOnShadedMode() == DisplayPref::kWireframeOnShadedNone);
if (needWireframe && !disableWireframeOnShaded)
{
setWireframeState(stateMgr);
gGLFT->glColor3fv(fWireframeColor);
gGLFT->glEnable(MGL_LINE_STIPPLE);
if (wireframeOnShaded) {
DisplayPref::WireframeOnShadedMode wireframeOnShadedMode =
DisplayPref::wireframeOnShadedMode();
if (wireframeOnShadedMode == DisplayPref::kWireframeOnShadedReduced) {
gGLFT->glLineStipple(1, Config::kLineStippleDotted);
}
else {
assert(wireframeOnShadedMode != DisplayPref::kWireframeOnShadedNone);
gGLFT->glLineStipple(1, Config::kLineStippleShortDashed);
}
}
else {
gGLFT->glLineStipple(1, Config::kLineStippleShortDashed);
}
drawWireframeSampleGL(frustum, xform, rootNode);
gGLFT->glDisable( MGL_LINE_STIPPLE );
}
if (displayStyle & MFrameContext::kGouraudShaded)
{
const DepthOffsetType depthOffsetType = needWireframe ?
kApplyDepthOffset : kNoDepthOffset;
const bool anyLights = setupLightingGL(context);
ColorType colorType = kSubNodeColor;
bool needOpaquePass =
rootNode->transparentType() != SubNode::kTransparent;
bool needTransparentPass =
rootNode->transparentType() != SubNode::kOpaque;
DrawShadedState::TransparentPruneType opaquePassPrune =
DrawShadedState::kPruneTransparent;
DrawShadedState::TransparentPruneType transparentPassPrune =
DrawShadedState::kPruneOpaque;
if (displayStyle & MFrameContext::kDefaultMaterial) {
colorType = kDefaultColor;
needOpaquePass = true;
needTransparentPass = false;
opaquePassPrune = DrawShadedState::kPruneNone;
if (anyLights) {
defaultDiffuseColor = Config::kDefaultGrayColor;
}
}
else if (displayStyle & MFrameContext::kXray) {
needOpaquePass = false;
needTransparentPass = true;
transparentPassPrune = DrawShadedState::kPruneNone;
colorType = anyLights ? kXrayColor : kXrayBlackColor;
}
else
if (!anyLights) {
colorType = kBlackColor;
}
setShadedBlendState(stateMgr);
if (needOpaquePass) {
setShadedSolidDepthState(stateMgr);
if (displayStyle & MFrameContext::kTwoSidedLighting) {
if (Config::emulateTwoSidedLighting()) {
setShadedTwoSidedLightingState(kOneSidedLighting);
drawShadedSampleGL(
frustum, stateMgr, MRasterizerState::kCullFront,
depthOffsetType, colorType, defaultDiffuseColor,
kBackNormals, opaquePassPrune, xform, rootNode);
drawShadedSampleGL(
frustum, stateMgr, MRasterizerState::kCullBack,
depthOffsetType, colorType, defaultDiffuseColor,
kFrontNormals, opaquePassPrune, xform, rootNode);
}
else {
setShadedTwoSidedLightingState(kTwoSidedLighting);
drawShadedSampleGL(
frustum, stateMgr, MRasterizerState::kCullNone,
depthOffsetType, colorType, defaultDiffuseColor,
kFrontNormals, opaquePassPrune, xform, rootNode);
}
}
else {
setShadedTwoSidedLightingState(kOneSidedLighting);
drawShadedSampleGL(
frustum, stateMgr, MRasterizerState::kCullNone,
depthOffsetType, colorType, defaultDiffuseColor,
kFrontNormals, opaquePassPrune, xform, rootNode);
}
}
if (needTransparentPass) {
setShadedAlphaDepthState(stateMgr);
if (displayStyle & MFrameContext::kTwoSidedLighting) {
setShadedTwoSidedLightingState(
Config::emulateTwoSidedLighting() ?
kOneSidedLighting : kTwoSidedLighting );
drawShadedSampleGL(
frustum, stateMgr, MRasterizerState::kCullFront,
depthOffsetType, colorType, defaultDiffuseColor,
Config::emulateTwoSidedLighting() ? kBackNormals : kFrontNormals,
transparentPassPrune, xform, rootNode);
drawShadedSampleGL(
frustum, stateMgr, MRasterizerState::kCullBack,
depthOffsetType, colorType, defaultDiffuseColor,
kFrontNormals, transparentPassPrune, xform, rootNode);
}
else {
setShadedTwoSidedLightingState(kOneSidedLighting);
drawShadedSampleGL(
frustum, stateMgr, MRasterizerState::kCullFront,
depthOffsetType, colorType, defaultDiffuseColor,
kFrontNormals, transparentPassPrune, xform, rootNode);
drawShadedSampleGL(
frustum, stateMgr, MRasterizerState::kCullBack,
depthOffsetType, colorType, defaultDiffuseColor,
kFrontNormals, transparentPassPrune, xform, rootNode);
}
}
unsetLightingGL(context);
}
gGLFT->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
gGLFT->glFrontFace(GL_CCW);
gGLFT->glLightModeli(MGL_LIGHT_MODEL_TWO_SIDE, 1);
gGLFT->glMatrixMode(MGL_PROJECTION);
gGLFT->glPopMatrix();
gGLFT->glMatrixMode(MGL_MODELVIEW);
gGLFT->glPopMatrix();
}
else {
}
}
void DrawOverride::drawCb(
{
draw(context, nullptr, userData);
}
void DrawOverride::draw(
{
ShapeNode::init3dViewPostRenderCallbacks();
InitializeGLFT();
const UserData* data = dynamic_cast<const UserData*>(userData);
if (data) data->draw(context, selectInfo);
}
DrawOverride::creator(
const MObject& obj)
{
return new DrawOverride(obj);
}
DrawOverride::DrawOverride(
const MObject& obj)
{}
DrawOverride::~DrawOverride()
{}
MHWRender::DrawAPI DrawOverride::supportedDrawAPIs() const
{
return MHWRender::kOpenGL;
}
bool DrawOverride::isBounded(
const MDagPath& ,
{
return true;
}
{
const ShapeNode* shapeNode = dynamic_cast<ShapeNode*>(node.userNode());
const SubNode::Ptr subNode = shapeNode->getCachedGeometry();
const SubNodeData::Ptr subNodeData = subNode->getData();
const XformData::Ptr xform =
std::dynamic_pointer_cast<const XformData>(subNodeData);
if (xform) {
const std::shared_ptr<const XformSample>& sample =
xform->getSample(seconds);
return sample->boundingBox();
}
const ShapeData::Ptr shape =
std::dynamic_pointer_cast<const ShapeData>(subNodeData);
if (shape) {
const std::shared_ptr<const ShapeSample>& sample =
shape->getSample(seconds);
return sample->boundingBox();
}
}
bool DrawOverride::disableInternalBoundingBoxDraw() const
{
return true;
}
{
UserData* data = dynamic_cast<UserData*>(oldData);
if (!data)
{
if (status)
{
data = new UserData(
dynamic_cast<ShapeNode*>(node.userNode()));
}
}
if (data) {
const DisplayStatus displayStatus =
const bool isSelected =
(displayStatus == kActive) ||
(displayStatus == kLead) ||
(displayStatus == kHilite);
data->set(
wireframeColor,
isSelected);
}
return data;
}
bool DrawOverride::wantUserSelection() const
{
return theRenderer && (theRenderer->
drawAPI() == MHWRender::kOpenGL || theRenderer->
drawAPI() == MHWRender::kOpenGLCoreProfile);
}
bool DrawOverride::userSelect(
{
const GLsizei BUF_SIZE = 10;
GLuint selectBuf[BUF_SIZE];
glSelectBuffer(BUF_SIZE, selectBuf);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
draw(context, &selectInfo, data);
glPopName();
GLint hits = glRenderMode(GL_RENDER);
if (hits <= 0) return false;
GLuint minZ = selectBuf[1];
GLuint maxZ = selectBuf[2];
double depth = (minZ*0.5 + maxZ*0.5) / 0xFFFFFFFF;
if (!camera.isOrtho())
{
const double Zf = camera.farClippingPlane();
depth *= Zn / (Zf - depth * (Zf - Zn));
}
unsigned int x, y, w, h;
const MPoint hitPoint = nearPw + depth * (farPw - nearPw);
selectionList.
add(objPath);
worldSpaceHitPts.
append(hitPoint);
return true;
}
}