Reuse the same FBO when creating new preview images.

This commit is contained in:
Leonardo
2017-12-29 06:50:18 -08:00
parent 1541d05c31
commit 50b3e95215
7 changed files with 202 additions and 129 deletions
+119 -105
View File
@@ -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
View File
@@ -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];
+10 -3
View File
@@ -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))
+3 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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++)
+1
View File
@@ -167,6 +167,7 @@ protected:
PieceInfo* mMouseDownPiece;
bool mHighlight;
QImage mRenderImage;
std::pair<lcFramebuffer, lcFramebuffer> mRenderFramebuffer;
lcVertexBuffer mGridBuffer;
int mGridSettings[7];