예제 #1
0
bool dx11ShaderOverride::draw(
    MHWRender::MDrawContext& context,
    const MHWRender::MRenderItemList& renderItemList) const
{
    // Get effect wrapper
    if (!fShaderNode) return false;

    // Sample code to debug pass information
    static const bool debugPassInformation = false;
    if (debugPassInformation)
    {
        const MHWRender::MPassContext & passCtx = context.getPassContext();
        const MString & passId = passCtx.passIdentifier();
        const MStringArray & passSem = passCtx.passSemantics();
        printf("dx11 shader drawing in pass[%s], semantic[", passId.asChar());
        for (unsigned int i=0; i<passSem.length(); i++)
            printf(" %s", passSem[i].asChar());
        printf("\n");
    }

    return fShaderNode->render(context, renderItemList);
}
/*
	Utility method to update shader parameters based on available
	lighting information.
*/
static void updateLightShader( MHWRender::MShaderInstance *shaderInstance,
						const MHWRender::MDrawContext & context,
						const MSelectionList * lightList )
{
	if (!shaderInstance)
		return;

	// Check pass context information to see if we are in a shadow 
	// map update pass. If so do nothing.
	//
	const MHWRender::MPassContext & passCtx = context.getPassContext();
	const MStringArray & passSem = passCtx.passSemantics();
	bool handlePass = true;
	for (unsigned int i=0; i<passSem.length() && handlePass; i++)
	{
		// Handle special pass drawing.
		//
		if (passSem[i] == MHWRender::MPassContext::kShadowPassSemantic)
		{
			handlePass = false;
		}
	}
	if (!handlePass) return;

	//
	// Perform light shader update with lighting information
	// If the light list is not empty then use that light's information.
	// Otherwise choose the first appropriate light which can cast shadows.
	//

	// Defaults in case there are no lights
	//
	bool globalShadowsOn = false;
	bool localShadowsOn = false;
	bool shadowDirty = false;
	MFloatVector direction(0.0f, 0.0f, 1.0f);
	float lightIntensity = 0.0f; // If no lights then black out the light
	float lightColor[3] = { 0.0f, 0.0f, 0.0f };

	MStatus status;

	// Scan to find the first N lights that has a direction component in it
	// It's possible we find no lights.
	//
	MHWRender::MDrawContext::LightFilter considerAllSceneLights = MHWRender::MDrawContext::kFilteredIgnoreLightLimit;
	unsigned int lightCount = context.numberOfActiveLights(considerAllSceneLights);
	if (lightCount)
	{
		MFloatArray floatVals;
		MIntArray intVals;
		MHWRender::MTextureAssignment shadowResource;
		shadowResource.texture = NULL;
		MHWRender::MSamplerStateDesc samplerDesc;
		MMatrix shadowViewProj;
		float shadowColor[3] = { 0.0f, 0.0f, 0.0f };

		unsigned int i=0;
		bool foundDirectional = false;
		for (i=0; i<lightCount && !foundDirectional ; i++)
		{
			MHWRender::MLightParameterInformation *lightParam = context.getLightParameterInformation( i, considerAllSceneLights );
			if (lightParam)
			{
				// Prune against light list if any.
				if (lightList && lightList->length())
				{
					if (!lightList->hasItem(lightParam->lightPath()))
						continue;
				}

				MStringArray params;
				lightParam->parameterList(params);
				for (unsigned int p=0; p<params.length(); p++)
				{
					MString pname = params[p];

					MHWRender::MLightParameterInformation::StockParameterSemantic semantic = lightParam->parameterSemantic( pname );
					switch (semantic)
					{
						// Pick a few light parameters to pick up as an example
					case MHWRender::MLightParameterInformation::kWorldDirection:
						lightParam->getParameter( pname, floatVals );
						direction = MFloatVector( floatVals[0], floatVals[1], floatVals[2] );
						foundDirectional = true;
						break;
					case MHWRender::MLightParameterInformation::kIntensity:
						lightParam->getParameter( pname, floatVals );
						lightIntensity = floatVals[0];
						break;
					case MHWRender::MLightParameterInformation::kColor:
						lightParam->getParameter( pname, floatVals );
						lightColor[0] = floatVals[0];
						lightColor[1] = floatVals[1];
						lightColor[2] = floatVals[2];
						break;

						// Pick up shadowing parameters
					case MHWRender::MLightParameterInformation::kGlobalShadowOn:
						lightParam->getParameter( pname, intVals );
						if (intVals.length())
							globalShadowsOn = (intVals[0] != 0) ? true : false;
						break;
					case MHWRender::MLightParameterInformation::kShadowOn:
						lightParam->getParameter( pname, intVals );
						if (intVals.length())
							localShadowsOn = (intVals[0] != 0) ? true : false;
						break;
					case MHWRender::MLightParameterInformation::kShadowViewProj:
						lightParam->getParameter( pname, shadowViewProj);
						break;
					case MHWRender::MLightParameterInformation::kShadowMap:
						lightParam->getParameter( pname, shadowResource );
						break;
					case MHWRender::MLightParameterInformation::kShadowDirty:
						if (intVals.length())
							shadowDirty = (intVals[0] != 0) ? true : false;
						break;
					case MHWRender::MLightParameterInformation::kShadowSamp:
						lightParam->getParameter( pname, samplerDesc );
						break;
					case MHWRender::MLightParameterInformation::kShadowColor:
						lightParam->getParameter( pname, floatVals );
						shadowColor[0] = floatVals[0];
						shadowColor[1] = floatVals[1];
						shadowColor[2] = floatVals[2];
						break;
					default:
						break;
					}
				} /* for params */
			}

			if (foundDirectional && globalShadowsOn && localShadowsOn && shadowResource.texture)
			{
				void *resourceHandle = shadowResource.texture->resourceHandle();
				if (resourceHandle)
				{
					static bool debugShadowBindings = false;
					status  = shaderInstance->setParameter("mayaShadowPCF1_shadowMap", shadowResource );
					if (status == MStatus::kSuccess && debugShadowBindings)
						fprintf(stderr, "Bound shadow map to shader param mayaShadowPCF1_shadowMap\n");
					status  = shaderInstance->setParameter("mayaShadowPCF1_shadowViewProj", shadowViewProj );
					if (status == MStatus::kSuccess && debugShadowBindings)
						fprintf(stderr, "Bound shadow map transform to shader param mayaShadowPCF1_shadowViewProj\n");
					status  = shaderInstance->setParameter("mayaShadowPCF1_shadowColor", &shadowColor[0] );
					if (status == MStatus::kSuccess && debugShadowBindings)
						fprintf(stderr, "Bound shadow map color to shader param mayaShadowPCF1_shadowColor\n");
				}

				MHWRender::MRenderer* renderer = MHWRender::MRenderer::theRenderer();
				if (renderer)
				{
					MHWRender::MTextureManager* textureManager = renderer->getTextureManager();
					if (textureManager)
					{
						textureManager->releaseTexture(shadowResource.texture);
					}
				}
				shadowResource.texture = NULL;
			}
		}
	}

	// Set up parameters which should be set regardless of light existence.
	status = shaderInstance->setParameter("mayaDirectionalLight_direction", &( direction[0] ));
	status = shaderInstance->setParameter("mayaDirectionalLight_intensity", lightIntensity );
	status = shaderInstance->setParameter("mayaDirectionalLight_color", &( lightColor[0] ));
	status = shaderInstance->setParameter("mayaShadowPCF1_mayaGlobalShadowOn", globalShadowsOn);
	status = shaderInstance->setParameter("mayaShadowPCF1_mayaShadowOn", localShadowsOn);
}
MStatus viewRenderUserOperation::execute( const MHWRender::MDrawContext & drawContext )
{
	// Sample code to debug pass information
	static const bool debugPassInformation = false;
	if (debugPassInformation)
	{
		const MHWRender::MPassContext & passCtx = drawContext.getPassContext();
		const MString & passId = passCtx.passIdentifier();
		const MStringArray & passSem = passCtx.passSemantics();
		printf("viewRenderUserOperation: drawing in pass[%s], semantic[", passId.asChar());
		for (unsigned int i=0; i<passSem.length(); i++)
			printf(" %s", passSem[i].asChar());
		printf("\n");
	}

	// Example code to find the active override.
	// This is not necessary if the operations just keep a reference
	// to the override, but this demonstrates how this
	// contextual information can be extracted.
	//
	MHWRender::MRenderer *theRenderer = MHWRender::MRenderer::theRenderer();
	const MHWRender::MRenderOverride *overridePtr = NULL;
	if (theRenderer)
	{
		const MString & overrideName = theRenderer->activeRenderOverride();
		overridePtr = theRenderer->findRenderOverride( overrideName );
	}

	// Some sample code to debug lighting information in the MDrawContext
	//
	if (fDebugLightingInfo)
	{
		viewRenderOverrideUtilities::printDrawContextLightInfo( drawContext );
	}

	// Some sample code to debug other MDrawContext information
	//
	if (fDebugDrawContext)
	{
		MStatus status;
		MMatrix matrix = drawContext.getMatrix(MHWRender::MFrameContext::kWorldMtx, &status);
		double dest[4][4];
		status = matrix.get(dest);
		printf("World matrix is:\n");
		printf("\t%f, %f, %f, %f\n", dest[0][0], dest[0][1], dest[0][2], dest[0][3]);
		printf("\t%f, %f, %f, %f\n", dest[1][0], dest[1][1], dest[1][2], dest[1][3]);
		printf("\t%f, %f, %f, %f\n", dest[2][0], dest[2][1], dest[2][2], dest[2][3]);
		printf("\t%f, %f, %f, %f\n", dest[3][0], dest[3][1], dest[3][2], dest[3][3]);

		MDoubleArray viewDirection = drawContext.getTuple(MHWRender::MFrameContext::kViewDirection, &status);
		printf("Viewdirection is: %f, %f, %f\n", viewDirection[0], viewDirection[1], viewDirection[2]);

		MBoundingBox box = drawContext.getSceneBox(&status);
		printf("Screen box is:\n");
		printf("\twidth=%f, height=%f, depth=%f\n", box.width(), box.height(), box.depth());
		float center[4];
		box.center().get(center);
		printf("\tcenter=(%f, %f, %f, %f)\n", center[0], center[1], center[2], center[3]);


		int originX, originY, width, height;
		status = drawContext.getViewportDimensions(originX, originY, width, height);
		printf("Viewport dimension: center(%d, %d), width=%d, heigh=%d\n", originX, originY, width, height);
	}

	//  Draw some addition things for scene draw
	//
	M3dView mView;
	if (mPanelName.length() &&
		(M3dView::getM3dViewFromModelPanel(mPanelName, mView) == MStatus::kSuccess))
	{
		// Get the current viewport and scale it relative to that
		//
		int targetW, targetH;
		drawContext.getRenderTargetSize( targetW, targetH );

		if (fDrawLabel)
		{
			MString testString("Drawing with override: ");
			testString += overridePtr->name();
			MPoint pos(0.0,0.0,0.0);
			glColor3f( 1.0f, 1.0f, 1.0f );
			mView.drawText( testString, pos);
		}

		// Some user drawing of scene bounding boxes
		//
		if (fDrawBoundingBoxes)
		{
			MDagPath cameraPath;
			mView.getCamera( cameraPath);
			MCustomSceneDraw userDraw;
			userDraw.draw( cameraPath, targetW, targetH );
		}
	}
	return MStatus::kSuccess;
}