2 mesaje
  • Mesaje: 19
  • Reacții: 11
  • Mesaje utile: 0
  • Medalii

    https://github.com/SpartanJ/SOIL2

    Primary (DirectX 8 / .dds): Used for compressed textures to save VRAM and improve loading speeds.

    Secondary (SOIL2): Handles standard formats like .png and .tga. It also acts as a fallback if a .dds file fails to load (e.g., due to unsupported pixel dimensions or header corruption).

    Alternative (stb_image): While stb_image is excellent for portability, it lacks native .dds support, making it less "hybrid-friendly" for this specific DX8 workflow compared to SOIL2.


    gemini AI



    GraphicImageTexture.cpp
    Code:
    #include "StdAfx.h"
    
    #include "../eterBase/MappedFile.h"
    
    #include "../eterPack/EterPackManager.h"
    
    #include "GrpImageTexture.h"
    
    
    
    #include "SOIL2.h"
    
    #pragma comment(lib, "soil2.lib")
    
    #pragma comment(lib, "legacy_stdio_definitions.lib")
    
    #pragma comment(lib, "Opengl32.lib")



    Code:
    bool CGraphicImageTexture::CreateFromMemoryFile(UINT bufSize, const void* c_pvBuf, D3DFORMAT d3dFmt, DWORD dwFilter)
    
    {
    
        assert(ms_lpd3dDevice != NULL);
    
        assert(m_lpd3dTexture == NULL);
    
    
    
        bool bDDSLoaded = false;
    
        static CDXTCImage image;
    
    
    
        // 1. Önce DDS olarak dene
    
        if (image.LoadHeaderFromMemory((const BYTE*)c_pvBuf))
    
        {
    
            // Header yüklendi, şimdi dokuyu oluşturmayı dene
    
            if (CreateDDSTexture(image, (const BYTE*)c_pvBuf))
    
            {
    
                bDDSLoaded = true;
    
            }
    
            else
    
            {
    
                // DDS oluşturma başarısız olduysa buraya düşer, SOIL2 deneyecek
    
                TraceError("CGraphicImageTexture::CreateFromMemoryFile: DDS CreateDDSTexture failed, trying SOIL2 fallback.");
    
            }
    
        }
    
    
    
        // 2. Eğer DDS yüklenemediyse veya hata verdiyse SOIL2 kullan
    
        if (!bDDSLoaded)
    
        {
    
            int width, height, channels;
    
            unsigned char* imgData = SOIL_load_image_from_memory(
    
                (const unsigned char*)c_pvBuf,
    
                bufSize,
    
                &width,
    
                &height,
    
                &channels,
    
                SOIL_LOAD_RGBA
    
            );
    
    
    
            if (!imgData)
    
            {
    
                TraceError("SOIL2 yukleme hatasi (DDS Fallback dahil): %s", SOIL_last_result());
    
                return false;
    
            }
    
    
    
            // D3D8 Texture oluştur
    
            if (FAILED(ms_lpd3dDevice->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_lpd3dTexture)))
    
            {
    
                SOIL_free_image_data(imgData);
    
                return false;
    
            }
    
    
    
            D3DLOCKED_RECT lockedRect;
    
            if (SUCCEEDED(m_lpd3dTexture->LockRect(0, &lockedRect, NULL, 0)))
    
            {
    
                unsigned char* pDst = (unsigned char*)lockedRect.pBits;
    
                for (int y = 0; y < height; ++y)
    
                {
    
                    for (int x = 0; x < width; ++x)
    
                    {
    
                        int i = (y * width + x) * 4;
    
                        // Pitch hesabı: D3D yüzey genişliği her zaman 4'ün katı olmayabilir,
    
                        // bu yüzden byte bazlı pitch (lockedRect.Pitch) kullanıyoruz.
    
                        int di = (y * lockedRect.Pitch) + (x * 4);
    
    
    
                        pDst[di + 0] = imgData[i + 2]; // Blue
    
                        pDst[di + 1] = imgData[i + 1]; // Green
    
                        pDst[di + 2] = imgData[i + 0]; // Red
    
                        pDst[di + 3] = imgData[i + 3]; // Alpha
    
                    }
    
                }
    
                m_lpd3dTexture->UnlockRect(0);
    
            }
    
    
    
            m_width = width;
    
            m_height = height;
    
            SOIL_free_image_data(imgData);
    
        }
    
    
    
        m_bEmpty = false;
    
        return true;
    
    }
    GuildMarkUploader.cpp
    Code:
    #include "SOIL2.h"
    
    
    
    bool CGuildMarkUploader::__Load(const char* c_szFileName, UINT* peError)
    
    {
    
        int width = 0;
    
        int height = 0;
    
        int channels = 0;
    
    
    
        // SOIL2 ile resmi RGBA olarak yükle
    
        unsigned char* imgData = SOIL_load_image(c_szFileName, &width, &height, &channels, SOIL_LOAD_RGBA);
    
    
    
        if (!imgData)
    
        {
    
            *peError = ERROR_LOAD;
    
            return false;
    
        }
    
    
    
        // Genişlik kontrolü
    
        if (width != SGuildMark::WIDTH)
    
        {
    
            SOIL_free_image_data(imgData);
    
            *peError = ERROR_WIDTH;
    
            return false;
    
        }
    
    
    
        // Yükseklik kontrolü
    
        if (height != SGuildMark::HEIGHT)
    
        {
    
            SOIL_free_image_data(imgData);
    
            *peError = ERROR_HEIGHT;
    
            return false;
    
        }
    
    
    
        // SOIL2 veriyi RGBA verir, Metin2 lonca simgesi için BGRA formatı gerekir.
    
        // Pikselleri m_kMark.m_apxBuf içine kopyalarken renk kanallarını çeviriyoruz.
    
        unsigned char* pDst = (unsigned char*)m_kMark.m_apxBuf;
    
     
    
        for (int i = 0; i < width * height; ++i)
    
        {
    
            int srcIdx = i * 4;
    
            int dstIdx = i * 4;
    
    
    
            pDst[dstIdx + 0] = imgData[srcIdx + 2]; // Blue
    
            pDst[dstIdx + 1] = imgData[srcIdx + 1]; // Green
    
            pDst[dstIdx + 2] = imgData[srcIdx + 0]; // Red
    
            pDst[dstIdx + 3] = imgData[srcIdx + 3]; // Alpha
    
        }
    
    
    
        // Belleği temizle
    
        SOIL_free_image_data(imgData);
    
     
    
        return true;
    
    }


    pythonappilciionmodule


    Code:
    #include "SOIL2.h"
    
    
    
    // #include <SOIL2.h>
    
    
    
    PyObject* appGetImageInfo(PyObject* poSelf, PyObject* poArgs)
    
    {
    
        char* szFileName;
    
        if (!PyTuple_GetString(poArgs, 0, &szFileName))
    
            return Py_BuildException();
    
    
    
        int width = 0;
    
        int height = 0;
    
        int channels = 0;
    
        BOOL canLoad = FALSE;
    
    
    
        // SOIL_load_image doğrudan resmi yüklemeye çalışır.
    
        // Eğer dosya yoksa veya formatı desteklemiyorsa NULL döner.
    
        unsigned char* temp_info = SOIL_load_image(szFileName, &width, &height, &channels, SOIL_LOAD_AUTO);
    
    
    
        if (temp_info)
    
        {
    
            canLoad = TRUE;
    
            // Boyutları aldık, belleği hemen temizle
    
            SOIL_free_image_data(temp_info);
    
        }
    
        else
    
        {
    
            // Dosya bulunamadı veya SOIL2 okuyamadı
    
            canLoad = FALSE;
    
            width = 0;
    
            height = 0;
    
        }
    
    
    
        return Py_BuildValue("iii", canLoad, width, height);
    
    }

    Project Specifications
    Platform: Windows 32-bit (x86)

    Compiler: Visual Studio 2022

    Language Standard: ISO C++20 Standard (/std:c++20)

    Runtime Library: Multi-threaded (/MT) — Static linking



    lib konuya ekliyorum.

    cmake ile build alabilirsiniz.

    cmke v3 latest
    Code:
    
    #include "image_array.h"
    
    #include <stdlib.h>
    
    #include <string.h>
    
    #include "image_helper.h"
    
    
    
    extern const char *result_string_pointer;
    
    
    
    void SOIL_image_array_free(SOIL_ImageArray *imgArray){
    
        if(imgArray == NULL){
    
            return;
    
        }
    
    
    
        if(imgArray->data != NULL){
    
            for(int i = 0; i < imgArray->layers; i++){
    
                if(imgArray->data[i] != NULL){
    
                    free(imgArray->data[i]);
    
                }
    
            }
    
            free(imgArray->data);
    
        }
    
    
    
        imgArray->data = NULL;
    
        imgArray->width = 0;
    
        imgArray->height = 0;
    
        imgArray->layers = 0;
    
        imgArray->channels = 0;
    
    }
    
    
    
    void image_array_invert_y(SOIL_ImageArray* imgArray){
    
    
    
        if (!imgArray || !imgArray->data)
    
            return;
    
    
    
        const size_t rowBytes = (size_t)(imgArray->width) * (size_t)(imgArray->channels);
    
    
    
        for (int layer = 0; layer < imgArray->layers; ++layer) {
    
    
    
            unsigned char *image = imgArray->data[layer];
    
    
    
            if (!image) continue;
    
    
    
            for (int y = 0; y < imgArray->height / 2; ++y) {
    
                unsigned char *rowTop = image + (size_t)y * rowBytes;
    
                unsigned char *rowBottom = image + (size_t)(imgArray->height - 1 - y) * rowBytes;
    
    
    
                for (size_t x = 0; x < rowBytes; ++x) {
    
                    unsigned char temp = rowTop[x];
    
                    rowTop[x] = rowBottom[x];
    
                    rowBottom[x] = temp;
    
                }
    
            }
    
        }
    
    }
    
    
    
    void image_array_premultiply_alpha(SOIL_ImageArray* imgArray){
    
    
    
        if (!imgArray || !imgArray->data)
    
            return;
    
    
    
        const size_t numPixels = (size_t)(imgArray->width) * (size_t)(imgArray->height);
    
    
    
        for (int layer = 0; layer < imgArray->layers; ++layer) {
    
    
    
            unsigned char *image = imgArray->data[layer];
    
    
    
            if (!image) continue;
    
    
    
            for (size_t i = 0; i < numPixels; ++i) {
    
                unsigned char *pixel = image + i * (size_t)(imgArray->channels);
    
    
    
                if (imgArray->channels >= 4) {
    
                    float alpha = pixel[3] / 255.0f;
    
                    pixel[0] = (unsigned char)(pixel[0] * alpha);
    
                    pixel[1] = (unsigned char)(pixel[1] * alpha);
    
                    pixel[2] = (unsigned char)(pixel[2] * alpha);
    
                }
    
            }
    
        }
    
    }
    
    
    
    void image_array_to_NTSC_safe(SOIL_ImageArray* imgArray){
    
    
    
        if (!imgArray || !imgArray->data)
    
            return;
    
    
    
        const size_t numPixels = (size_t)(imgArray->width) * (size_t)(imgArray->height);
    
    
    
        for (int layer = 0; layer < imgArray->layers; ++layer) {
    
    
    
            unsigned char *image = imgArray->data[layer];
    
    
    
            if (!image) continue;
    
    
    
            for (size_t i = 0; i < numPixels; ++i) {
    
                unsigned char *pixel = image + i * (size_t)(imgArray->channels);
    
    
    
                if (imgArray->channels >= 3) {
    
                    unsigned char r = pixel[0];
    
                    unsigned char g = pixel[1];
    
                    unsigned char b = pixel[2];
    
    
    
                    unsigned char y  = (unsigned char)(0.299f * r + 0.587f * g + 0.114f * b);
    
                    unsigned char co = (unsigned char)(r - b + 128);
    
                    unsigned char cg = (unsigned char)(-0.168736f * r - 0.331264f * g + 0.5f * b + 128);
    
    
    
                    pixel[0] = co;
    
                    pixel[1] = cg;
    
                    pixel[2] = y;
    
                }
    
            }
    
        }
    
    
    
    }
    
    
    
    void image_array_to_YCoCg(SOIL_ImageArray* imgArray){
    
    
    
        if (!imgArray || !imgArray->data)
    
            return;
    
    
    
        const size_t numPixels = (size_t)(imgArray->width) * (size_t)(imgArray->height);
    
    
    
        for (int layer = 0; layer < imgArray->layers; ++layer) {
    
    
    
            unsigned char *image = imgArray->data[layer];
    
    
    
            if (!image) continue;
    
    
    
            for (size_t i = 0; i < numPixels; ++i) {
    
                unsigned char *pixel = image + i * (size_t)(imgArray->channels);
    
    
    
                if (imgArray->channels >= 3) {
    
                    unsigned char r = pixel[0];
    
                    unsigned char g = pixel[1];
    
                    unsigned char b = pixel[2];
    
    
    
                    int y  = (  r + ( 2 * g ) +   b ) >> 2;
    
                    int co = (  r           -   b ) >> 1;
    
                    int cg = ( -r + ( 2 * g ) -   b ) >> 2;
    
    
    
                    pixel[0] = (unsigned char)(co + 128);
    
                    pixel[1] = (unsigned char)(cg + 128);
    
                    pixel[2] = (unsigned char)(y);
    
                }
    
            }
    
        }
    
    }
    
    
    
    static int next_power_of_two(int v)
    
    {
    
        int r = 1;
    
        while (r < v)
    
            r <<= 1;
    
        return r;
    
    }
    
    
    
    int image_array_resize_POT(SOIL_ImageArray *imgArray)
    
    {
    
        if (!imgArray || !imgArray->data)
    
            return 1;
    
    
    
        int new_w = next_power_of_two(imgArray->width);
    
        int new_h = next_power_of_two(imgArray->height);
    
    
    
        if (new_w == imgArray->width && new_h == imgArray->height)
    
            return 1;
    
    
    
        for (int layer = 0; layer < imgArray->layers; ++layer) {
    
    
    
            unsigned char *src = imgArray->data[layer];
    
            if (!src)
    
                continue;
    
    
    
            unsigned char *dst = (unsigned char*)malloc(
    
                (size_t)new_w * (size_t)new_h * (size_t)imgArray->channels
    
            );
    
    
    
            if (!dst)
    
                return 0;
    
    
    
            up_scale_image(
    
                src,
    
                imgArray->width,
    
                imgArray->height,
    
                imgArray->channels,
    
                dst,
    
                new_w,
    
                new_h
    
            );
    
    
    
            free(src);
    
            imgArray->data[layer] = dst;
    
        }
    
    
    
        imgArray->width  = new_w;
    
        imgArray->height = new_h;
    
    
    
        return 1;
    
    }
    
    
    
    int image_array_reduce_to_max(SOIL_ImageArray *imgArray, int max_size)
    
    {
    
        if (!imgArray || !imgArray->data)
    
            return 1;
    
    
    
        if (imgArray->width <= max_size &&
    
            imgArray->height <= max_size)
    
            return 1;
    
    
    
        int reduce_block_x = 1;
    
        int reduce_block_y = 1;
    
    
    
        if (imgArray->width > max_size)
    
            reduce_block_x = imgArray->width / max_size;
    
    
    
        if (imgArray->height > max_size)
    
            reduce_block_y = imgArray->height / max_size;
    
    
    
        int new_w = imgArray->width  / reduce_block_x;
    
        int new_h = imgArray->height / reduce_block_y;
    
    
    
        for (int layer = 0; layer < imgArray->layers; ++layer) {
    
    
    
            unsigned char *src = imgArray->data[layer];
    
            if (!src)
    
                continue;
    
    
    
            unsigned char *dst = (unsigned char*)malloc(
    
                (size_t)new_w * (size_t)new_h * (size_t)imgArray->channels
    
            );
    
    
    
            if (!dst)
    
                return 0;
    
    
    
            mipmap_image(
    
                src,
    
                imgArray->width,
    
                imgArray->height,
    
                imgArray->channels,
    
                dst,
    
                reduce_block_x,
    
                reduce_block_y
    
            );
    
    
    
            free(src);
    
            imgArray->data[layer] = dst;
    
        }
    
    
    
        imgArray->width  = new_w;
    
        imgArray->height = new_h;
    
    
    
        return 1;
    
    }
    
    
    
    SOIL_ImageArray extract_image_array_from_atlas_grid(
    
        const unsigned char *atlasData,
    
        int atlasW,
    
        int atlasH,
    
        int cols,
    
        int rows,
    
        int channels
    
    ){
    
        SOIL_ImageArray result = {0};
    
    
    
        if (!atlasData || cols <= 0 || rows <= 0 || channels <= 0)
    
            return result;
    
    
    
        if (atlasW % cols != 0 || atlasH % rows != 0)
    
        {
    
            result_string_pointer = "Atlas cannot be evenly divided by grid";
    
            return result;
    
        }
    
    
    
        int tile_w = atlasW / cols;
    
        int tile_h = atlasH / rows;
    
        int numLayers = cols * rows;
    
    
    
        result.width    = tile_w;
    
        result.height   = tile_h;
    
        result.layers   = numLayers;
    
        result.channels = channels;
    
    
    
        result.data = (unsigned char**)malloc(sizeof(unsigned char*) * numLayers);
    
        if (!result.data){
    
            SOIL_ImageArray empty;
    
            memset(&empty, 0, sizeof(empty));
    
            return empty;
    
        }
    
    
    
        for (int i = 0; i < numLayers; ++i)
    
            result.data[i] = NULL;
    
    
    
        const size_t bytesPerPixel = (size_t)channels;
    
        const size_t tileRowBytes  = (size_t)tile_w * bytesPerPixel;
    
        const size_t atlasRowBytes = (size_t)atlasW * bytesPerPixel;
    
    
    
        for (int r = 0; r < rows; ++r) {
    
            for (int c = 0; c < cols; ++c) {
    
                int layer = r * cols + c;
    
    
    
                unsigned char *tile =
    
                    (unsigned char*)malloc((size_t)tile_w * tile_h * bytesPerPixel);
    
    
    
                if (!tile) {
    
                    /* cleanup */
    
                    for (int i = 0; i < numLayers; ++i)
    
                        free(result.data[i]);
    
                    free(result.data);
    
    
    
                    SOIL_ImageArray empty;
    
                    memset(&empty, 0, sizeof(empty));
    
    
    
                    return empty;
    
                }
    
    
    
                for (int y = 0; y < tile_h; ++y) {
    
                    const unsigned char *src =
    
                        atlasData +
    
                        ((size_t)(r * tile_h + y) * atlasRowBytes) +
    
                        ((size_t)c * tileRowBytes);
    
    
    
                    unsigned char *dst = tile + (size_t)y * tileRowBytes;
    
                    memcpy(dst, src, tileRowBytes);
    
                }
    
    
    
                result.data[layer] = tile;
    
            }
    
        }
    
    
    
        return result;
    
    }
    
    
    [C++] SOIL2 HIBRIT - Mesaj 1 - Imagine 1
    [img]./download/file.php?mode=view&amp;id=6140[/img]
    [img]./download/file.php?mode=view&id=6140[/img]
    https://virusscan.jotti.org/en-US/filescanjob/4syfytu8os



    1767472146467.png

    Nou Cum descarc de pe TeraBox?

    Afișează detalii Ascunde detalii
    • Este asemănător cu Mega.nz
    • Instalați-vă clientul lor de Download de aici
    • Faceți-vă un cont (vă puteți loga cu Facebook / Google / etc)
    • Nou Dacă nu vreți să descărcați clientul de Download, folosiți acest site
    • Gata! Acum puteți descărca resursele rapid & simplu.

    De ce folosim TeraBox?

    • Este gratuit
    • Primești 1TB de spațiu gratuit la orice cont creat!
    • Este ușor de folosit și varianta premium este foarte ieftină
    • Fișierele nu sunt șterse niciodată
    TeraBox logo

    📢 Resurse Metin2 Premium!

    Zeci de resurse Metin2 Premium - exclusive și 100% funcționale începând cu 15.99€!.

    Vezi resursele Cumpără premium
    Premium
    Premium
    Anunț
  • Mesaje: 19
  • Reacții: 11
  • Mesaje utile: 0
  • Medalii

    up
    Code:
    bool CGraphicImageTexture::CreateFromMemoryFile(UINT bufSize, const void * c_pvBuf, D3DFORMAT d3dFmt, DWORD dwFilter)
    {
        assert(ms_lpd3dDevice != NULL);
        assert(m_lpd3dTexture == NULL);
    
        static CDXTCImage image;
    
        // --- 1. ADIM: DDS (DXTC) KONTROLÜ ---
        if (image.LoadHeaderFromMemory((const BYTE *) c_pvBuf))
        {
            if (CreateDDSTexture(image, (const BYTE *) c_pvBuf))
            {
                m_bEmpty = false;
                return true;
            }
        }
    
        // --- 2. ADIM: STANDART D3DX YÜKLEME DENEMESİ ---
        D3DXIMAGE_INFO imageInfo;
        HRESULT hr = D3DXCreateTextureFromFileInMemoryEx(
                    ms_lpd3dDevice,
                    c_pvBuf,
                    bufSize,
                    D3DX_DEFAULT,
                    D3DX_DEFAULT,
                    D3DX_DEFAULT,
                    0,
                    d3dFmt,
                    D3DPOOL_MANAGED,
                    dwFilter,
                    dwFilter,
                    0xffff00ff, // Color Key (Magenta)
                    &imageInfo,
                    NULL,
                    &m_lpd3dTexture);
    
        if (SUCCEEDED(hr))
        {
            m_width = imageInfo.Width;
            m_height = imageInfo.Height;
    
            // Orijinal kodunuzdaki format optimizasyonları
            D3DFORMAT format = imageInfo.Format;
            switch(imageInfo.Format) {
                case D3DFMT_A8R8G8B8:
                    format = D3DFMT_A4R4G4B4;
                    break;
                case D3DFMT_X8R8G8B8:
                case D3DFMT_R8G8B8:
                    format = D3DFMT_A1R5G5B5;
                    break;
            }
    
            UINT uTexBias = 0;
            extern bool GRAPHICS_CAPS_HALF_SIZE_IMAGE;
            if (GRAPHICS_CAPS_HALF_SIZE_IMAGE)
                uTexBias = 1;
    
            if (IsLowTextureMemory() && (uTexBias || format != imageInfo.Format))
            {
                IDirect3DTexture8* pkTexSrc = m_lpd3dTexture;
                IDirect3DTexture8* pkTexDst = NULL;
    
                if (SUCCEEDED(D3DXCreateTexture(
                    ms_lpd3dDevice,
                    imageInfo.Width >> uTexBias,
                    imageInfo.Height >> uTexBias,
                    imageInfo.MipLevels,
                    0,
                    format,
                    D3DPOOL_MANAGED,
                    &pkTexDst)))
                {
                    m_lpd3dTexture = pkTexDst;
                    for(int i = 0; i < (int)imageInfo.MipLevels; ++i) {
                        IDirect3DSurface8* ppsSrc = NULL;
                        IDirect3DSurface8* ppsDst = NULL;
                        if (SUCCEEDED(pkTexSrc->GetSurfaceLevel(i, &ppsSrc))) {
                            if (SUCCEEDED(pkTexDst->GetSurfaceLevel(i, &ppsDst))) {
                                D3DXLoadSurfaceFromSurface(ppsDst, NULL, NULL, ppsSrc, NULL, NULL, D3DX_FILTER_LINEAR, 0);
                                ppsDst->Release();
                            }
                            ppsSrc->Release();
                        }
                    }
                    pkTexSrc->Release();
                }
            }
            
            m_bEmpty = false;
            return true;
        }
    
        // --- 3. ADIM: HATA DURUMUNDA SOIL2 FALLBACK ---
        // Eğer buraya geldiyse D3DX dosyayı açamamış demektir.
        int width, height, channels;
        unsigned char* imgData = SOIL_load_image_from_memory(
            (const unsigned char*)c_pvBuf,
            bufSize,
            &width, &height, &channels,
            SOIL_LOAD_RGBA
        );
    
        if (imgData)
        {
            // SOIL2 ile başarıyla decode edildi, şimdi manuel D3D Texture oluşturuyoruz
            if (SUCCEEDED(D3DXCreateTexture(ms_lpd3dDevice, width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_lpd3dTexture)))
            {
                D3DLOCKED_RECT rect;
                if (SUCCEEDED(m_lpd3dTexture->LockRect(0, &rect, NULL, 0)))
                {
                    unsigned char* pDestBase = (unsigned char*)rect.pBits;
                    for (int y = 0; y < height; ++y)
                    {
                        unsigned char* pDestRow = pDestBase + (y * rect.Pitch);
                        for (int x = 0; x < width; ++x)
                        {
                            int srcIdx = (y * width + x) * 4;
                            int dstIdx = x * 4;
                            // SOIL (RGBA) -> D3D (BGRA) dönüşümü
                            pDestRow[dstIdx + 0] = imgData[srcIdx + 2]; // B
                            pDestRow[dstIdx + 1] = imgData[srcIdx + 1]; // G
                            pDestRow[dstIdx + 2] = imgData[srcIdx + 0]; // R
                            pDestRow[dstIdx + 3] = imgData[srcIdx + 3]; // A
                        }
                    }
                    m_lpd3dTexture->UnlockRect(0);
                    m_width = width;
                    m_height = height;
                    m_bEmpty = false;
                    SOIL_free_image_data(imgData);
                    return true;
                }
            }
            SOIL_free_image_data(imgData);
        }
    
        // Tüm yöntemler başarısız oldu
        TraceError("CreateFromMemoryFile: Texture creation failed (D3DX and SOIL2)");
        return false;
    }
    Code:
    #include <SOIL2.h>
    
    bool CPythonGraphic::SaveJPEG(const char * pszFileName, LPBYTE pbyBuffer, UINT uWidth, UINT uHeight)
    {
        // SOIL2 doğrudan dosyaya yazabilir.
        // Not: SOIL_save_image RGB formatında veri bekler.
        int result = SOIL_save_image(
            pszFileName,
            SOIL_SAVE_TYPE_JPG,
            uWidth, uHeight, 3, // 3 kanal (RGB)
            pbyBuffer
        );
    
        return result != 0;
    }
    
    bool CPythonGraphic::SaveScreenShot(const char * c_pszFileName)
    {
        LPDIRECT3DSURFACE8 lpSurface;
        if (FAILED(ms_lpd3dDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &lpSurface)))
            return false;
    
        D3DSURFACE_DESC stSurfaceDesc;
        lpSurface->GetDesc(&stSurfaceDesc);
    
        D3DLOCKED_RECT lockRect;
        if (FAILED(lpSurface->LockRect(&lockRect, NULL, D3DLOCK_READONLY)))
        {
            lpSurface->Release();
            return false;
        }
    
        UINT uWidth = stSurfaceDesc.Width;
        UINT uHeight = stSurfaceDesc.Height;
    
        // SOIL2 için RGB buffer oluşturuyoruz (Pixel başına 3 byte)
        BYTE* pbyBuffer = new BYTE[uWidth * uHeight * 3];
        BYTE* pbySource = (BYTE*)lockRect.pBits;
        BYTE* pbyDest = pbyBuffer;
    
        for (UINT y = 0; y < uHeight; ++y)
        {
            BYTE* pRow = pbySource + (y * lockRect.Pitch);
            for (UINT x = 0; x < uWidth; ++x)
            {
                // D3D Backbuffer genellikle BGRA formatındadır.
                // SOIL_save_image bizden RGB beklediği için çeviriyoruz:
                if (stSurfaceDesc.Format == D3DFMT_A8R8G8B8 || stSurfaceDesc.Format == D3DFMT_X8R8G8B8)
                {
                    pbyDest[0] = pRow[x * 4 + 2]; // R
                    pbyDest[1] = pRow[x * 4 + 1]; // G
                    pbyDest[2] = pRow[x * 4 + 0]; // B
                    pbyDest += 3;
                }
                else if (stSurfaceDesc.Format == D3DFMT_R8G8B8)
                {
                    pbyDest[0] = pRow[x * 3 + 2]; // R
                    pbyDest[1] = pRow[x * 3 + 1]; // G
                    pbyDest[2] = pRow[x * 3 + 0]; // B
                    pbyDest += 3;
                }
                // Diğer formatlar (16 bit vs) ihtiyaca göre eklenebilir ama güncel sistemlerde Backbuffer genelde 32 bittir.
            }
        }
    
        lpSurface->UnlockRect();
        lpSurface->Release();
    
        // SOIL2 ile JPEG olarak kaydet
        bool bSaved = SaveJPEG(c_pszFileName, pbyBuffer, uWidth, uHeight);
        delete[] pbyBuffer;
    
        if (!bSaved)
            return false;
    
        if (g_isScreenShotKey)
        {
            FILE* srcFilePtr = fopen(c_pszFileName, "rb");
            if (srcFilePtr)
            {
                fseek(srcFilePtr, 0, SEEK_END);
                size_t fileSize = ftell(srcFilePtr);
                fseek(srcFilePtr, 0, SEEK_SET);
    
                char head[21];
                size_t tailSize = fileSize - sizeof(head);
                char* tail = (char*)malloc(tailSize);
    
                fread(head, sizeof(head), 1, srcFilePtr);
                fread(tail, tailSize, 1, srcFilePtr);
                fclose(srcFilePtr);
    
                char imgDesc[64];
                GenScreenShotTag(c_pszFileName, GetCRC32(tail, tailSize), imgDesc, sizeof(imgDesc));
    
                int imgDescLen = strlen(imgDesc) + 1;
    
                unsigned char exifHeader[] = {
                    0xe1,
                    0, // blockLen[1],
                    0, // blockLen[0],
                    0x45,
                    0x78,
                    0x69,
                    0x66,
                    0x0,
                    0x0,
                    0x49,
                    0x49,
                    0x2a,
                    0x0,
                    0x8,
                    0x0,
                    0x0,
                    0x0,
                    0x1,
                    0x0,
                    0xe,
                    0x1,
                    0x2,
                    0x0,
                    imgDescLen, // textLen[0],
                    0, // textLen[1],
                    0, // textLen[2],
                    0, // textLen[3],
                    0x1a,
                    0x0,
                    0x0,
                    0x0,
                    0x0,
                    0x0,
                    0x0,
                    0x0,
                };
    
                exifHeader[2] = sizeof(exifHeader) + imgDescLen;
    
                FILE* dstFilePtr = fopen(c_pszFileName, "wb");
                //FILE* dstFilePtr = fopen("temp.jpg", "wb");
                if (dstFilePtr)
                {
                    fwrite(head, sizeof(head), 1, dstFilePtr);
                    fwrite(exifHeader, sizeof(exifHeader), 1, dstFilePtr);
                    fwrite(imgDesc, imgDescLen, 1, dstFilePtr);
                    fputc(0x00, dstFilePtr);
                    fputc(0xff, dstFilePtr);
                    fwrite(tail, tailSize, 1, dstFilePtr);
                    fclose(dstFilePtr);
                }
    
                free(tail);
            }
        }
        return true;
    }

    🔥 Hai pe Discord! - Chat activ și support direct

    Te așteptăm și pe serverul de Discord - aici ne-am strâns toată comunitatea de Metin2 din România.

    Alătură-te acum!
    Suntem aproape: 
    Robot Discord
    Roboțelu'
    Anunț
    Scrie răspuns

    Creează-ți un cont sau autentifică-te pentru a participa la discuție

    Trebuie să fii membru pentru a răspunde

    Creează-ți un cont

    Membrii pot crea subiecte noi și pot descărca resurse Metin2 Gratuit!


    Te poți înregistra sau conecta rapid utilizând contul tău de Discord, Github sau Google.

    Înregistrare

    Autentifică-te

    Înapoi la “Sisteme Metin2”

    Informații

    Utilizatori ce navighează pe acest forum: pdz0, PepsiZero, Robert Antoci, salexandru9982 și 2 vizitatori

    Discord ID copiat: