SOIL2 HIBRIT SİSTEM.

apikomt2

Level 6
Katılım
11 May 2023
Konular
237
Mesajlar
1,032
Online süresi
1ay 23g
Reaksiyon Skoru
676
Altın Konu
1
Başarım Puanı
176
TM Yaşı
2 Yıl 11 Ay 14 Gün
MmoLira
497
DevLira
315

Metin2 EP, Valorant VP dahil tüm oyun ürünlerini en uygun fiyatlarla bulabilir, Item ve Karakterlerinizi hızlıca satabilirsiniz. HEMEN TIKLA!

include githundan alıp konudaki .libi kulalanbilrisiniz yada cmakeyle libi siz olsutabilrisniz vs farkı oalbiliyor
Burdaki yapılan çalışma.

Oyunda .dds ler dx8
geri kalan png .tgalar soil2
eğer olduki .dds yüklenmedi
soil2yle devam ediliyor.

yüklenmedi derken diyelim .dds pixel uymuyor soil2 bunu okuyabilir.
aynı şekilde stbliblede yapılır fakat .dds desteği yok.
şöyle yapılır.
dds dx8 geri kalan stblib ama .dds okuyamdığı için tam hibrit olmaz


n2play incelenerek yapay zeka geminiye yazdırılmıştır.n2play stdlib kullanıyor.

GraphicImageTexture.cpp
Kod:
#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")

tekrardan güncellendi.
fonksiyonun dx8 okuması devam edecek.
herhangi bir okumama çökme durumunda soil2 devreye giricek.

grpimageinstance.cpp
Kod:
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;
}

pythonappilciionmodule

Kod:
#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);
}

hazır vs 2022 c++20 lib. 32 bit
Çok iş parçacıklı (/MT)
build ederken dx10 32 bitte build olmuyor dx10 satırları silin öyle build edin.

lib konuya ekliyorum.
cmake ile build alabilirsiniz.
cmke v3 latest
Kod:
#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;
}



 

Ekli dosyalar

  • soil2.zip
    120.8 KB · Görüntüleme: 0
Son düzenleme:
Eline sağlık
 

libjpeg ss yerine


Kod:
#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;
}
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)