D3DXSaveSurfaceToFileA не сохраняет в png

gaZmanoV

Участник
Автор темы
31
3
trash.cpp:
void TakeScreenshot() {
    auto            pDevice = reinterpret_cast<LPDIRECT3DDEVICE9>(RwD3D9GetCurrentD3DDevice());
    std::string sFileName;

    int iCount = GetScreenshotFileName(sFileName);
    g_Log.Write("sFileName: %s", sFileName.c_str());

    //LPDIRECT3DTEXTURE9 pFrontBuff;
    LPDIRECT3DSURFACE9 pTemp;
    //D3DXCreateTexture(pDevice, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 1, NULL, D3DFMT_A8R8G8B8,
                      //D3DPOOL_SCRATCH, &pFrontBuff);
    //pFrontBuff->GetSurfaceLevel(0, &pTemp);
    pDevice->CreateOffscreenPlainSurface(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pTemp, NULL);
    if (SUCCEEDED(pDevice->GetFrontBufferData(0, pTemp))) {
        POINT point{};
        ClientToScreen(**(HWND**)0xC17054, &point);
        RECT rect;
        GetClientRect(**(HWND**)0xC17054, &rect);
        rect.left += point.x; rect.right += point.x;
        rect.top += point.y; rect.bottom += point.y;

        //D3DXSaveTextureToFileA(sFileName.c_str(), D3DXIFF_PNG, pFrontBuff, nullptr);
        D3DXSaveSurfaceToFileA(sFileName.c_str(), D3DXIFF_PNG, pTemp, NULL, &rect); // <- на конце строки будет .png. Да, я не дурак, я это проверил
        g_pSAMP->addChatMessage(0x99'00'00, "Скриншот сделан - sa-mp-%03i.png", iCount);
    } else {
        g_pSAMP->addChatMessage(0x99'00'00, "Не удалось сохранить скриншот.");
    }
    pTemp->Release();

    *LPBOOL(g_sampBase.getAddress(0x12DD3C)) = FALSE; // g_bTakeScreenshot
}
Если в качестве D3DXIMAGE_FILEFORMAT использовать D3DXIFF_PNG, то ничего толкового не сохраняется.
1647147057712.png

Но, если заменить на D3DXIFF_JPG, то изображение получается нормальным.
1647147156588.png

Мне jpg не нужен, нужен именно png. Как быть? Попробовал даже обновить DXSDK, но ничего не поменялось. Если использовать функу из SAMP(вызов импла, __imp_D3DXSaveSurfaceToFileA), то всё ок. что я делаю не так?😢
 
Решение
вызов импла, __imp_D3DXSaveSurfaceToFileA
И все-таки это похоже на разные версии DXSDK. Скачай прогу depends walker и посмотри какую версию либы d3dx9_??.dll использует твой плагин. ?? - тут версия, для сампа это 25. Можешь в ручную загрузить d3dx9_25.dll и вызвать эту функцию из нее - должно работать

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,746
4,831
trash.cpp:
void TakeScreenshot() {
    auto            pDevice = reinterpret_cast<LPDIRECT3DDEVICE9>(RwD3D9GetCurrentD3DDevice());
    std::string sFileName;

    int iCount = GetScreenshotFileName(sFileName);
    g_Log.Write("sFileName: %s", sFileName.c_str());

    //LPDIRECT3DTEXTURE9 pFrontBuff;
    LPDIRECT3DSURFACE9 pTemp;
    //D3DXCreateTexture(pDevice, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 1, NULL, D3DFMT_A8R8G8B8,
                      //D3DPOOL_SCRATCH, &pFrontBuff);
    //pFrontBuff->GetSurfaceLevel(0, &pTemp);
    pDevice->CreateOffscreenPlainSurface(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pTemp, NULL);
    if (SUCCEEDED(pDevice->GetFrontBufferData(0, pTemp))) {
        POINT point{};
        ClientToScreen(**(HWND**)0xC17054, &point);
        RECT rect;
        GetClientRect(**(HWND**)0xC17054, &rect);
        rect.left += point.x; rect.right += point.x;
        rect.top += point.y; rect.bottom += point.y;

        //D3DXSaveTextureToFileA(sFileName.c_str(), D3DXIFF_PNG, pFrontBuff, nullptr);
        D3DXSaveSurfaceToFileA(sFileName.c_str(), D3DXIFF_PNG, pTemp, NULL, &rect); // <- на конце строки будет .png. Да, я не дурак, я это проверил
        g_pSAMP->addChatMessage(0x99'00'00, "Скриншот сделан - sa-mp-%03i.png", iCount);
    } else {
        g_pSAMP->addChatMessage(0x99'00'00, "Не удалось сохранить скриншот.");
    }
    pTemp->Release();

    *LPBOOL(g_sampBase.getAddress(0x12DD3C)) = FALSE; // g_bTakeScreenshot
}
Если в качестве D3DXIMAGE_FILEFORMAT использовать D3DXIFF_PNG, то ничего толкового не сохраняется.
Посмотреть вложение 139625
Но, если заменить на D3DXIFF_JPG, то изображение получается нормальным.
Посмотреть вложение 139626
Мне jpg не нужен, нужен именно png. Как быть? Попробовал даже обновить DXSDK, но ничего не поменялось. Если использовать функу из SAMP(вызов импла, __imp_D3DXSaveSurfaceToFileA), то всё ок. что я делаю не так?😢
Попробуй не RwD3D9GetCurrentD3DDevice, а RefDevice у сампа(26E888 на R3)
 
  • Нравится
Реакции: gaZmanoV

SR_team

like pancake
BH Team
4,809
6,487
вызов импла, __imp_D3DXSaveSurfaceToFileA
И все-таки это похоже на разные версии DXSDK. Скачай прогу depends walker и посмотри какую версию либы d3dx9_??.dll использует твой плагин. ?? - тут версия, для сампа это 25. Можешь в ручную загрузить d3dx9_25.dll и вызвать эту функцию из нее - должно работать
 
  • Нравится
Реакции: gaZmanoV