动画精灵问题 (C++/DirectX9)
Posted
技术标签:
【中文标题】动画精灵问题 (C++/DirectX9)【英文标题】:Animating Sprites issue (C++/DirectX9) 【发布时间】:2015-07-24 18:17:28 【问题描述】:我正在学习有关使用 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();
就像我说的一切正常,它只是保持上一帧的图像仍然在屏幕上。我将如何清除帧之间的屏幕?
编辑: 作为参考,这里是我试图描述的问题的图像:
【问题讨论】:
检查d3ddev->Clear
的返回值是否失败。更一般地,您应该检查所有返回值以查看它们是否失败。
我把它改成检查清除场景,没有出现错误..
如果您不是在 Windows 8 上,您可以使用 DirectX SDK 的 DirectX 控制面板来启用 DirectX9 的调试层。通常,它可以简化查找此类基本错误的过程,因为您会在无效调用时收到有用的错误消息通知。
【参考方案1】:
想通了,我没有正确设置演示参数。
这是原始代码:
//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;
【讨论】:
以上是关于动画精灵问题 (C++/DirectX9)的主要内容,如果未能解决你的问题,请参考以下文章