我正在编写一个使用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, ¢er, 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();
}
就像我说一切正常,它只是让前一帧的图像仍然在屏幕上。我如何在帧之间清除屏幕?
编辑: 这里参考的是我试图描述的问题的图像:
答案 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;