Мое приложение должно рисовать много спрайтов. Но почему-то это кажется медленным (30 самолетов, которые сражаются друг с другом, означает + ~ 30 анимированных ракет и взрывов).
Как я могу это исправить, чтобы оно плавно анимировалось? Заранее спасибо за помощь!
Не знаю, как подойти к проблеме.
struct d3dsprite_s {
std::wstring wszFile; //File name
LPD3DXSPRITE pSprite; //Pointer to the sprite object
LPDIRECT3DTEXTURE9 pTexture; //Pointer to the sprite texture
int iFrameCount; //Total amount of frames
int iFramesPerLine; //Amount of frames per line
int iFrameWidth; //Single frame width
int iFrameHeight; //Single frame height
};
std::vector<d3dsprite_s> m_vSprites;
HD3DSPRITE LoadSprite(const std::wstring& wszTexture, int iFrameCount, int iFrameWidth, int iFrameHeight, int iFramesPerLine, const bool bForceCustomSize = false)
{
//Load sprite
if (!wszTexture.length())
return GFX_INVALID_SPRITE_ID;
d3dsprite_s sSpriteData;
//Create sprite
if (FAILED(D3DXCreateSprite(this->m_pDevice, &sSpriteData.pSprite)))
return GFX_INVALID_SPRITE_ID;
//Load texture from file
if (FAILED(D3DXCreateTextureFromFileEx(this->m_pDevice, wszTexture.c_str(), (bForceCustomSize) ? iFrameWidth : D3DX_DEFAULT_NONPOW2, (bForceCustomSize) ? iFrameHeight : D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT, 0, D3DFMT_FROM_FILE, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0xFF000000, nullptr, nullptr, &sSpriteData.pTexture))) {
sSpriteData.pSprite->Release();
return GFX_INVALID_SPRITE_ID;
}
//Save further data
sSpriteData.wszFile = wszTexture;
sSpriteData.iFrameCount = iFrameCount;
sSpriteData.iFramesPerLine = iFramesPerLine;
sSpriteData.iFrameWidth = iFrameWidth;
sSpriteData.iFrameHeight = iFrameHeight;
//Add to list
this->m_vSprites.push_back(sSpriteData);
//Return handle
return sSpriteData.pSprite;
}
bool DrawSprite(const HD3DSPRITE hSprite, int x, int y, int iFrame, float fRotation, int rotx, int roty, float fScale1, float fScale2, const bool bUseCustomColorMask, byte r, byte g, byte b, byte a)
{
//Add sprite to drawing list
if (!hSprite)
return false;
//Find sprite
size_t uiSprite = this->FindSprite(hSprite);
if (uiSprite == GFX_INVALID_LIST_ID)
return false;
if ((!this->m_vSprites[uiSprite].pTexture) || (!this->m_vSprites[uiSprite].pSprite))
return false;
//Calculate horizontal line ID
int iFrameLineId = (this->m_vSprites[uiSprite].iFramesPerLine > 0) ? iFrame / this->m_vSprites[uiSprite].iFramesPerLine : 0;
//Calculate vertical frame ID
int iFrameVerticalId = (this->m_vSprites[uiSprite].iFramesPerLine > 0) ? iFrame % this->m_vSprites[uiSprite].iFramesPerLine : 0;
//Calculate x position of frame
int iFrameXPos = iFrameVerticalId * this->m_vSprites[uiSprite].iFrameWidth;
//Calculate y position of frame
int iFrameYPos = iFrameLineId * this->m_vSprites[uiSprite].iFrameHeight;
//Setup rectangle info
RECT sRect;
sRect.top = iFrameYPos;
sRect.left = iFrameXPos;
sRect.bottom = iFrameYPos + this->m_vSprites[uiSprite].iFrameHeight;
sRect.right = iFrameXPos + this->m_vSprites[uiSprite].iFrameWidth;
//Begin drawing sprite
if (FAILED(this->m_vSprites[uiSprite].pSprite->Begin(D3DXSPRITE_ALPHABLEND)))
return false;
//Setup vector with position
D3DXVECTOR2 vPosition = { (float)x, (float)y };
//Setup vector with sprite center
D3DXVECTOR2 vRotCenter;
if ((rotx != -1) && (roty != -1))
vRotCenter = { (float)(rotx), (float)(roty) };
else
vRotCenter = { (float)(this->m_vSprites[uiSprite].iFrameWidth / 2) , (float)(this->m_vSprites[uiSprite].iFrameHeight / 2) };
D3DXMATRIX vNewMatrix;
//Setup scale vector
D3DXVECTOR2 vScale(fScale1, fScale2);
//Calculate transformation matrix
if (!D3DXMatrixTransformation2D(&vNewMatrix, ((fScale1 != 0.0f) && (fScale2 != 0.0f)) ? &vRotCenter : nullptr, 0.0f, ((fScale1 != 0.0f) && (fScale2 != 0.0f)) ? &vScale : nullptr, (D3DXVECTOR2*)&vRotCenter, fRotation, &vPosition))
return false;
//Apply transformation
if (FAILED(this->m_vSprites[uiSprite].pSprite->SetTransform(&vNewMatrix)))
return false;
//Add sprite to batch list
if (FAILED(this->m_vSprites[uiSprite].pSprite->Draw(this->m_vSprites[uiSprite].pTexture, &sRect, nullptr, nullptr, (bUseCustomColorMask) ? D3DCOLOR_RGBA(r, g, b, a) : 0xFFFFFFFF)))
return false;
//End drawing sprite
return SUCCEEDED(this->m_vSprites[uiSprite].pSprite->End());
}
const size_t FindSprite(const HD3DSPRITE hSprite)
{
//Get list ID of sprite handle if exists
for (size_t i = 0; i < this->m_vSprites.size(); i++) {
if (this->m_vSprites[i].pSprite == hSprite)
return i;
}
return GFX_INVALID_LIST_ID;
}
Ожидаемое: быстрое рисование спрайтов.
Актуально: Медленное рисование спрайтов