diff --git a/common/lc_context.cpp b/common/lc_context.cpp index 890dc4eb..ea5f44e4 100644 --- a/common/lc_context.cpp +++ b/common/lc_context.cpp @@ -52,8 +52,6 @@ lcContext::lcContext() mTextureEnabled = false; #endif - mFramebufferObject = 0; - mColor = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mWorldMatrix = lcMatrix44Identity(); mViewMatrix = lcMatrix44Identity(); @@ -645,165 +643,6 @@ void lcContext::SetInterfaceColor(lcInterfaceColor InterfaceColor) SetColor(gInterfaceColors[InterfaceColor]); } -void lcContext::ClearFramebuffer() -{ - if (!mFramebufferObject) - return; - - glBindFramebuffer(GL_FRAMEBUFFER, mContext->defaultFramebufferObject()); - - mFramebufferObject = 0; -} - -lcFramebuffer lcContext::CreateFramebuffer(int Width, int Height, bool Depth, bool Multisample) -{ - lcFramebuffer Framebuffer(Width, Height); - - if (gSupportsFramebufferObject) - { - int Samples = (Multisample && gSupportsTexImage2DMultisample && QSurfaceFormat::defaultFormat().samples() > 1) ? QSurfaceFormat::defaultFormat().samples() : 1; - - glGenFramebuffers(1, &Framebuffer.mObject); - glBindFramebuffer(GL_FRAMEBUFFER, Framebuffer.mObject); - - glGenTextures(1, &Framebuffer.mColorTexture); - if (Depth) - glGenRenderbuffers(1, &Framebuffer.mDepthRenderbuffer); - - if (Samples == 1) - { - BindTexture2D(Framebuffer.mColorTexture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - BindTexture2D(0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Framebuffer.mColorTexture, 0); - - if (Depth) - { - glBindRenderbuffer(GL_RENDERBUFFER, Framebuffer.mDepthRenderbuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, Width, Height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, Framebuffer.mDepthRenderbuffer); - } - } - else - { - QOpenGLFunctions_3_2_Core* Funcs = mContext->versionFunctions(); - - BindTexture2DMS(Framebuffer.mColorTexture); - Funcs->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, Samples, GL_RGBA, Width, Height, GL_TRUE); - BindTexture2DMS(0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, Framebuffer.mColorTexture, 0); - - if (Depth) - { - glBindRenderbuffer(GL_RENDERBUFFER, Framebuffer.mDepthRenderbuffer); - Funcs->glRenderbufferStorageMultisample(GL_RENDERBUFFER, Samples, GL_DEPTH_COMPONENT24, Width, Height); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, Framebuffer.mDepthRenderbuffer); - } - } - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - DestroyFramebuffer(Framebuffer); - - glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferObject); - } - - return Framebuffer; -} - -void lcContext::DestroyFramebuffer(lcFramebuffer& Framebuffer) -{ - if (gSupportsFramebufferObject) - { - glDeleteFramebuffers(1, &Framebuffer.mObject); - glDeleteTextures(1, &Framebuffer.mColorTexture); - glDeleteRenderbuffers(1, &Framebuffer.mDepthRenderbuffer); - } - - Framebuffer.mObject = 0; - Framebuffer.mColorTexture = 0; - Framebuffer.mDepthRenderbuffer = 0; - Framebuffer.mWidth = 0; - Framebuffer.mHeight = 0; -} - -void lcContext::BindFramebuffer(GLuint FramebufferObject) -{ - if (FramebufferObject == mFramebufferObject) - return; - - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferObject); - - mFramebufferObject = FramebufferObject; -} - -std::pair lcContext::CreateRenderFramebuffer(int Width, int Height) -{ - if (gSupportsFramebufferObject && gSupportsTexImage2DMultisample && QSurfaceFormat::defaultFormat().samples() > 1) - return std::make_pair(CreateFramebuffer(Width, Height, true, true), CreateFramebuffer(Width, Height, false, false)); - else - return std::make_pair(CreateFramebuffer(Width, Height, true, false), lcFramebuffer()); -} - -void lcContext::DestroyRenderFramebuffer(std::pair& RenderFramebuffer) -{ - DestroyFramebuffer(RenderFramebuffer.first); - DestroyFramebuffer(RenderFramebuffer.second); -} - -QImage lcContext::GetRenderFramebufferImage(const std::pair& RenderFramebuffer) -{ - QImage Image(RenderFramebuffer.first.mWidth, RenderFramebuffer.first.mHeight, QImage::Format_ARGB32); - - GetRenderFramebufferImage(RenderFramebuffer, Image.bits()); - - return Image; -} - -void lcContext::GetRenderFramebufferImage(const std::pair& RenderFramebuffer, quint8* Buffer) -{ - const int Width = RenderFramebuffer.first.mWidth; - const int Height = RenderFramebuffer.first.mHeight; - const GLuint SavedFramebuffer = mFramebufferObject; - - if (RenderFramebuffer.second.IsValid()) - { -#ifndef LC_OPENGLES - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, RenderFramebuffer.second.mObject); - glBindFramebuffer(GL_READ_FRAMEBUFFER, RenderFramebuffer.first.mObject); - - QOpenGLFunctions_3_2_Core* Funcs = mContext->versionFunctions(); - Funcs->glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height, GL_COLOR_BUFFER_BIT, GL_LINEAR); - - BindFramebuffer(RenderFramebuffer.second); -#endif - } - else - BindFramebuffer(RenderFramebuffer.first); - - glFinish(); - glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Buffer); - BindFramebuffer(SavedFramebuffer); - - for (int y = 0; y < (Height + 1) / 2; y++) - { - quint8* Top = Buffer + ((Height - y - 1) * Width * 4); - quint8* Bottom = Buffer + y * Width * 4; - - for (int x = 0; x < Width; x++) - { - QRgb TopColor = qRgba(Top[0], Top[1], Top[2], Top[3]); - QRgb BottomColor = qRgba(Bottom[0], Bottom[1], Bottom[2], Bottom[3]); - - *(QRgb*)Top = BottomColor; - *(QRgb*)Bottom = TopColor; - - Top += 4; - Bottom += 4; - } - } -} - lcVertexBuffer lcContext::CreateVertexBuffer(int Size, const void* Data) { lcVertexBuffer VertexBuffer; diff --git a/common/lc_context.h b/common/lc_context.h index 324db87f..890a0ac1 100644 --- a/common/lc_context.h +++ b/common/lc_context.h @@ -76,30 +76,6 @@ struct lcProgram GLint HighlightParamsLocation; }; -class lcFramebuffer -{ -public: - lcFramebuffer() - { - } - - lcFramebuffer(int Width, int Height) - : mWidth(Width), mHeight(Height) - { - } - - bool IsValid() const - { - return mObject != 0; - } - - GLuint mObject = 0; - GLuint mColorTexture = 0; - GLuint mDepthRenderbuffer = 0; - int mWidth = 0; - int mHeight = 0; -}; - enum class lcPolygonOffset { None, @@ -193,20 +169,6 @@ public: void SetEdgeColorIndexTinted(int ColorIndex, const lcVector4& Tint); void SetInterfaceColor(lcInterfaceColor InterfaceColor); - void ClearFramebuffer(); - lcFramebuffer CreateFramebuffer(int Width, int Height, bool Depth, bool Multisample); - void DestroyFramebuffer(lcFramebuffer& Framebuffer); - void BindFramebuffer(GLuint FramebufferObject); - void BindFramebuffer(const lcFramebuffer& Framebuffer) - { - BindFramebuffer(Framebuffer.mObject); - } - - std::pair CreateRenderFramebuffer(int Width, int Height); - void DestroyRenderFramebuffer(std::pair& RenderFramebuffer); - QImage GetRenderFramebufferImage(const std::pair& RenderFramebuffer); - void GetRenderFramebufferImage(const std::pair& RenderFramebuffer, quint8* Buffer); - lcVertexBuffer CreateVertexBuffer(int Size, const void* Data); void DestroyVertexBuffer(lcVertexBuffer& VertexBuffer); lcIndexBuffer CreateIndexBuffer(int Size, const void* Data); @@ -268,8 +230,6 @@ protected: bool mViewProjectionMatrixDirty; bool mHighlightParamsDirty; - GLuint mFramebufferObject; - static std::unique_ptr mOffscreenContext; static std::unique_ptr mOffscreenSurface; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 61062110..4f45d4e4 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -1332,21 +1332,20 @@ QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step) const std::sort(Images.begin(), Images.end(), ImageCompare); - lcView* View = gMainWindow->GetActiveView(); - View->MakeCurrent(); - lcContext* Context = View->mContext; + lcView View(lcViewType::PartsList, nullptr); + View.SetOffscreenContext(); + View.MakeCurrent(); + lcContext* Context = View.mContext; const int ThumbnailSize = qMin(MaxWidth, 512); - std::pair RenderFramebuffer = Context->CreateRenderFramebuffer(ThumbnailSize, ThumbnailSize); + View.SetSize(ThumbnailSize, ThumbnailSize); - if (!RenderFramebuffer.first.IsValid()) + if (!View.BeginRenderToImage(ThumbnailSize, ThumbnailSize)) { QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Error creating images.")); return QImage(); } - Context->BindFramebuffer(RenderFramebuffer.first); - float OrthoSize = 200.0f; lcMatrix44 ProjectionMatrix = lcMatrix44Ortho(-OrthoSize, OrthoSize, -OrthoSize, OrthoSize, -5000.0f, 5000.0f); @@ -1405,11 +1404,10 @@ QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step) const Scene.Draw(Context); - Image.Thumbnail = Context->GetRenderFramebufferImage(RenderFramebuffer); + Image.Thumbnail = View.GetRenderFramebufferImage().convertToFormat(QImage::Format_ARGB32); } - Context->ClearFramebuffer(); - Context->DestroyRenderFramebuffer(RenderFramebuffer); + View.EndRenderToImage(); Context->ClearResources(); auto CalculateImageBounds = [](lcPartsListImage& Image)