DirectX 10 3D场景随着2D绘图而消失

DirectX 10 3D scene disappears with 2D drawing

本文关键字:2D 绘图 消失 3D DirectX      更新时间:2023-10-16

由于我无法理解的原因,当我调用时,我的3D场景消失了

this->sp->Begin(D3DX10_SPRITE_SORT_TEXTURE);

此处->sp为LPD3DX10SPRITE。

以渲染我的2D场景。当我调用时,我的3D场景也会消失

RECT rc = {5, 5, 0, 0};
this->TR.Font->DrawText(
NULL, 
SS.str().c_str(), 
-1, 
&rc, 
DT_NOCLIP, 
D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f));

此处->TR.Font为ID3DX10Font。

我应该为每个场景使用ID3D10RenderTargetView,然后在绘图功能结束时进行组合吗?

如果有帮助的话,这里有Draw()函数。

void Draw()
{
this->GDM.Clear(Color(100, 149, 237));
this->GDM.Device->RSSetState(this->GDM.RasterizerState);
this->GDM.Device->OMSetBlendState(this->GDM.BlendState, 0, 0xffffffff);
this->GDM.EnableZBuffer(true);
static float r;
D3DXMATRIX w;
D3DXMatrixIdentity(&w);
//D3DXMatrixRotationY(&w, r);
r += 0.01f * (3.14f / 180.0f);// * (float)Time->Scalar;

this->effect.WorldMatrix->SetMatrix(w);
this->effect.ViewMatrix->SetMatrix(viewMatrix);
this->effect.ProjectionMatrix->SetMatrix(projectionMatrix);
Vertex_PosCol * v = NULL;
this->VertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &v);
v[0] = Vertex_PosCol(D3DXVECTOR3(-1,-1,0), D3DXVECTOR4(1,0,0,1));
v[1] = Vertex_PosCol(D3DXVECTOR3(0,1,0), D3DXVECTOR4(0,1,0,1));
v[2] = Vertex_PosCol(D3DXVECTOR3(1,-1,0), D3DXVECTOR4(0,0,1,1));
this->VertexBuffer->Unmap();
this->GDM.Device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
//this->GDM.Device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP);
D3D10_TECHNIQUE_DESC techDesc;
this->effect.Technique->GetDesc( &techDesc );
for (int p = 0; p < techDesc.Passes; p++)
{
this->effect.Technique->GetPassByIndex( p )->Apply( 0 );
this->GDM.Device->Draw(3, 0);
}
this->GDM.EnableZBuffer(false);
this->sBatch->Begin();
if (loaded)
{
this->sBatch->Draw(
s1,
this->Input->Mouse.Position.x,
this->Input->Mouse.Position.y,
200,
200,
45.0f * (3.14f / 180.0f));
this->sBatch->Draw(s2, x, y, 200, 200);
}
this->sBatch->End();
SS << "Graphics Test And Development" << "n";
SS << "FPS: " << this->Time->FPS << "n";
SS << "X: " << x << "n";
SS << "Y: " << y << "n";
RECT rc = {5, 5, 0, 0};
this->TR.RenderText(this->SS.str().c_str(), 5, 5, &Color(0.0f, 1.0f, 0.0f, 1.0f));
this->SS.str("");
}

正如上面评论中提到的,设置D3DX10_SPRITE_SAVE_STATE解决了用3D渲染2D的问题。然而,这并没有阻止DrawText删除3D场景。几年前我有这个工作,所以我花了一个小时试图找到我的旧代码。遗憾的是,我做不到,但我确实找到了我当时遵循的教程。

以下是解决方案:

而不是像我那样在每一帧中创建和丢弃顶点:

this->VertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &v);
v[0] = Vertex_PosCol(D3DXVECTOR3(-1,-1,0), D3DXVECTOR4(1,0,0,1));
v[1] = Vertex_PosCol(D3DXVECTOR3(0,1,0), D3DXVECTOR4(0,1,0,1));
v[2] = Vertex_PosCol(D3DXVECTOR3(1,-1,0), D3DXVECTOR4(0,0,1,1));
this->VertexBuffer->Unmap();

我在Load()函数中创建了一个顶点和索引缓冲区:

UINT VerticeCount = 3;
ULONG IndexCount = 3;
Vertex_PosCol * vertices = NULL;
vertices = new Vertex_PosCol[VerticeCount];
vertices[0].Position = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);  // Bottom left.
vertices[0].Color = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);
vertices[1].Position = D3DXVECTOR3(0.0f, 1.0f, 0.0f);  // Top middle.
vertices[1].Color = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f);
vertices[2].Position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);  // Bottom right.
vertices[2].Color = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f);
unsigned long * indices = new unsigned long[IndexCount];
indices[0] = 0;  // Bottom left.
indices[1] = 1;  // Top middle.
indices[2] = 2;  // Bottom right.
D3D10_BUFFER_DESC vbd;
vbd.Usage = D3D10_USAGE_DEFAULT;
vbd.ByteWidth = sizeof(Vertex_PosCol) * VerticeCount;
vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA vertexData;
vertexData.pSysMem = vertices;
HRESULT result = this->GDM.Device->CreateBuffer(&vbd, &vertexData, &VertexBuffer);
UINT stride = sizeof( Vertex_PosCol );
UINT offset = 0;
if(FAILED(result))
{
bool b = false;
}
D3D10_BUFFER_DESC ibd;
ibd.Usage = D3D10_USAGE_DEFAULT;
ibd.ByteWidth = sizeof(unsigned long) * IndexCount;
ibd.BindFlags = D3D10_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA indexData;
indexData.pSysMem = indices;
result = this->GDM.Device->CreateBuffer(&ibd, &indexData, &IndexBuffer);
if(FAILED(result))
{
bool b = false;
}
delete [] vertices;
delete [] indices;

然后在Draw()函数中,我设置了顶点和索引缓冲区、基元拓扑以及特定缓冲区的输入布局。然后我画了三维场景,然后是文本。以下是Draw()函数代码:

void Draw()
{
this->GDM.Clear(Color(100, 149, 237));
this->GDM.Device->RSSetState(this->GDM.RasterizerState);
this->GDM.Device->OMSetBlendState(this->GDM.BlendState, 0, 0xffffffff);
this->GDM.EnableZBuffer(true);
static float r;
D3DXMATRIX w;
D3DXMatrixIdentity(&w);
//D3DXMatrixRotationY(&w, r);
r += 0.01f * (3.14f / 180.0f);// * (float)Time->Scalar;

this->effect.WorldMatrix->SetMatrix(w);
this->effect.ViewMatrix->SetMatrix(viewMatrix);
this->effect.ProjectionMatrix->SetMatrix(projectionMatrix);

UINT stride = sizeof(Vertex_PosCol);
UINT offset = 0;
this->GDM.Device->IASetVertexBuffers(0, 1, &this->VertexBuffer, &stride, &offset);
this->GDM.Device->IASetIndexBuffer(this->IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
this->GDM.Device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
//this->GDM.Device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP);
this->GDM.Device->IASetInputLayout(Vertex_PosCol::GetInputLayout());
D3D10_TECHNIQUE_DESC techDesc;
this->effect.Technique->GetDesc( &techDesc );
for (int p = 0; p < techDesc.Passes; p++)
{
this->effect.Technique->GetPassByIndex( p )->Apply( 0 );
this->GDM.Device->DrawIndexed(3,0,0);
}
this->GDM.EnableZBuffer(false);
this->sBatch->Begin();
if (loaded)
{
this->sBatch->Draw(
s1,
this->Input->Mouse.Position.x,
this->Input->Mouse.Position.y,
200,
200,
45.0f * (3.14f / 180.0f));
this->sBatch->Draw(s2, x, y, 200, 200);
}
this->sBatch->End();
SS << "Graphics Test And Development" << "n";
SS << "FPS: " << this->Time->FPS << "n";
SS << "X: " << x << "n";
SS << "Y: " << y << "n";
RECT rc = {5, 5, 0, 0};
this->TR.RenderText(this->SS.str().c_str(), 5, 5, &Color(0.0f, 1.0f, 0.0f, 1.0f));
this->SS.str("");
}

由于犯了愚蠢的错误,我在这件事上花的时间远远超过了我应该花的时间。当我创建缓冲区时,我为每个顶点和索引缓冲区创建了一个D3D10_SUBRESOURCE_DATA对象,但我忘记了设置它们,因此,我根本没有得到3D场景。

根据我目前使用的3D场景渲染方法,D3DX10_SPRITE_SAVE_STATE作为LPD3DX10SPRITE.Beggin()中的标志是不必要的,但我无论如何都会保留它,除非它碰巧会带来任何性能问题,但我怀疑情况是否会如此。

无论如何,我确实意识到,一个简单的"嘿,我改变了这个,它起作用了"可能已经足够作为一个答案了,但我想彻底一点。希望这能帮助到别人!