頂点バッファー(DrawPrimitive)を使用してDX9で2Dスプライトをレンダリングしています。一部のアニメーションには、サイズの異なる異なるテクスチャファイルが含まれています。
ここで、次の問題が発生します。テクスチャファイルが異なる2つのアニメーションを切り替える非常に単一のフレーム(たとえば、歩行を開始するとき、または歩行を終了して立ち始めるとき)で、新しいテクスチャの座標でレンダリングされます。しかし、まだ古いテクスチャを提示しています。これは、新しいアニメーションのテクスチャを設定しなかったかのように見えます。唯一の問題は-私がやったことです。
何が問題なのかをどのように理解したか:そのフレームでスクリーンショットを撮ったところ、一方のテクスチャがもう一方のテクスチャに適合する座標でレンダリングされていることに気付きました。
レンダリング関数では、座標を計算するのではなく、最初に新しいテクスチャを取得してDXに送信し、最後に、座標と新しいテクスチャセットを使用して頂点をレンダリングします。私はそれを何百万回もチェックしてデバッグしました、そしてすべての値は正しいです、それでもバグは起こります。
なぜこれが起こるのか、何か考えはありますか?
ありがとう!
編集:いくつかのコードを追加しました:
// Render a quad using the vertex buffer
void CGraphicsManager::RenderQuadViaVertexBuffer(const SVertex* pVertices) const
{
// Increase renders count
this->m_RenderCount++;
// vb_vertices now points to our vertices inside the Vertex buffer, so
// to fill in our VB, we copy to vb_vertices.
memcpy(this->m_pVertexBufferBuffPtr + this->m_OffsetInVertexBuffer, pVertices, sizeof(SVertex) * (VERTICES_IN_QUAD));
// Render the rectanlge using the vertices we got.
this->m_pD3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, this->m_OffsetInVertexBuffer, PRIMITIVES_IN_QUAD);
// Increment the offset in the vertex buffer
this->m_OffsetInVertexBuffer += VERTICES_IN_QUAD;
}
// Render a quad
void CGraphicsManager::Render(const STexture& p_Texture, SLocation p_RenderLocation, SSize p_RenderSize, const SQuad& p_TextureQuad, SfColor p_RenderColor, ERenderEffects p_RenderEffect) const
{
// Set render effect
this->SetRenderEffect(p_RenderEffect);
// Set texture
this->SetTexture(p_Texture);
// Set the vertex needed for the rendering
VerticesForQuadRender[0].Position.x = p_RenderLocation.x;
VerticesForQuadRender[0].Position.y = p_RenderLocation.y;
VerticesForQuadRender[0].Position.z = 0.0f;
VerticesForQuadRender[0].color = p_RenderColor;
VerticesForQuadRender[0].tv = p_TextureQuad.left;
VerticesForQuadRender[0].tu = p_TextureQuad.top;
VerticesForQuadRender[1].Position.x = p_RenderLocation.x + p_RenderSize.x;
VerticesForQuadRender[1].Position.y = p_RenderLocation.y;
VerticesForQuadRender[1].Position.z = 0.0f;
VerticesForQuadRender[1].color = p_RenderColor;
VerticesForQuadRender[1].tv = p_TextureQuad.right;
VerticesForQuadRender[1].tu = p_TextureQuad.top;
VerticesForQuadRender[2].Position.x = p_RenderLocation.x;
VerticesForQuadRender[2].Position.y = p_RenderLocation.y + p_RenderSize.y;
VerticesForQuadRender[2].Position.z = 0.0f;
VerticesForQuadRender[2].color = p_RenderColor;
VerticesForQuadRender[2].tv = p_TextureQuad.left;
VerticesForQuadRender[2].tu = p_TextureQuad.bottom;
VerticesForQuadRender[3].Position.x = p_RenderLocation.x + p_RenderSize.x;
VerticesForQuadRender[3].Position.y = p_RenderLocation.y + p_RenderSize.y;
VerticesForQuadRender[3].Position.z = 0.0f;
VerticesForQuadRender[3].color = p_RenderColor;
VerticesForQuadRender[3].tv = p_TextureQuad.right;
VerticesForQuadRender[3].tu = p_TextureQuad.bottom;
this->RenderQuadViaVertexBuffer(VerticesForQuadRender);
}
// Starts a rendering frame
bool CGraphicsManager::StartFrame()
{
// Clear texture
this->ClearTexture();
// Zero renders count
this->m_RenderCount = 0;
// Clear screen
if (!this->ClearScreen())
{
this->ResetDevice();
return false;
}
// Begin new rendering scene
if (FAILED(this->m_pD3dDevice->BeginScene()))
{
this->ResetDevice();
return false;
}
// Set render from our vertex buffer
this->BeginRenderFromVertexBuffer();
return true;
}
// Finish rendering
bool CGraphicsManager::EndFrame()
{
// Unlock vertex buffer
this->m_pVertexBuffer->Unlock();
// Notify the device that we're finished rendering for this frame
if (FAILED(this->m_pD3dDevice->EndScene()))
{
this->ResetDevice();
return false;
}
// Present scene
if(FAILED(this->m_pD3dDevice->Present(NULL, //Source rectangle to display, NULL for all of it
NULL, //Destination rectangle, NULL to fill whole display
NULL, //Target window, if NULL uses device window set in CreateDevice
NULL ))) //Dirty Region, set it to NULL
{
this->ResetDevice();
return false;
}
// Finish rendering
return true;
}
// This function must be called before rendering textured surfaces
void CGraphicsManager::BeginRenderFromVertexBuffer() const
{
// Lock the vertex buffer (unlock on release) and get the pointer to the begining of the buffer
HRESULT hr = this->m_pVertexBuffer->Lock
(0, // Offset, we want to start at the beginning
0, //SizeToLock, 0 means lock the whole thing
(void**)&this->m_pVertexBufferBuffPtr, //If successful, this will point to the data in the vertex buffer
0);
ASSERT(SUCCEEDED(hr), "Failed to lock vertex buffer! (err: " << hr << ")");
// Set offset in vertex buffer back to 0
this->m_OffsetInVertexBuffer = 0;
}