mirror of
https://github.com/leozide/leocad
synced 2024-12-27 21:58:37 +01:00
Framebuffer cleanup.
This commit is contained in:
parent
31ce044a65
commit
a0867c9b80
3 changed files with 8 additions and 211 deletions
|
@ -52,8 +52,6 @@ lcContext::lcContext()
|
||||||
mTextureEnabled = false;
|
mTextureEnabled = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mFramebufferObject = 0;
|
|
||||||
|
|
||||||
mColor = lcVector4(0.0f, 0.0f, 0.0f, 0.0f);
|
mColor = lcVector4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
mWorldMatrix = lcMatrix44Identity();
|
mWorldMatrix = lcMatrix44Identity();
|
||||||
mViewMatrix = lcMatrix44Identity();
|
mViewMatrix = lcMatrix44Identity();
|
||||||
|
@ -645,165 +643,6 @@ void lcContext::SetInterfaceColor(lcInterfaceColor InterfaceColor)
|
||||||
SetColor(gInterfaceColors[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<QOpenGLFunctions_3_2_Core>();
|
|
||||||
|
|
||||||
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<lcFramebuffer, lcFramebuffer> 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<lcFramebuffer, lcFramebuffer>& RenderFramebuffer)
|
|
||||||
{
|
|
||||||
DestroyFramebuffer(RenderFramebuffer.first);
|
|
||||||
DestroyFramebuffer(RenderFramebuffer.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage lcContext::GetRenderFramebufferImage(const std::pair<lcFramebuffer, lcFramebuffer>& RenderFramebuffer)
|
|
||||||
{
|
|
||||||
QImage Image(RenderFramebuffer.first.mWidth, RenderFramebuffer.first.mHeight, QImage::Format_ARGB32);
|
|
||||||
|
|
||||||
GetRenderFramebufferImage(RenderFramebuffer, Image.bits());
|
|
||||||
|
|
||||||
return Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lcContext::GetRenderFramebufferImage(const std::pair<lcFramebuffer, lcFramebuffer>& 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<QOpenGLFunctions_3_2_Core>();
|
|
||||||
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 lcContext::CreateVertexBuffer(int Size, const void* Data)
|
||||||
{
|
{
|
||||||
lcVertexBuffer VertexBuffer;
|
lcVertexBuffer VertexBuffer;
|
||||||
|
|
|
@ -76,30 +76,6 @@ struct lcProgram
|
||||||
GLint HighlightParamsLocation;
|
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
|
enum class lcPolygonOffset
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
@ -193,20 +169,6 @@ public:
|
||||||
void SetEdgeColorIndexTinted(int ColorIndex, const lcVector4& Tint);
|
void SetEdgeColorIndexTinted(int ColorIndex, const lcVector4& Tint);
|
||||||
void SetInterfaceColor(lcInterfaceColor InterfaceColor);
|
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<lcFramebuffer, lcFramebuffer> CreateRenderFramebuffer(int Width, int Height);
|
|
||||||
void DestroyRenderFramebuffer(std::pair<lcFramebuffer, lcFramebuffer>& RenderFramebuffer);
|
|
||||||
QImage GetRenderFramebufferImage(const std::pair<lcFramebuffer, lcFramebuffer>& RenderFramebuffer);
|
|
||||||
void GetRenderFramebufferImage(const std::pair<lcFramebuffer, lcFramebuffer>& RenderFramebuffer, quint8* Buffer);
|
|
||||||
|
|
||||||
lcVertexBuffer CreateVertexBuffer(int Size, const void* Data);
|
lcVertexBuffer CreateVertexBuffer(int Size, const void* Data);
|
||||||
void DestroyVertexBuffer(lcVertexBuffer& VertexBuffer);
|
void DestroyVertexBuffer(lcVertexBuffer& VertexBuffer);
|
||||||
lcIndexBuffer CreateIndexBuffer(int Size, const void* Data);
|
lcIndexBuffer CreateIndexBuffer(int Size, const void* Data);
|
||||||
|
@ -268,8 +230,6 @@ protected:
|
||||||
bool mViewProjectionMatrixDirty;
|
bool mViewProjectionMatrixDirty;
|
||||||
bool mHighlightParamsDirty;
|
bool mHighlightParamsDirty;
|
||||||
|
|
||||||
GLuint mFramebufferObject;
|
|
||||||
|
|
||||||
static std::unique_ptr<QOpenGLContext> mOffscreenContext;
|
static std::unique_ptr<QOpenGLContext> mOffscreenContext;
|
||||||
static std::unique_ptr<QOffscreenSurface> mOffscreenSurface;
|
static std::unique_ptr<QOffscreenSurface> mOffscreenSurface;
|
||||||
|
|
||||||
|
|
|
@ -1332,21 +1332,20 @@ QImage lcModel::GetPartsListImage(int MaxWidth, lcStep Step) const
|
||||||
|
|
||||||
std::sort(Images.begin(), Images.end(), ImageCompare);
|
std::sort(Images.begin(), Images.end(), ImageCompare);
|
||||||
|
|
||||||
lcView* View = gMainWindow->GetActiveView();
|
lcView View(lcViewType::PartsList, nullptr);
|
||||||
View->MakeCurrent();
|
View.SetOffscreenContext();
|
||||||
lcContext* Context = View->mContext;
|
View.MakeCurrent();
|
||||||
|
lcContext* Context = View.mContext;
|
||||||
const int ThumbnailSize = qMin(MaxWidth, 512);
|
const int ThumbnailSize = qMin(MaxWidth, 512);
|
||||||
|
|
||||||
std::pair<lcFramebuffer, lcFramebuffer> 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."));
|
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Error creating images."));
|
||||||
return QImage();
|
return QImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
Context->BindFramebuffer(RenderFramebuffer.first);
|
|
||||||
|
|
||||||
float OrthoSize = 200.0f;
|
float OrthoSize = 200.0f;
|
||||||
|
|
||||||
lcMatrix44 ProjectionMatrix = lcMatrix44Ortho(-OrthoSize, OrthoSize, -OrthoSize, OrthoSize, -5000.0f, 5000.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);
|
Scene.Draw(Context);
|
||||||
|
|
||||||
Image.Thumbnail = Context->GetRenderFramebufferImage(RenderFramebuffer);
|
Image.Thumbnail = View.GetRenderFramebufferImage().convertToFormat(QImage::Format_ARGB32);
|
||||||
}
|
}
|
||||||
|
|
||||||
Context->ClearFramebuffer();
|
View.EndRenderToImage();
|
||||||
Context->DestroyRenderFramebuffer(RenderFramebuffer);
|
|
||||||
Context->ClearResources();
|
Context->ClearResources();
|
||||||
|
|
||||||
auto CalculateImageBounds = [](lcPartsListImage& Image)
|
auto CalculateImageBounds = [](lcPartsListImage& Image)
|
||||||
|
|
Loading…
Reference in a new issue