Деформированная текстура при использовании спрайтов (Directx 9)

Я собираюсь сделать простую 2D-игру с использованием ID3DXSprite. Когда мне удалось нарисовать изображение, я заметил, что оно не такого качества, как когда я его редактировал. Я читал, что в Directx 8 и новее все текстуры должны быть кратны 2, но это не мой случай, так как изображение 32x32.

Исходное изображение: ссылка

Рендеринг изображения: ссылка

Код инициализации:

bool D3DEngine::InitD3D(HWND hwnd)
{
    D3D = Direct3DCreate9(D3D_SDK_VERSION);    
    D3DPRESENT_PARAMETERS D3DPP;

    ZeroMemory(&D3DPP, sizeof(D3DPP));    
    D3DPP.Windowed = true;    
    D3DPP.SwapEffect = D3DSWAPEFFECT_DISCARD;    
    D3DPP.hDeviceWindow = hwnd;
    D3DPP.BackBufferFormat = D3DFMT_A8R8G8B8;
    D3DPP.BackBufferWidth = 300;
    D3DPP.BackBufferHeight = 300;
    D3DPP.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

    if (D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &D3DPP, &D3DDevice) != D3D_OK)
    {
        return false;
    }
    else
    {
        D3DXCreateTextureFromFile(D3DDevice, ".bmp", &Texture);

        D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
        D3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

        Sprite = new D3DSprite(D3DDevice);
        Camera = new Camera2D(0, 0, ScreenPosX, ScreenPosY, 1.0f, 0.0f);

        Debug->Output("Started DirectX");
        return true;
    }
}

Код рендеринга:

void D3DSprite::DrawTexture(LPDIRECT3DTEXTURE9 Texture, CONST RECT* Rect, ScreenPos Pos, D3DCOLOR Color)
{
    D3DXVECTOR3 Center(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 Position(Pos.x - Camera->GetX(), Pos.y - Camera->GetY(), 0.0f);

    Handle->Draw(Texture, Rect, &Center, &Position, Color);
}

struct ScreenPos
{
    float x;
    float y;
};

class D3DSprite 
{
    public:

        LPD3DXSPRITE Handle;

        D3DSprite(LPDIRECT3DDEVICE9 Device);
        ~D3DSprite();

        void DrawTexture(LPDIRECT3DTEXTURE9 Texture, CONST RECT* Rect, ScreenPos Pos, D3DCOLOR Color);
        void DrawTexture(LPDIRECT3DTEXTURE9 Texture, CONST RECT* Rect, WorldPos Pos, D3DCOLOR Color);
        void Begin(DWORD Flags) { Handle->Begin(Flags); };
        void End() { Handle->End(); };
};

void D3DEngine::Render()
{
    D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_COLORVALUE(0.0f, 0.0f, 0.0, 1.0f), 1.0f, 0);

    D3DDevice->BeginScene();

    ScreenPos Position = {0, 0};

    Sprite->Begin(D3DXSPRITE_OBJECTSPACE | D3DXSPRITE_ALPHABLEND);

    Sprite->DrawTexture(Texture, NULL, Position, D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f));

    Sprite->End();
    D3DDevice->EndScene();
    D3DDevice->Present(NULL, NULL, NULL, NULL);

}

person Nvreformat    schedule 23.08.2013    source источник
comment
Camera->GetX() возвращает значения с плавающей запятой? Что произойдет, если вы урежете их до int?   -  person Nico Schertler    schedule 23.08.2013


Ответы (1)


Не совсем понятно, что вы подразумеваете под "деформированной текстурой". Я вижу, что вторая картинка размыта первой. А также есть черная рамка слева и сверху.

Размытие.

Размытие может быть вызвано

    D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    D3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

При рисовании простых спрайтов, таких как тайловые карты, вам, возможно, захочется отключить мипмаппинг. Поэтому попробуйте закомментировать эти строки или используйте D3DTEXF_NONE в качестве третьего аргумента.

Смешанное программное/аппаратное устройство.

Еще одна странность — флаг D3DCREATE_MIXED_VERTEXPROCESSING при создании устройства. Не совсем уверен, может ли это вызвать размытие, но чаще всего устанавливается D3DCREATE_HARDWARE_VERTEXPROCESSING. Маловероятно, что в 2013 году вы сможете найти какое-либо устройство на базе Windows, которое аппаратно не поддерживает DirectX 9.

Черная граница.

Что касается черной границы, я понятия не имею. Надеюсь, вы только что пропустили 1 пиксель при кадрировании скриншота =)

Сила 2 текстур.

Я читал, что в Directx 8 и новее все текстуры должны быть кратны 2, но это не мой случай, так как изображение 32x32.

Это неправильно (в основном). В настоящее время вы можете (и захотите) использовать текстуры любого размера. Это зависит только от аппаратных возможностей. Но опять же, здесь вряд ли можно найти не-pow2-текстурное устройство 2013 года.

Представьте, что у вас большие текстуры, например 800х800. Изменение его размера до 1024x1024 потребовало бы огромного пространства на жестком диске, системной памяти и памяти графического процессора.

Если вы все еще сомневаетесь, есть ли у вас устройство с поддержкой pow-2 или нет, используйте GetDeviceCaps и установите флажок D3DPTEXTURECAPS_POW2.

Еще немного ворчания.

Что касается этих странных старых вещей в вашем коде, со времен, когда DirectX 8 был обычным явлением, а DirectX 9 был высокотехнологичным. В 2013 году для него места больше нет. Возможно, вам захочется выбросить (и сжечь) свой текущий путеводитель или книгу и взять что-нибудь посвежее, вроде DirectX 11 (не 10) и почувствовать мощь. Или хотя бы последний DirectX 9, а не древний.

Удачи и счастливого кодирования! знак равно

person Ivan Aksamentov - Drop    schedule 24.08.2013