HdTaskSharedPtrVector UsdMayaGLBatchRenderer::TaskDelegate::GetSetupTasks() { HdTaskSharedPtrVector tasks; // lighting tasks.push_back(GetRenderIndex().GetTask(_simpleLightTaskId)); return tasks; }
void My_TestGLDrawing:: DrawScene(PickParam const * pickParam) { int width = GetWidth(), height = GetHeight(); GfMatrix4d viewMatrix = GetViewMatrix(); GfFrustum frustum = GetFrustum(); GfVec4d viewport(0, 0, width, height); if (pickParam) { frustum = frustum.ComputeNarrowedFrustum( GfVec2d((2.0 * pickParam->location[0]) / width - 1.0, (2.0 * (height-pickParam->location[1])) / height - 1.0), GfVec2d(1.0 / width, 1.0 / height)); viewport = pickParam->viewport; } GfMatrix4d projMatrix = frustum.ComputeProjectionMatrix(); _delegate->SetCamera(viewMatrix, projMatrix); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); HdTaskSharedPtrVector tasks; SdfPath renderSetupTask("/renderSetupTask"); SdfPath renderTask("/renderTask"); tasks.push_back(_delegate->GetRenderIndex().GetTask(renderSetupTask)); tasks.push_back(_delegate->GetRenderIndex().GetTask(renderTask)); HdxRenderTaskParams param = _delegate->GetTaskParam( renderSetupTask, HdTokens->params).Get<HdxRenderTaskParams>(); param.enableIdRender = (pickParam != NULL); param.viewport = viewport; _delegate->SetTaskParam(renderSetupTask, HdTokens->params, VtValue(param)); glEnable(GL_DEPTH_TEST); glBindVertexArray(vao); _engine.Execute(_delegate->GetRenderIndex(), tasks); glBindVertexArray(0); }
void My_TestGLDrawing::DrawScene() { _Clear(); int width = GetWidth(), height = GetHeight(); GfMatrix4d viewMatrix = GetViewMatrix(); GfFrustum frustum = GetFrustum(); GfVec4d viewport(0, 0, width, height); GfMatrix4d projMatrix = frustum.ComputeProjectionMatrix(); _delegate->SetCamera(viewMatrix, projMatrix); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); SdfPath renderSetupTask("/renderSetupTask"); SdfPath renderTask("/renderTask"); SdfPath selectionTask("/selectionTask"); // viewport HdxRenderTaskParams param = _delegate->GetTaskParam( renderSetupTask, HdTokens->params).Get<HdxRenderTaskParams>(); param.viewport = viewport; _delegate->SetTaskParam(renderSetupTask, HdTokens->params, VtValue(param)); HdTaskSharedPtrVector tasks; tasks.push_back(_delegate->GetRenderIndex().GetTask(renderSetupTask)); tasks.push_back(_delegate->GetRenderIndex().GetTask(renderTask)); tasks.push_back(_delegate->GetRenderIndex().GetTask(selectionTask)); glEnable(GL_DEPTH_TEST); glBindVertexArray(vao); VtValue v(_picker.GetSelectionTracker()); _engine.SetTaskContextData(HdxTokens->selectionState, v); _engine.Execute(_delegate->GetRenderIndex(), tasks); glBindVertexArray(0); }
bool HdxIntersector::Query(HdxIntersector::Params const& params, HdRprimCollection const& col, HdEngine* engine, HdxIntersector::Result* result) { TRACE_FUNCTION(); // Make sure we're in a sane GL state before attempting anything. if (GlfHasLegacyGraphics()) { TF_RUNTIME_ERROR("framebuffer object not supported"); return false; } GlfGLContextSharedPtr context = GlfGLContext::GetCurrentGLContext(); if (!TF_VERIFY(context)) { TF_RUNTIME_ERROR("Invalid GL context"); return false; } if (!_drawTarget) { // Initialize the shared draw target late to ensure there is a valid GL // context, which may not be the case at constructon time. _Init(GfVec2i(128,128)); } GfVec2i size(_drawTarget->GetSize()); GfVec4i viewport(0, 0, size[0], size[1]); if (!TF_VERIFY(_renderPass)) { return false; } _renderPass->SetRprimCollection(col); // Setup state based on incoming params. _renderPassState->SetAlphaThreshold(params.alphaThreshold); _renderPassState->SetClipPlanes(params.clipPlanes); _renderPassState->SetCullStyle(params.cullStyle); _renderPassState->SetCamera(params.viewMatrix, params.projectionMatrix, viewport); _renderPassState->SetLightingEnabled(false); // Use a separate drawTarget (framebuffer object) for each GL context // that uses this renderer, but the drawTargets share attachments/textures. GlfDrawTargetRefPtr drawTarget = GlfDrawTarget::New(size); // Clone attachments into this context. Note that this will do a // light-weight copy of the textures, it does not produce a full copy of the // underlying images. drawTarget->Bind(); drawTarget->CloneAttachments(_drawTarget); // // Setup GL raster state // GLenum drawBuffers[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; glDrawBuffers(3, drawBuffers); glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL); glClearColor(0,0,0,0); glClearStencil(0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); GLF_POST_PENDING_GL_ERRORS(); // // Execute the picking pass // { GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Setup stencil state and prevent writes to color buffer. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_KEEP, // stencil failed GL_KEEP, // stencil passed, depth failed GL_REPLACE); // stencil passed, depth passed // // Condition the stencil buffer. // params.depthMaskCallback(); // we expect any GL state changes are restored. // Disable stencil updates and setup the stencil test. glStencilFunc(GL_LESS, 0, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // Clear depth incase the depthMaskCallback pollutes the depth buffer. glClear(GL_DEPTH_BUFFER_BIT); // Restore color outputs & setup state for rendering glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDisable(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glFrontFace(GL_CCW); // // Enable conservative rasterization, if available. // // XXX: This wont work until it's in the Glew build. bool convRstr = glewIsSupported("GL_NV_conservative_raster"); if (convRstr) { // XXX: this should come from Glew #define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 glEnable(GL_CONSERVATIVE_RASTERIZATION_NV); } // // Execute // // XXX: make intersector a Task HdTaskSharedPtrVector tasks; tasks.push_back(boost::make_shared<HdxIntersector_DrawTask>(_renderPass, _renderPassState, params.renderTags)); engine->Execute(*_index, tasks); glDisable(GL_STENCIL_TEST); if (convRstr) { // XXX: this should come from Glew #define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 glDisable(GL_CONSERVATIVE_RASTERIZATION_NV); } // Restore glBindVertexArray(0); glDeleteVertexArrays(1, &vao); } GLF_POST_PENDING_GL_ERRORS(); // // Capture the result buffers to be resolved later. // size_t len = size[0] * size[1]; std::unique_ptr<unsigned char[]> primId(new unsigned char[len*4]); std::unique_ptr<unsigned char[]> instanceId(new unsigned char[len*4]); std::unique_ptr<unsigned char[]> elementId(new unsigned char[len*4]); std::unique_ptr<float[]> depths(new float[len]); glBindTexture(GL_TEXTURE_2D, drawTarget->GetAttachments().at("primId")->GetGlTextureName()); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &primId[0]); glBindTexture(GL_TEXTURE_2D, drawTarget->GetAttachments().at("instanceId")->GetGlTextureName()); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &instanceId[0]); glBindTexture(GL_TEXTURE_2D, drawTarget->GetAttachments().at("elementId")->GetGlTextureName()); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &elementId[0]); glBindTexture(GL_TEXTURE_2D, drawTarget->GetAttachments().at("depth")->GetGlTextureName()); glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, &depths[0]); glBindTexture(GL_TEXTURE_2D, 0); GLF_POST_PENDING_GL_ERRORS(); if (result) { *result = HdxIntersector::Result( std::move(primId), std::move(instanceId), std::move(elementId), std::move(depths), _index, params, viewport); } drawTarget->Unbind(); GLF_POST_PENDING_GL_ERRORS(); return true; }
void UsdMayaGLBatchRenderer::_RenderBatches( const MHWRender::MDrawContext* vp2Context, const MMatrix& viewMat, const MMatrix& projectionMat, const GfVec4d& viewport ) { if( _renderQueue.empty() ) return; if( !_populateQueue.empty() ) { TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg( "____________ POPULATE STAGE START ______________ (%zu)\n",_populateQueue.size()); std::vector<UsdImagingDelegate*> delegates; UsdPrimVector rootPrims; std::vector<SdfPathVector> excludedPrimPaths; std::vector<SdfPathVector> invisedPrimPaths; for( ShapeRenderer *shapeRenderer : _populateQueue ) { delegates.push_back(shapeRenderer->_delegate.get()); rootPrims.push_back(shapeRenderer->_rootPrim); excludedPrimPaths.push_back(shapeRenderer->_excludedPaths); invisedPrimPaths.push_back(SdfPathVector()); shapeRenderer->_isPopulated = true; } UsdImagingDelegate::Populate( delegates, rootPrims, excludedPrimPaths, invisedPrimPaths ); _populateQueue.clear(); TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg( "^^^^^^^^^^^^ POPULATE STAGE FINISH ^^^^^^^^^^^^^ (%zu)\n",_populateQueue.size()); } TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg( "____________ RENDER STAGE START ______________ (%zu)\n",_renderQueue.size()); // A new display refresh signifies that the cached selection data is no // longer valid. _selectQueue.clear(); _selectResults.clear(); // We've already populated with all the selection info we need. We Reset // and the first call to GetSoftSelectHelper in the next render pass will // re-populate it. _softSelectHelper.Reset(); GfMatrix4d modelViewMatrix(viewMat.matrix); GfMatrix4d projectionMatrix(projectionMat.matrix); _taskDelegate->SetCameraState(modelViewMatrix, projectionMatrix, viewport); // save the current GL states which hydra may reset to default glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_VIEWPORT_BIT); // hydra orients all geometry during topological processing so that // front faces have ccw winding. We disable culling because culling // is handled by fragment shader discard. glFrontFace(GL_CCW); // < State is pushed via GL_POLYGON_BIT glDisable(GL_CULL_FACE); // note: to get benefit of alpha-to-coverage, the target framebuffer // has to be a MSAA buffer. glDisable(GL_BLEND); glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); if (vp2Context) { _taskDelegate->SetLightingStateFromMayaDrawContext(*vp2Context); } else { _taskDelegate->SetLightingStateFromVP1(viewMat); } // The legacy viewport does not support color management, // so we roll our own gamma correction by GL means (only in // non-highlight mode) bool gammaCorrect = !vp2Context; if( gammaCorrect ) glEnable(GL_FRAMEBUFFER_SRGB_EXT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // render task setup HdTaskSharedPtrVector tasks = _taskDelegate->GetSetupTasks(); // lighting etc for( const auto &renderSetIter : _renderQueue ) { size_t hash = renderSetIter.first; const RenderParams ¶ms = renderSetIter.second.first; const _SdfPathSet &renderPaths = renderSetIter.second.second; TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg( "*** renderQueue, batch %zx, size %zu\n", renderSetIter.first, renderPaths.size() ); SdfPathVector roots(renderPaths.begin(), renderPaths.end()); tasks.push_back(_taskDelegate->GetRenderTask(hash, params, roots)); } _hdEngine.Execute(*_renderIndex, tasks); if( gammaCorrect ) glDisable(GL_FRAMEBUFFER_SRGB_EXT); glPopAttrib(); // GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT // Selection is based on what we have last rendered to the display. The // selection queue is cleared above, so this has the effect of resetting // the render queue and prepping the selection queue without any // significant memory hit. _renderQueue.swap( _selectQueue ); TF_DEBUG(PXRUSDMAYAGL_QUEUE_INFO).Msg( "^^^^^^^^^^^^ RENDER STAGE FINISH ^^^^^^^^^^^^^ (%zu)\n",_renderQueue.size()); }