我正在使用顶点缓冲区(DrawPrimitive)使用 DX9 渲染 2D 精灵。一些动画有不同大小的不同纹理文件。
现在我遇到了以下问题:在非常单一的帧上,我在两个具有不同纹理文件的动画之间切换(例如,当开始行走或完成行走并开始站立时),它使用新纹理的坐标进行渲染,但仍然呈现旧纹理。这看起来好像我没有为新动画设置纹理。唯一的问题是 - 我做到了。
我如何理解问题出在哪里:我在该帧上截取了一张屏幕截图,并注意到它渲染了一个纹理,其坐标与另一个纹理相匹配。
在我的渲染函数中,我首先获取新纹理并将其发送到 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;
}