Hi Robert,
I used a QOpenGLWindow to render with Hydra Storm in an OpenGL context using a draw target and saving it to the disk. Not sure this is super helpful for what you want to do though…
The magic with Hydra Storm is that if you have defined an OpenGL context and set it as the current context, it will find it and render in it.
So in theory you shouldn’t need the drawTarget I used, only setting the QT openGL context should be enough.
The pseudo code was this :
I was storing in the class :
QOpenGLContext *m_context = nullptr;
pxr::GlfGLContextSharedPtr mpOpenGLContext;
pxr::GlfDrawTargetRefPtr mDrawTarget;
Then in the cpp file :
void HydraOpenGLWindow::initializeGL()
{
QOpenGLWindow::initializeGL();
mGLInitialized = true;
InitializeHydra();
}
void HydraOpenGLWindow::InitializeHydra()
{
// prep draw target
if (nullptr == mDrawTarget){
GlfGLContextScopeHolder contextHolder(mpOpenGLContext);
mDrawTarget = GlfDrawTarget::New(GfVec2i(width(), height()));
mDrawTarget->Bind();
mDrawTarget->AddAttachment("color", GL_RGBA, GL_FLOAT, GL_RGBA);
mDrawTarget->AddAttachment("depth", GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT);
mDrawTarget->Unbind();
}
}
void HydraOpenGLWindow::renderNow()
{
if (!isExposed())
return;
bool needsInitialize = false;
if (!m_context) {
m_context = new QOpenGLContext(this);
QSurfaceFormat s = requestedFormat();
DebugSurfaceFormat(s);
m_context->setFormat(s);
m_context->create();
needsInitialize = true;
}
//GlfGLContextScopeHolder contextHolder(mpOpenGLContext);
m_context->makeCurrent(this);
if (needsInitialize) {
initializeOpenGLFunctions();
initialize();
auto logger = new QOpenGLDebugLogger(m_context);
logger->connect(logger, &QOpenGLDebugLogger::messageLogged,
[](const QOpenGLDebugMessage& message) { qInfo() << message; });
if (logger->initialize())
{
qInfo() << "OpenGL logger initialized";
logger->startLogging(QOpenGLDebugLogger::SynchronousLogging);
logger->enableMessages();
// Disable NVidia performance spam "APISource", 131185,
// "Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is "
// "GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.",
// "NotificationSeverity", "OtherType"
//logger->disableMessages(QVector<GLuint>{ 131185 });
}
else
{
qInfo() << "!!!OpenGL logger not initialized!!!";
}
}
render();
m_context->swapBuffers(this);
}
void HydraOpenGLWindow::render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
const int pixelRatio = devicePixelRatio();
m_device->setSize(size() * pixelRatio);
m_device->setDevicePixelRatio(pixelRatio);
glViewport(0, 0, width() * pixelRatio, height() * pixelRatio);
DrawTexture();
DrawTriangle();
renderHydra();
++m_frame;
}
void HydraOpenGLWindow::renderHydra()
{
//GlfGLContextScopeHolder contextHolder(mpOpenGLContext);
const int w = width();
const int h = height();
mDrawTarget->Bind();
mDrawTarget->SetSize(GfVec2i(w, h));
int viewportWidth = 0;
int viewportHeight = 0;
mpHydraViewportData->GetViewportSize(viewportWidth, viewportHeight);
DbgAssert(w == viewportWidth && h == viewportHeight);
mpHydraViewportData->HydraRender();
mDrawTarget->Unbind();
mDrawTarget->Resolve();
mDrawTarget->WriteToFile("color", "d:\\colorHydraOpenGL.png");
/*
I am not sure if this was working or not.
// Blit the resulting color buffer to the window
GLint restoreReadBuffer;
glGetIntegerv(GL_READ_BUFFER, &restoreReadBuffer);//Save values
GLint restoreDrawBuffer;
glGetIntegerv(GL_DRAW_BUFFER, &restoreDrawBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mDrawTarget->GetFramebufferId());
glBlitFramebuffer(0, 0, w, h,
0, 0, w, h,
GL_COLOR_BUFFER_BIT,
GL_NEAREST);
//Restore values
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, restoreDrawBuffer);
glBindFramebuffer(GL_READ_FRAMEBUFFER, restoreReadBuffer);
*/
}