使用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(¶meters, 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, ¶meters, &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 :(得分:0)
为了提高效率,纹理表面的尺寸通常要求为2:例如64,512等 尽管不同的硬件以不同方式实现光栅化,但是对纹理的各个像素进行寻址将需要大量的乘法。例如,要处理图像中的纹理元素,可以使用以下代码:
texel = PixelDataArray[y * texture_width + x];
然而,如果&#39; texture_width&#39;是256的幂,比如说256,然后会做同样的工作:
int texture_width_shift_by = 8;
texel = PixelDataArray[y << texture_width_shift_by + x];
优势在于实现硬件转换需要更少的硅,其运行速度比乘法运行快得多。当您使用并行硬件每帧进行数百万次此类操作时,增益可能会很大。
无论如何,结果是你必须用二维的力量保存那个图像然后,如果你想在那个表面内使用一个被剪裁的区域,使用UV坐标来做这个。