diff --git a/common/lc_context.cpp b/common/lc_context.cpp index 646e7cc1..7d36943d 100644 --- a/common/lc_context.cpp +++ b/common/lc_context.cpp @@ -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 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& 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::GetRenderToTextureImage(int Width, int Height, quint8* Buffer) +void lcContext::GetRenderFramebufferImage(const std::pair& 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; diff --git a/common/lc_context.h b/common/lc_context.h index 863ab45c..7aa2a1ba 100644 --- a/common/lc_context.h +++ b/common/lc_context.h @@ -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 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); @@ -189,10 +221,6 @@ protected: bool mViewProjectionMatrixDirty; GLuint mFramebufferObject; - GLuint mFramebufferTexture; - GLuint mFramebufferObjectMS; - GLuint mFramebufferTextureMS; - GLuint mDepthRenderbufferObject; static lcProgram mPrograms[LC_NUM_MATERIALS]; diff --git a/common/lc_partselectionwidget.cpp b/common/lc_partselectionwidget.cpp index 6eeabeac..75fda9bb 100644 --- a/common/lc_partselectionwidget.cpp +++ b/common/lc_partselectionwidget.cpp @@ -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)) diff --git a/common/lc_partselectionwidget.h b/common/lc_partselectionwidget.h index 4c80820c..f05e739d 100644 --- a/common/lc_partselectionwidget.h +++ b/common/lc_partselectionwidget.h @@ -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 mRenderFramebuffer; }; class lcPartSelectionListView : public QListView @@ -179,4 +182,3 @@ protected: lcPartSelectionListView* mPartsWidget; QSplitter* mSplitter; }; - diff --git a/common/project.cpp b/common/project.cpp index 3f9a6a7b..6d60332f 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -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 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 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(); } } diff --git a/common/view.cpp b/common/view.cpp index 50da0daf..0ce8efde 100644 --- a/common/view.cpp +++ b/common/view.cpp @@ -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++) diff --git a/common/view.h b/common/view.h index 1c2efc19..49250c8d 100644 --- a/common/view.h +++ b/common/view.h @@ -167,6 +167,7 @@ protected: PieceInfo* mMouseDownPiece; bool mHighlight; QImage mRenderImage; + std::pair mRenderFramebuffer; lcVertexBuffer mGridBuffer; int mGridSettings[7];