Программирование 2D с помощью Direct3D 9 — тестовое изображение искажено

Я пытаюсь создать простую 2D-игру, используя 2D-спрайты с DirectX 9, и у меня возникают проблемы с выводом изображений. Я хотел бы загрузить bmp-изображения и отобразить их на экране как есть (без интерполяции, без увеличения, без фильтрации или сглаживания и т. д.).

Я уверен, что что-то упускаю, но когда я пытаюсь отобразить на экране изображение 100x100 bmp, оно выглядит прерывистым и искаженным, как обычно выглядит пиксель-арт, слегка уменьшенный. Я хочу, чтобы bmp выглядел точно так же, как при загрузке в MS Paint.

Кто-нибудь знает, почему это может быть так? Мой код показан ниже:

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

g_DxCom = Direct3DCreate9( D3D_SDK_VERSION );
if ( g_DxCom == NULL )
{
    return false;
}

D3DDISPLAYMODE d3dDisplayMode;

if ( FAILED( g_DxCom->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3dDisplayMode ) ) )
{
    return false;
}

D3DPRESENT_PARAMETERS d3dPresentParameters;
::ZeroMemory( &d3dPresentParameters, sizeof(D3DPRESENT_PARAMETERS) );
d3dPresentParameters.Windowed = FALSE;
d3dPresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dPresentParameters.BackBufferFormat = d3dDisplayMode.Format;  // D3DFMT_X8R8G8B8
d3dPresentParameters.BackBufferWidth = d3dDisplayMode.Width;
d3dPresentParameters.BackBufferHeight = d3dDisplayMode.Height;
d3dPresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

if ( FAILED( g_DxCom->CreateDevice( D3DADAPTER_DEFAULT,
                                    D3DDEVTYPE_HAL,
                                    this->hWnd,
                                    D3DCREATE_HARDWARE_VERTEXPROCESSING,
                                    &d3dPresentParameters,
                                    &pd3dDevice ) ) )
{
    if ( FAILED( g_DxCom->CreateDevice( D3DADAPTER_DEFAULT,
                                        D3DDEVTYPE_HAL,
                                        this->hWnd,
                                        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                        &d3dPresentParameters,
                                        &pd3dDevice ) ) )
    {
        return false;
    }
}

texture = NULL;
bg_texture = NULL;

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

LPDIRECT3DDEVICE9   g_dxDevice;

float float1 = 99.5f;    // I'd like to render my 100x100 sprite from screen coordinates 100, 100 to 200, 200
float float2 = 198.5f;

CUSTOMVERTEX OurVertices[] =
{
    { float1, float2, 1.0f, 1.0f, 0.0f, 1.0f },
    { float1, float1, 1.0f, 1.0f, 0.0f, 0.0f },
    { float2, float1, 1.0f, 1.0f, 1.0f, 0.0f },
    { float1, float2, 1.0f, 1.0f, 0.0f, 1.0f },
    { float2, float1, 1.0f, 1.0f, 1.0f, 0.0f },
    { float2, float2, 1.0f, 1.0f, 1.0f, 1.0f }
};

LPDIRECT3DVERTEXBUFFER9 v_buffer;

g_dxDevice->CreateVertexBuffer( 6 * sizeof(CUSTOMVERTEX),
                                0,
                                CUSTOMFVF,
                                D3DPOOL_MANAGED,
                                &v_buffer,
                                NULL );

VOID* pVoid;

// Lock the vertex buffer into memory
v_buffer->Lock( 0, 0, &pVoid, 0 );

// Copy our vertex buffer to memory
::memcpy( pVoid, OurVertices, sizeof(OurVertices) );

// Unlock buffer
v_buffer->Unlock();

LPDIRECT3DTEXTURE9 g_texture;
HRESULT hError;

DWORD dwTextureFilter = D3DTEXF_NONE;

g_dxDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, dwTextureFilter );
g_dxDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, dwTextureFilter );
g_dxDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, dwTextureFilter );

g_dxDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
g_dxDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
g_dxDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);

hError = D3DXCreateTextureFromFile( g_dxDevice, L"Test.bmp", &g_texture );   // 100x100 sprite

g_dxDevice->SetTexture( 0, g_texture );

g_dxDevice->Clear( 0,
                   NULL,
                   D3DCLEAR_TARGET,
                   D3DCOLOR_XRGB( 0, 40, 100 ),
                   1.0f,
                   0 );

g_dxDevice->BeginScene();

// Do rendering on the back buffer here
g_dxDevice->SetFVF( CUSTOMFVF );
g_dxDevice->SetStreamSource( 0, v_buffer, 0, sizeof(CUSTOMVERTEX) );
g_dxDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 6 );

g_dxDevice->EndScene();

g_dxDevice->Present( NULL, NULL, NULL, NULL );

g_texture->Release();
v_buffer->Release();

person 8bitcartridge    schedule 04.03.2013    source источник


Ответы (1)


Итак, я, наконец, понял это, и я должен был знать, что это так. Похоже, что DirectX9 работает только с текстурами, размер которых кратен 2. Если я изменю текстуру так, чтобы квадрат спрайта был 128 x 128 (просто добавив немного прозрачности), и запущу приложение с соответствующим образом измененным значением float2, искажения в текстуре не будет. визуализируемое изображение.

Ура...

person 8bitcartridge    schedule 04.03.2013