196 lines
5.6 KiB
C++
196 lines
5.6 KiB
C++
#include "viewer/OsgOpenGLWindow.h"
|
|
#include "viewer/OSGRenderer.h"
|
|
|
|
#include <osgViewer/Viewer>
|
|
#include <osg/GL>
|
|
|
|
#include <QApplication>
|
|
#include <QKeyEvent>
|
|
#include <QInputDialog>
|
|
#include <QLayout>
|
|
#include <QMainWindow>
|
|
#include <QScreen>
|
|
#include <QWindow>
|
|
#include <QOpenGLShaderProgram>
|
|
#include <QOpenGLVertexArrayObject>
|
|
|
|
#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);
|
|
widget_->setAttribute(Qt::WA_PaintOnScreen, true);
|
|
widget_->setAttribute(Qt::WA_StaticContents, true);
|
|
widget_->setAttribute(Qt::WA_NoSystemBackground, true);
|
|
widget_->setAttribute(Qt::WA_OpaquePaintEvent, true);
|
|
widget_->setAttribute(Qt::WA_DontCreateNativeAncestors, false);
|
|
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();
|
|
}
|