Beispiel #1
0
		void BaseShapeUI::getDrawRequests( const MDrawInfo & info, bool objectAndActiveOnly, MDrawRequestQueue & requests ) {
			MStatus status;

			MDrawData data;

			BaseShape *shape = (BaseShape *) surfaceShape();
			MDrawRequest request = info.getPrototype(*this);
			M3dView view = info.view();

			getDrawData(shape, data);

			request.setDrawData(data);

			MDagPath path = request.multiPath();
			MMaterial material = MPxSurfaceShapeUI::material(path);

			if (!(status = material.evaluateMaterial(view, path)))
				status.perror("MMaterial::evaluateMaterial");

			if (!(status = material.evaluateDiffuse()))
				status.perror("MMaterial::evaluateDiffuse");

			request.setMaterial(material);
			request.setToken(info.displayStyle());
	
			requests.add(request);
		}
// 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;
}
Beispiel #3
0
/* override */
void apiSimpleShapeUI::draw( const MDrawRequest & request, M3dView & view ) const
//
// Description:
//
//     Main (OpenGL) draw routine
//
// Arguments:
//
//     request - request to be drawn
//     view    - view to draw into
//
{ 
	// Get the token from the draw request.
	// The token specifies what needs to be drawn.
	//
	int token = request.token();
	switch( token )
	{
		case kDrawWireframe :
		case kDrawWireframeOnShaded :
		case kDrawVertices :
			drawVertices( request, view );
			break;

		case kDrawSmoothShaded :
			break;			// Not implemented, left as exercise

		case kDrawFlatShaded : // Not implemented, left as exercise
			break;
	}
}
Beispiel #4
0
void
UsdMayaGLBatchRenderer::ShapeRenderer::QueueShapeForDraw(
    MPxSurfaceShapeUI *shapeUI,
    MDrawRequest &drawRequest,
    const RenderParams &params,
    bool drawShape,
    MBoundingBox *boxToDraw )
{
    // VP 1.0 Implementation
    //
    // In Viewport 1.0, we can use MDrawData to communicate between the
    // draw prep and draw call itself. Since the internal data is open
    // to the client, we choose to use a MUserData object, so that the
    // internal data will mimic the the VP 2.0 implementation. This
    // allow for more code reuse.
    //
    // The one caveat here is that VP 1.0 does not manage the data allocated
    // in the MDrawData object, so we must remember to delete the MUserData
    // object in our Draw call. 
    
    MUserData* userData;
    
    QueueShapeForDraw( userData, params, drawShape, boxToDraw );
    
    MDrawData drawData;
    shapeUI->getDrawData( userData, drawData );
    
    drawRequest.setDrawData( drawData );
}
void ProceduralHolderUI::setWireFrameColors( MDrawRequest &request, M3dView::DisplayStatus status )
{
	// yes, this does use magic numbers for the color indices, and
	// no, i don't know how to get them properly. the quadricShape api
	// example is just doing this too.
	switch( status )
	{
		case M3dView::kLead :
			request.setColor( 18, M3dView::kActiveColors );
			break;
		case M3dView::kActive :
			request.setColor( 15, M3dView::kActiveColors );
			break;
		case M3dView::kActiveAffected :
			request.setColor( 8, M3dView::kActiveColors );
			break;
		case M3dView::kHilite :
			request.setColor( 17, M3dView::kActiveColors );
			break;
		case M3dView::kTemplate :
			request.setColor( 2, M3dView::kDormantColors );
			break;
		case M3dView::kActiveTemplate :
			request.setColor( 19, M3dView::kActiveColors );
			break;
		default :
			// dormant
			request.setColor( 4, M3dView::kDormantColors );
			break;
	}
}
Beispiel #6
0
void
UsdMayaGLBatchRenderer::Draw(
    const MDrawRequest& request,
    M3dView &view )
{
    // VP 1.0 Implementation
    //
    MDrawData drawData = request.drawData();
    
    _BatchDrawUserData* batchData =
                static_cast<_BatchDrawUserData*>(drawData.geometry());
    if( !batchData )
        return;
    
    MMatrix projectionMat;
    view.projectionMatrix(projectionMat);
    
    MMatrix modelViewMat;
    view.modelViewMatrix(modelViewMat);

    if( batchData->_bounds )
    {
        px_vp20Utils::RenderBoundingBox(*(batchData->_bounds),
                                        *(batchData->_wireframeColor),
                                        modelViewMat,
                                        projectionMat);
    }
    
    if( batchData->_drawShape && !_renderQueue.empty() )
    {
        MMatrix viewMat( request.matrix().inverse() * modelViewMat );

        unsigned int viewX, viewY, viewWidth, viewHeight;
        view.viewport(viewX, viewY, viewWidth, viewHeight);
        GfVec4d viewport(viewX, viewY, viewWidth, viewHeight);

        // Only the first call to this will do anything... After that the batch
        // queue is cleared.
        //
        _RenderBatches( NULL, viewMat, projectionMat, viewport );
    }
    
    // Clean up the _BatchDrawUserData!
    delete batchData;
}
void DrawableHolderUI::draw( const MDrawRequest &request, M3dView &view ) const
{
	MDrawData drawData = request.drawData();
	DrawableHolder *drawableHolder = (DrawableHolder *)drawData.geometry();
	assert( drawableHolder );

	IECoreGL::ConstScenePtr s = drawableHolder->scene();
	if( !s )
	{
		return;
	}

	view.beginGL();

		// 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 )
		{
		}

		// if we're being drawn as part of a selection operation we need
		// to make sure there's a name on the name stack, as the IECoreGL::NameStateComponent
		// expects to be able to load a name into it (it fails with an invalid operation if
		// there's no name slot to load into).
		if( view.selectMode() )
		{
			view.pushName( 0 );
		}

		try
		{
			// do the main render
			s->render( m_displayStyle.baseState( request.displayStyle() ) );

			// do a wireframe render over the top if we're selected and we just did a solid
			// draw.
			bool selected = request.displayStatus()==M3dView::kActive || request.displayStatus()==M3dView::kLead;
			bool solid = request.displayStyle()==M3dView::kFlatShaded || request.displayStyle()==M3dView::kGouraudShaded;
			if( selected && solid )
			{
				s->render( m_displayStyle.baseState( M3dView::kWireFrame ) );
			}
		}
		catch( std::exception &e )
		{
			IECore::msg( IECore::Msg::Error, "DrawableHolderUI::draw", e.what() );
		}

	view.endGL();
}
void ProceduralHolderUI::draw( const MDrawRequest &request, M3dView &view ) const
{
	MStatus s;
	MDrawData drawData = request.drawData();
	ProceduralHolder *proceduralHolder = (ProceduralHolder *)drawData.geometry();
	assert( proceduralHolder );
	
	view.beginGL();
	
	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>( proceduralHolder->boundingBox() ) );
		}

		// draw the scene if asked
		if( request.token()==SceneDrawMode )
		{
			resetHilites();

			IECoreGL::ConstScenePtr scene = proceduralHolder->scene();
			if( scene )
			{
				IECoreGL::State *displayState = m_displayStyle.baseState( (M3dView::DisplayStyle)request.displayStyle() );

				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 );
					for ( int j = 0; j < len; j++ )
					{
						int compId = fnComp.element(j);

						assert( proceduralHolder->m_componentToGroupMap.find( compId ) != proceduralHolder->m_componentToGroupMap.end() );

						hiliteGroups(
							proceduralHolder->m_componentToGroupMap[compId],
							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, "ProceduralHolderUI::draw", boost::format( "IECoreGL Exception : %s" ) % e.what() );
	}

	if( restoreLightState )
	{
		restoreLights( &lightingState );	
	}
	
	view.endGL();
}
void DrawableHolderUI::getDrawRequests( const MDrawInfo &info, bool objectAndActiveOnly, MDrawRequestQueue &requests )
{
	// it's easy if noone want to look at us
	if( !info.objectDisplayStatus( M3dView::kDisplayLocators ) )
	{
		return;
	}

	// the node we're meant to be drawing
	DrawableHolder *drawableHolder = dynamic_cast<DrawableHolder *>( surfaceShape() );
	if( !drawableHolder )
	{
		return;
	}

	// do we actually want to draw it?
	MPlug pDraw( drawableHolder->thisMObject(), DrawableHolder::aDraw );
	bool draw = true;
	pDraw.getValue( draw );

	if( !draw )
	{
		return;
	}

	// draw data encapsulating that node
	MDrawData drawData;
	getDrawData( drawableHolder, drawData );

	MDrawRequest request = info.getPrototype( *this );
	request.setDrawData( drawData );

	// set correct drawing colour:
	switch( info.displayStatus() )
	{
		case M3dView::kLead :
			request.setColor( 18, M3dView::kActiveColors );
			break;
		case M3dView::kActive :
			request.setColor( 15, M3dView::kActiveColors );
			break;
		case M3dView::kActiveAffected :
			request.setColor( 8, M3dView::kActiveColors );
			break;
		case M3dView::kHilite :
			request.setColor( 17, M3dView::kActiveColors );
			break;
		case M3dView::kTemplate :
			request.setColor( 2, M3dView::kDormantColors );
			break;
		case M3dView::kActiveTemplate :
			request.setColor( 19, M3dView::kActiveColors );
			break;
		default :
			// dormant
			request.setColor( 4, M3dView::kDormantColors );
			break;
	}

	requests.add( request );
}
Beispiel #10
0
void SceneShapeUI::getDrawRequests( const MDrawInfo &info, bool objectAndActiveOnly, MDrawRequestQueue &requests )
{
	// it's easy if no one want to look at us
	if( !info.objectDisplayStatus( M3dView::kDisplayMeshes ) )
	{
		return;
	}
	// the node we're meant to be drawing
	SceneShape *sceneShape = (SceneShape *)surfaceShape();

	if( !sceneShape->getSceneInterface() )
	{
		return;
	}
	
	// draw data encapsulating that node
	MDrawData drawData;
	getDrawData( sceneShape, drawData );

	// a request for the bound if necessary
	MPlug pDrawBound( sceneShape->thisMObject(), SceneShape::aDrawRootBound );
	bool drawBound;
	pDrawBound.getValue( drawBound );
	
	if( drawBound )
	{
		bool doDrawBound = true;
		
		// If objectOnly is true, check for an object. If none found, no need to add the bound request.
		MPlug pObjectOnly( sceneShape->thisMObject(), SceneShape::aObjectOnly );
		bool objectOnly;
		pObjectOnly.getValue( objectOnly );
		if( objectOnly && !sceneShape->getSceneInterface()->hasObject() )
		{
			doDrawBound = false;
		}
		
		if( doDrawBound )
		{
			MDrawRequest request = info.getPrototype( *this );
			request.setDrawData( drawData );
			request.setToken( BoundDrawMode );
			request.setDisplayStyle( M3dView::kWireFrame );
			setWireFrameColors( request, info.displayStatus() );
			requests.add( request );
		}

	}

	MPlug pDrawAllBounds( sceneShape->thisMObject(), SceneShape::aDrawChildBounds );
	bool drawAllBounds = false;
	pDrawAllBounds.getValue( drawAllBounds );
	
	// requests for the scene if necessary
	MPlug pGLPreview( sceneShape->thisMObject(), SceneShape::aDrawGeometry );
	bool glPreview;
	pGLPreview.getValue( glPreview );
	
	if( glPreview || drawAllBounds )
	{
		if( info.displayStyle()==M3dView::kGouraudShaded || info.displayStyle()==M3dView::kFlatShaded )
		{
			// make a request for solid drawing with a material
			MDrawRequest solidRequest = info.getPrototype( *this );
			solidRequest.setDrawData( drawData );

			MDagPath path = info.multiPath();
			M3dView view = info.view();
			MMaterial material = MPxSurfaceShapeUI::material( path );
			if( !material.evaluateMaterial( view, path ) )
			{
				MString pathName = path.fullPathName();
				IECore::msg( IECore::Msg::Warning, "SceneShapeUI::getDrawRequests", boost::format( "Failed to evaluate material for \"%s\"." ) % pathName.asChar() );
			}
			if( material.materialIsTextured() )
			{
				material.evaluateTexture( drawData );
			}
			solidRequest.setMaterial( material );
			// set the transparency request. we don't have a decent way of finding out
			// if shaders applied by the procedural are transparent, so we've got a transparency
			// attribute on the procedural holder for users to use. maya materials may also say
			// they're transparent. if either asks for transparency then we'll ask for it here
			bool transparent = false;
			material.getHasTransparency( transparent );
			solidRequest.setIsTransparent( transparent );
			solidRequest.setToken( SceneDrawMode );
			requests.add( solidRequest );

			if( info.displayStatus()==M3dView::kActive || info.displayStatus()==M3dView::kLead || info.displayStatus()==M3dView::kHilite )
			{
				MDrawRequest wireRequest = info.getPrototype( *this );
				wireRequest.setDrawData( drawData );
				wireRequest.setDisplayStyle( M3dView::kWireFrame );
				wireRequest.setToken( SceneDrawMode );
				setWireFrameColors( wireRequest, info.displayStatus() );
				wireRequest.setComponent( MObject::kNullObj );

				if ( !objectAndActiveOnly )
				{
					if ( sceneShape->hasActiveComponents() )
					{
						MObjectArray components = sceneShape->activeComponents();
						MObject component = components[0];
						wireRequest.setComponent( component );
					}
				}

				requests.add( wireRequest );
			}
			
		}
		else
		{
			MDrawRequest request = info.getPrototype( *this );
			request.setDrawData( drawData );
			setWireFrameColors( request, info.displayStatus() );
			request.setToken( SceneDrawMode );

			request.setComponent( MObject::kNullObj );

			if ( !objectAndActiveOnly )
			{
				if ( sceneShape->hasActiveComponents() )
				{
					MObjectArray components = sceneShape->activeComponents();
		    			MObject component = components[0];
		   			request.setComponent( component );
				}
			}
			requests.add( request );
		}
	}
	
	
}
Beispiel #11
0
void apiSimpleShapeUI::drawVertices( const MDrawRequest & request,
							  M3dView & view ) const
//
// Description:
//
//     Component (vertex) drawing routine
//
// Arguments:
//
//     request - request to be drawn
//     view    - view to draw into
//
{
	MDrawData data = request.drawData();
	MVectorArray * geom = (MVectorArray*)data.geometry();

	view.beginGL(); 

	// Query current state so it can be restored
	//
	bool lightingWasOn = glIsEnabled( GL_LIGHTING ) ? true : false;
	if ( lightingWasOn ) {
		glDisable( GL_LIGHTING );
	}
	float lastPointSize;
	glGetFloatv( GL_POINT_SIZE, &lastPointSize );

	// Set the point size of the vertices
	//
	glPointSize( POINT_SIZE );

	// If there is a component specified by the draw request
	// then loop over comp (using an MFnComponent class) and draw the
	// active vertices, otherwise draw all vertices.
	//
	MObject comp = request.component();
	if ( ! comp.isNull() ) {
		MFnSingleIndexedComponent fnComponent( comp );
		for ( int i=0; i<fnComponent.elementCount(); i++ )
		{
			int index = fnComponent.element( i );
			glBegin( GL_POINTS );
			MVector& point = (*geom)[index];
			glVertex3f( (float)point[0], 
						(float)point[1], 
						(float)point[2] );
			glEnd();

			char annotation[32];
			sprintf( annotation, "%d", index );
			view.drawText( annotation, point );
		}
	}
	else {
		for ( unsigned int i=0; i<geom->length(); i++ )
		{
			glBegin( GL_POINTS );
			MVector point = (*geom)[ i ];
			glVertex3f( (float)point[0], (float)point[1], (float)point[2] );
			glEnd();
		}
	}

	// Restore the state
	//
	if ( lightingWasOn ) {
		glEnable( GL_LIGHTING );
	}
	glPointSize( lastPointSize );

	view.endGL(); 
}
Beispiel #12
0
/// \todo We should be firing off a separate drawRequest for the components, then we can be done with the "hiliteGroups" mechanism.
void ProceduralHolderUI::getDrawRequests( const MDrawInfo &info, bool objectAndActiveOnly, MDrawRequestQueue &requests )
{
	// it's easy if noone want to look at us
	if( !info.objectDisplayStatus( M3dView::kDisplayMeshes ) )
	{
		return;
	}

	// the node we're meant to be drawing
	ProceduralHolder *proceduralHolder = (ProceduralHolder *)surfaceShape();

	// draw data encapsulating that node
	MDrawData drawData;
	getDrawData( proceduralHolder, drawData );

	// a request for the bound if necessary
	MPlug pDrawBound( proceduralHolder->thisMObject(), ProceduralHolder::aDrawBound );
	bool drawBound = true;
	pDrawBound.getValue( drawBound );

	if( drawBound )
	{
		MDrawRequest request = info.getPrototype( *this );
		request.setDrawData( drawData );
		request.setToken( BoundDrawMode );
		request.setDisplayStyle( M3dView::kWireFrame );
		setWireFrameColors( request, info.displayStatus() );
		requests.add( request );
	}

	// requests for the scene if necessary
	MPlug pGLPreview( proceduralHolder->thisMObject(), ProceduralHolder::aGLPreview );
	bool glPreview = false;
	pGLPreview.getValue( glPreview );
	if( glPreview )
	{
		if( info.displayStyle()==M3dView::kGouraudShaded || info.displayStyle()==M3dView::kFlatShaded )
		{
			// make a request for solid drawing with a material
			MDrawRequest solidRequest = info.getPrototype( *this );
			solidRequest.setDrawData( drawData );

			MDagPath path = info.multiPath();
			M3dView view = info.view();
			MMaterial material = MPxSurfaceShapeUI::material( path );
			if( !material.evaluateMaterial( view, path ) )
			{
				MString pathName = path.fullPathName();
				IECore::msg( IECore::Msg::Warning, "ProceduralHolderUI::getDrawRequests", boost::format( "Failed to evaluate material for \"%s\"." ) % pathName.asChar() );
			}
			if( material.materialIsTextured() )
			{
				material.evaluateTexture( drawData );
			}
			solidRequest.setMaterial( material );
			// set the transparency request. we don't have a decent way of finding out
			// if shaders applied by the procedural are transparent, so we've got a transparency
			// attribute on the procedural holder for users to use. maya materials may also say
			// they're transparent. if either asks for transparency then we'll ask for it here
			bool transparent = false;
			material.getHasTransparency( transparent );
			if( !transparent )
			{
				MPlug pT( proceduralHolder->thisMObject(), ProceduralHolder::aTransparent );
				bool transparent = false;
				pT.getValue( transparent );
			}
			solidRequest.setIsTransparent( transparent );
			solidRequest.setToken( SceneDrawMode );
			requests.add( solidRequest );
			// and add another request for wireframe drawing if we're selected
			if( info.displayStatus()==M3dView::kActive || info.displayStatus()==M3dView::kLead || info.displayStatus()==M3dView::kHilite )
			{
				MDrawRequest wireRequest = info.getPrototype( *this );
				wireRequest.setDrawData( drawData );
				wireRequest.setDisplayStyle( M3dView::kWireFrame );
				wireRequest.setToken( SceneDrawMode );
				setWireFrameColors( wireRequest, info.displayStatus() );
				wireRequest.setComponent( MObject::kNullObj );

				if ( !objectAndActiveOnly )
				{

					if ( proceduralHolder->hasActiveComponents() )
					{
						MObjectArray components = proceduralHolder->activeComponents();
		    				MObject component = components[0]; // Should filter list
		   				wireRequest.setComponent( component );
					}
				}

				requests.add( wireRequest );
			}
		}
		else
		{
			MDrawRequest request = info.getPrototype( *this );
			request.setDrawData( drawData );
			setWireFrameColors( request, info.displayStatus() );
			request.setToken( SceneDrawMode );

			request.setComponent( MObject::kNullObj );

			if ( !objectAndActiveOnly )
			{

				if ( proceduralHolder->hasActiveComponents() )
				{
					MObjectArray components = proceduralHolder->activeComponents();
		    			MObject component = components[0]; // Should filter list
		   			request.setComponent( component );
				}
			}

			requests.add( request );
		}
	}
}
Beispiel #13
0
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();
}
Beispiel #14
0
		void BaseShapeUI::draw( const MDrawRequest & request, M3dView & view ) const {
			if (s_drawData.failure)
				return;

			MStatus status;

			view.beginGL();

			if (!s_drawData.initialized)
				initializeDraw();

			BaseShape *shape = (BaseShape *) surfaceShape();

			Model::Base base(MFnDagNode(shape->thisMObject()).parent(0, &status));

			if (!status) {
				status.perror("MFnDagNode::parent");
				return;
			}

			//MDagPath path = request.multiPath();
			MMaterial material = request.material();
			MColor color, borderColor;

			if (!(status = material.getDiffuse(color))) {
				status.perror("MMaterial::getDiffuse");
				return;
			}

			bool wireframe = (M3dView::DisplayStyle) request.token() == M3dView::kWireFrame;

			if (wireframe) {
				glPushAttrib(GL_POLYGON_BIT);

				glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
			}

			glUseProgram(s_drawData.program);
			
			switch (request.displayStatus())
            {
            case M3dView::kLead :
				borderColor = view.colorAtIndex( LEAD_COLOR);
				//glUniform1f(s_drawData.border_uniform, 1.0f);
				s_drawData.updateBorderUniform(1.0f);
				//glUniform3f(s_drawData.borderColor_uniform, borderColor.r, borderColor.g, borderColor.b);
				s_drawData.updateBorderColorUniform(borderColor.r, borderColor.g, borderColor.b);
				break;
            case M3dView::kActive :
                borderColor = view.colorAtIndex( ACTIVE_COLOR);
				//glUniform1f(s_drawData.border_uniform, 1.0f);
				s_drawData.updateBorderUniform(1.0f);
				//glUniform3f(s_drawData.borderColor_uniform, borderColor.r, borderColor.g, borderColor.b);
				s_drawData.updateBorderColorUniform(borderColor.r, borderColor.g, borderColor.b);
                break;
            case M3dView::kActiveAffected :
                borderColor = view.colorAtIndex( ACTIVE_AFFECTED_COLOR);
				//glUniform1f(s_drawData.border_uniform, 0.0f);
				s_drawData.updateBorderUniform(0.0f);
                break;
            case M3dView::kDormant :
				borderColor = view.colorAtIndex( DORMANT_COLOR, M3dView::kDormantColors);
				//glUniform1f(s_drawData.border_uniform, 0.0f);
				s_drawData.updateBorderUniform(0.0f);
                break;
            case M3dView::kHilite :
                borderColor = view.colorAtIndex( HILITE_COLOR);
				//glUniform1f(s_drawData.border_uniform, 1.0f);
				s_drawData.updateBorderUniform(1.0f);
				//glUniform3f(s_drawData.borderColor_uniform, borderColor.r, borderColor.g, borderColor.b);
				s_drawData.updateBorderColorUniform(borderColor.r, borderColor.g, borderColor.b);
                break;
            }

			//glUniform3f(s_drawData.color_uniform, color.r, color.g, color.b);
			s_drawData.updateColorUniform(color.r, color.g, color.b);

			glCallList(s_drawData.display_list);

			if (wireframe)
				glPopAttrib();

			view.endGL();
		}
Beispiel #15
0
/* virtual */
MStatus	pnTriangles::bind(const MDrawRequest& request, M3dView& view)
//
// Description:
//		This bind demonstrates the usage of internal material
//		and texture properties. This shader must be connected
//		to the "hardwareShader" attribute of a lambert derived
//		shader.
//
{
	// Setup the view
	view.beginGL();
	glPushAttrib( GL_ALL_ATTRIB_BITS );
	glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);

	MColor diffuse(1.0F, 1.0F, 0.0F, 1.0F);
	MColor specular(1.0F, 1.0F, 1.0F, 1.0F);
	MColor emission(0.0F, 0.0F, 0.0F, 1.0F);
	MColor ambient(0.2F, 0.2F, 0.2F, 1.0F);

	// Get the diffuse and specular colors
	//
	float shininess;
	bool hasTransparency = false;

	MMaterial material = request.material();
	fInTexturedMode = material.materialIsTextured();

	// Setting this to true will get the default "green" material back
	// since it will try and evaluate this shader, which internally
	// Maya does not understand -> thus giving the "green" material back
	bool useInternalMaterialSetting = false;
	
	if (!useInternalMaterialSetting)
	{
		material.getEmission( emission );
		material.getSpecular( specular );
		shininess = 13.0;
	}
	material.getHasTransparency( hasTransparency );	

	if (!fInTexturedMode)
	{
		if (!fTestVertexProgram && !useInternalMaterialSetting)
			material.getDiffuse( diffuse );
	}
	// In textured mode. Diffuse material is always white
	// for texture blends
	else
	{
		if (!useInternalMaterialSetting)
			diffuse.r = diffuse.g = diffuse.b = diffuse.a = 1.0;
	}

	// Use a vertex program to set up shading
	//
	if (fTestVertexProgram)
	{
		bindVertexProgram(diffuse, specular, emission, ambient);
	}
	else if (fTestFragmentProgram)
	{
		bindFragmentProgram();
	}

	// Don't use a vertex program to set up shading
	//
	else
	{
		// Set up the material state
		//
		glEnable(GL_COLOR_MATERIAL);
		glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
		glColor4fv(&ambient.r);

		if (fInTexturedMode)
		{
			glEnable( GL_TEXTURE_2D );
			MDrawData drawData = request.drawData();
			material.applyTexture( view, drawData );

			float scaleS, scaleT, translateS, translateT, rotate;

			material.getTextureTransformation(scaleS, scaleT, translateS,
											  translateT, rotate);

			rotate = DEG_TO_RAD(-rotate);
			float c = cosf(rotate);
			float s = sinf(rotate);
			translateS += ((c+s)/2.0F);
			translateT += ((c-s)/2.0F);

			glMatrixMode(GL_TEXTURE);
			glPushMatrix();
			glLoadIdentity();

			if(scaleS != 1.0f || scaleT != 1.0f)
				glScalef(1.0f/scaleS, 1.0f/scaleT, 1.0f);
			if(translateS != 0.0f || translateT != 0.0f)
				glTranslatef(0.5f-translateS, 0.5f-translateT, 0.0f);
			else
				glTranslatef(0.5f, 0.5f, 0.0f);

			if(rotate != 0.0f)
				glRotatef(-rotate, 0.0f, 0.0f, 1.0f);

			glMatrixMode(GL_MODELVIEW);
		}

		if (!useInternalMaterialSetting)
		{
			glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
			glColor4fv(&diffuse.r);
			glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
			glColor4fv(&specular.r);
			glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
			glColor4fv(&emission.r);
			glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
		}
		else
		{
			const MDagPath dagPath =  request.multiPath();
			material.evaluateMaterial( view, dagPath );
			material.setMaterial(dagPath, hasTransparency);
		}
	}

	// Do PN triangles in hardware, or do nothing
	// if LOD = 0
	if (fExtensionSupported[kPNTriangesEXT] || (fSubdivisions == 0))
	{
		if (fSubdivisions != 0)
		{
			glEnable( GL_PN_TRIANGLES_ATI );

			// Set point mode
			//
			if (fPointMode == kPointLinear)
				glPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, 
								   GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI);
			else
				glPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, 
								   GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI);

			// Set normal mode
			//
			if (fNormalMode == kNormalLinear)
				glPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, 
								   GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI);
			else
				glPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, 
								   GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI);

			// Set tessellation level
			//
			glPNTrianglesiATI( GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI,
							  fSubdivisions );
		}
	}

	view.endGL();

	return MS::kSuccess;
}
Beispiel #16
0
/* virtual */
MStatus	hwUnlitShader::bind(const MDrawRequest& request,
							M3dView& view)
{
	MStatus status;

	// white, opaque.
	float bgColor[4] = {1,1,1,1};

	// Get path of current object in draw request
	currentObjectPath = request.multiPath();
	MString currentPathName( currentObjectPath.partialPathName() );

	updateTransparencyFlags(currentPathName);

	// Get decal texture name
	MString decalName = "";
	ShadingConnection colorConnection(thisMObject(), currentPathName, "color");

	// If the color attribute is ultimately connected to a file texture, find its filename.
	// otherwise use the default color texture.
	if (colorConnection.type() == ShadingConnection::TEXTURE &&
		colorConnection.texture().hasFn(MFn::kFileTexture))
	{
		// Get the filename of the texture.
		MFnDependencyNode textureNode(colorConnection.texture());
		MPlug filenamePlug( colorConnection.texture(), textureNode.attribute(MString("fileTextureName")) );
		filenamePlug.getValue(decalName);
		if (decalName == "")
			getFloat3(color, bgColor);
	}
	else
	{
		decalName = "";
		getFloat3(color, bgColor);
	}
	
	assert(glGetError() == GL_NO_ERROR);

	view.beginGL();

	glPushAttrib( GL_ALL_ATTRIB_BITS );
	glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);

	// Set the standard OpenGL blending mode.
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	
	// Change the constant alpha value. 
	float alpha = 1.0f - fConstantTransparency;

	// Set a color (with alpha). This color will be used directly if
	// the shader is not textured. Otherwise, the texture will get modulated
	// by the alpha.
	glColor4f(bgColor[0], bgColor[1], bgColor[2], alpha);


	// If the shader is textured...
	if (decalName.length() != 0)
	{
		// Enable 2D texturing.
		glEnable(GL_TEXTURE_2D);

		assert(glGetError() == GL_NO_ERROR);

		// Bind the 2D texture through the texture cache. The cache will keep
		// the texture around, so that it will only be loaded in video
		// memory once. In this example, the third parameter (mipmapping) is
		// false, so no mipmaps are generated. Note that mipmaps only work if
		// the texture has even dimensions.

		if(m_pTextureCache)
			m_pTextureCache->bind(colorConnection.texture(), MTexture::RGBA, false);	
		
		// Set minification and magnification filtering to linear interpolation.
		// For better quality, you could enable mipmapping while binding and
		// use GL_MIPMAP_LINEAR_MIPMAP in for minification filtering.
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
	}

	// Disable lighting.
	glDisable(GL_LIGHTING);

	view.endGL();

	return MS::kSuccess;
}
Beispiel #17
0
/* override */
void apiSimpleShapeUI::getDrawRequests( const MDrawInfo & info,
							 bool objectAndActiveOnly,
							 MDrawRequestQueue & queue )
//
// Description:
//
//     Add draw requests to the draw queue
//
// Arguments:
//
//     info                 - current drawing state
//     objectsAndActiveOnly - no components if true
//     queue                - queue of draw requests to add to
//
{
	// Get the data necessary to draw the shape
	//
	MDrawData data;
	apiSimpleShape* shape = (apiSimpleShape*) surfaceShape();
	MVectorArray* geomPtr = shape->getControlPoints();

	// This call creates a prototype draw request that we can fill
	// in and then add to the draw queue.
	//
	MDrawRequest request = info.getPrototype( *this );

	// Stuff our data into the draw request, it'll be used when the drawing
	// actually happens
	getDrawData( geomPtr, data );

	request.setDrawData( data );


	// Decode the draw info and determine what needs to be drawn
	//

	M3dView::DisplayStyle  appearance    = info.displayStyle();
	M3dView::DisplayStatus displayStatus = info.displayStatus();

	switch ( appearance )
	{
		case M3dView::kWireFrame :
		{
			request.setToken( kDrawWireframe );

			M3dView::ColorTable activeColorTable = M3dView::kActiveColors;
			M3dView::ColorTable dormantColorTable = M3dView::kDormantColors;

			switch ( displayStatus )
			{
				case M3dView::kLead :
					request.setColor( LEAD_COLOR, activeColorTable );
					break;
				case M3dView::kActive :
					request.setColor( ACTIVE_COLOR, activeColorTable );
					break;
				case M3dView::kActiveAffected :
					request.setColor( ACTIVE_AFFECTED_COLOR, activeColorTable );
					break;
				case M3dView::kDormant :
					request.setColor( DORMANT_COLOR, dormantColorTable );
					break;
				case M3dView::kHilite :
					request.setColor( HILITE_COLOR, activeColorTable );
					break;

				default:
						break;
			}

			queue.add( request );

			break;
		}

		case M3dView::kGouraudShaded :
		{
			// Create the smooth shaded draw request
			//
			request.setToken( kDrawSmoothShaded );

			// Need to get the material info
			//
			MDagPath path = info.multiPath();	// path to your dag object 
			M3dView view = info.view();; 		// view to draw to
			MMaterial material = MPxSurfaceShapeUI::material( path );

			// Evaluate the material and if necessary, the texture.
			//
			if ( ! material.evaluateMaterial( view, path ) ) {
				cerr << "Couldnt evaluate\n";
			}

			bool drawTexture = true;
			if ( drawTexture && material.materialIsTextured() ) {
				material.evaluateTexture( data );
			}

			request.setMaterial( material );

			// request.setDisplayStyle( appearance );

			bool materialTransparent = false;
			material.getHasTransparency( materialTransparent );
			if ( materialTransparent ) {
				request.setIsTransparent( true );
			}

			queue.add( request );

			// create a draw request for wireframe on shaded if
			// necessary.
			//
			if ( (displayStatus == M3dView::kActive) ||
				 (displayStatus == M3dView::kLead) ||
				 (displayStatus == M3dView::kHilite) )
			{
				MDrawRequest wireRequest = info.getPrototype( *this );
				wireRequest.setDrawData( data );
				wireRequest.setToken( kDrawWireframeOnShaded );
				wireRequest.setDisplayStyle( M3dView::kWireFrame );

				M3dView::ColorTable activeColorTable = M3dView::kActiveColors;

				switch ( displayStatus )
				{
					case M3dView::kLead :
						wireRequest.setColor( LEAD_COLOR, activeColorTable );
						break;
					case M3dView::kActive :
						wireRequest.setColor( ACTIVE_COLOR, activeColorTable );
						break;
					case M3dView::kHilite :
						wireRequest.setColor( HILITE_COLOR, activeColorTable );
						break;

					default :	
						break;
				}

				queue.add( wireRequest );
			}

			break;
		}

		case M3dView::kFlatShaded :
			request.setToken( kDrawFlatShaded );
			break;

		default:
			break;

	}

	// Add draw requests for components
	//
	if ( !objectAndActiveOnly ) {

		// Inactive components
		//
		if ( (appearance == M3dView::kPoints) ||
			 (displayStatus == M3dView::kHilite) )
		{
			MDrawRequest vertexRequest = info.getPrototype( *this ); 
			vertexRequest.setDrawData( data );
			vertexRequest.setToken( kDrawVertices );
			vertexRequest.setColor( DORMANT_VERTEX_COLOR,
									M3dView::kActiveColors );

			queue.add( vertexRequest );
		}

		// Active components
		//
		if ( surfaceShape()->hasActiveComponents() ) {

			MDrawRequest activeVertexRequest = info.getPrototype( *this ); 
			activeVertexRequest.setDrawData( data );
		    activeVertexRequest.setToken( kDrawVertices );
		    activeVertexRequest.setColor( ACTIVE_VERTEX_COLOR,
										  M3dView::kActiveColors );

		    MObjectArray clist = surfaceShape()->activeComponents();
		    MObject vertexComponent = clist[0]; // Should filter list
		    activeVertexRequest.setComponent( vertexComponent );

			queue.add( activeVertexRequest );
		}
	}
}
// Load the file textures for the cube maps.
//
MStatus	hwRefractReflectShader_NV20::loadTextures(const MDrawRequest& request, M3dView& view)
{
	// Get the cube map file names
	//
	MStringArray	decalNames;
	MString			decalName;

	// Find the cubemap textures by tracing through the connection from the color atttribute
	//
	ShadingConnection	colorConnection(thisMObject(), request.multiPath().partialPathName(), "color");

	// If the color attribute is ultimately connected to a environment, 
	// find its filenames, otherwise use the default color texture.
	//
	bool gotAllEnvironmentMaps = TRUE;
	if (colorConnection.type() == ShadingConnection::TEXTURE &&
		colorConnection.texture().hasFn(MFn::kEnvCube))
	{
		// Get the filenames of the texture.
		MFnDependencyNode textureNode(colorConnection.texture());
		MString attributeName;
		MString envNames[6] = { "top", "bottom", "left", "right", "front", "back" };

		// Scan for connected file textures to the environment map node
		//
		for (int i=0; i<6; i++)
		{
			ShadingConnection conn(colorConnection.texture(), request.multiPath().partialPathName(), 
							envNames[i]);

			if (conn.type() == ShadingConnection::TEXTURE &&
				conn.texture().hasFn(MFn::kFileTexture))
			{
				MFnDependencyNode envNode(conn.texture());
				MPlug filenamePlug( conn.texture(), envNode.attribute(MString("fileTextureName")) );

				filenamePlug.getValue(decalName);

				if (decalName.length() == 0)	decalName = "internalDefaultTexture";

				// Append next environment map name
				decalNames.append( decalName );
			}

			// If any of the environment maps are not mapped put in a fake texture
			else
			{
				decalName = "internalDefaultTexture";
				decalNames.append( decalName );
			}
		}
	}
	else
	{
		// Put in a fake texture for each side
		decalName = "internalDefaultTexture";
		for (int i=0; i<6; i++)
		{
			decalNames.append( decalName );
		}
	}

	// Reload cube maps if the name of the textures
	// for any of the cube maps changes
	//
	bool reload = FALSE;
	for (int i=0; i<6; i++)
	{
		if (currentTextureNames[i] != decalNames[i])
		{
			reload = TRUE;
			break;
		}
	}

	view.beginGL();
	{
		if ( reload )
		{
			MString	ypTexName(decalNames[0]);	// y+ == top
			MString	ynTexName(decalNames[1]);	// y- == bottom
			MString	xpTexName(decalNames[2]);	// x+ == left
			MString	xnTexName(decalNames[3]);	// x- == right
			MString	zpTexName(decalNames[4]);	// z+ == front
			MString	znTexName(decalNames[5]);	// z- == back

			MStatus stat;
			if (! (stat = theImage_XP.readFromFile(xpTexName)) )	return MS::kFailure;
			if (! (stat = theImage_XN.readFromFile(xnTexName)) )	return MS::kFailure;
			if (! (stat = theImage_YP.readFromFile(ypTexName)) )	return MS::kFailure;
			if (! (stat = theImage_YN.readFromFile(ynTexName)) )	return MS::kFailure;
			if (! (stat = theImage_ZP.readFromFile(zpTexName)) )	return MS::kFailure;
			if (! (stat = theImage_ZN.readFromFile(znTexName)) )	return MS::kFailure;

			// Only create texture names the first time
			if (fTextureName == -1) 	glGenTextures(1, &fTextureName);

			glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, fTextureName );
			glEnable( GL_TEXTURE_CUBE_MAP_ARB );

			// The cubeMap textures have to have the same size
			//
			unsigned int width, height;
			stat = theImage_XP.getSize( width, height );

			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
				0, GL_RGBA8, width,	height, 0, GL_RGBA,	GL_UNSIGNED_BYTE, theImage_XP.pixels() );
			glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
				0, GL_RGBA8, width,	height,	0, GL_RGBA,	GL_UNSIGNED_BYTE, theImage_XN.pixels() );
			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
				0, GL_RGBA8, width,	height,	0, GL_RGBA,	GL_UNSIGNED_BYTE, theImage_YP.pixels() );
			glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
				0, GL_RGBA8, width,	height,	0, GL_RGBA,	GL_UNSIGNED_BYTE, theImage_YN.pixels() );
			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
				0, GL_RGBA8, width,	height,	0, GL_RGBA,	GL_UNSIGNED_BYTE, theImage_ZP.pixels() );
			glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
				0, GL_RGBA8, width,	height,	0, GL_RGBA,	GL_UNSIGNED_BYTE, theImage_ZN.pixels() );

			glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

			for (i=0; i<6; i++)		currentTextureNames[i] = decalNames[i];
		}

		// stage 0 -- cubeMap texture for the refraction
		//
		glActiveTextureARB( GL_TEXTURE0_ARB );
		glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, fTextureName );
		glEnable( GL_TEXTURE_CUBE_MAP_ARB );

		// stage 1 -- cubeMap texture for the reflection
		//
		glActiveTextureARB( GL_TEXTURE1_ARB );
		glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, fTextureName );
		glEnable( GL_TEXTURE_CUBE_MAP_ARB );
	}
	view.endGL();

	return MS::kSuccess;
}
/* virtual */
MStatus	hwDecalBumpShader_NV20::bind(const MDrawRequest& request, M3dView& view)
{
	MStatus status;

	// Get the diffuse color
	//
	float diffuse_color[4];
	status = getFloat3(color, diffuse_color);
	diffuse_color[3] = 1.0;
	if (!status)
        return status;

	// Get the light color
	//
	float light_color[4];
	light_color[3] = 1.0f;
	status = getFloat3(lightColor, light_color);
	if (!status)
        return status;

	// Get the light direction (for directionalLight)
	//
	status = getFloat3(light, &lightRotation[0]);
	if (!status)
        return status;

	// Get the bumpScale value
	//
	float	bumpScaleValue = 2.0f;

	// Get the bumpMap type
	//
	bool	isHeightFieldMap = true;


	// Direction of the directional light
	//
	// Convert the light direction (which is assumed in originally be in world space, in euler coordinates) 
	// into an eye space vector.
	//
	double	scale = M_PI/180.0;		// Internal rotations are in radian and not in degrees
	MEulerRotation	lightRot( lightRotation[0] * scale, lightRotation[1] * scale, lightRotation[2] * scale );
	MVector	light_v = MVector(0, 0, -1).rotateBy( lightRot );	// WS light vector

	MDagPath camDag;
	view.getCamera(camDag);

	light_v = light_v * camDag.inclusiveMatrixInverse();
	lightRotation[0] = (float) light_v[0];
	lightRotation[1] = (float) light_v[1];
	lightRotation[2] = (float) light_v[2];


	// Get the camera position
	//
	status = getFloat3(camera, &cameraPos[0]);
	if (!status)
        return status;

	// Get the decal and bump map file names
	//
	MString decalName = "";
	MString bumpName  = "";

	ShadingConnection colorConnection(thisMObject(), request.multiPath().partialPathName(), "color");
	ShadingConnection bumpConnection (thisMObject(), request.multiPath().partialPathName(), "bump");

	// If the color attribute is ultimately connected to a file texture, find its filename.
	// otherwise use the default color texture.
	if (colorConnection.type() == ShadingConnection::TEXTURE &&
		colorConnection.texture().hasFn(MFn::kFileTexture))
	{
		// Get the filename of the texture.
		MFnDependencyNode textureNode(colorConnection.texture());
		MPlug filenamePlug( colorConnection.texture(), textureNode.attribute(MString("fileTextureName")) );
		filenamePlug.getValue(decalName);
	}

	// If the bump attribute is ultimately connected to a file texture, find its filename.
	// otherwise use the default bump texture.
	if (bumpConnection.type() == ShadingConnection::TEXTURE &&
		bumpConnection.texture().hasFn(MFn::kFileTexture))
	{
		// Get the filename of the texture.
		MFnDependencyNode textureNode(colorConnection.texture());
		MPlug filenamePlug( bumpConnection.texture(), textureNode.attribute(MString("fileTextureName")) );
		filenamePlug.getValue(bumpName);
	}

	// Fail safe quit
	//
	if (bumpName.length() == 0 ||
		decalName.length() == 0)
	{
		view.beginGL();
		glPushAttrib( GL_ALL_ATTRIB_BITS );		// This might be too conservative
		glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
		glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
		glEnable(GL_COLOR_MATERIAL);
		glColor4fv(diffuse_color);
		view.endGL();
		return MS::kSuccess;
	}

	view.beginGL();

	glPushAttrib( GL_ALL_ATTRIB_BITS );
	glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);

    /* Starts Here... */
	glEnable(GL_TEXTURE_SHADER_NV);
	
	// stage 0 -- decal map
	glActiveTextureARB( GL_TEXTURE0_ARB );
	if(m_pTextureCache)
		m_pTextureCache->bind(colorConnection.texture(), MTexture::RGBA, false);
	glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
	
    // stage 1 -- bumpped normal map
	glActiveTextureARB( GL_TEXTURE1_ARB );
	// We need to be able to pass the bumpScaleValue
	// to the texture cache and rebuild the bump or normal map
	if( isHeightFieldMap ) {
		// convert the HeightField to the NormalMap
		if(m_pTextureCache)
			m_pTextureCache->bind(bumpConnection.texture(), MTexture::NMAP, false);
	}
	else {
		if(m_pTextureCache)
			m_pTextureCache->bind(bumpConnection.texture(), MTexture::RGBA, false);
	}
   	glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);
	
	// stage 2 -- dot product (diffuse component)
	glActiveTextureARB( GL_TEXTURE2_ARB );
	glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
	glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
	glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE1_ARB);

	// stage 3 -- dot product (specular component)
	glActiveTextureARB( GL_TEXTURE3_ARB );
	bind_lookup_table();	// 2D texture to get the diffuse and specular illumination
	glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV);
	glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
	glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE1_ARB);
	
	// With light color and intensity
	//
	glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, diffuse_color);
	glCombinerParameterfvNV(GL_CONSTANT_COLOR1_NV, light_color);

	// The register combiner will do the multiplication between
	// the illumination and the decal color
	//
	glEnable(GL_REGISTER_COMBINERS_NV);

	
#ifndef DEBUGGING_VERTEX_PROGRAM
	glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 2);
#else
	// For testing, only use one general register combiner.
	glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 1);
#endif

	float constColor0[4];
	constColor0[0] = constColor0[1] = constColor0[2] = constColor0[3] = 1.0;
	glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, constColor0);

#ifndef DEBUGGING_VERTEX_PROGRAM
	// Combiner stage 0 does the illumination modulation on the surface decal color
	//
	glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
	glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
	glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
	glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);

	glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE1_NV, 
					   GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);

	// Combiner stage 1, modulate the surface color by the light color
	//
	glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
	glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);

	glCombinerOutputNV(GL_COMBINER1_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE1_NV, 
					   GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
#else
	// Simplified register combiners to help debugging vertex program.
	glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
	glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
	glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
	glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);

	glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV, GL_DISCARD_NV, 
					   GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
#endif // DEBUGGING_VERTEX_PROGRAM

	// The final Combiner just pass through
	//
	glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
	glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
	glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
	glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB);

	view.endGL();

	return MS::kSuccess;
}