// Currently, Maya leaves lights in GL when you reduce the number of active lights in // your scene. It fills the GL light space from 0 with the visible lights, so, we simply // need to reset the potentially 'old' state of lights after the last one we know to be // visible. We'll put it all back as we found it though. For the moment, this assumes // Maya is filling GL consecutively, if they stop doing that, we'll need to get the // actual light indexes from the view. Its just a bit quicker to assume this, whilst we can. bool ProceduralHolderUI::cleanupLights( const MDrawRequest &request, M3dView &view, LightingState *s ) const { if( !(request.displayStyle()==M3dView::kFlatShaded || request.displayStyle()==M3dView::kGouraudShaded) ) { return false; } M3dView::LightingMode mode; view.getLightingMode(mode); if (mode == M3dView::kLightDefault) { s->numMayaLights = 1; } else { view.getLightCount( s->numMayaLights ); } int sGlMaxLights = 0; glGetIntegerv( GL_MAX_LIGHTS, &sGlMaxLights ); s->numGlLights = sGlMaxLights; if( s->numMayaLights >= s->numGlLights || s->numGlLights == 0 ) { return false; } unsigned int vectorSize = s->numGlLights - s->numMayaLights; s->diffuses.resize( vectorSize ); s->specs.resize( vectorSize ); s->ambients.resize( vectorSize ); static float s_defaultColor[] = { 0.0, 0.0, 0.0, 1.0 }; GLenum light; unsigned int j = 0; for( unsigned int i = s->numMayaLights; i < s->numGlLights; i++ ) { light = GL_LIGHT0 + i; glGetLightfv( light, GL_DIFFUSE, s->diffuses[j].getValue() ); glLightfv( light, GL_DIFFUSE, s_defaultColor ); glGetLightfv( light, GL_SPECULAR, s->specs[j].getValue() ); glLightfv( light, GL_SPECULAR, s_defaultColor ); glGetLightfv( light, GL_AMBIENT, s->ambients[j].getValue() ); glLightfv( light, GL_AMBIENT, s_defaultColor ); j++; } return true; }
void SceneShapeUI::draw( const MDrawRequest &request, M3dView &view ) const { MStatus s; MDrawData drawData = request.drawData(); SceneShape *sceneShape = (SceneShape *)drawData.geometry(); assert( sceneShape ); view.beginGL(); M3dView::LightingMode lightingMode; view.getLightingMode( lightingMode ); LightingState lightingState; bool restoreLightState = cleanupLights( request, view, &lightingState ); // maya can sometimes leave an error from it's own code, // and we don't want that to confuse us in our drawing code. while( glGetError()!=GL_NO_ERROR ) { } try { // draw the bound if asked if( request.token()==BoundDrawMode ) { IECoreGL::BoxPrimitive::renderWireframe( IECore::convert<Imath::Box3f>( sceneShape->boundingBox() ) ); } // draw the scene if asked if( request.token()==SceneDrawMode ) { resetHilites(); IECoreGL::ConstScenePtr scene = sceneShape->glScene(); if( scene ) { IECoreGL::State *displayState = m_displayStyle.baseState( (M3dView::DisplayStyle)request.displayStyle(), lightingMode ); if ( request.component() != MObject::kNullObj ) { MDoubleArray col; s = MGlobal::executeCommand( "colorIndex -q 21", col ); assert( s ); IECoreGL::WireframeColorStateComponentPtr hilite = new IECoreGL::WireframeColorStateComponent( Imath::Color4f( col[0], col[1], col[2], 1.0f ) ); MFnSingleIndexedComponent fnComp( request.component(), &s ); assert( s ); int len = fnComp.elementCount( &s ); assert( s ); std::vector<IECore::InternedString> groupNames; for ( int j = 0; j < len; j++ ) { int index = fnComp.element(j); groupNames.push_back( sceneShape->selectionName( index ) ); } // Sort by name to make sure we don't unhilite selected items that are further down the hierarchy std::sort( groupNames.begin(), groupNames.end() ); for ( std::vector<IECore::InternedString>::iterator it = groupNames.begin(); it!= groupNames.end(); ++it) { IECoreGL::GroupPtr group = sceneShape->glGroup( *it ); hiliteGroups( group, hilite, const_cast<IECoreGL::WireframeColorStateComponent *>( displayState->get< IECoreGL::WireframeColorStateComponent >() ) ); } } scene->render( displayState ); } } } catch( const IECoreGL::Exception &e ) { // much better to catch and report this than to let the application die IECore::msg( IECore::Msg::Error, "SceneShapeUI::draw", boost::format( "IECoreGL Exception : %s" ) % e.what() ); } if( restoreLightState ) { restoreLights( &lightingState ); } view.endGL(); }