Winapi DirectX纹理扭曲

Winapi DirectX纹理扭曲,winapi,directx,textures,sprite,directx-9,Winapi,Directx,Textures,Sprite,Directx 9,我正在编写一个WIN32 DirectX 9程序,在其中加载一些纹理(一个人和一个背景)并在屏幕上显示它们。然而,它们变得扭曲(拉伸),而不是我在绘画中所画的一对一的表现。我尝试了不同的窗口大小和不同的屏幕分辨率,但仍然不起作用 在绘制精灵之前,我可以通过调用D3DXMatrixTransformation2D来强制进行非常接近原始的模拟。然而,这并不能解决问题。我的程序依赖于我确切地知道人在哪里与背景相关(在现实中,背景移动和人停留在屏幕中间)。 是否有一些简单的事情我遗漏了,或者是因为某种原

我正在编写一个WIN32 DirectX 9程序,在其中加载一些纹理(一个人和一个背景)并在屏幕上显示它们。然而,它们变得扭曲(拉伸),而不是我在绘画中所画的一对一的表现。我尝试了不同的窗口大小和不同的屏幕分辨率,但仍然不起作用

在绘制精灵之前,我可以通过调用D3DXMatrixTransformation2D来强制进行非常接近原始的模拟。然而,这并不能解决问题。我的程序依赖于我确切地知道人在哪里与背景相关(在现实中,背景移动和人停留在屏幕中间)。 是否有一些简单的事情我遗漏了,或者是因为某种原因我无法做到?我可以给代码,如果它不仅仅是一个简单的修复,但我希望不是。作为记录,我没有收到任何错误或警告;这只是一个视觉和运动跟踪问题。多谢各位

编辑:以下是一些代码:

    //start of program
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

    //Define and register the Windows Class ***Function
    createWindowClass(hInstance);

    //Create the window (still not shown)
    HWND hWnd = CreateWindow("Sample Window Class", "Person With Ship", WS_OVERLAPPEDWINDOW, 
        CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);

    //Define and create the DirectX9 object ***Function
    HRESULT hr = createDirectX(hWnd);

    D3DXCreateSprite(d3dDevice, &sprite);
    D3DXCreateTextureFromFile(d3dDevice, "landingPad2.png", &texture);
    D3DXCreateTextureFromFile(d3dDevice, "person.png", &person);
    //D3DXCreateTextureFromFile(d3dDevice, "secondRoom.png", &secondRoom);





    //Set up text
    LPD3DXFONT mFont;
    D3DXCreateFont(d3dDevice, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, 
        DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &mFont );


    //Finally show window
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    //setup keyboard
    RAWINPUTDEVICE Rid[1]; // array of structs for input devices
    Rid[0].usUsagePage = 1; // use 1 for most inputs
    Rid[0].usUsage = 6; //2-mouse, 4-joystick, 6-keyboard
    Rid[0].dwFlags = 0; //use 0
    Rid[0].hwndTarget=NULL; //use NULL
    RegisterRawInputDevices(Rid,1,sizeof(RAWINPUTDEVICE)); // registers all of the input devices


    //MAIN LOOP!!
    MSG msg;
    ZeroMemory(&msg, sizeof(msg));
    while (msg.message!=WM_QUIT) 
    {
        while(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        updateGraphics(hr, mFont);
        updatePosition();

    }
    mFont->Release();
    texture->Release();
    return msg.wParam;
}


void createWindowClass(HINSTANCE hInstance)
{
    const LPCSTR CLASS_NAME  = "Sample Window Class";

    //create windows object
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style= CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc= (WNDPROC)WndProc;
    wcex.cbClsExtra= 0;
    wcex.cbWndExtra= 0;
    wcex.hInstance= hInstance;
    wcex.hIcon= 0;
    wcex.hCursor= LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName= 0;
    wcex.lpszClassName= CLASS_NAME;
    wcex.hIconSm= 0;

    //register windows class
    RegisterClassEx(&wcex);
}

HRESULT createDirectX(HWND hWnd)
{
    //create directx object
    d3dObject = Direct3DCreate9(D3D_SDK_VERSION);
    if (d3dObject==NULL)
    {
        exit(1);
    }

    //Present Parameters struct
    D3DPRESENT_PARAMETERS presParams;

    //Sets everything to 0
    ZeroMemory(&presParams, sizeof(presParams));

    presParams.Windowed = TRUE;
    presParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
    presParams.BackBufferFormat = D3DFMT_UNKNOWN;
    presParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;

    //DIRECT3D Stuff (not used currently)
    //presParams.EnableAutoDepthStencil = TRUE;
    //presParams.AutoDepthStencilFormat = D3DFMT_D16;
    //d3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
    //D3DXMatrixIdentity( &worldMatrix );

    HRESULT hr = d3dObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &presParams, &d3dDevice);
    return hr;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message) 
    {
        case WM_INPUT:
        {


            UINT bufferSize;
            GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &bufferSize, sizeof (RAWINPUTHEADER));

            // Create a buffer of the correct size
            BYTE *buffer=new BYTE[bufferSize];

            // Call the function again, this time with the buffer to get the data
            GetRawInputData((HRAWINPUT)lParam, RID_INPUT, (LPVOID)buffer, &bufferSize, sizeof (RAWINPUTHEADER));

            PRAWINPUT raw = (RAWINPUT*) buffer;

            getInput(raw);

            break;
        }
        case WM_COMMAND:
        {
            int wmId    = LOWORD(wParam); 
            int wmEvent = HIWORD(wParam); 

            // Parse the menu selections:
            switch (wmId)
            {
                case IDM_EXIT:
                   DestroyWindow(hWnd);
                break;
            }
            break;
        }
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

void getInput(PRAWINPUT raw)
{
    if (raw->header.dwType== RIM_TYPEKEYBOARD)
            {
                USHORT keyCode = raw->data.keyboard.VKey;

                switch(keyCode)
                {
                    case VK_LEFT:
                        keyUp=raw->data.keyboard.Flags & RI_KEY_BREAK;
                        if (keyUp == false)
                            counterTrue = true;
                        else
                            counterTrue = false;
                        break;
                    case VK_RIGHT:
                        keyUp=raw->data.keyboard.Flags & RI_KEY_BREAK;
                        if (keyUp == false)
                            clockwiseTrue = true;
                        else
                            clockwiseTrue = false;
                        break;
                    case VK_UP:
                        keyUp=raw->data.keyboard.Flags & RI_KEY_BREAK;
                        if (keyUp == false)
                            upTrue = true;
                        else
                            upTrue = false;
                        break;
                    case VK_DOWN:
                        keyUp=raw->data.keyboard.Flags & RI_KEY_BREAK;
                        if (keyUp == false)
                            downTrue = true;
                        else
                            downTrue = false;
                        break;
                    default:
                        break;
                }
                if (keyCode == 'A')
                {
                    keyUp=raw->data.keyboard.Flags & RI_KEY_BREAK;
                    if (keyUp == false)
                        leftTrue = true;
                    else
                        leftTrue = false;
                }
                if (keyCode == 'D')
                {
                    keyUp=raw->data.keyboard.Flags & RI_KEY_BREAK;
                    if (keyUp == false)
                        rightTrue = true;
                    else
                        rightTrue = false;
                }
                if (keyCode == 'W')
                {
                    keyUp=raw->data.keyboard.Flags & RI_KEY_BREAK;
                    if (keyUp == false)
                        upTrue = true;
                    else
                        upTrue = false;
                }
                if (keyCode == 'S')
                {
                    keyUp=raw->data.keyboard.Flags & RI_KEY_BREAK;
                    if (keyUp == false)
                        downTrue = true;
                    else
                        downTrue = false;
                }
        }
}

void updateGraphics(HRESULT hr, LPD3DXFONT mFont)
{
        hr = d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET| D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
        hr = d3dDevice->BeginScene();



        sprite->Begin(D3DXSPRITE_ALPHABLEND);

        // Texture being used is 64 by 64:
        D3DXVECTOR2 spriteCentre=D3DXVECTOR2(rotationCenter.x, rotationCenter.y);

        // Screen position of the sprite
        D3DXVECTOR2 trans=D3DXVECTOR2(pos.x, pos.y);

        // Build our matrix to rotate, scale and position our sprite
        D3DXMATRIX mat;

        D3DXVECTOR2 scaling(0.5798f, 0.784f);

        // out, scaling centre, scaling rotation, scaling, rotation centre, rotation, translation
        D3DXMatrixTransformation2D(&mat,NULL, NULL, &scaling,&spriteCentre,rotation,NULL/*&trans*/);

        // Tell the sprite about the matrix
        sprite->SetTransform(&mat);

        sprite->Draw(texture, NULL, &rotationCenter, &pos, 0xFFFFFFFF);

        scaling.x = 0.53;
        scaling.y = 0.57f;

        D3DXMatrixTransformation2D(&mat,NULL,0.0, &scaling,&spriteCentre, 0,NULL/*&trans*/);
        sprite->SetTransform(&mat);

        sprite->Draw(person, NULL, NULL, &personPos, 0xFFFFFFFF);

        sprite->End();

        DisplaySomeText(mFont);

        d3dDevice->EndScene();
        d3dDevice->Present(NULL, NULL, NULL, NULL);
}

void updatePosition()
{
        if (clockwiseTrue == true)
        {
            rotation -= (float)0.03;
        }
        else if (counterTrue == true)
        {
            rotation += (float)0.03;
        }

        if (rotation >(PI))
        {
            rotation -= (float)(2*PI);
        }
        if (rotation <= -(PI))
        {
            rotation += (float)(2*PI);
        }

        if (upTrue == true)
        {
            pos.y += (3*cos(rotation));
            pos.x += (3*sin(rotation));
        }
        else if (downTrue == true)
        {
            pos.y -= (3*cos(rotation));
            pos.x -= (3*sin(rotation));
        }

        if (leftTrue == true)
        {
            pos.x += (3*cos(rotation));
            pos.y -= (3*sin(rotation));
        }
        else if (rightTrue == true)
        {
            pos.x -= (3*cos(rotation));
            pos.y += (3*sin(rotation));
        }

        //collision detection
        if (rotation >=0 && rotation < (PI/2))
        {
            if (pos.y - (30*cos(rotation)) - (30*sin(rotation)) < -138 && pos.x < 350 && pos.x > -550)
            {
                pos.y = -142 + (30*cos(rotation)) + (30*sin(rotation));
            }
        }
        if (rotation < 0 && rotation > -(PI/2))
        {
            if (pos.y - (51*cos(rotation)) + (14*sin(rotation)) < -142 && pos.x < 350 && pos.x > -550)
            {
                pos.y = -142 + (51*cos(rotation)) - (14*sin(rotation));
            }
        }
        if (rotation < -(PI/2) && rotation > -(PI))
        {
            if (pos.y + (51*cos(rotation)) + (14*sin(rotation)) < -142 && pos.x < 350 && pos.x > -550)
            {
                pos.y = -142 - (51*cos(rotation)) - (14*sin(rotation));
            }
        }
        if (rotation > (PI/2) && rotation <= (PI))
        {
            if (pos.y + (51*cos(rotation)) - (14*sin(rotation)) < -142 && pos.x < 350 && pos.x > -550)
            {
                pos.y = -142 - (51*cos(rotation)) + (14*sin(rotation));
            }
        }
}

void DisplaySomeText(LPD3DXFONT mFont)
{

// Create a colour for the text - in this case blue
D3DCOLOR fontColor = D3DCOLOR_ARGB(255,0,0,255);    

// Create a rectangle to indicate where on the screen it should be drawn
RECT rct;
rct.left=200;
rct.right=780;
rct.top=10;
rct.bottom=rct.top+20;





TCHAR cX[30] = "x";
TCHAR cY[30] = "y";
TCHAR cR[30] = "r";
TCHAR cQ[30] = "q";
size_t cchDest = 30;

LPCTSTR pszFormat = TEXT("%f");

HRESULT har = StringCchPrintf(cX, cchDest, pszFormat, pos.x);
HRESULT her = StringCchPrintf(cY, cchDest, pszFormat, pos.y);
HRESULT hir = StringCchPrintf(cR, cchDest, pszFormat, rotation);
HRESULT hur = StringCchPrintf(cQ, cchDest, pszFormat, (pos.y - (43*cos(rotation))));


mFont->DrawText(NULL, cX, -1, &rct, 0, fontColor);

rct.left += 100;

mFont->DrawText(NULL, cY, -1, &rct, 0, fontColor);

rct.left += 100;

mFont->DrawText(NULL, cR, -1, &rct, 0, fontColor);

rct.left += 100;

mFont->DrawText(NULL, cQ, -1, &rct, 0, fontColor);

}
//程序开始
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE HPPreInstance、LPSTR lpCmdLine、int nCmdShow)
{
//定义并注册Windows类***函数
createWindowClass(hInstance);
//创建窗口(仍未显示)
HWND HWND=CreateWindow(“示例窗口类”、“有船的人”、WS_OVERLAPPEDWINDOW、,
CW_usefault,CW_usefault,800,600,NULL,NULL,hInstance,NULL);
//定义并创建DirectX9对象***函数
HRESULT hr=createDirectX(hWnd);
D3DXCreateSprite(d3dDevice和sprite);
D3DXCreateTextureFromFile(d3dDevice,“landingPad2.png”和纹理);
D3DXCreateTextureFromFile(d3dDevice,“person.png”、&person);
//D3DXCreateTextureFromFile(d3dDevice,“secondRoom.png”和secondRoom);
//设置文本
LPD3DXFONT-mFont;
D3DXCreateFont(d3dDevice,20,0,FW_BOLD,0,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,
默认音质、默认音高(FF_DONTCARE、文本(“Arial”)、&mFont);
//最后显示窗口
显示窗口(hWnd、nCmdShow);
更新窗口(hWnd);
//设置键盘
RAWINPUTDEVICE Rid[1];//输入设备的结构数组
Rid[0]。usUsagePage=1;//对大多数输入使用1
Rid[0]。usUsage=6;//2-鼠标,4-操纵杆,6-键盘
Rid[0]。dwFlags=0;//使用0
Rid[0]。hwndTarget=NULL;//使用NULL
RegisterRawInputDevices(Rid,1,sizeof(RAWINPUTDEVICE));//注册所有输入设备
//主回路!!
味精;
零内存(&msg,sizeof(msg));
while(msg.message!=WM\u退出)
{
while(peek消息(&msg,NULL,0U,0U,PM_删除))
{
翻译信息(&msg);
发送消息(&msg);
}
更新图形(hr、mFont);
updatePosition();
}
mFont->Release();
纹理->释放();
返回msg.wParam;
}
void createWindowClass(HINSTANCE HINSTANCE)
{
const LPCSTR CLASS_NAME=“示例窗口类”;
//创建windows对象
WNDCLASSEX wcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc=(WNDPROC)WNDPROC;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=0;
wcex.hCursor=LoadCursor(空,IDC_箭头);
wcex.hbrBackground=(HBRUSH)(彩色窗口+1);
wcex.lpszMenuName=0;
wcex.lpszClassName=CLASS_NAME;
wcex.hIconSm=0;
//注册windows类
注册类别(&wcex);
}
HRESULT createDirectX(HWND HWND)
{
//创建directx对象
d3dObject=Direct3DCreate9(D3D_SDK_版本);
if(d3dObject==NULL)
{
出口(1);
}
//当前参数结构
D3D当前参数预参数;
//将所有设置为0
零内存(&presParams,sizeof(presParams));
预参数加窗=真;
PRESPARMS.SwapEffect=D3DSWAPEEFFECT_丢弃;
presParams.BackBufferFormat=D3DFMT_未知;
presParams.PresentationInterval=D3D当前时间间隔;
//DIRECT3D素材(当前未使用)
//presParams.EnableAutoDepthStencil=TRUE;
//presParams.AutoDepthStencilFormat=D3DFMT_D16;
//d3dDevice->SetRenderState(D3DRS_ZENABLE,D3DZB_TRUE);
//D3DXMatrix实体(和worldMatrix);
HRESULT hr=d3dObject->CreateDevice(D3DADAPTER\u默认值、D3DDEVTYPE\u HAL、hWnd、D3DCREATE\u硬件\u VERTEXPROCESSING、&presParams、&d3dDevice);
返回人力资源;
}
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
开关(信息)
{
案例WM_输入:
{
单位缓冲区大小;
GetRawInputData((HRAWINPUT)lParam、RID_INPUT、NULL和bufferSize、sizeof(rawinpuheader));
//创建正确大小的缓冲区
字节*缓冲区=新字节[缓冲区大小];
//再次调用函数,这次使用缓冲区获取数据
GetRawInputData((HRAWINPUT)LPRAM、RID_输入、(LPVOID)缓冲区和缓冲区大小、sizeof(RAWINPUTHEADER));
PRAWINPUT raw=(RAWINPUT*)缓冲区;
获取输入(原始);
打破
}
case WM_命令:
{
int wmId=低ORD(wParam);
int wmEvent=HIWORD(wParam);
//解析菜单选项:
交换机(wmId)
{
案例IDM_退出:
窗口(hWnd);
打破
}
打破
}
案例WM_销毁:
PostQuitMessage(0);
打破
违约:
返回DefWindowProc(hWnd、message、wParam、lParam);
}
返回0;
}
void getInput(PRAWINPUT原始)
{
if(原始->标题.dwType==RIM\u类型键盘)
{
USHORT keyCode=raw->data.keyboard.VKey;
开关(钥匙代码)
{
案例VK_左:
keyUp=raw->data.keyboard.Flags和RI\u KEY\u BREAK;
如果(keyUp==false)
反真=真;
其他的