mirror of
https://github.com/leozide/leocad
synced 2025-01-18 22:26:44 +01:00
Create offscreen context at startup and reuse it.
This commit is contained in:
parent
6b2f8fa68c
commit
72763ddc11
9 changed files with 143 additions and 58 deletions
|
@ -772,6 +772,11 @@ lcStartupMode lcApplication::Initialize(QList<QPair<QString, bool>>& LibraryPath
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
if (!lcContext::CreateOffscreenContext())
|
||||
return lcStartupMode::Error;
|
||||
#endif
|
||||
|
||||
gMainWindow = new lcMainWindow();
|
||||
lcLoadDefaultKeyboardShortcuts();
|
||||
lcLoadDefaultMouseShortcuts();
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
#define GL_STATIC_DRAW_ARB GL_STATIC_DRAW
|
||||
#endif
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
std::unique_ptr<QOpenGLContext> lcContext::mOffscreenContext;
|
||||
std::unique_ptr<QOffscreenSurface> lcContext::mOffscreenSurface;
|
||||
#endif
|
||||
lcProgram lcContext::mPrograms[static_cast<int>(lcMaterialType::Count)];
|
||||
int lcContext::mValidContexts;
|
||||
|
||||
|
@ -93,6 +97,47 @@ lcContext::~lcContext()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
|
||||
bool lcContext::CreateOffscreenContext()
|
||||
{
|
||||
std::unique_ptr<QOpenGLContext> OffscreenContext(new QOpenGLContext());
|
||||
|
||||
if (!OffscreenContext)
|
||||
return false;
|
||||
|
||||
OffscreenContext->setShareContext(QOpenGLContext::globalShareContext());
|
||||
|
||||
if (!OffscreenContext->create() || !OffscreenContext->isValid())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<QOffscreenSurface> OffscreenSurface(new QOffscreenSurface());
|
||||
|
||||
if (!OffscreenSurface)
|
||||
return false;
|
||||
|
||||
OffscreenSurface->create();
|
||||
|
||||
if (!OffscreenSurface->isValid())
|
||||
return false;
|
||||
|
||||
if (!OffscreenContext->makeCurrent(OffscreenSurface.get()))
|
||||
return false;
|
||||
|
||||
mOffscreenContext = std::move(OffscreenContext);
|
||||
mOffscreenSurface = std::move(OffscreenSurface);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void lcContext::DestroyOffscreenContext()
|
||||
{
|
||||
mOffscreenSurface.reset();
|
||||
mOffscreenContext.reset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void lcContext::CreateShaderPrograms()
|
||||
{
|
||||
const char* ShaderPrefix =
|
||||
|
@ -255,20 +300,33 @@ void lcContext::DestroyResources()
|
|||
}
|
||||
}
|
||||
|
||||
void lcContext::MakeCurrent()
|
||||
{
|
||||
if (mWidget)
|
||||
mWidget->makeCurrent();
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
void lcContext::SetGLContext(QOpenGLContext* GLContext)
|
||||
else
|
||||
mOffscreenContext->makeCurrent(mOffscreenSurface.get());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
void lcContext::SetGLContext(QOpenGLContext* Context, QOpenGLWidget* Widget)
|
||||
#else
|
||||
void lcContext::SetGLContext(const QGLContext* GLContext)
|
||||
void lcContext::SetGLContext(const QGLContext* Context, QGLWidget* Widget)
|
||||
#endif
|
||||
{
|
||||
mContext = Context;
|
||||
mWidget = Widget;
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
MakeCurrent();
|
||||
initializeOpenGLFunctions();
|
||||
mGLContext = GLContext;
|
||||
#endif
|
||||
|
||||
if (!mValidContexts)
|
||||
{
|
||||
lcInitializeGLExtensions(GLContext);
|
||||
lcInitializeGLExtensions(Context);
|
||||
|
||||
// TODO: Find a better place for the grid texture and font
|
||||
gStringCache.Initialize(this);
|
||||
|
@ -289,6 +347,15 @@ void lcContext::SetGLContext(const QGLContext* GLContext)
|
|||
mValidContexts++;
|
||||
}
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
|
||||
void lcContext::SetOffscreenContext()
|
||||
{
|
||||
SetGLContext(mOffscreenContext.get(), nullptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void lcContext::SetDefaultState()
|
||||
{
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
|
@ -610,7 +677,7 @@ void lcContext::ClearFramebuffer()
|
|||
return;
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mGLContext->defaultFramebufferObject());
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mContext->defaultFramebufferObject());
|
||||
#else
|
||||
if (gSupportsFramebufferObjectARB)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
@ -664,7 +731,7 @@ lcFramebuffer lcContext::CreateFramebuffer(int Width, int Height, bool Depth, bo
|
|||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
else
|
||||
{
|
||||
QOpenGLFunctions_3_2_Core* Funcs = mGLContext->versionFunctions<QOpenGLFunctions_3_2_Core>();
|
||||
QOpenGLFunctions_3_2_Core* Funcs = mContext->versionFunctions<QOpenGLFunctions_3_2_Core>();
|
||||
|
||||
BindTexture2DMS(Framebuffer.mColorTexture);
|
||||
Funcs->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, Samples, GL_RGBA, Width, Height, GL_TRUE);
|
||||
|
@ -824,7 +891,7 @@ void lcContext::GetRenderFramebufferImage(const std::pair<lcFramebuffer, lcFrame
|
|||
glBindFramebuffer(GL_READ_FRAMEBUFFER, RenderFramebuffer.first.mObject);
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
QOpenGLFunctions_3_2_Core* Funcs = mGLContext->versionFunctions<QOpenGLFunctions_3_2_Core>();
|
||||
QOpenGLFunctions_3_2_Core* Funcs = mContext->versionFunctions<QOpenGLFunctions_3_2_Core>();
|
||||
Funcs->glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
#else
|
||||
glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
|
|
@ -120,16 +120,23 @@ public:
|
|||
lcContext(const lcContext&) = delete;
|
||||
lcContext& operator=(const lcContext&) = delete;
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
static bool CreateOffscreenContext();
|
||||
static void DestroyOffscreenContext();
|
||||
#endif
|
||||
|
||||
void CreateResources();
|
||||
void DestroyResources();
|
||||
|
||||
void SetDefaultState();
|
||||
void ClearResources();
|
||||
|
||||
void MakeCurrent();
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
void SetGLContext(QOpenGLContext* GLContext);
|
||||
void SetGLContext(QOpenGLContext* GLContext, QOpenGLWidget* Widget);
|
||||
void SetOffscreenContext();
|
||||
#else
|
||||
void SetGLContext(const QGLContext* GLContext);
|
||||
void SetGLContext(const QGLContext* GLContext, QGLWidget* Widget);
|
||||
#endif
|
||||
|
||||
void ClearColorAndDepth(const lcVector4& ClearColor);
|
||||
|
@ -234,7 +241,8 @@ protected:
|
|||
void FlushState();
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
QOpenGLContext* mGLContext = nullptr;
|
||||
QOpenGLWidget* mWidget = nullptr;
|
||||
QOpenGLContext* mContext = nullptr;
|
||||
#endif
|
||||
bool mValid = false;
|
||||
|
||||
|
@ -273,6 +281,11 @@ protected:
|
|||
|
||||
GLuint mFramebufferObject;
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
static std::unique_ptr<QOpenGLContext> mOffscreenContext;
|
||||
static std::unique_ptr<QOffscreenSurface> mOffscreenSurface;
|
||||
#endif
|
||||
|
||||
static lcProgram mPrograms[static_cast<int>(lcMaterialType::Count)];
|
||||
static int mValidContexts;
|
||||
|
||||
|
|
|
@ -1276,9 +1276,12 @@ QImage lcModel::GetStepImage(bool Zoom, int Width, int Height, lcStep Step)
|
|||
lcCamera* Camera = ActiveView->GetCamera();
|
||||
|
||||
lcView View(lcViewType::View, this);
|
||||
View.SetCamera(Camera, false);
|
||||
View.SetCamera(Camera, true);
|
||||
|
||||
#ifndef LC_USE_QOPENGLWIDGET
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
View.SetOffscreenContext();
|
||||
View.MakeCurrent();
|
||||
#else
|
||||
ActiveView->MakeCurrent();
|
||||
lcContext* Context = ActiveView->mContext;
|
||||
View.SetContext(Context);
|
||||
|
|
|
@ -398,6 +398,9 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex)
|
|||
{
|
||||
mView = std::unique_ptr<lcView>(new lcView(lcViewType::PartsList, nullptr));
|
||||
|
||||
mView->SetOffscreenContext();
|
||||
mView->MakeCurrent();
|
||||
|
||||
if (!mView->BeginRenderToImage(Width, Height))
|
||||
{
|
||||
mView.reset();
|
||||
|
@ -406,6 +409,7 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex)
|
|||
}
|
||||
|
||||
mView->MakeCurrent();
|
||||
mView->BindRenderFramebuffer();
|
||||
|
||||
lcContext* Context = mView->mContext;
|
||||
#else
|
||||
|
@ -456,6 +460,7 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex)
|
|||
Scene.Draw(Context);
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
mView->UnbindRenderFramebuffer();
|
||||
QImage Image = mView->GetRenderFramebufferImage().convertToFormat(QImage::Format_ARGB32);
|
||||
#else
|
||||
QImage Image = Context->GetRenderFramebufferImage(mRenderFramebuffer);
|
||||
|
|
|
@ -76,12 +76,7 @@ void lcView::UpdateAllViews()
|
|||
|
||||
void lcView::MakeCurrent()
|
||||
{
|
||||
if (mWidget)
|
||||
mWidget->makeCurrent();
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
else if (mOffscreenContext)
|
||||
mOffscreenContext->makeCurrent(mOffscreenSurface.get());
|
||||
#endif
|
||||
mContext->MakeCurrent();
|
||||
}
|
||||
|
||||
void lcView::Redraw()
|
||||
|
@ -90,6 +85,15 @@ void lcView::Redraw()
|
|||
mWidget->update();
|
||||
}
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
|
||||
void lcView::SetOffscreenContext()
|
||||
{
|
||||
mContext->SetOffscreenContext();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void lcView::SetContext(lcContext* Context)
|
||||
{
|
||||
if (mDeleteContext)
|
||||
|
@ -99,6 +103,8 @@ void lcView::SetContext(lcContext* Context)
|
|||
mDeleteContext = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void lcView::SetFocus(bool Focus)
|
||||
{
|
||||
if (Focus)
|
||||
|
@ -725,36 +731,6 @@ lcArray<lcObject*> lcView::FindObjectsInBox(float x1, float y1, float x2, float
|
|||
|
||||
bool lcView::BeginRenderToImage(int Width, int Height)
|
||||
{
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
std::unique_ptr<QOpenGLContext> OffscreenContext(new QOpenGLContext());
|
||||
|
||||
if (!OffscreenContext)
|
||||
return false;
|
||||
|
||||
OffscreenContext->setShareContext(QOpenGLContext::globalShareContext());
|
||||
|
||||
if (!OffscreenContext->create() || !OffscreenContext->isValid())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<QOffscreenSurface> OffscreenSurface(new QOffscreenSurface());
|
||||
|
||||
if (!OffscreenSurface)
|
||||
return false;
|
||||
|
||||
OffscreenSurface->create();
|
||||
|
||||
if (!OffscreenSurface->isValid())
|
||||
return false;
|
||||
|
||||
if (!OffscreenContext->makeCurrent(OffscreenSurface.get()))
|
||||
return false;
|
||||
|
||||
mContext->SetGLContext(OffscreenContext.get());
|
||||
|
||||
mOffscreenContext = std::move(OffscreenContext);
|
||||
mOffscreenSurface = std::move(OffscreenSurface);
|
||||
#endif
|
||||
|
||||
GLint MaxTexture;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTexture);
|
||||
|
||||
|
@ -795,8 +771,6 @@ bool lcView::BeginRenderToImage(int Width, int Height)
|
|||
void lcView::EndRenderToImage()
|
||||
{
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
mOffscreenContext.reset();
|
||||
mOffscreenSurface.reset();
|
||||
mRenderFramebuffer.reset();
|
||||
#else
|
||||
mRenderImage = QImage();
|
||||
|
@ -812,13 +786,19 @@ QImage lcView::GetRenderImage() const
|
|||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
|
||||
QImage lcView::GetRenderFramebufferImage() const
|
||||
void lcView::BindRenderFramebuffer()
|
||||
{
|
||||
mRenderFramebuffer->bind();
|
||||
}
|
||||
|
||||
void lcView::UnbindRenderFramebuffer()
|
||||
{
|
||||
mRenderFramebuffer->release();
|
||||
QImage Image = mRenderFramebuffer->toImage();
|
||||
mRenderFramebuffer->bind();
|
||||
}
|
||||
|
||||
return Image;
|
||||
QImage lcView::GetRenderFramebufferImage() const
|
||||
{
|
||||
return mRenderFramebuffer->toImage();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -918,7 +898,9 @@ void lcView::OnDraw()
|
|||
if (!mRenderImage.isNull())
|
||||
{
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
UnbindRenderFramebuffer();
|
||||
QImage TileImage = GetRenderFramebufferImage();
|
||||
BindRenderFramebuffer();
|
||||
quint8* Buffer = TileImage.bits();
|
||||
#else
|
||||
quint8* Buffer = (quint8*)malloc(mWidth * mHeight * 4);
|
||||
|
|
|
@ -176,7 +176,12 @@ public:
|
|||
|
||||
void MakeCurrent();
|
||||
void Redraw();
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
void SetOffscreenContext();
|
||||
#else
|
||||
void SetContext(lcContext* Context);
|
||||
#endif
|
||||
|
||||
void SetFocus(bool Focus);
|
||||
void SetMousePosition(int MouseX, int MouseY);
|
||||
|
@ -236,6 +241,8 @@ public:
|
|||
void EndRenderToImage();
|
||||
QImage GetRenderImage() const;
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
void BindRenderFramebuffer();
|
||||
void UnbindRenderFramebuffer();
|
||||
QImage GetRenderFramebufferImage() const;
|
||||
#endif
|
||||
|
||||
|
@ -300,8 +307,6 @@ protected:
|
|||
|
||||
QImage mRenderImage;
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
std::unique_ptr<QOpenGLContext> mOffscreenContext;
|
||||
std::unique_ptr<QOffscreenSurface> mOffscreenSurface;
|
||||
std::unique_ptr<QOpenGLFramebufferObject> mRenderFramebuffer;
|
||||
#else
|
||||
std::pair<lcFramebuffer, lcFramebuffer> mRenderFramebuffer;
|
||||
|
|
|
@ -56,7 +56,7 @@ void lcViewWidget::SetView(lcView* View)
|
|||
if (context())
|
||||
{
|
||||
makeCurrent();
|
||||
View->mContext->SetGLContext(context());
|
||||
View->mContext->SetGLContext(context(), this);
|
||||
}
|
||||
|
||||
View->SetWidget(this);
|
||||
|
@ -73,7 +73,7 @@ void lcViewWidget::SetView(lcView* View)
|
|||
|
||||
void lcViewWidget::initializeGL()
|
||||
{
|
||||
mView->mContext->SetGLContext(context());
|
||||
mView->mContext->SetGLContext(context(), this);
|
||||
}
|
||||
|
||||
void lcViewWidget::resizeGL(int Width, int Height)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "lc_qupdatedialog.h"
|
||||
#include "lc_mainwindow.h"
|
||||
#include "lc_profile.h"
|
||||
#include "lc_context.h"
|
||||
#include <QApplication>
|
||||
#include <locale.h>
|
||||
|
||||
|
@ -197,6 +198,10 @@ int main(int argc, char *argv[])
|
|||
ExecReturn = Application.exec();
|
||||
}
|
||||
|
||||
#ifdef LC_USE_QOPENGLWIDGET
|
||||
lcContext::DestroyOffscreenContext();
|
||||
#endif
|
||||
|
||||
delete gMainWindow;
|
||||
gMainWindow = nullptr;
|
||||
|
||||
|
|
Loading…
Reference in a new issue