void ovalLocatorDrawOverride::draw (const MHWRender::MDrawContext &context, const MUserData *data) { MPointArray vertices =ovalLocator::vertices () ; // get cached data float color [3] ={ 0.0f, 1.0f, 0.0f } ; float multiplier =1.0f ; const ovalLocatorData *ovalData =dynamic_cast<const ovalLocatorData *>(data) ; if ( ovalData ) multiplier =ovalData->multiplier ; // get state data MStatus status ; const MMatrix transform =context.getMatrix (MHWRender::MDrawContext::kWorldViewMtx, &status) ; if ( status !=MStatus::kSuccess ) return ; const MMatrix projection =context.getMatrix (MHWRender::MDrawContext::kProjectionMtx, &status) ; if ( status !=MStatus::kSuccess ) return ; const int displayStyle =context.getDisplayStyle () ; // get renderer MHWRender::MRenderer *theRenderer =MHWRender::MRenderer::theRenderer () ; if ( !theRenderer ) return ; // GL Draw if ( theRenderer->drawAPIIsOpenGL () ) { // set colour glColor3fv (color) ; // set world matrix glMatrixMode (GL_MODELVIEW) ; glPushMatrix () ; glLoadMatrixd (transform.matrix [0]) ; // set projection matrix glMatrixMode (GL_PROJECTION) ; glPushMatrix () ; glLoadMatrixd (projection.matrix [0]) ; if ( displayStyle & MHWRender::MDrawContext::kGouraudShaded ) { // See myShadedDraw glPushAttrib (GL_CURRENT_BIT) ; glBegin (GL_TRIANGLE_FAN) ; glVertex3f (0, 0, 0) ; for ( int i =0 ; i < vertices.length () ; ++i ) glVertex3f (vertices [i].x * multiplier, vertices [i].y * multiplier, vertices [i].z * multiplier) ; glEnd () ; glPopAttrib () ; } if ( displayStyle & MHWRender::MDrawContext::kWireFrame ) { // See myWireFrameDraw glBegin (GL_LINES) ; for ( int i =0 ; i < vertices.length () - 1 ; ++i ) { glVertex3f (vertices [i].x * multiplier, vertices [i].y * multiplier, vertices [i].z * multiplier) ; glVertex3f (vertices [i + 1].x * multiplier, vertices [i + 1].y * multiplier, vertices [i + 1].z * multiplier) ; } glEnd () ; } glPopMatrix () ; glMatrixMode (GL_MODELVIEW) ; glPopMatrix () ; } }
void arrowLocatorOverride::draw( const MHWRender::MDrawContext& context, const MUserData* data) { MAngle rotationAngle; float color [3] ={ 0.0f, 1.0f, 0.0f } ; // data MStatus status; MHWRender::MStateManager* stateMgr = context.getStateManager(); const arrowLocatorData* locatorData = dynamic_cast<const arrowLocatorData*>(data); if (!stateMgr || !locatorData) return; if ( locatorData ) rotationAngle = locatorData->rotateAngle; // matrices const MMatrix transform = context.getMatrix(MHWRender::MFrameContext::kWorldViewMtx, &status); if (status != MStatus::kSuccess) return; const MMatrix projection = context.getMatrix(MHWRender::MFrameContext::kProjectionMtx, &status); if (status != MStatus::kSuccess) return; // get renderer MHWRender::MRenderer *theRenderer =MHWRender::MRenderer::theRenderer () ; if ( !theRenderer ) return ; if ( theRenderer->drawAPIIsOpenGL () ) { glPushAttrib(GL_CURRENT_BIT); glColor4fv(color); glPushMatrix(); glRotated(-rotationAngle.asDegrees(), 0.0, 1.0, 0.0); glBegin( GL_LINE_STRIP); glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]); glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]); glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]); glEnd(); glBegin( GL_LINE_STRIP ); glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]); glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]); glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]); glEnd(); glPopMatrix(); } }
void UsdMayaGLBatchRenderer::Draw( const MHWRender::MDrawContext& context, const MUserData *userData) { // VP 2.0 Implementation // MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer(); if( !theRenderer || !theRenderer->drawAPIIsOpenGL() ) return; const _BatchDrawUserData* batchData = static_cast<const _BatchDrawUserData*>(userData); if( !batchData ) return; MStatus status; MMatrix projectionMat = context.getMatrix(MHWRender::MDrawContext::kProjectionMtx, &status); if( batchData->_bounds ) { MMatrix worldViewMat = context.getMatrix(MHWRender::MDrawContext::kWorldViewMtx, &status); px_vp20Utils::RenderBoundingBox(*(batchData->_bounds), *(batchData->_wireframeColor), worldViewMat, projectionMat); } if( batchData->_drawShape && !_renderQueue.empty() ) { MMatrix viewMat = context.getMatrix(MHWRender::MDrawContext::kViewMtx, &status); // Extract camera settings from maya view int viewX, viewY, viewWidth, viewHeight; context.getViewportDimensions(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( &context, viewMat, projectionMat, viewport ); } }
MStatus PluginTestUserOperation::execute(const MHWRender::MDrawContext & drawContext) { //return MStatus::kSuccess; M3dView view; if(M3dView::getM3dViewFromModelPanel(panelName, view) == MStatus::kSuccess) { // Get the current viewport and scale it relative to that // int targetW, targetH; drawContext.getRenderTargetSize(targetW, targetH); // Some user drawing of scene bounding boxes // MDagPath cameraPath; MFnCamera fnCamera; view.getCamera(cameraPath); MMatrix m3dViewProjection, m3dViewModelView; view.projectionMatrix(m3dViewProjection); view.modelViewMatrix(m3dViewModelView); MFloatMatrix m3dFloatViewProjection(m3dViewProjection.matrix); MFloatMatrix m3dFloatViewModelView(m3dViewModelView.matrix); MFloatMatrix viewProjection = m3dFloatViewModelView * m3dFloatViewProjection; SurfaceDrawTraversal traversal; traversal.enableFiltering(true); traversal.setFrustum(cameraPath, targetW, targetH); traversal.traverse(); unsigned int numItems = traversal.numberOfItems(); MFnMesh fnMesh; for (int i = 0; i < numItems; i++) { MDagPath path; traversal.itemPath(i, path); if (path.hasFn(MFn::kMesh)) { fnMesh.setObject(path); MFloatMatrix modelWorld(path.inclusiveMatrix().matrix); MTransformationMatrix transformMatrix; MFloatMatrix modelViewProjection = modelWorld * viewProjection; modelViewProjection = modelViewProjection.transpose(); MIntArray triangleCounts; MIntArray triangleVertices; // This is the index list for all the triangles in the mesh in one big list. Ie. first 3 are for tri 1 etc. Index into getPoints() fnMesh.getTriangles(triangleCounts, triangleVertices); //int indices[100]; //triangleVertices.get(indices); MFloatPointArray vertexArray; //float points[1000][4]; fnMesh.getPoints(vertexArray); //vertexArray.get(points); UserSceneRenderer::get()->render(triangleVertices, vertexArray, modelViewProjection); } } } return MStatus::kSuccess; }
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); }
void UsdMayaGLHdRenderer::RenderVp2( const RequestDataArray &requests, const MHWRender::MDrawContext& context, UsdImagingGLRenderParams params) const { using namespace MHWRender; MStatus status; MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer(); if (!theRenderer) return; MHWRender::MStateManager* stateMgr = context.getStateManager(); if (!stateMgr) return; const int displayStyle = context.getDisplayStyle(); if (displayStyle == 0) return; if (displayStyle & MDrawContext::kXray) { // Viewport 2.0 will call draw() twice when drawing transparent objects // (X-Ray mode). We skip the first draw() call. const MRasterizerState* rasterState = stateMgr->getRasterizerState(); if (rasterState && rasterState->desc().cullMode == MRasterizerState::kCullFront) { return; } } if (!theRenderer->drawAPIIsOpenGL()) return; glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT); const MMatrix worldView = context.getMatrix(MHWRender::MDrawContext::kWorldViewMtx, &status); GfMatrix4d modelViewMatrix(worldView.matrix); const MMatrix projection = context.getMatrix(MHWRender::MDrawContext::kProjectionMtx, &status); GfMatrix4d projectionMatrix(projection.matrix); // get root matrix MMatrix root = context.getMatrix(MHWRender::MDrawContext::kWorldMtx, &status); GfMatrix4d rootMatrix(root.matrix); // Extract camera settings from maya view int viewX, viewY, viewWidth, viewHeight; context.getViewportDimensions(viewX, viewY, viewWidth, viewHeight); GfVec4d viewport(viewX, viewY, viewWidth, viewHeight); M3dView::DisplayStyle viewDisplayStyle = displayStyle & MDrawContext::kWireFrame ? M3dView::kWireFrame : M3dView::kGouraudShaded; if(viewDisplayStyle == M3dView::kGouraudShaded) { px_vp20Utils::setupLightingGL(context); glEnable(GL_LIGHTING); } _renderer->SetCameraState(modelViewMatrix, projectionMatrix, viewport); _renderer->SetLightingStateFromOpenGL(); TF_FOR_ALL(it, requests) { RequestData request = *it; if(viewDisplayStyle == M3dView::kWireFrame && request.drawRequest.displayStyle() == M3dView::kGouraudShaded) { request.drawRequest.setDisplayStyle(viewDisplayStyle); } switch(request.drawRequest.token()) { case UsdMayaGLHdRenderer::DRAW_WIREFRAME: case UsdMayaGLHdRenderer::DRAW_POINTS: { params.drawMode = request.drawRequest.token() == UsdMayaGLHdRenderer::DRAW_WIREFRAME ? UsdImagingGLDrawMode::DRAW_WIREFRAME : UsdImagingGLDrawMode::DRAW_POINTS; params.enableLighting = false; params.cullStyle = UsdImagingGLCullStyle::CULL_STYLE_NOTHING; params.overrideColor = request.fWireframeColor; // Get and render usdPrim _renderer->Render(_renderedPrim, params); break; } case UsdMayaGLHdRenderer::DRAW_SHADED_FLAT: case UsdMayaGLHdRenderer::DRAW_SHADED_SMOOTH: { params.drawMode = ((request.drawRequest.token() == UsdMayaGLHdRenderer::DRAW_SHADED_FLAT) ? UsdImagingGLDrawMode::DRAW_GEOM_FLAT : UsdImagingGLDrawMode::DRAW_GEOM_SMOOTH); params.enableLighting = true; params.cullStyle = UsdImagingGLCullStyle::CULL_STYLE_BACK_UNLESS_DOUBLE_SIDED; _renderer->Render(_renderedPrim, params); break; } case UsdMayaGLHdRenderer::DRAW_BOUNDING_BOX: { px_vp20Utils::RenderBoundingBox(request.bounds, request.fWireframeColor, worldView, projection); break; } } }
GLuint OpenSubdivPtexShader::bindProgram(const MHWRender::MDrawContext & mDrawContext, OpenSubdiv::OsdGLDrawContext *osdDrawContext, const OpenSubdiv::OsdPatchArray & patch) { CHECK_GL_ERROR("bindProgram begin\n"); // Build shader Effect effect; effect.color = _enableColor; effect.occlusion = _enableOcclusion; effect.displacement = _enableDisplacement; effect.normal = _enableNormal; EffectDesc effectDesc( patch.desc, effect ); EffectDrawRegistry::ConfigType * config = effectRegistry.GetDrawConfig(effectDesc); // Install shader GLuint program = config->program; glUseProgram(program); // Update and bind transform state struct Transform { float ModelViewMatrix[16]; float ProjectionMatrix[16]; float ModelViewProjectionMatrix[16]; } transformData; setMatrix(mDrawContext.getMatrix(MHWRender::MDrawContext::kWorldViewMtx), transformData.ModelViewMatrix); setMatrix(mDrawContext.getMatrix(MHWRender::MDrawContext::kProjectionMtx), transformData.ProjectionMatrix); setMatrix(mDrawContext.getMatrix(MHWRender::MDrawContext::kWorldViewProjMtx), transformData.ModelViewProjectionMatrix); if (!g_transformUB) { glGenBuffers(1, &g_transformUB); glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(transformData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(transformData), &transformData); glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBufferBase(GL_UNIFORM_BUFFER, g_transformBinding, g_transformUB); // Update and bind tessellation state struct Tessellation { float TessLevel; int GregoryQuadOffsetBase; int PrimitiveIdBase; } tessellationData; tessellationData.TessLevel = static_cast<float>(1 << _tessFactor); tessellationData.GregoryQuadOffsetBase = patch.GetQuadOffsetBase; tessellationData.PrimitiveIdBase = patch.GetPatchIndex();; if (!g_tessellationUB) { glGenBuffers(1, &g_tessellationUB); glBindBuffer(GL_UNIFORM_BUFFER, g_tessellationUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(tessellationData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_tessellationUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(tessellationData), &tessellationData); glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBufferBase(GL_UNIFORM_BUFFER, g_tessellationBinding, g_tessellationUB); #ifdef USE_NON_IMAGE_BASED_LIGHTING // Update and bind lighting state int numLights = mDrawContext.numberOfActiveLights(); struct Lighting { struct Light { float position[4]; float diffuse[4]; float ambient[4]; float specular[4]; } lightSource[2]; } lightingData; memset(&lightingData, 0, sizeof(lightingData)); for (int i = 0; i < numLights && i < 1; ++i) { MFloatPointArray positions; MFloatVector direction; float intensity; MColor color; bool hasDirection, hasPosition; mDrawContext.getLightInformation(i, positions, direction, intensity, color, hasDirection, hasPosition); Lighting::Light &light = lightingData.lightSource[i]; if (hasDirection) { light.position[0] = -direction[0]; light.position[1] = -direction[1]; light.position[2] = -direction[2]; for (int j = 0; j < 4; ++j) { light.diffuse[j] = color[j] * intensity; light.ambient[j] = color[j] * intensity; light.specular[j] = color[j] * intensity; } } } if (!g_lightingUB) { glGenBuffers(1, &g_lightingUB); glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(lightingData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(lightingData), &lightingData); glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBufferBase(GL_UNIFORM_BUFFER, g_lightingBinding, g_lightingUB); #endif GLint eye = glGetUniformLocation(program, "eyePositionInWorld"); MPoint e = MPoint(0, 0, 0) * mDrawContext.getMatrix(MHWRender::MDrawContext::kWorldViewInverseMtx); glProgramUniform3f(program, eye, static_cast<float>(e.x), static_cast<float>(e.y), static_cast<float>(e.z)); // update other uniforms float color[4] = { 0, 0, 0, 1 }; _diffuse.get(color); glProgramUniform4fv(program, glGetUniformLocation(program, "diffuseColor"), 1, color); _ambient.get(color); glProgramUniform4fv(program, glGetUniformLocation(program, "ambientColor"), 1, color); _specular.get(color); glProgramUniform4fv(program, glGetUniformLocation(program, "specularColor"), 1, color); glProgramUniform1f(program, glGetUniformLocation(program, "fresnelBias"), _fresnelBias); glProgramUniform1f(program, glGetUniformLocation(program, "fresnelScale"), _fresnelScale); glProgramUniform1f(program, glGetUniformLocation(program, "fresnelPower"), _fresnelPower); // Ptex bindings // color ptex if (effectRegistry.getPtexColorValid()) { GLint texData = glGetUniformLocation(program, "textureImage_Data"); glProgramUniform1i(program, texData, CLR_TEXTURE_UNIT + 0); GLint texPacking = glGetUniformLocation(program, "textureImage_Packing"); glProgramUniform1i(program, texPacking, CLR_TEXTURE_UNIT + 1); GLint texPages = glGetUniformLocation(program, "textureImage_Pages"); glProgramUniform1i(program, texPages, CLR_TEXTURE_UNIT + 2); } // displacement ptex if (effectRegistry.getPtexDisplacementValid()) { GLint texData = glGetUniformLocation(program, "textureDisplace_Data"); glProgramUniform1i(program, texData, DISP_TEXTURE_UNIT + 0); GLint texPacking = glGetUniformLocation(program, "textureDisplace_Packing"); glProgramUniform1i(program, texPacking, DISP_TEXTURE_UNIT + 1); GLint texPages = glGetUniformLocation(program, "textureDisplace_Pages"); glProgramUniform1i(program, texPages, DISP_TEXTURE_UNIT + 2); } // occlusion ptex if (effectRegistry.getPtexOcclusionValid()) { GLint texData = glGetUniformLocation(program, "textureOcclusion_Data"); glProgramUniform1i(program, texData, OCC_TEXTURE_UNIT + 0); GLint texPacking = glGetUniformLocation(program, "textureOcclusion_Packing"); glProgramUniform1i(program, texPacking, OCC_TEXTURE_UNIT + 1); GLint texPages = glGetUniformLocation(program, "textureOcclusion_Pages"); glProgramUniform1i(program, texPages, OCC_TEXTURE_UNIT + 2); } // diffuse environment map if (effectRegistry.getDiffuseEnvironmentId() != 0) { GLint difmap = glGetUniformLocation(program, "diffuseEnvironmentMap"); glProgramUniform1i(program, difmap, DIFF_TEXTURE_UNIT); } // specular environment map if (effectRegistry.getSpecularEnvironmentId() != 0) { GLint envmap = glGetUniformLocation(program, "specularEnvironmentMap"); glProgramUniform1i(program, envmap, ENV_TEXTURE_UNIT); } glActiveTexture(GL_TEXTURE0); CHECK_GL_ERROR("bindProgram leave\n"); return program; }
void OpenSubdivDrawOverride::draw(const MHWRender::MDrawContext& context, const MUserData* data) { // get cached data bool isSelected = false; SubdivUserData* mesh = const_cast<SubdivUserData*>(dynamic_cast<const SubdivUserData*>(data)); if (mesh) { isSelected = mesh->fIsSelected; } // set colour static const float colorData[] = {1.0f, 0.0f, 0.0f}; static const float selectedColorData[] = {0.0f, 1.0f, 0.0f}; if(isSelected) glColor3fv(selectedColorData); else glColor3fv(colorData); MStatus status; // set world matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); MMatrix transform = context.getMatrix(MHWRender::MDrawContext::kWorldViewMtx, &status); if (status) { glLoadMatrixd(transform.matrix[0]); } // set projection matrix glMatrixMode(GL_PROJECTION); glPushMatrix(); MMatrix projection = context.getMatrix(MHWRender::MDrawContext::kProjectionMtx, &status); if (status) { glLoadMatrixd(projection.matrix[0]); } const int displayStyle = context.getDisplayStyle(); glPushAttrib( GL_CURRENT_BIT ); glPushAttrib( GL_ENABLE_BIT); if(displayStyle & MHWRender::MDrawContext::kGouraudShaded) { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); }else if(displayStyle & MHWRender::MDrawContext::kWireFrame){ glDisable(GL_LIGHTING); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } { int vertexStride = mesh->GetVertexStride(); // int varyingStride = mesh->GetVaryingStride(); //printf("Draw. stride = %d\n", stride); glBindBuffer(GL_ARRAY_BUFFER, mesh->GetVertexBuffer()); glVertexPointer(3, GL_FLOAT, vertexStride, ((char*)(0))); glEnableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, mesh->GetVertexBuffer()); glNormalPointer(GL_FLOAT, vertexStride, ((char*)(12))); // glBindBuffer(GL_ARRAY_BUFFER, mesh->GetVaryingBuffer()); // glNormalPointer(GL_FLOAT, varyingStride, ((char*)(0))); glEnableClientState(GL_NORMAL_ARRAY); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->GetElementBuffer()); glDrawElements(mesh->GetPrimType(), mesh->GetNumIndices(), GL_UNSIGNED_INT, NULL); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } glPopAttrib(); glPopAttrib(); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glColor3f(1, 1, 1); }
/* From the draw context, get the list of lights and queue the ones we are interested in into the "desired list" */ MStatus shadowPrepass::execute( const MHWRender::MDrawContext & context ) { MHWRender::MRenderer* theRenderer = MHWRender::MRenderer::theRenderer(); if (!theRenderer) return MStatus::kSuccess; // Skip lighting modes where there are no lights which can // cast shadows MHWRender::MDrawContext::LightingMode lightingMode = context.getLightingMode(); if (lightingMode != MHWRender::MDrawContext::kSelectedLights && lightingMode != MHWRender::MDrawContext::kSceneLights) { return MStatus::kSuccess; } MHWRender::MDrawContext::LightFilter lightFilter = MHWRender::MDrawContext::kFilteredIgnoreLightLimit; unsigned int nbSceneLights = context.numberOfActiveLights(lightFilter); for (unsigned int i=0; i<nbSceneLights; i++) { MHWRender::MLightParameterInformation* lightInfo = context.getLightParameterInformation( i, lightFilter ); if (!lightInfo) continue; // Get the actually Maya light node MStatus status = MStatus::kFailure; MDagPath lightPath = lightInfo->lightPath(&status); if (status != MStatus::kSuccess || !lightPath.isValid()) continue; // Would be good to have an API method here to indicate if it // casts shadows MIntArray intVals; // Check if light is enabled, and emits any lighting MHWRender::MLightParameterInformation::StockParameterSemantic semantic = MHWRender::MLightParameterInformation::kLightEnabled; if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals )) { if (intVals.length()) { if (intVals[0] == 0) continue; } } semantic = MHWRender::MLightParameterInformation::kEmitsDiffuse; if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals )) { if (intVals.length()) { if (intVals[0] == 0) continue; } } semantic = MHWRender::MLightParameterInformation::kEmitsSpecular; if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals )) { if (intVals.length()) { if (intVals[0] == 0) continue; } } // Check if local shadows are enabled. semantic = MHWRender::MLightParameterInformation::kShadowOn; if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals )) { if (intVals.length()) { if (intVals[0] == 0) continue; } } // Check if the shadow is "dirty" bool shadowIsDirty = false; semantic = MHWRender::MLightParameterInformation::kShadowDirty; if (MStatus::kSuccess == lightInfo->getParameter( semantic, intVals )) { if (intVals.length()) { if (intVals[0] == 0) // continue; shadowIsDirty = intVals[0] != 0 ? true : false ; } } // Check the light list to prune, if not already pruned bool prune = false; if (lightingMode != MHWRender::MDrawContext::kSelectedLights) { if (mLightList && mLightList->length()) { prune = !mLightList->hasItem(lightInfo->lightPath()); } } static bool debugShadowRequests = false; // Set that we require shadows for this light if (!prune) { if (debugShadowRequests) fprintf(stderr, "QUEUE light shadows for %s, shadowDirty = %d\n", lightPath.fullPathName().asChar(), shadowIsDirty); theRenderer->setLightRequiresShadows( lightPath.node(), true ); } // Set that we DON'T require shadows for this light else { if (debugShadowRequests) fprintf(stderr, "DEQUEUE light shadows for %s, shadowDirty = %d\n", lightPath.fullPathName().asChar(), shadowIsDirty); theRenderer->setLightRequiresShadows( lightPath.node(), false ); } } return MStatus::kSuccess; }
/* 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; }
// // #### Override draw method. // // Setup draw state and call osdMeshData methods to setup // and refine geometry. Call to shader to do actual drawing. // bool OpenSubdivShaderOverride::draw( MHWRender::MDrawContext &context, const MHWRender::MRenderItemList &renderItemList) const { { MHWRender::MStateManager *stateMgr = context.getStateManager(); static const MDepthStencilState * depthState = NULL; if (!depthState) { MDepthStencilStateDesc desc; depthState = stateMgr->acquireDepthStencilState(desc); } static const MBlendState *blendState = NULL; if (!blendState) { MBlendStateDesc desc; int ntargets = desc.independentBlendEnable ? MHWRender::MBlendState::kMaxTargets : 1; for (int i = 0; i < ntargets; ++i) { desc.targetBlends[i].blendEnable = false; } blendState = stateMgr->acquireBlendState(desc); } stateMgr->setDepthStencilState(depthState); stateMgr->setBlendState(blendState); } for (int i = 0; i < renderItemList.length(); i++) { const MHWRender::MRenderItem *renderItem = renderItemList.itemAt(i); OsdMeshData *data = static_cast<OsdMeshData*>(renderItem->customData()); if (data == NULL) { return false; } // If attributes or topology have changed which affect // the HBR mesh it will be regenerated here. data->rebuildHbrMeshIfNeeded(_shader); const MHWRender::MVertexBuffer *position = NULL; { const MHWRender::MGeometry *geometry = renderItem->geometry(); for (int i = 0; i < geometry->vertexBufferCount(); i++) { const MHWRender::MVertexBuffer *vb = geometry->vertexBuffer(i); const MHWRender::MVertexBufferDescriptor &vdesc = vb->descriptor(); if (vdesc.name() == "osdPosition") position = vb; } } // If HBR mesh was regenerated, rebuild FAR mesh factory // and recreate OSD draw context data->prepare(); // Refine geometry data->updateGeometry(position); // Draw patches _shader->draw(context, data); } return true; }
bool OpenSubdivShaderOverride::draw(MHWRender::MDrawContext &context, const MHWRender::MRenderItemList &renderItemList) const { using namespace MHWRender; { MHWRender::MStateManager *stateMgr = context.getStateManager(); static const MDepthStencilState * depthState = NULL; if (!depthState) { MDepthStencilStateDesc desc; depthState = stateMgr->acquireDepthStencilState(desc); } static const MBlendState *blendState = NULL; if (!blendState) { MBlendStateDesc desc; for(int i = 0; i < (desc.independentBlendEnable ? MHWRender::MBlendState::kMaxTargets : 1); ++i) { desc.targetBlends[i].blendEnable = false; } blendState = stateMgr->acquireBlendState(desc); } stateMgr->setDepthStencilState(depthState); stateMgr->setBlendState(blendState); } for(int i=0; i< renderItemList.length(); i++){ const MHWRender::MRenderItem *renderItem = renderItemList.itemAt(i); OsdMeshData *data = (OsdMeshData*)(renderItem->customData()); if (data == NULL) { return false; } data->populateIfNeeded(_shader->getLevel(), _shader->getScheme(), _shader->getKernel()); const MHWRender::MVertexBuffer *position = NULL, *normal = NULL; { const MHWRender::MGeometry *geometry = renderItem->geometry(); for(int i = 0; i < geometry->vertexBufferCount(); i++){ const MHWRender::MVertexBuffer *vb = geometry->vertexBuffer(i); const MHWRender::MVertexBufferDescriptor &vdesc = vb->descriptor(); if (vdesc.name() == "osdPosition") position = vb; if (vdesc.name() == "osdNormal") normal = vb; } } float diffuse[4] = {1, 1, 1, 1}; float ambient[4] = {0.1f, 0.1f, 0.1f, 0.1f}; float specular[4] = {1, 1, 1, 1}; glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_SPECULAR, specular); glPushAttrib(GL_POLYGON_BIT); glPushAttrib(GL_ENABLE_BIT); if (_shader->isWireframe()) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } // draw meshdata data->prepare(); data->updateGeometry(position, normal); data->draw(); glPopAttrib(); glPopAttrib(); } return true; }
// #### bindProgram // // Do all the work to build and install shader including // set up buffer blocks for uniform variables, set up // default lighting parameters, pass material uniforms // and bind texture buffers used by texture maps and by // OpenSubdiv's built-in shading code. // GLuint OpenSubdivShader::bindProgram(const MHWRender::MDrawContext & mDrawContext, OpenSubdiv::OsdGLDrawContext *osdDrawContext, const OpenSubdiv::OsdDrawContext::PatchArray & patch) { CHECK_GL_ERROR("bindProgram begin\n"); // Primitives are triangles for Loop subdivision, quads otherwise Effect effect = kFill; EffectDesc effectDesc( patch.GetDescriptor(), effect ); // Build shader EffectDrawRegistry::ConfigType * config = g_effectRegistry.GetDrawConfig(effectDesc); // Install shader GLuint program = config->program; glUseProgram(program); // Update and bind transform state struct Transform { float ModelViewMatrix[16]; float ProjectionMatrix[16]; float ModelViewProjectionMatrix[16]; } transformData; setMatrix(mDrawContext.getMatrix(MHWRender::MDrawContext::kWorldViewMtx), transformData.ModelViewMatrix); setMatrix(mDrawContext.getMatrix(MHWRender::MDrawContext::kProjectionMtx), transformData.ProjectionMatrix); setMatrix(mDrawContext.getMatrix(MHWRender::MDrawContext::kWorldViewProjMtx), transformData.ModelViewProjectionMatrix); if (!g_transformUB) { glGenBuffers(1, &g_transformUB); glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(transformData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(transformData), &transformData); glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBufferBase(GL_UNIFORM_BUFFER, g_transformBinding, g_transformUB); // Update and bind tessellation state struct Tessellation { float TessLevel; } tessellationData; tessellationData.TessLevel = static_cast<float>(1 << _tessFactor); if (!g_tessellationUB) { glGenBuffers(1, &g_tessellationUB); glBindBuffer(GL_UNIFORM_BUFFER, g_tessellationUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(tessellationData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_tessellationUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(tessellationData), &tessellationData); glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBufferBase(GL_UNIFORM_BUFFER, g_tessellationBinding, g_tessellationUB); // Update and bind lighting state int numLights = mDrawContext.numberOfActiveLights(); struct Lighting { struct Light { float position[4]; float diffuse[4]; float ambient[4]; float specular[4]; } lightSource[2]; } lightingData; memset(&lightingData, 0, sizeof(lightingData)); for (int i = 0; i < numLights && i < 2; ++i) { MFloatPointArray positions; MFloatVector direction; float intensity; MColor color; bool hasDirection, hasPosition; mDrawContext.getLightInformation(i, positions, direction, intensity, color, hasDirection, hasPosition); MMatrix modelView = mDrawContext.getMatrix(MHWRender::MDrawContext::kWorldViewMtx); direction = MVector(direction) * modelView; Lighting::Light &light = lightingData.lightSource[i]; if (hasDirection) { light.position[0] = -direction[0]; light.position[1] = -direction[1]; light.position[2] = -direction[2]; for (int j = 0; j < 4; ++j) { light.diffuse[j] = color[j] * intensity; light.ambient[j] = color[j] * intensity; light.specular[j] = color[j] * intensity; } } } if (!g_lightingUB) { glGenBuffers(1, &g_lightingUB); glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(lightingData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(lightingData), &lightingData); glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBufferBase(GL_UNIFORM_BUFFER, g_lightingBinding, g_lightingUB); // Update other uniforms float color[4] = { 0, 0, 0, 1 }; _diffuse.get(color); glProgramUniform4fv(program, glGetUniformLocation(program, "diffuseColor"), 1, color); _ambient.get(color); glProgramUniform4fv(program, glGetUniformLocation(program, "ambientColor"), 1, color); _specular.get(color); glProgramUniform4fv(program, glGetUniformLocation(program, "specularColor"), 1, color); glProgramUniform1f(program, glGetUniformLocation(program, "shininess"), _shininess); // Bind diffuse map if (g_effectRegistry.getDiffuseId()!=0) { GLint difmap = glGetUniformLocation(program, "diffuseMap"); glProgramUniform1i(program, difmap, DIFF_TEXTURE_UNIT); } // Bind all texture buffers // OpenSubdiv's geometric shading code depends on additional // GL texture buffers. These are managed by the DrawContext // and must be bound for use by the program in addition to // any buffers used by the client/application shading code. if (osdDrawContext->GetVertexTextureBuffer()) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_BUFFER, osdDrawContext->GetVertexTextureBuffer()); } if (osdDrawContext->GetVertexValenceTextureBuffer()) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_BUFFER, osdDrawContext->GetVertexValenceTextureBuffer()); } if (osdDrawContext->GetQuadOffsetsTextureBuffer()) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_BUFFER, osdDrawContext->GetQuadOffsetsTextureBuffer()); } if (osdDrawContext->GetPatchParamTextureBuffer()) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_BUFFER, osdDrawContext->GetPatchParamTextureBuffer()); } if (osdDrawContext->GetFvarDataTextureBuffer()) { glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_BUFFER, osdDrawContext->GetFvarDataTextureBuffer() ); } glActiveTexture(GL_TEXTURE0); CHECK_GL_ERROR("bindProgram leave\n"); return program; }
bool OpenSubdivPtexShaderOverride::draw( MHWRender::MDrawContext &context, const MHWRender::MRenderItemList &renderItemList) const { { MHWRender::MStateManager *stateMgr = context.getStateManager(); static const MDepthStencilState * depthState = NULL; if (!depthState) { MDepthStencilStateDesc desc; depthState = stateMgr->acquireDepthStencilState(desc); } static const MBlendState *blendState = NULL; if (!blendState) { MBlendStateDesc desc; int ntargets = desc.independentBlendEnable ? MHWRender::MBlendState::kMaxTargets : 1; for (int i = 0; i < ntargets; ++i) { desc.targetBlends[i].blendEnable = false; } blendState = stateMgr->acquireBlendState(desc); } stateMgr->setDepthStencilState(depthState); stateMgr->setBlendState(blendState); } for (int i = 0; i < renderItemList.length(); i++) { const MHWRender::MRenderItem *renderItem = renderItemList.itemAt(i); OsdPtexMeshData *data = static_cast<OsdPtexMeshData*>(renderItem->customData()); if (data == NULL) { return false; } // pass attribute values into osdPtexMeshData data->rebuildHbrMeshIfNeeded(_shader); const MHWRender::MVertexBuffer *position = NULL, *normal = NULL; { const MHWRender::MGeometry *geometry = renderItem->geometry(); for (int i = 0; i < geometry->vertexBufferCount(); i++) { const MHWRender::MVertexBuffer *vb = geometry->vertexBuffer(i); const MHWRender::MVertexBufferDescriptor &vdesc = vb->descriptor(); if (vdesc.name() == "osdPosition") position = vb; else if (vdesc.name() == "osdNormal") normal = vb; } } // draw meshdata data->prepare(); data->updateGeometry(position, normal); _shader->draw(context, data); } return true; }
PXR_NAMESPACE_OPEN_SCOPE /* static */ bool px_vp20Utils::setupLightingGL(const MHWRender::MDrawContext& context) { MStatus status; // Take into account only the 8 lights supported by the basic // OpenGL profile. const unsigned int nbLights = std::min(context.numberOfActiveLights(&status), 8u); if (status != MStatus::kSuccess) return false; if (nbLights > 0) { // Lights are specified in world space and needs to be // converted to view space. glMatrixMode(GL_MODELVIEW); glPushMatrix(); const MMatrix worldToView = context.getMatrix(MHWRender::MDrawContext::kViewMtx, &status); if (status != MStatus::kSuccess) return false; glLoadMatrixd(worldToView.matrix[0]); glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL) ; glEnable(GL_NORMALIZE) ; { const GLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat specular[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); } for (unsigned int i=0; i<nbLights; ++i) { MFloatVector direction; float intensity; MColor color; bool hasDirection; bool hasPosition; #if MAYA_API_VERSION >= 201300 // Starting with Maya 2013, getLightInformation() uses MFloatPointArray for positions MFloatPointArray positions; status = context.getLightInformation( i, positions, direction, intensity, color, hasDirection, hasPosition); const MFloatPoint &position = positions[0]; #else // Maya 2012, getLightInformation() uses MFloatPoint for position MFloatPoint position; status = context.getLightInformation( i, position, direction, intensity, color, hasDirection, hasPosition); #endif if (status != MStatus::kSuccess) return false; if (hasDirection) { if (hasPosition) { // Assumes a Maya Spot Light! const GLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat diffuse[4] = { intensity * color[0], intensity * color[1], intensity * color[2], 1.0f }; const GLfloat pos[4] = { position[0], position[1], position[2], 1.0f }; const GLfloat dir[3] = { direction[0], direction[1], direction[2]}; glLightfv(GL_LIGHT0+i, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0+i, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0+i, GL_POSITION, pos); glLightfv(GL_LIGHT0+i, GL_SPOT_DIRECTION, dir); // Maya's default value's for spot lights. glLightf(GL_LIGHT0+i, GL_SPOT_EXPONENT, 0.0); glLightf(GL_LIGHT0+i, GL_SPOT_CUTOFF, 20.0); } else { // Assumes a Maya Directional Light! const GLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat diffuse[4] = { intensity * color[0], intensity * color[1], intensity * color[2], 1.0f }; const GLfloat pos[4] = { -direction[0], -direction[1], -direction[2], 0.0f }; glLightfv(GL_LIGHT0+i, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0+i, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0+i, GL_POSITION, pos); glLightf(GL_LIGHT0+i, GL_SPOT_CUTOFF, 180.0); } } else if (hasPosition) { // Assumes a Maya Point Light! const GLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat diffuse[4] = { intensity * color[0], intensity * color[1], intensity * color[2], 1.0f }; const GLfloat pos[4] = { position[0], position[1], position[2], 1.0f }; glLightfv(GL_LIGHT0+i, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0+i, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0+i, GL_POSITION, pos); glLightf(GL_LIGHT0+i, GL_SPOT_CUTOFF, 180.0); } else { // Assumes a Maya Ambient Light! const GLfloat ambient[4] = { intensity * color[0], intensity * color[1], intensity * color[2], 1.0f }; const GLfloat diffuse[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; const GLfloat pos[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; glLightfv(GL_LIGHT0+i, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0+i, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0+i, GL_POSITION, pos); glLightf(GL_LIGHT0+i, GL_SPOT_CUTOFF, 180.0); } glEnable(GL_LIGHT0+i); } glPopMatrix(); } glDisable(GL_LIGHTING); return nbLights > 0; }
/* static */ GlfSimpleLightingContextRefPtr px_vp20Utils::GetLightingContextFromDrawContext( const MHWRender::MDrawContext& context) { const GfVec4f blackColor(0.0f, 0.0f, 0.0f, 1.0f); const GfVec4f whiteColor(1.0f, 1.0f, 1.0f, 1.0f); GlfSimpleLightingContextRefPtr lightingContext = GlfSimpleLightingContext::New(); MStatus status; unsigned int numMayaLights = context.numberOfActiveLights(MHWRender::MDrawContext::kFilteredToLightLimit, &status); if (status != MS::kSuccess || numMayaLights < 1) { return lightingContext; } bool viewDirectionAlongNegZ = context.viewDirectionAlongNegZ(&status); if (status != MS::kSuccess) { // If we fail to find out the view direction for some reason, assume // that it's along the negative Z axis (OpenGL). viewDirectionAlongNegZ = true; } GlfSimpleLightVector lights; for (unsigned int i = 0; i < numMayaLights; ++i) { MHWRender::MLightParameterInformation* mayaLightParamInfo = context.getLightParameterInformation(i); if (!mayaLightParamInfo) { continue; } // Setup some default values before we read the light parameters. bool lightEnabled = true; bool lightHasPosition = false; GfVec4f lightPosition(0.0f, 0.0f, 0.0f, 1.0f); bool lightHasDirection = false; GfVec3f lightDirection(0.0f, 0.0f, -1.0f); if (!viewDirectionAlongNegZ) { // The convention for DirectX is positive Z. lightDirection[2] = 1.0f; } float lightIntensity = 1.0f; GfVec4f lightColor = blackColor; bool lightEmitsDiffuse = true; bool lightEmitsSpecular = false; float lightDecayRate = 0.0f; float lightDropoff = 0.0f; // The cone angle is 180 degrees by default. GfVec2f lightCosineConeAngle(-1.0f); float lightShadowBias = 0.0f; bool lightShadowOn = false; bool globalShadowOn = false; MStringArray paramNames; mayaLightParamInfo->parameterList(paramNames); for (unsigned int paramIndex = 0; paramIndex < paramNames.length(); ++paramIndex) { const MString paramName = paramNames[paramIndex]; const MHWRender::MLightParameterInformation::ParameterType paramType = mayaLightParamInfo->parameterType(paramName); const MHWRender::MLightParameterInformation::StockParameterSemantic paramSemantic = mayaLightParamInfo->parameterSemantic(paramName); MIntArray intValues; MFloatArray floatValues; switch (paramType) { case MHWRender::MLightParameterInformation::kBoolean: case MHWRender::MLightParameterInformation::kInteger: mayaLightParamInfo->getParameter(paramName, intValues); break; case MHWRender::MLightParameterInformation::kFloat: case MHWRender::MLightParameterInformation::kFloat2: case MHWRender::MLightParameterInformation::kFloat3: case MHWRender::MLightParameterInformation::kFloat4: mayaLightParamInfo->getParameter(paramName, floatValues); break; default: // Unsupported paramType. continue; break; } switch (paramSemantic) { case MHWRender::MLightParameterInformation::kLightEnabled: _GetLightingParam(intValues, floatValues, lightEnabled); break; case MHWRender::MLightParameterInformation::kWorldPosition: if (_GetLightingParam(intValues, floatValues, lightPosition)) { lightHasPosition = true; } break; case MHWRender::MLightParameterInformation::kWorldDirection: if (_GetLightingParam(intValues, floatValues, lightDirection)) { lightHasDirection = true; } break; case MHWRender::MLightParameterInformation::kIntensity: _GetLightingParam(intValues, floatValues, lightIntensity); break; case MHWRender::MLightParameterInformation::kColor: _GetLightingParam(intValues, floatValues, lightColor); break; case MHWRender::MLightParameterInformation::kEmitsDiffuse: _GetLightingParam(intValues, floatValues, lightEmitsDiffuse); break; case MHWRender::MLightParameterInformation::kEmitsSpecular: _GetLightingParam(intValues, floatValues, lightEmitsSpecular); break; case MHWRender::MLightParameterInformation::kDecayRate: _GetLightingParam(intValues, floatValues, lightDecayRate); break; case MHWRender::MLightParameterInformation::kDropoff: _GetLightingParam(intValues, floatValues, lightDropoff); break; case MHWRender::MLightParameterInformation::kCosConeAngle: _GetLightingParam(intValues, floatValues, lightCosineConeAngle); break; case MHWRender::MLightParameterInformation::kShadowBias: _GetLightingParam(intValues, floatValues, lightShadowBias); break; case MHWRender::MLightParameterInformation::kShadowOn: _GetLightingParam(intValues, floatValues, lightShadowOn); break; case MHWRender::MLightParameterInformation::kGlobalShadowOn: _GetLightingParam(intValues, floatValues, globalShadowOn); break; default: // Unsupported paramSemantic. continue; break; } if (!lightEnabled) { // Stop reading light parameters if the light is disabled. break; } } if (!lightEnabled) { // Skip to the next light if this light is disabled. continue; } lightColor[0] *= lightIntensity; lightColor[1] *= lightIntensity; lightColor[2] *= lightIntensity; // Populate a GlfSimpleLight from the light information from Maya. GlfSimpleLight light; GfVec4f lightAmbient = blackColor; GfVec4f lightDiffuse = blackColor; GfVec4f lightSpecular = blackColor; // We receive the cone angle from Maya as a pair of floats which // includes the penumbra, but GlfSimpleLights don't currently support // that, so we only use the primary cone angle value. float lightCutoff = GfRadiansToDegrees(std::acos(lightCosineConeAngle[0])); float lightFalloff = lightDropoff; // decayRate is actually an enum in Maya that we receive as a float: // - 0.0 = no attenuation // - 1.0 = linear attenuation // - 2.0 = quadratic attenuation // - 3.0 = cubic attenuation (not supported by GlfSimpleLight) GfVec3f lightAttenuation(0.0f); if (lightDecayRate > 1.5) { // Quadratic attenuation. lightAttenuation[2] = 1.0f; } else if (lightDecayRate > 0.5f) { // Linear attenuation. lightAttenuation[1] = 1.0f; } else { // No/constant attenuation. lightAttenuation[0] = 1.0f; } if (lightHasDirection && !lightHasPosition) { // This is a directional light. Set the direction as its position. lightPosition[0] = -lightDirection[0]; lightPosition[1] = -lightDirection[1]; lightPosition[2] = -lightDirection[2]; lightPosition[3] = 0.0f; // Revert direction to the default value. lightDirection = GfVec3f(0.0f, 0.0f, -1.0f); if (!viewDirectionAlongNegZ) { lightDirection[2] = 1.0f; } } if (!lightHasPosition && !lightHasDirection) { // This is an ambient light. lightAmbient = lightColor; } else { if (lightEmitsDiffuse) { lightDiffuse = lightColor; } if (lightEmitsSpecular) { // XXX: It seems that the specular color cannot be specified // separately from the diffuse color on Maya lights. lightSpecular = lightColor; } } light.SetAmbient(lightAmbient); light.SetDiffuse(lightDiffuse); light.SetSpecular(lightSpecular); light.SetPosition(lightPosition); light.SetSpotDirection(lightDirection); light.SetSpotCutoff(lightCutoff); light.SetSpotFalloff(lightFalloff); light.SetAttenuation(lightAttenuation); light.SetShadowBias(lightShadowBias); light.SetHasShadow(lightShadowOn && globalShadowOn); lights.push_back(light); } lightingContext->SetLights(lights); // XXX: These material settings match what we used to get when we read the // material from OpenGL. This should probably eventually be something more // sophisticated. GlfSimpleMaterial material; material.SetAmbient(whiteColor); material.SetDiffuse(whiteColor); material.SetSpecular(blackColor); material.SetEmission(blackColor); material.SetShininess(0.0001f); lightingContext->SetMaterial(material); lightingContext->SetSceneAmbient(blackColor); return lightingContext; }
/* static */ void px_vp20Utils::unsetLightingGL(const MHWRender::MDrawContext& context) { MStatus status; // Take into account only the 8 lights supported by the basic // OpenGL profile. const unsigned int nbLights = std::min(context.numberOfActiveLights(&status), 8u); if (status != MStatus::kSuccess) return; // Restore OpenGL default values for anything that we have // modified. if (nbLights > 0) { for (unsigned int i=0; i<nbLights; ++i) { glDisable(GL_LIGHT0+i); const GLfloat ambient[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; glLightfv(GL_LIGHT0+i, GL_AMBIENT, ambient); if (i==0) { const GLfloat diffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; glLightfv(GL_LIGHT0+i, GL_DIFFUSE, diffuse); const GLfloat spec[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; glLightfv(GL_LIGHT0+i, GL_SPECULAR, spec); } else { const GLfloat diffuse[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; glLightfv(GL_LIGHT0+i, GL_DIFFUSE, diffuse); const GLfloat spec[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; glLightfv(GL_LIGHT0+i, GL_SPECULAR, spec); } const GLfloat pos[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; glLightfv(GL_LIGHT0+i, GL_POSITION, pos); const GLfloat dir[3] = { 0.0f, 0.0f, -1.0f }; glLightfv(GL_LIGHT0+i, GL_SPOT_DIRECTION, dir); glLightf(GL_LIGHT0+i, GL_SPOT_EXPONENT, 0.0); glLightf(GL_LIGHT0+i, GL_SPOT_CUTOFF, 180.0); } glDisable(GL_LIGHTING); glDisable(GL_COLOR_MATERIAL) ; glDisable(GL_NORMALIZE) ; const GLfloat ambient[4] = { 0.2f, 0.2f, 0.2f, 1.0f }; const GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f }; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); } }