Reuse the same FBO when creating new preview images.
This commit is contained in:
+119
-105
@@ -41,10 +41,6 @@ lcContext::lcContext()
|
||||
#endif
|
||||
|
||||
mFramebufferObject = 0;
|
||||
mFramebufferObjectMS = 0;
|
||||
mFramebufferTexture = 0;
|
||||
mFramebufferTextureMS = 0;
|
||||
mDepthRenderbufferObject = 0;
|
||||
|
||||
mColor = lcVector4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
mWorldMatrix = lcMatrix44Identity();
|
||||
@@ -547,155 +543,186 @@ void lcContext::SetInterfaceColor(lcInterfaceColor InterfaceColor)
|
||||
SetColor(gInterfaceColors[InterfaceColor]);
|
||||
}
|
||||
|
||||
bool lcContext::BeginRenderToTexture(int Width, int Height)
|
||||
void lcContext::ClearFramebuffer()
|
||||
{
|
||||
if (!mFramebufferObject)
|
||||
return;
|
||||
|
||||
if (gSupportsFramebufferObjectARB)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#ifndef LC_OPENGLES
|
||||
else if (gSupportsFramebufferObjectEXT)
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
#endif
|
||||
|
||||
mFramebufferObject = 0;
|
||||
}
|
||||
|
||||
lcFramebuffer lcContext::CreateFramebuffer(int Width, int Height, bool Depth, bool Multisample)
|
||||
{
|
||||
lcFramebuffer Framebuffer(Width, Height);
|
||||
|
||||
if (gSupportsFramebufferObjectARB)
|
||||
{
|
||||
int Samples = gSupportsTexImage2DMultisample ? QGLFormat::defaultFormat().samples() : 1;
|
||||
int Samples = (Multisample && gSupportsTexImage2DMultisample) ? QGLFormat::defaultFormat().samples() : 1;
|
||||
|
||||
glGenFramebuffers(1, &mFramebufferObject);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferObject);
|
||||
glGenFramebuffers(1, &Framebuffer.mObject);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, Framebuffer.mObject);
|
||||
|
||||
glGenTextures(1, &mFramebufferTexture);
|
||||
BindTexture2D(mFramebufferTexture);
|
||||
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, mFramebufferTexture, 0);
|
||||
|
||||
glGenRenderbuffers(1, &mDepthRenderbufferObject);
|
||||
glGenTextures(1, &Framebuffer.mColorTexture);
|
||||
if (Depth)
|
||||
glGenRenderbuffers(1, &Framebuffer.mDepthRenderbuffer);
|
||||
|
||||
if (Samples == 1)
|
||||
{
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbufferObject);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, Width, Height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbufferObject);
|
||||
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
|
||||
{
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
EndRenderToTexture();
|
||||
return false;
|
||||
}
|
||||
|
||||
glGenFramebuffers(1, &mFramebufferObjectMS);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferObjectMS);
|
||||
|
||||
glGenTextures(1, &mFramebufferTextureMS);
|
||||
BindTexture2DMS(mFramebufferTextureMS);
|
||||
BindTexture2DMS(Framebuffer.mColorTexture);
|
||||
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, Samples, GL_RGBA, Width, Height, GL_TRUE);
|
||||
BindTexture2DMS(0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, mFramebufferTextureMS, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, Framebuffer.mColorTexture, 0);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbufferObject);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, Samples, GL_DEPTH_COMPONENT24, Width, Height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbufferObject);
|
||||
if (Depth)
|
||||
{
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, Framebuffer.mDepthRenderbuffer);
|
||||
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)
|
||||
{
|
||||
EndRenderToTexture();
|
||||
return false;
|
||||
}
|
||||
DestroyFramebuffer(Framebuffer);
|
||||
|
||||
return true;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferObject);
|
||||
}
|
||||
|
||||
#ifndef LC_OPENGLES
|
||||
if (gSupportsFramebufferObjectEXT)
|
||||
else if (gSupportsFramebufferObjectEXT)
|
||||
{
|
||||
glGenFramebuffersEXT(1, &mFramebufferObject);
|
||||
glGenTextures(1, &mFramebufferTexture);
|
||||
glGenFramebuffersEXT(1, &Framebuffer.mObject);
|
||||
glGenTextures(1, &Framebuffer.mColorTexture);
|
||||
|
||||
BindTexture2D(mFramebufferTexture);
|
||||
BindTexture2D(Framebuffer.mColorTexture);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebufferObject);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mFramebufferTexture, 0);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Framebuffer.mObject);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Framebuffer.mColorTexture, 0);
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebufferObject);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Framebuffer.mObject);
|
||||
|
||||
glGenRenderbuffersEXT(1, &mDepthRenderbufferObject);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mDepthRenderbufferObject);
|
||||
glGenRenderbuffersEXT(1, &Framebuffer.mDepthRenderbuffer);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, Framebuffer.mDepthRenderbuffer);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, Width, Height);
|
||||
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepthRenderbufferObject);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, Framebuffer.mDepthRenderbuffer);
|
||||
|
||||
BindTexture2D(0);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebufferObject);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Framebuffer.mObject);
|
||||
|
||||
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
EndRenderToTexture();
|
||||
return false;
|
||||
}
|
||||
DestroyFramebuffer(Framebuffer);
|
||||
|
||||
return true;
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFramebufferObject);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
|
||||
return Framebuffer;
|
||||
}
|
||||
|
||||
void lcContext::EndRenderToTexture()
|
||||
void lcContext::DestroyFramebuffer(lcFramebuffer& Framebuffer)
|
||||
{
|
||||
if (gSupportsFramebufferObjectARB)
|
||||
{
|
||||
glDeleteFramebuffers(1, &mFramebufferObject);
|
||||
mFramebufferObject = 0;
|
||||
glDeleteTextures(1, &mFramebufferTexture);
|
||||
mFramebufferTexture = 0;
|
||||
glDeleteFramebuffers(1, &mFramebufferObjectMS);
|
||||
mFramebufferObjectMS = 0;
|
||||
glDeleteTextures(1, &mFramebufferTextureMS);
|
||||
mFramebufferTextureMS = 0;
|
||||
glDeleteRenderbuffers(1, &mDepthRenderbufferObject);
|
||||
mDepthRenderbufferObject = 0;
|
||||
|
||||
return;
|
||||
glDeleteFramebuffers(1, &Framebuffer.mObject);
|
||||
glDeleteTextures(1, &Framebuffer.mColorTexture);
|
||||
glDeleteRenderbuffers(1, &Framebuffer.mDepthRenderbuffer);
|
||||
}
|
||||
|
||||
#ifndef LC_OPENGLES
|
||||
if (gSupportsFramebufferObjectEXT)
|
||||
else if (gSupportsFramebufferObjectEXT)
|
||||
{
|
||||
glDeleteFramebuffersEXT(1, &mFramebufferObject);
|
||||
mFramebufferObject = 0;
|
||||
glDeleteTextures(1, &mFramebufferTexture);
|
||||
mFramebufferTexture = 0;
|
||||
glDeleteRenderbuffersEXT(1, &mDepthRenderbufferObject);
|
||||
mDepthRenderbufferObject = 0;
|
||||
glDeleteFramebuffersEXT(1, &Framebuffer.mObject);
|
||||
glDeleteTextures(1, &Framebuffer.mColorTexture);
|
||||
glDeleteRenderbuffersEXT(1, &Framebuffer.mDepthRenderbuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
Framebuffer.mObject = 0;
|
||||
Framebuffer.mColorTexture = 0;
|
||||
Framebuffer.mDepthRenderbuffer = 0;
|
||||
Framebuffer.mWidth = 0;
|
||||
Framebuffer.mHeight = 0;
|
||||
}
|
||||
|
||||
QImage lcContext::GetRenderToTextureImage(int Width, int Height)
|
||||
void lcContext::BindFramebuffer(GLuint FramebufferObject)
|
||||
{
|
||||
QImage Image(Width, Height, QImage::Format_ARGB32);
|
||||
if (FramebufferObject == mFramebufferObject)
|
||||
return;
|
||||
|
||||
GetRenderToTextureImage(Width, Height, Image.bits());
|
||||
if (gSupportsFramebufferObjectARB)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferObject);
|
||||
#ifndef LC_OPENGLES
|
||||
else if (gSupportsFramebufferObjectEXT)
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FramebufferObject);
|
||||
#endif
|
||||
|
||||
mFramebufferObject = FramebufferObject;
|
||||
}
|
||||
|
||||
std::pair<lcFramebuffer, lcFramebuffer> lcContext::CreateRenderFramebuffer(int Width, int Height)
|
||||
{
|
||||
if (gSupportsFramebufferObjectARB && QGLFormat::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, false, true), 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::GetRenderToTextureImage(int Width, int Height, quint8* Buffer)
|
||||
void lcContext::GetRenderFramebufferImage(const std::pair<lcFramebuffer, lcFramebuffer>& RenderFramebuffer, quint8* Buffer)
|
||||
{
|
||||
if (mFramebufferTextureMS)
|
||||
const int Width = RenderFramebuffer.first.mWidth;
|
||||
const int Height = RenderFramebuffer.first.mHeight;
|
||||
GLuint SavedFramebuffer = mFramebufferObject;
|
||||
|
||||
if (RenderFramebuffer.second.IsValid())
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferObjectMS);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferObject);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, RenderFramebuffer.second.mObject);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, RenderFramebuffer.first.mObject);
|
||||
glBlitFrameBuffer(0, 0, Width, Height, 0, 0, Width, Height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferObject);
|
||||
BindFramebuffer(RenderFramebuffer.second);
|
||||
}
|
||||
else
|
||||
BindFramebuffer(RenderFramebuffer.first);
|
||||
|
||||
glFinish();
|
||||
glReadPixels(0, 0, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, Buffer);
|
||||
|
||||
if (mFramebufferTextureMS)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferObjectMS);
|
||||
BindFramebuffer(SavedFramebuffer);
|
||||
|
||||
for (int y = 0; y < (Height + 1) / 2; y++)
|
||||
{
|
||||
@@ -716,19 +743,6 @@ void lcContext::GetRenderToTextureImage(int Width, int Height, quint8* Buffer)
|
||||
}
|
||||
}
|
||||
|
||||
bool lcContext::SaveRenderToTextureImage(const QString& FileName, int Width, int Height)
|
||||
{
|
||||
QImage Image = GetRenderToTextureImage(Width, Height);
|
||||
QImageWriter Writer(FileName);
|
||||
|
||||
bool Result = Writer.write(Image);
|
||||
|
||||
if (!Result)
|
||||
QMessageBox::information(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, Writer.errorString()));
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
lcVertexBuffer lcContext::CreateVertexBuffer(int Size, const void* Data)
|
||||
{
|
||||
lcVertexBuffer VertexBuffer;
|
||||
|
||||
+37
-9
@@ -74,6 +74,30 @@ struct lcProgram
|
||||
GLint EyePositionLocation;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
class lcContext
|
||||
{
|
||||
public:
|
||||
@@ -130,11 +154,19 @@ public:
|
||||
void SetEdgeColorIndex(int ColorIndex);
|
||||
void SetInterfaceColor(lcInterfaceColor InterfaceColor);
|
||||
|
||||
bool BeginRenderToTexture(int Width, int Height);
|
||||
void EndRenderToTexture();
|
||||
QImage GetRenderToTextureImage(int Width, int Height);
|
||||
void GetRenderToTextureImage(int Width, int Height, quint8* Buffer);
|
||||
bool SaveRenderToTextureImage(const QString& FileName, int Width, int Height);
|
||||
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);
|
||||
void DestroyVertexBuffer(lcVertexBuffer& VertexBuffer);
|
||||
@@ -189,10 +221,6 @@ protected:
|
||||
bool mViewProjectionMatrixDirty;
|
||||
|
||||
GLuint mFramebufferObject;
|
||||
GLuint mFramebufferTexture;
|
||||
GLuint mFramebufferObjectMS;
|
||||
GLuint mFramebufferTextureMS;
|
||||
GLuint mDepthRenderbufferObject;
|
||||
|
||||
static lcProgram mPrograms[LC_NUM_MATERIALS];
|
||||
|
||||
|
||||
@@ -337,13 +337,20 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex)
|
||||
int Width = mIconSize * 2;
|
||||
int Height = mIconSize * 2;
|
||||
|
||||
if (!Context->BeginRenderToTexture(Width, Height))
|
||||
if (mRenderFramebuffer.first.mWidth != Width || mRenderFramebuffer.first.mHeight != Height)
|
||||
{
|
||||
Context->DestroyRenderFramebuffer(mRenderFramebuffer);
|
||||
mRenderFramebuffer = Context->CreateRenderFramebuffer(Width, Height);
|
||||
}
|
||||
|
||||
if (!mRenderFramebuffer.first.IsValid())
|
||||
return;
|
||||
|
||||
float Aspect = (float)Width / (float)Height;
|
||||
Context->SetViewport(0, 0, Width, Height);
|
||||
|
||||
Context->SetDefaultState();
|
||||
Context->BindFramebuffer(mRenderFramebuffer.first);
|
||||
|
||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||
PieceInfo* Info = mParts[InfoIndex].first;
|
||||
@@ -366,11 +373,11 @@ void lcPartSelectionListModel::DrawPreview(int InfoIndex)
|
||||
|
||||
Scene.Draw(Context);
|
||||
|
||||
mParts[InfoIndex].second = QPixmap::fromImage(Context->GetRenderToTextureImage(Width, Height)).scaled(mIconSize, mIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
mParts[InfoIndex].second = QPixmap::fromImage(Context->GetRenderFramebufferImage(mRenderFramebuffer)).scaled(mIconSize, mIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
Library->ReleasePieceInfo(Info);
|
||||
|
||||
Context->EndRenderToTexture();
|
||||
Context->ClearFramebuffer();
|
||||
Context->ClearResources();
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "lc_context.h"
|
||||
|
||||
class lcPartSelectionListModel;
|
||||
class lcPartSelectionListView;
|
||||
|
||||
@@ -98,6 +100,7 @@ protected:
|
||||
bool mListMode;
|
||||
bool mShowDecoratedParts;
|
||||
QByteArray mFilter;
|
||||
std::pair<lcFramebuffer, lcFramebuffer> mRenderFramebuffer;
|
||||
};
|
||||
|
||||
class lcPartSelectionListView : public QListView
|
||||
@@ -179,4 +182,3 @@ protected:
|
||||
lcPartSelectionListView* mPartsWidget;
|
||||
QSplitter* mSplitter;
|
||||
};
|
||||
|
||||
|
||||
+24
-6
@@ -1498,12 +1498,16 @@ QImage Project::CreatePartsListImage(lcModel* Model, lcStep Step)
|
||||
const int ThumbnailWidth = 512;
|
||||
const int ThumbnailHeight = 512;
|
||||
|
||||
if (!Context->BeginRenderToTexture(ThumbnailWidth, ThumbnailHeight))
|
||||
std::pair<lcFramebuffer, lcFramebuffer> RenderFramebuffer = Context->CreateRenderFramebuffer(ThumbnailWidth, ThumbnailHeight);
|
||||
|
||||
if (!RenderFramebuffer.first.IsValid())
|
||||
{
|
||||
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Error creating images."));
|
||||
return QImage();
|
||||
}
|
||||
|
||||
Context->BindFramebuffer(RenderFramebuffer.first);
|
||||
|
||||
float Aspect = (float)ThumbnailWidth / (float)ThumbnailHeight;
|
||||
float OrthoHeight = 200.0f;
|
||||
float OrthoWidth = OrthoHeight * Aspect;
|
||||
@@ -1529,10 +1533,11 @@ QImage Project::CreatePartsListImage(lcModel* Model, lcStep Step)
|
||||
|
||||
Scene.Draw(Context);
|
||||
|
||||
Image.Thumbnail = Context->GetRenderToTextureImage(ThumbnailWidth, ThumbnailHeight);
|
||||
Image.Thumbnail = Context->GetRenderFramebufferImage(RenderFramebuffer);
|
||||
}
|
||||
|
||||
Context->EndRenderToTexture();
|
||||
Context->ClearFramebuffer();
|
||||
Context->DestroyRenderFramebuffer(RenderFramebuffer);
|
||||
Context->ClearResources();
|
||||
|
||||
auto CalculateImageBounds = [](lcPartsListImage& Image)
|
||||
@@ -1876,12 +1881,16 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options)
|
||||
int Width = Options.PartImagesWidth;
|
||||
int Height = Options.PartImagesHeight;
|
||||
|
||||
if (!Context->BeginRenderToTexture(Width, Height))
|
||||
std::pair<lcFramebuffer, lcFramebuffer> RenderFramebuffer = Context->CreateRenderFramebuffer(Width, Height);
|
||||
|
||||
if (!RenderFramebuffer.first.IsValid())
|
||||
{
|
||||
QMessageBox::warning(gMainWindow, tr("LeoCAD"), tr("Error creating images."));
|
||||
return;
|
||||
}
|
||||
|
||||
Context->BindFramebuffer(RenderFramebuffer.first);
|
||||
|
||||
float AspectRatio = (float)Width / (float)Height;
|
||||
Context->SetViewport(0, 0, Width, Height);
|
||||
|
||||
@@ -1913,10 +1922,19 @@ void Project::ExportHTML(const lcHTMLExportOptions& Options)
|
||||
Scene.Draw(Context);
|
||||
|
||||
QString FileName = QFileInfo(Dir, QLatin1String(Info->mFileName) + QLatin1String(".png")).absoluteFilePath();
|
||||
if (!Context->SaveRenderToTextureImage(FileName, Width, Height))
|
||||
QImage Image = Context->GetRenderFramebufferImage(RenderFramebuffer);
|
||||
|
||||
QImageWriter Writer(FileName);
|
||||
|
||||
if (!Writer.write(Image))
|
||||
{
|
||||
QMessageBox::information(gMainWindow, tr("Error"), tr("Error writing to file '%1':\n%2").arg(FileName, Writer.errorString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
Context->EndRenderToTexture();
|
||||
|
||||
Context->ClearFramebuffer();
|
||||
Context->DestroyRenderFramebuffer(RenderFramebuffer);
|
||||
Context->ClearResources();
|
||||
}
|
||||
}
|
||||
|
||||
+8
-5
@@ -645,13 +645,16 @@ bool View::BeginRenderToImage(int Width, int Height)
|
||||
else
|
||||
mRenderImage = QImage(TileWidth, TileHeight, QImage::Format_ARGB32);
|
||||
|
||||
return mContext->BeginRenderToTexture(TileWidth, TileHeight);
|
||||
mRenderFramebuffer = mContext->CreateRenderFramebuffer(Width, Height);
|
||||
mContext->BindFramebuffer(mRenderFramebuffer.first);
|
||||
return mRenderFramebuffer.first.IsValid();
|
||||
}
|
||||
|
||||
void View::EndRenderToImage()
|
||||
{
|
||||
mRenderImage = QImage();
|
||||
mContext->EndRenderToTexture();
|
||||
mContext->DestroyRenderFramebuffer(mRenderFramebuffer);
|
||||
mContext->ClearFramebuffer();
|
||||
}
|
||||
|
||||
void View::OnDraw()
|
||||
@@ -728,14 +731,14 @@ void View::OnDraw()
|
||||
quint8* Buffer = (quint8*)malloc(mWidth * mHeight * 4);
|
||||
uchar* ImageBuffer = mRenderImage.bits();
|
||||
|
||||
mContext->GetRenderToTextureImage(mWidth, mHeight, Buffer);
|
||||
mContext->GetRenderFramebufferImage(mRenderFramebuffer, Buffer);
|
||||
|
||||
quint32 TileY = 0, SrcY = 0;
|
||||
if (CurrentTileRow != TotalTileRows - 1)
|
||||
TileY = (TotalTileRows - CurrentTileRow - 1) * mHeight - (mHeight - mRenderImage.height() % mHeight);
|
||||
else
|
||||
else if (TotalTileRows > 1 || TotalTileColumns > 1)
|
||||
SrcY = mHeight - mRenderImage.height() % mHeight;
|
||||
qDebug() << SrcY << TileY;
|
||||
|
||||
quint32 TileStart = ((CurrentTileColumn * mWidth) + (TileY * mRenderImage.width())) * 4;
|
||||
|
||||
for (int y = 0; y < CurrentTileHeight; y++)
|
||||
|
||||
@@ -167,6 +167,7 @@ protected:
|
||||
PieceInfo* mMouseDownPiece;
|
||||
bool mHighlight;
|
||||
QImage mRenderImage;
|
||||
std::pair<lcFramebuffer, lcFramebuffer> mRenderFramebuffer;
|
||||
|
||||
lcVertexBuffer mGridBuffer;
|
||||
int mGridSettings[7];
|
||||
|
||||
Reference in New Issue
Block a user