动画精灵问题(C ++ / DirectX9)

时间:2015-07-24 18:17:29

标签: c++ visual-studio visual-studio-2013 directx

我正在编写一个使用DirectX9动画精灵的教程,我正确地做了一切我只需要一些我想要纠正的问题的帮助。到目前为止,我可以正确地为精灵设置动画,问题是当精灵动画时,它会在绘制下一帧之前留下前一帧中的图像。我该如何解决这个问题?

以下是头文件中的声明:

LPDIRECT3DTEXTURE9 LoadTexture(string filename, D3DCOLOR transcolor = D3DCOLOR_XRGB(0, 0, 0));
void Sprite_Transform_Draw(LPDIRECT3DTEXTURE9 image, int x, int y, int width, int height, 
    int frame = 0, int columns = 1, float rotation = 0.0f, float scaling = 1.0f, 
    D3DCOLOR color = D3DCOLOR_XRGB(255,255,255));

以下是cpp文件中的定义:

//Loads a bitmap onto a texture
LPDIRECT3DTEXTURE9 LoadTexture(std::string filename, D3DCOLOR transcolor)
{
    LPDIRECT3DTEXTURE9 texture = NULL;

    //get width and height from bitmap file
    D3DXIMAGE_INFO info;
    HRESULT result = D3DXGetImageInfoFromFile(filename.c_str(), &info);
    if (result != D3D_OK) return NULL;

    //create the new textur by loading a bitmap image file
    D3DXCreateTextureFromFileEx(
        d3ddev,
        filename.c_str(),
        info.Width, info.Height,
        1,
        D3DPOOL_DEFAULT,
        D3DFMT_UNKNOWN,
        D3DPOOL_DEFAULT,
        D3DX_DEFAULT, D3DX_DEFAULT,
        transcolor,
        &info,
        NULL,
        &texture);

    //make sure the bitmap texture was loaded correctly
    if (result != D3D_OK) return NULL;

    return texture;
}

void Sprite_Transform_Draw(LPDIRECT3DTEXTURE9 image, int x, int y, int width, int height, 
    int frame, int columns, float rotation, float scaling, D3DCOLOR color)
{
    //Create a scale vector
    D3DXVECTOR2 scale(scaling, scaling);

    //Create a translate vector
    D3DXVECTOR2 trans(x, y);

    //Set center by dividing width and height by two
    D3DXVECTOR2 center((float)(width * scaling) / 2, (float)(height * scaling)/2);

    //Create 2D transformation matrix
    D3DXMATRIX mat;
    D3DXMatrixTransformation2D(&mat, NULL, 0, &scale, &center, rotation, &trans);

    //Tell sprite object to use the transform
    spriteobj->SetTransform( &mat );

    //Calculate frame location in source image
    int fx = (frame % columns) * width;
    int fy = (frame / columns) * height;
    RECT srcRect = {fx, fy, fx + width, fy + height};

    //draw the sprite frame
    spriteobj->Draw(image, &srcRect, NULL, NULL, color);
}

我如何在Game_Init函数中加载图像:

bool Game_Init(HWND window)
{
    //initialize Direct3D
    if (!Direct3D_Init(window, SCREENW, SCREENH, false))
    {
        MessageBox(0, "Error initializing Direct3D", "Error", 0);
        return false;
    }

    //initialize DirectInput
    if (!DirectInput_Init(window))
    {
        MessageBox(0, "Error initializing DirectInput", "Error", 0);
        return false;
    }

    //load the sprite image
    sunflower = LoadTexture("images/Sun.bmp");
    if (!sunflower) return false;

    return true;
}

以及我如何在Game_Run函数中绘制图像:

void Game_Run(HWND window)
{
    static float scale = 0.001f;
    static float r = 0;
    static float s = 1.0f;

    //make sure the Direct3D device is valid
    if (!d3ddev) return;

    //update input devices
    DirectInput_Update();

    //clear the scene
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 100), 1.0f, 0);

    //start rendering
    if (d3ddev->BeginScene())
    {
        //start drawing
        spriteobj->Begin(D3DXSPRITE_ALPHABLEND);

        //set rotation and scaling
        r = timeGetTime() / 600.0f;
        s += scale;
        if (s < 0.1 || s > 1.25f) scale *= -1;

        //draw sprite
        width = height = 64;
        frame = 0;
        columns = 1;
        color = D3DCOLOR_XRGB(255,255,255);
        Sprite_Transform_Draw(sunflower, 300, 150, width, height, frame, columns, r, s, color);

        //stop drawing
        spriteobj->End();

        //stop rendering
        d3ddev->EndScene();
        d3ddev->Present(NULL, NULL, NULL, NULL);
    }

    //escape key exits
    if (Key_Down(DIK_SPACE) || Key_Down(DIK_ESCAPE))
        gameover = true;
}

void Game_End()
{
    sunflower->Release();

    DirectInput_Shutdown();
    Direct3D_Shutdown();
}

就像我说一切正常,它只是让前一帧的图像仍然在屏幕上。我如何在帧之间清除屏幕?

编辑: 这里参考的是我试图描述的问题的图像: Sprite Animation Issue

1 个答案:

答案 0 :(得分:0)

想出来,我没有正确设置演示参数。

以下是原始代码:

//set Direct3D presentation parameters
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = (!fullscreen);
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.hDeviceWindow = window;

以下是正确需要的代码:

//set Direct3D presentation parameters
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = (!fullscreen);
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
d3dpp.EnableAutoDepthStencil = 1;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.hDeviceWindow = window;