diff --git a/common/image.cpp b/common/image.cpp index 523f28c1..82acb6be 100644 --- a/common/image.cpp +++ b/common/image.cpp @@ -33,6 +33,19 @@ Image::Image() mFormat = LC_PIXEL_FORMAT_INVALID; } +Image::Image(Image&& Other) +{ + mData = Other.mData; + mWidth = Other.mWidth; + mHeight = Other.mHeight; + mFormat = Other.mFormat; + + Other.mData = nullptr; + Other.mWidth = 0; + Other.mHeight = 0; + Other.mFormat = LC_PIXEL_FORMAT_INVALID; +} + Image::~Image() { FreeData(); diff --git a/common/image.h b/common/image.h index 714f6787..31597a6e 100644 --- a/common/image.h +++ b/common/image.h @@ -17,6 +17,7 @@ class Image { public: Image(); + Image(Image&& Other); virtual ~Image(); int GetBPP() const; diff --git a/common/lc_library.cpp b/common/lc_library.cpp index 82b7574b..c0cf4045 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -1777,12 +1777,12 @@ void lcPiecesLibrary::QueueTextureUpload(lcTexture* Texture) mTextureUploads.push_back(Texture); } -void lcPiecesLibrary::UploadTextures() +void lcPiecesLibrary::UploadTextures(lcContext* Context) { QMutexLocker Lock(&mTextureMutex); for (lcTexture* Texture : mTextureUploads) - Texture->Upload(); + Texture->Upload(Context); mTextureUploads.clear(); } diff --git a/common/lc_library.h b/common/lc_library.h index 5cf8143d..c87321fc 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -190,7 +190,7 @@ public: bool LoadTexture(lcTexture* Texture); void ReleaseTexture(lcTexture* Texture); void QueueTextureUpload(lcTexture* Texture); - void UploadTextures(); + void UploadTextures(lcContext* Context); bool PieceInCategory(PieceInfo* Info, const char* CategoryKeywords) const; void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray& SinglePieces, lcArray& GroupedPieces); diff --git a/common/lc_scene.cpp b/common/lc_scene.cpp index 4e4d7527..5f751301 100644 --- a/common/lc_scene.cpp +++ b/common/lc_scene.cpp @@ -233,7 +233,7 @@ void lcScene::Draw(lcContext* Context) const { // TODO: find a better place for these updates lcGetPiecesLibrary()->UpdateBuffers(Context); - lcGetPiecesLibrary()->UploadTextures(); + lcGetPiecesLibrary()->UploadTextures(Context); Context->SetViewMatrix(mViewMatrix); diff --git a/common/lc_stringcache.cpp b/common/lc_stringcache.cpp index f3a01263..43bf6cc1 100644 --- a/common/lc_stringcache.cpp +++ b/common/lc_stringcache.cpp @@ -8,13 +8,11 @@ lcStringCache gStringCache; lcStringCache::lcStringCache() { mTexture = nullptr; - mBuffer = nullptr; mRefCount = 0; } lcStringCache::~lcStringCache() { - delete mBuffer; delete mTexture; } @@ -23,21 +21,7 @@ void lcStringCache::AddRef(lcContext* Context) mRefCount++; if (mRefCount == 1) - { mTexture = new lcTexture(); - mTexture->mWidth = 256; - mTexture->mHeight = 256; - - glGenTextures(1, &mTexture->mTexture); - Context->BindTexture2D(mTexture->mTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - mBuffer = new unsigned char[mTexture->mWidth * mTexture->mHeight * 2]; - - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, mTexture->mWidth, mTexture->mHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, mBuffer); - } } void lcStringCache::Release(lcContext* Context) @@ -50,12 +34,10 @@ void lcStringCache::Release(lcContext* Context) delete mTexture; mTexture = nullptr; - delete mBuffer; - mBuffer = nullptr; } } -void lcStringCache::CacheStrings(lcContext* Context, const QStringList& Strings) +void lcStringCache::CacheStrings(const QStringList& Strings) { bool Update = false; @@ -71,11 +53,14 @@ void lcStringCache::CacheStrings(lcContext* Context, const QStringList& Strings) if (!Update) return; + Image TextureImage; + TextureImage.Allocate(256, 256, LC_PIXEL_FORMAT_L8A8); + QImage Image(128, 128, QImage::Format_ARGB32); QPainter Painter; QFont Font("Helvetica", 20); int DestX = 0, DestY = 0, DestHeight = 0; - memset(mBuffer, 0, mTexture->mWidth * mTexture->mHeight * 2); + memset(TextureImage.mData, 0, TextureImage.mWidth * TextureImage.mHeight * 2); for (auto& Entry : mStrings) { @@ -89,29 +74,29 @@ void lcStringCache::CacheStrings(lcContext* Context, const QStringList& Strings) Painter.drawText(0, 0, Image.width(), Image.height(), 0, Entry.first, &SourceRect); Painter.end(); - if (DestX + SourceRect.width() > mTexture->mWidth) + if (DestX + SourceRect.width() + 2 > TextureImage.mWidth) { DestX = 0; - DestY += DestHeight; + DestY += DestHeight + 2; DestHeight = 0; } lcStringCacheEntry& String = Entry.second; - if (SourceRect.width() > mTexture->mWidth || DestY + SourceRect.height() > mTexture->mHeight) + if (SourceRect.width() + 2 > TextureImage.mWidth || DestY + SourceRect.height() + 2 > TextureImage.mHeight || DestY + SourceRect.height() + 2 > TextureImage.mHeight) { memset(&String, 0, sizeof(String)); break; } - String.Top = mTexture->mHeight - DestY - 1; - String.Bottom = String.Top - SourceRect.height(); - String.Left = DestX; - String.Right = DestX + SourceRect.width(); + String.Top = TextureImage.mHeight - DestY - 2; + String.Bottom = String.Top - SourceRect.height() + 1; + String.Left = DestX + 1; + String.Right = String.Left + SourceRect.width() - 2; for (int y = SourceRect.top(); y < SourceRect.bottom(); y++) { - unsigned char* Dest = mBuffer + ((String.Top - y) * mTexture->mWidth + String.Left) * 2; + unsigned char* Dest = TextureImage.mData + ((String.Top - y) * TextureImage.mWidth + String.Left) * 2; for (int x = SourceRect.left(); x < SourceRect.right(); x++) { @@ -120,12 +105,11 @@ void lcStringCache::CacheStrings(lcContext* Context, const QStringList& Strings) } } - DestX += SourceRect.width(); + DestX += SourceRect.width() + 2; DestHeight = qMax(DestHeight, SourceRect.height()); } - Context->BindTexture2D(mTexture->mTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, mTexture->mWidth, mTexture->mHeight, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, mBuffer); + mTexture->SetImage(&TextureImage, LC_TEXTURE_MIPMAPS | LC_TEXTURE_ANISOTROPIC); } void lcStringCache::GetStringDimensions(int* cx, int* cy, const QString& String) const diff --git a/common/lc_stringcache.h b/common/lc_stringcache.h index 13a4fb96..a7201807 100644 --- a/common/lc_stringcache.h +++ b/common/lc_stringcache.h @@ -14,13 +14,12 @@ public: void AddRef(lcContext* Context); void Release(lcContext* Context); - void CacheStrings(lcContext* Context, const QStringList& Strings); + void CacheStrings(const QStringList& Strings); void GetStringDimensions(int* cx, int* cy, const QString& String) const; void DrawStrings(lcContext* Context, const lcMatrix44* Transforms, const QStringList& Strings) const; protected: lcTexture* mTexture; - unsigned char* mBuffer; int mRefCount; std::map mStrings; diff --git a/common/lc_texture.cpp b/common/lc_texture.cpp index ecd03a22..796a24a2 100644 --- a/common/lc_texture.cpp +++ b/common/lc_texture.cpp @@ -187,12 +187,21 @@ bool lcTexture::Load(lcMemFile& File, int Flags) return Load(Flags); } -void lcTexture::Upload() +void lcTexture::SetImage(Image* Image, int Flags) +{ + mImages.clear(); + mImages.emplace_back(std::move(*Image)); + + Load(Flags); +} + +void lcTexture::Upload(lcContext* Context) { mWidth = mImages[0].mWidth; mHeight = mImages[0].mHeight; - glGenTextures(1, &mTexture); + if (!mTexture) + glGenTextures(1, &mTexture); int Filters[2][5] = { @@ -204,7 +213,7 @@ void lcTexture::Upload() int FilterIndex = FilterFlags >> LC_TEXTURE_FILTER_SHIFT; int MipIndex = mFlags & LC_TEXTURE_MIPMAPS ? 0 : 1; - glBindTexture(GL_TEXTURE_2D, mTexture); + Context->BindTexture2D(mTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (mFlags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (mFlags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filters[MipIndex][FilterIndex]); @@ -269,7 +278,7 @@ void lcTexture::Upload() } } - glBindTexture(GL_TEXTURE_2D, 0); + Context->UnbindTexture2D(mTexture); } bool lcTexture::Load(int Flags) diff --git a/common/lc_texture.h b/common/lc_texture.h index 44ad0b68..87b5209a 100644 --- a/common/lc_texture.h +++ b/common/lc_texture.h @@ -26,7 +26,8 @@ public: bool Load(const QString& FileName, int Flags = 0); bool Load(lcMemFile& File, int Flags = 0); - void Upload(); + void SetImage(Image* Image, int Flags = 0); + void Upload(lcContext* Context); void Unload(); void AddRef() diff --git a/common/lc_viewcube.cpp b/common/lc_viewcube.cpp index d3c9612b..4585d319 100644 --- a/common/lc_viewcube.cpp +++ b/common/lc_viewcube.cpp @@ -228,7 +228,7 @@ void lcViewCube::Draw() lcMatrix44(lcVector4(0.0f, -Scale, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, Scale, 0.0f), lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(-BoxSize - 0.01f, 0.0f, 0.0f, 1.0f)) }; - gStringCache.CacheStrings(Context, ViewNames); + gStringCache.CacheStrings(ViewNames); // todo: precache earlier because the texture only gets uploaded on the next frame gStringCache.DrawStrings(Context, ViewMatrices, ViewNames); glDisable(GL_BLEND);