modify render

This commit is contained in:
jiegeaiai 2025-01-16 00:13:05 +08:00
parent 7effa0e8f4
commit c3bb7a8054
5 changed files with 116 additions and 17 deletions

View File

@ -46,6 +46,9 @@ public:
void UpdateWindowScale(float scale) {
windowScale_ = scale;
}
unsigned int GetFrameBufferId() const {
return frameBufferId_;
}
public:
void keyPressEvent(class QKeyEvent* event);

View File

@ -78,6 +78,15 @@ void OSGRenderer::Resize(osg::GraphicsContext* gc, int width, int height) {
window->resized(0, 0, width, height);
}
void OSGRenderer::Render() {
frame();
emit RenderFlush();
}
void OSGRenderer::Destoy() {
done();
}
bool OSGRenderer::event(QEvent* event) {
switch (event->type()) {
case INIT: {
@ -85,12 +94,20 @@ bool OSGRenderer::event(QEvent* event) {
Init(e->gc_.get());
return true;
}
case RENDER: {
Render();
return true;
}
case RESIZE: {
GraphicsWindowResizeEvent* e = reinterpret_cast<GraphicsWindowResizeEvent*>(event);
Resize(e->gc_.get(), e->width_, e->height_);
return true;
}
case DESTROY: {
GraphicsWindowResizeEvent* e = reinterpret_cast<GraphicsWindowResizeEvent*>(event);
Resize(e->gc_.get(), e->width_, e->height_);
return true;
}
}
return QObject::event(event);
}

View File

@ -25,9 +25,9 @@
namespace {
enum RenderEvent {
INIT = QEvent::Type(QEvent::User + 1),
RENDER_START,
RENDER,
RESIZE,
RENDER_STOP
DESTROY
};
struct RenderBindGraphicsContextEvent : public QEvent {
@ -62,9 +62,14 @@ public:
bool event(QEvent* event) override;
Q_SIGNALS:
void RenderFlush();
private:
void Init(osg::GraphicsContext* gc);
void Resize(osg::GraphicsContext* gc, int width, int height);
void Render();
void Destoy();
private:
bool isInited_{ false };

View File

@ -11,15 +11,47 @@
#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);
renderer_ = new OSGRenderer(this);
connect(renderer_, &OSGRenderer::RenderFlush, this, &OsgOpenGLWindow::OnRenderFlush);
}
OsgOpenGLWindow::~OsgOpenGLWindow()
@ -45,12 +77,36 @@ void OsgOpenGLWindow::initializeGL()
//emit initialized();
context()->doneCurrent();
gw_->SetSharedContext(context());
QApplication::postEvent(this, new RenderBindGraphicsContextEvent(gw_));
QApplication::postEvent(renderer_, new RenderBindGraphicsContextEvent(gw_));
double pixelRatio = screen()->devicePixelRatio();
gw_->UpdateWindowScale(pixelRatio);
QApplication::postEvent(this, new GraphicsWindowResizeEvent(gw_, width() * pixelRatio, height() * 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;
}
}
void OsgOpenGLWindow::resizeGL(int w, int h)
@ -58,17 +114,27 @@ void OsgOpenGLWindow::resizeGL(int w, int h)
Q_ASSERT(m_renderer);
double pixelRatio = screen()->devicePixelRatio();
gw_->UpdateWindowScale(pixelRatio);
QApplication::postEvent(this, new GraphicsWindowResizeEvent(gw_, w * pixelRatio, h * pixelRatio));
QApplication::postEvent(renderer_, new GraphicsWindowResizeEvent(gw_, w * pixelRatio, h * pixelRatio));
}
void OsgOpenGLWindow::paintGL()
{
OpenThreads::ScopedReadLock locker(_osgMutex);
if (_isFirstFrame) {
_isFirstFrame = false;
m_renderer->getCamera()->getGraphicsContext()->setDefaultFboId(defaultFramebufferObject());
}
m_renderer->frame();
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)
@ -136,3 +202,8 @@ void OsgOpenGLWindow::createRenderer()
double pixelRatio = screen()->devicePixelRatio();
m_renderer->setupOSG(width(), height(), pixelRatio);*/
}
void OsgOpenGLWindow::OnRenderFlush() {
shaderTextureId_ = gw_->GetFrameBufferId();
updateTexture_ = true;
}

View File

@ -63,9 +63,7 @@ protected:
void initializeGL() override;
void resizeGL(int w, int h) override;
//! lock scene graph and call osgViewer::frame()
void paintGL() override;
void paintUnderGL() override;
//! called before creating renderer
virtual void setDefaultDisplaySettings();
@ -80,12 +78,17 @@ protected:
void createRenderer();
private:
void OnRenderFlush();
private:
QWidget* widget_{ nullptr };
osg::ref_ptr<class GraphicsWindowEx> gw_;
OSGRenderer* renderer_{ nullptr };
class QOpenGLShaderProgram* shaderProgram_{nullptr};
class QOpenGLVertexArrayObject* vao_{ nullptr };
uint32_t shaderTextureId_{ 0 };
bool updateTexture_{ false };
};
#endif // OSGQOPENGLWINDOW_H