/* virtual */ void Hdx_UnitTestWindow::OnPaintGL() { // // Update the draw target's size and execute the unit test with // the draw target bound. // _drawTarget->Bind(); _drawTarget->SetSize(GfVec2i(GetWidth(), GetHeight())); _unitTest->DrawTest(); _drawTarget->Unbind(); // // Blit the resulting color buffer to the window (this is a noop // if we're drawing offscreen). // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, _drawTarget->GetFramebufferId()); glBlitFramebuffer(0, 0, GetWidth(), GetHeight(), 0, 0, GetWidth(), GetHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); }
bool Hdx_UnitTestWindow::WriteToFile(std::string const & attachment, std::string const & filename) { _drawTarget->Unbind(); bool ret = _drawTarget->WriteToFile(attachment, filename); _drawTarget->Bind(); return ret; }
void Hdx_UnitTestWindow::OffscreenTest() { _drawTarget->Bind(); _drawTarget->SetSize(GfVec2i(GetWidth(), GetHeight())); _unitTest->OffscreenTest(); _drawTarget->Unbind(); }
/* virtual */ void Hdx_UnitTestWindow::OnInitializeGL() { GlfGlewInit(); GlfRegisterDefaultDebugOutputMessageCallback(); GlfContextCaps::InitInstance(); std::cout << glGetString(GL_VENDOR) << "\n"; std::cout << glGetString(GL_RENDERER) << "\n"; std::cout << glGetString(GL_VERSION) << "\n"; // // Create an offscreen draw target which is the same size as this // widget and initialize the unit test with the draw target bound. // _drawTarget = GlfDrawTarget::New(GfVec2i(GetWidth(), GetHeight())); _drawTarget->Bind(); _drawTarget->AddAttachment("color", GL_RGBA, GL_FLOAT, GL_RGBA); _drawTarget->AddAttachment("depth", GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8); _unitTest->InitTest(); _drawTarget->Unbind(); }
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; }
SdfPath My_TestGLDrawing::PickScene(int pickX, int pickY, int * outInstanceIndex, int * outElementIndex) { int width = 128; int height = 128; GlfDrawTargetRefPtr drawTarget = GlfDrawTarget::New(GfVec2i(width, height)); drawTarget->Bind(); drawTarget->AddAttachment( "primId", GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8); drawTarget->AddAttachment( "instanceId", GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8); drawTarget->AddAttachment( "elementId", GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8); drawTarget->AddAttachment( "depth", GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F); drawTarget->Unbind(); drawTarget->Bind(); GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; glDrawBuffers(3, drawBuffers); glEnable(GL_DEPTH_TEST); GLfloat clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; glClearBufferfv(GL_COLOR, 0, clearColor); glClearBufferfv(GL_COLOR, 1, clearColor); GLfloat clearDepth[1] = { 1.0f }; glClearBufferfv(GL_DEPTH, 0, clearDepth); PickParam pickParam; pickParam.location = GfVec2d(pickX, pickY); pickParam.viewport = GfVec4d(0, 0, width, height); DrawScene(&pickParam); drawTarget->Unbind(); GLubyte primId[width*height*4]; glBindTexture(GL_TEXTURE_2D, drawTarget->GetAttachments().at("primId")->GetGlTextureName()); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, primId); GLubyte instanceId[width*height*4]; glBindTexture(GL_TEXTURE_2D, drawTarget->GetAttachments().at("instanceId")->GetGlTextureName()); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, instanceId); GLubyte elementId[width*height*4]; glBindTexture(GL_TEXTURE_2D, drawTarget->GetAttachments().at("elementId")->GetGlTextureName()); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, elementId); GLfloat depths[width*height]; glBindTexture(GL_TEXTURE_2D, drawTarget->GetAttachments().at("depth")->GetGlTextureName()); glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, depths); double zMin = 1.0; int zMinIndex = -1; for (int y=0, i=0; y<height; y++) { for (int x=0; x<width; x++, i++) { if (depths[i] < zMin) { zMin = depths[i]; zMinIndex = i; } } } bool didHit = (zMin < 1.0); SdfPath result; if (didHit) { int idIndex = zMinIndex*4; result = _delegate->GetRenderIndex().GetRprimPathFromPrimId( HdxRenderSetupTask::DecodeIDRenderColor(&primId[idIndex])); if (outInstanceIndex) { *outInstanceIndex = HdxRenderSetupTask::DecodeIDRenderColor( &instanceId[idIndex]); } if (outElementIndex) { *outElementIndex = HdxRenderSetupTask::DecodeIDRenderColor( &elementId[idIndex]); } } return result; }