2014-01-24 3 views
0

Использование Direct-X9, как я могу масштабировать текстуру до точного размера в файле?Масштабирование текстур

Я просматриваю свою текстуру в MSPaint и имеет размер 261 x 210. Он отлично отображает MSPaint. Однако, когда я рисую текстуру, она рисует намного больше, чем обычно. По какой-то причине он растягивается, хотя я установил масштабирование на 0f.

Мой код выглядит следующим образом:

#if defined(UNICODE) && !defined(_UNICODE) 
#define _UNICODE 
#elif defined(_UNICODE) && !defined(UNICODE) 
#define UNICODE 
#endif 

#include <tchar.h> 
#include <windows.h> 
#include <d3d9.h> 
#include <d3dx9.h> 
#include <d3dx9tex.h> 

IDirect3D9* d3d = nullptr; 
IDirect3DDevice9* device = nullptr; 
IDirect3DTexture9* Texture = nullptr; 
ID3DXSprite* Sprite = nullptr; 

const int Width = 800; 
const int Height = 600; 

void init(HWND hwnd, IDirect3D9* &d3d, IDirect3DDevice9* &device, int Width, int Height); 
void render(IDirect3DDevice9* device); 
void cleanup(IDirect3D9* &d3d, IDirect3DDevice9* &device); 
void LoadTexture(const char* FilePath, IDirect3DTexture9* &Texture, ID3DXSprite* &Sprite); 
void LoadTexture(unsigned char* buffer, int width, int height, IDirect3DTexture9* &Texture, ID3DXSprite* &Sprite); 


LRESULT __stdcall WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
     case WM_DESTROY: 
      PostQuitMessage(0); 
      break; 

     default: 
      return DefWindowProc(hwnd, message, wParam, lParam); 
    } 

    return 0; 
} 

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
    MSG msg = {0}; 

    WNDCLASSEX wc = 
    { 
     sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW | CS_OWNDC, 
     WindowProcedure, 0, 0, hInstance, nullptr, nullptr, (HBRUSH)(COLOR_WINDOW+1), 
     nullptr, _T("DXClass"), nullptr 
    }; 

    if(RegisterClassEx(&wc)) 
    { 
     HWND hwnd = CreateWindow(_T("DXClass"), _T("DirectX Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, Width, Height, nullptr, nullptr, hInstance, nullptr); 
     ShowWindow(hwnd, nCmdShow); 
     UpdateWindow(hwnd); 
     init(hwnd, d3d, device, Width, Height); 
     LoadTexture("C:/Users/School/Desktop/Test.bmp", Texture, Sprite); 

     while(true) 
     { 
      while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) 
      { 
       TranslateMessage(&msg); 
       DispatchMessage(&msg); 
      } 

      if(msg.message == WM_QUIT) 
       break; 

      render(device); 
     } 

     cleanup(d3d, device); 
     return msg.wParam; 
    } 
    return 0; 
} 


void init(HWND hwnd, IDirect3D9* &d3d, IDirect3DDevice9* &device, int Width, int Height) 
{ 
    d3d = Direct3DCreate9(D3D_SDK_VERSION); 
    D3DPRESENT_PARAMETERS parameters = {0}; 
    ZeroMemory(&parameters, sizeof(parameters)); 
    parameters.Windowed = true; 
    parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; 
    parameters.hDeviceWindow = hwnd; 
    parameters.BackBufferFormat = D3DFMT_X8R8G8B8; 
    parameters.BackBufferWidth = Width; 
    parameters.BackBufferHeight = Height; 
    d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parameters, &device); 
} 

void render(IDirect3DDevice9* device) 
{ 
    device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0); 
    device->BeginScene(); 

    if (Sprite && Texture) 
    { 
     D3DXMATRIX world = {0}, rotation = {0}, scale = {0}, translation = {0}; 
     D3DXMatrixIdentity(&world); 

     D3DXMatrixScaling(&scale, 1.0f, 1.0f, 1.0f); 
     D3DXMatrixRotationYawPitchRoll(&rotation, 0.0f, 0.0f, 0.0f); 
     D3DXMatrixTranslation(&translation, 0.0f, 0.0f, 0.0f); 
     world = rotation * scale * translation; 

     Sprite->SetTransform(&world); 
     D3DXVECTOR3 Position = D3DXVECTOR3(0, 0, 0); 

     Sprite->Begin(D3DXSPRITE_ALPHABLEND); 
     Sprite->Draw(Texture, nullptr, nullptr, &Position, 0xFFFFFFFF); 
     Sprite->End(); 
    } 

    device->EndScene(); 
    device->Present(nullptr, nullptr, nullptr, nullptr); 
} 

void cleanup(IDirect3D9* &d3d, IDirect3DDevice9* &device) 
{ 
    if (Sprite) Sprite->Release(); 
    if (Texture) Texture->Release(); 
    if (device) device->Release(); 
    if (d3d) d3d->Release(); 
} 

void LoadTexture(const char* FilePath, IDirect3DTexture9* &Texture, ID3DXSprite* &Sprite) 
{ 
    D3DXCreateTextureFromFile(device, FilePath, &Texture); 
    D3DXCreateSprite(device, &Sprite); 
} 

void LoadTexture(unsigned char* buffer, int width, int height, IDirect3DTexture9* &Texture, ID3DXSprite* &Sprite) 
{ 
    device->CreateTexture(width, height, 1, 0, D3DFMT_X8B8G8R8, D3DPOOL_MANAGED, &Texture, 0); 
    D3DXCreateSprite(device, &Sprite); 

    D3DLOCKED_RECT rect; 
    Texture->LockRect(0, &rect, nullptr, D3DLOCK_DISCARD); 
    unsigned char* dest = static_cast<unsigned char*>(rect.pBits); 
    memcpy(dest, buffer, width * height * 4); 
    Texture->UnlockRect(0); 
} 

Есть идеи? Кроме того, есть ли лучший способ рисовать текстуру? Например, может быть, без спрайта? Я очень новичок в Direct-X.

ответ

0

Для эффективности поверхности текстуры обычно должны иметь мощность 2 в размерах: например. 64, 512 и т. Д. Хотя разные аппаратные средства реализуют растеризацию по-разному, обращение к отдельным пикселям текстуры потребует большого умножения. Например, для решения текселей в изображении, вы можете использовать этот код:

texel = PixelDataArray[y * texture_width + x]; 

однако, если «texture_width» является степенью двойки, скажем 256, то тогда будет делать ту же работу:

int texture_width_shift_by = 8; 
texel = PixelDataArray[y << texture_width_shift_by + x]; 

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

В любом случае, вы должны сохранить это изображение с мощностью двух измерений, а затем, если вы хотите использовать обрезанную область внутри этой поверхности, сделайте это, используя UV-координаты.

Смежные вопросы