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; }