#include "viewer/OsgOpenGLWindow.h" #include "viewer/OSGRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "common/SpdLogger.h" #include "viewer/GraphicsWindowEx.h" static const char* vertexShaderSource = "#version 330\n" "out vec2 uv;\n" "void main(void)\n" "{\n" "vec2 pos[] = vec2[](vec2(-1.0, -1.0),\n" "vec2( 1.0, -1.0),\n" "vec2(-1.0, 1.0),\n" "vec2( 1.0, 1.0));\n" "vec2 uvpos[] = vec2[](vec2(0, 0.0),\n" "vec2( 1.0, 0.0),\n" "vec2(0.0, 1.0),\n" "vec2( 1.0, 1.0));\n" "gl_Position = vec4(pos[gl_VertexID], 0.0, 1.0);\n" "uv = uvpos[gl_VertexID];\n" "}\n"; static const char* fragmentShaderSource = "#version 330\n" "in vec2 uv;\n" "uniform sampler2D tex;\n" "out vec4 vFragColor;" "void main() {\n" " vFragColor = vec4(texture(tex, uv).rgb, 1.0);\n" "}\n"; OsgOpenGLWindow::OsgOpenGLWindow(QWidget* parent) : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, nullptr) { widget_ = QWidget::createWindowContainer(this); gw_ = new GraphicsWindowEx(0, 0, width(), height()); renderer_ = new OSGRenderer(this); connect(renderer_, &OSGRenderer::RenderFlush, this, &OsgOpenGLWindow::OnRenderFlush, Qt::QueuedConnection); connect(&timer_, &QTimer::timeout, this, &OsgOpenGLWindow::OnRender); } OsgOpenGLWindow::~OsgOpenGLWindow() {} osgViewer::Viewer* OsgOpenGLWindow::getOsgViewer() { return renderer_; } void OsgOpenGLWindow::initializeGL() { //// Initializes OpenGL function resolution for the current context. //initializeOpenGLFunctions(); //createRenderer(); //emit initialized(); QOpenGLContext* ctx = context(); dyt_check(nullptr != ctx); ctx->doneCurrent(); gw_->SetSharedContext(context()); QApplication::postEvent(renderer_, new RenderBindGraphicsContextEvent(gw_)); setDefaultDisplaySettings(); double pixelRatio = screen()->devicePixelRatio(); gw_->UpdateWindowScale(pixelRatio); QApplication::postEvent(renderer_, new GraphicsWindowResizeEvent(gw_, width() * pixelRatio, height() * pixelRatio)); QApplication::postEvent(renderer_, new QEvent(QEvent::Type(RENDER))); context()->makeCurrent(this); shaderProgram_ = new QOpenGLShaderProgram(this); vao_ = new QOpenGLVertexArrayObject(this); if (!vao_->create()) { LOG_ERROR("Failed to create VAO"); return; } if (!shaderProgram_->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource)) { LOG_ERROR("Failed to add vertex shader"); return; } if (!shaderProgram_->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource)) { LOG_ERROR("Failed to add fragment shader"); return; } if (!shaderProgram_->link()) { LOG_ERROR("Failed to link shader program, {}", shaderProgram_->log().toLocal8Bit().constData()); return; } timer_.start(1000 / 60); } void OsgOpenGLWindow::resizeGL(int w, int h) { double pixelRatio = screen()->devicePixelRatio(); gw_->UpdateWindowScale(pixelRatio); QApplication::postEvent(renderer_, new GraphicsWindowResizeEvent(gw_, w * pixelRatio, h * pixelRatio)); } void OsgOpenGLWindow::paintUnderGL() { if (0 == shaderTextureId_) { return; } QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); f->glViewport(0, 0, width() * devicePixelRatio(), height() * devicePixelRatio()); f->glBindTexture(GL_TEXTURE_2D, shaderTextureId_); dyt_check(nullptr != shaderProgram_); dyt_check(shaderProgram_->bind()); QOpenGLVertexArrayObject::Binder vaoBinder(vao_); f->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); shaderProgram_->release(); if (updateTexture_) { updateTexture_ = false; QApplication::postEvent(renderer_, new QEvent(QEvent::Type(RENDER))); } } void OsgOpenGLWindow::keyPressEvent(QKeyEvent* event) { Q_ASSERT(gw_); // forward event to renderer gw_->keyPressEvent(event); } void OsgOpenGLWindow::keyReleaseEvent(QKeyEvent* event) { Q_ASSERT(gw_); // forward event to renderer gw_->keyReleaseEvent(event); } void OsgOpenGLWindow::mousePressEvent(QMouseEvent* event) { Q_ASSERT(gw_); // forward event to renderer gw_->mousePressEvent(event); } void OsgOpenGLWindow::mouseReleaseEvent(QMouseEvent* event) { Q_ASSERT(gw_); // forward event to renderer gw_->mouseReleaseEvent(event); } void OsgOpenGLWindow::mouseDoubleClickEvent(QMouseEvent* event) { Q_ASSERT(gw_); // forward event to renderer gw_->mouseDoubleClickEvent(event); } void OsgOpenGLWindow::mouseMoveEvent(QMouseEvent* event) { Q_ASSERT(gw_); // forward event to renderer gw_->mouseMoveEvent(event); } void OsgOpenGLWindow::wheelEvent(QWheelEvent* event) { Q_ASSERT(gw_); // forward event to renderer gw_->wheelEvent(event); } void OsgOpenGLWindow::setDefaultDisplaySettings() { osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); ds->setNvOptimusEnablement(1); ds->setStereo(false); } void OsgOpenGLWindow::OnRenderFlush() { shaderTextureId_ = gw_->GetFrameBufferId(); updateTexture_ = true; } void OsgOpenGLWindow::OnRender() { requestUpdate(); }