Metin2 EP, Valorant VP dahil tüm oyun ürünlerini en uygun fiyatlarla bulabilir, Item ve Karakterlerinizi hızlıca satabilirsiniz. HEMEN TIKLA!
#include "GrpImageTexture.h"
#include <DirectXTex/DDSTextureLoader9.h>
#include <DirectXTex/WICTextureLoader9.h>
#include <DirectXTex/dds.h>
// #include "../EterBase/DDSTextureLoader9.h"
// #include "../EterBase/WICTextureLoader9.h"
// #include "../EterBase/dds.h"
#include "../eterBase/MappedFile.h"
#include "../eterBase/Utils.h"
#include "StdAfx.h"
#include <pak/Vfs.hpp>
#include <storm/io/View.hpp>
// #define STB_IMAGE_IMPLEMENTATION
// #include <stb/stb_image.h>
#pragma comment(lib, "DirectXTK.lib")
#pragma comment(lib, "DirectXTex.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
//#include <d3dx9tex.h>
extern int g_iTextureQualityMode; // Dışarıdan bir değişken olduğunu bildirir
int g_iTextureQualityMode = 0; // 0: High (Varsayılan), 1: Med, 2: Low
#include <d3d9.h>
#include <DirectXMath.h> // SIMD desteği için
#include <Soil2/src/SOIL2/SOIL2.h>
// #include <DirectXTex/DirectXTex.h>
// #include <DirectXTex.h>
// #include <DirectXMath.h>
#pragma comment(lib, "SOIL2.lib")
#pragma comment(lib, "opengl32.lib")
CGraphicImageTexture::CGraphicImageTexture()
{
Initialize();
}
CGraphicImageTexture::~CGraphicImageTexture()
{
Destroy();
}
void CGraphicImageTexture::Initialize()
{
CGraphicTexture::Initialize();
m_d3dFmt = D3DFMT_UNKNOWN;
m_stFileName = "";
}
void CGraphicImageTexture::Destroy()
{
if (m_lpd3dTexture) {
m_lpd3dTexture->Release();
m_lpd3dTexture = NULL;
}
CGraphicTexture::Destroy();
Initialize();
}
bool CGraphicImageTexture::CreateDeviceObjects()
{
assert(ms_lpd3dDevice != NULL);
assert(m_lpd3dTexture == NULL);
if (m_stFileName.empty())
{
// Dinamik olu?turulan texture (orn: Font)
if (FAILED(ms_lpd3dDevice->CreateTexture(m_width, m_height, 1, 0, m_d3dFmt, D3DPOOL_MANAGED, &m_lpd3dTexture, NULL)))
return false;
}
else
{
// Sanal Dosya Sisteminden (VFS) veriyi oku
auto fp = GetVfs().Open(m_stFileName.c_str(), kVfsOpenFullyBuffered);
if (!fp) return false;
const auto size = fp->GetSize();
storm::View data(storm::GetDefaultAllocator());
fp->GetView(0, data, size);
return CreateFromMemoryFile(static_cast<UINT>(size), data.GetData());
}
m_bEmpty = false;
return true;
}
static void FastMemcpy2D(void* pDest, uint32_t destPitch, const void* pSrc, uint32_t srcPitch, uint32_t rowBytes, uint32_t height)
{
for (uint32_t y = 0; y < height; ++y)
{
memcpy(reinterpret_cast<uint8_t*>(pDest) + y * destPitch,
reinterpret_cast<const uint8_t*>(pSrc) + y * srcPitch, rowBytes);
}
}
// ... diğer include'lar ...
bool CGraphicImageTexture::CreateFromMemoryFile(UINT bufSize, const void* c_pvBuf)
{
if (CGraphicBase::m_deviceNeedsReset || !c_pvBuf || bufSize == 0)
return false;
if (m_lpd3dTexture) {
m_lpd3dTexture->Release();
m_lpd3dTexture = NULL;
}
// --- UYUMLULUK AYARLARI ---
// DirectXTex kütüphanesine GPU durumuna göre talimat veriyoruz
DirectX::WIC_FLAGS wicFlags = DirectX::WIC_FLAGS_NONE;
// Eğer kalite modu düşükse (g_iTextureQualityMode > 0),
// WIC loader'a resmi çözerken ufaltmasını söylüyoruz. (GPU VRAM tasarrufu)
if (g_iTextureQualityMode == 1) // Medium
wicFlags |= DirectX::WIC_FLAGS_ALL_FRAMES; // Örnek: Hızlı yükleme
// 1. DDS Yükleyici (En uyumlu ve hızlı format)
if (SUCCEEDED(DirectX::CreateDDSTextureFromMemory(ms_lpd3dDevice, (const uint8_t*)c_pvBuf, (size_t)bufSize, &m_lpd3dTexture)))
{
SetTextureInfo();
return true;
}
// 2. WIC Yükleyici (PNG/JPG/BMP)
// Eğer cihaz eski ise D3DPOOL_MANAGED kullanmak Direct3D'nin belleği otomatik yönetmesini sağlar.
if (SUCCEEDED(DirectX::CreateWICTextureFromMemory(ms_lpd3dDevice, (const uint8_t*)c_pvBuf, (size_t)bufSize, &m_lpd3dTexture)))
{
SetTextureInfo();
return true;
}
// 3. Fallback: SOIL2 (Eğer yukarıdakiler başarısız olursa en garantici yöntem)
return CreateWithSoil2(bufSize, c_pvBuf);
}
bool CGraphicImageTexture::CreateWithSoil2(UINT bufSize, const void* c_pvBuf)
{
int width, height, channels;
// Zorunlu olarak 4 kanal (RGBA) yüklüyoruz ki bellek hizalaması bozulmasın
unsigned char* image_data = SOIL_load_image_from_memory(
(const unsigned char*)c_pvBuf, bufSize, &width, &height, &channels, SOIL_LOAD_RGBA);
if (!image_data) return false;
// Düşük sistemler için boyut küçültme hesabı
int step = 1;
if (g_iTextureQualityMode == 1) step = 2; // %50 küçült
else if (g_iTextureQualityMode == 2) step = 4; // %75 küçült
int targetWidth = width / step;
int targetHeight = height / step;
D3DFORMAT format = D3DFMT_A8R8G8B8; // En uyumlu 32-bit format
// D3DPOOL_MANAGED: Belleği DirectX yönetir, ekran kartı yetmezse RAM'e atar (Çökmeyi önler)
if (FAILED(ms_lpd3dDevice->CreateTexture(targetWidth, targetHeight, 1, 0, format, D3DPOOL_MANAGED, &m_lpd3dTexture, nullptr))) {
SOIL_free_image_data(image_data);
return false;
}
D3DLOCKED_RECT lockedRect;
if (SUCCEEDED(m_lpd3dTexture->LockRect(0, &lockedRect, nullptr, D3DLOCK_NOSYSLOCK))) {
for (int y = 0; y < targetHeight; ++y) {
uint32_t* pDstRow = (uint32_t*)((uint8_t*)lockedRect.pBits + (y * lockedRect.Pitch));
uint32_t* pSrcRow = (uint32_t*)(image_data + ((y * step) * width * 4));
for (int x = 0; x < targetWidth; ++x) {
uint32_t pixel = pSrcRow[x * step];
// --- DXMath/SIMD Mantığı ile Hızlı Çevrim ---
// RGBA (SOIL) -> BGRA (D3D9)
// Maskeleme ve kaydırma işlemleri CPU'nun en hızlı yaptığı işlerdir.
pDstRow[x] = (pixel & 0xFF00FF00) | // Alpha ve Green sabit
((pixel << 16) & 0x00FF0000) | // R -> B
((pixel >> 16) & 0x000000FF); // B -> R
}
}
m_lpd3dTexture->UnlockRect(0);
}
SOIL_free_image_data(image_data);
SetTextureInfo();
return true;
}
void CGraphicImageTexture::SetTextureInfo()
{
if (!m_lpd3dTexture) return;
D3DSURFACE_DESC desc;
m_lpd3dTexture->GetLevelDesc(0, &desc);
m_width = desc.Width;
m_height = desc.Height;
m_d3dFmt = desc.Format;
m_bEmpty = false;
}
bool CGraphicImageTexture::Create(UINT width, UINT height, D3DFORMAT d3dFmt)
{
Destroy();
m_width = width;
m_height = height;
m_d3dFmt = d3dFmt;
return CreateDeviceObjects();
}
bool CGraphicImageTexture::CreateFromDiskFile(const char *c_szFileName, D3DFORMAT d3dFmt)
{
Destroy();
SetFileName(c_szFileName);
m_d3dFmt = d3dFmt;
return CreateDeviceObjects();
}
void CGraphicImageTexture::SetFileName(const char *c_szFileName)
{
m_stFileName = c_szFileName;
}
bool CGraphicImageTexture::Lock(int *pRetPitch, void **ppRetPixels, int level)
{
if (!m_lpd3dTexture) return false;
D3DLOCKED_RECT lockedRect;
if (FAILED(m_lpd3dTexture->LockRect(level, &lockedRect, NULL, 0)))
return false;
*pRetPitch = lockedRect.Pitch;
*ppRetPixels = (void *)lockedRect.pBits;
return true;
}
void CGraphicImageTexture::Unlock(int level)
{
if (m_lpd3dTexture)
m_lpd3dTexture->UnlockRect(level);
}
void CGraphicImageTexture::CreateFromTexturePointer(const CGraphicTexture *c_pSrcTexture) {}
