gpt4 book ai didi

c++ - 如何在 DirectX 11 中绘制/渲染不同的形状

转载 作者:太空宇宙 更新时间:2023-11-04 12:58:45 25 4
gpt4 key购买 nike

我一直在尝试使用 MSDN tutorial05 示例代码学习 DirectX 11 编程的基础知识,但我遇到了一个问题,我无法在 Internet 上找到解决方案(无论如何我都能看到)。基本上我试图绘制和渲染一个玩家立方体对象,完成用户输入,以及玩家必须收集的类似金字塔的对象。

我的问题是,当我渲染场景时,只有立方体顶点(和索引)数据被读取,所以所有对象都是立方体,而它们不应该是立方体。

这是生成顶点数据的函数:

PyramidVertex Pyramid[] =
{
// Square base of the pyramid
{ XMFLOAT3( -0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },

// The tip of the pyramid
{ XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
};
D3D11_BUFFER_DESC bdP;
ZeroMemory(&bdP, sizeof(bdP));
bdP.Usage = D3D11_USAGE_DEFAULT;
bdP.ByteWidth = sizeof(PyramidVertex) * 5;
bdP.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bdP.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitPData;
ZeroMemory(&InitPData, sizeof(InitPData));
InitPData.pSysMem = Pyramid;
hr = g_pd3dDevice->CreateBuffer(&bdP, &InitPData, &g_pVertexBufferP);
if (FAILED(hr))
return hr;

// Set vertex buffer
UINT pStride = sizeof(PyramidVertex);
UINT pOffset = 1;
g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBufferP, &pStride, &pOffset);

// create the index buffer
DWORD pIndex[] =
{
0, 2, 1,
1, 2, 3,
0, 1, 4,
1, 3, 4,
3, 2, 4,
2, 0, 4,
};

// create the index buffer
bdP.Usage = D3D11_USAGE_DYNAMIC;
bdP.ByteWidth = sizeof(DWORD) * 18;
bdP.BindFlags = D3D11_BIND_INDEX_BUFFER;
bdP.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bdP.MiscFlags = 0;
InitPData.pSysMem = pIndex;
hr = g_pd3dDevice->CreateBuffer(&bdP, &InitPData, &g_pIndexBufferP);
if (FAILED(hr))
return hr;

// Set index buffer
g_pImmediateContext->IASetIndexBuffer(g_pIndexBufferP, DXGI_FORMAT_R16_UINT, 0);

// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);


// Create vertex buffer
SimpleVertex vertices[] =
{
{ XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( .0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4 (1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( .0f, 1.0f, 1.0f, 1.0f ) },
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 8;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) )
return hr;

// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

// Create index buffer
WORD indices[] =
{
3,1,0,
2,1,3,

0,5,4,
1,5,0,

3,4,7,
0,4,3,

1,6,5,
2,6,1,

2,7,6,
3,7,2,

6,4,5,
7,4,6,
};
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( WORD ) * 36; // 36 vertices needed for 12 triangles in a triangle list
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
InitData.pSysMem = indices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
if( FAILED( hr ) )
return hr;

// Set index buffer
g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );

// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);


// Create the constant buffer
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBuffer);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pConstantBuffer );
if( FAILED( hr ) )
return hr;

// Create the constant buffer
bdP.Usage = D3D11_USAGE_DEFAULT;
bdP.ByteWidth = sizeof(ConstantBuffer);
bdP.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bdP.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer(&bdP, nullptr, &g_pConstantBufferP);
if (FAILED(hr))
return hr;

// Initialize the world matrix
g_Player = XMMatrixIdentity();

for (int i = 0; i < 10; ++i)
{
g_Shapes[i] = XMMatrixIdentity();
}

// Initialize the view matrix
XMVECTOR Eye = XMVectorSet( 0.0f, 1.0f, -5.0f, 0.0f );
XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
XMVECTOR Up = XMVectorSet( 0.0f, 4.0f, 0.0f, 0.0f );
g_View = XMMatrixLookAtLH( Eye, At, Up );

// Initialize the projection matrix
g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f );

我认为问题出在此处,我的理论是金字塔 g_pImmediateContext 在绘制立方体时被覆盖。如果是这种情况,那么我不知道如何解决或研究这个问题。我花了一个小时才弄清楚如何将我的代码正确地放在这个页面上,但得到了奇怪的结果,所以我会留下一个指向我的 Google Drive 的链接。如果有人想深入了解(无论出于何种原因)代码,请包含此代码。

这是渲染函数:

//
// Clear the back buffer
//
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, Colors::Black);

//
// Clear the depth buffer to 1.0 (max depth)
//
g_pImmediateContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);

XMMATRIX mRotate = XMMatrixRotationZ(DXGame->playerUser->getRotation());
XMMATRIX mTranslate = XMMatrixTranslation(DXGame->playerUser->getXpos(), DXGame->playerUser->getYpos(), DXGame->playerUser->getZpos());
XMMATRIX mScale = XMMatrixScaling(0.7f, 0.7f, 0.7f);
g_Player = mScale * mRotate * mTranslate;

ConstantBuffer cb1;
cb1.mWorld = XMMatrixTranspose(g_Player);
cb1.mView = XMMatrixTranspose(g_View);
cb1.mProjection = XMMatrixTranspose(g_Projection);
g_pImmediateContext->UpdateSubresource(g_pConstantBuffer, 0, nullptr, &cb1, 0, 0);

g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBuffer);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
g_pImmediateContext->DrawIndexed(36, 0, 0);


for (int i = 0; i < 10; i++)
{
XMMATRIX sRotate = XMMatrixRotationY((DXGame->pickUps[i].rotation += 0.001f));
XMMATRIX sTranslate = XMMatrixTranslation(DXGame->pickUps[i].xPos, DXGame->pickUps[i].yPos, DXGame->pickUps[i].zPos);
XMMATRIX sScale = XMMatrixScaling(0.2f, 0.2f, 0.2f);

g_Shapes[i] = sScale * sRotate * sTranslate;

ConstantBuffer constB;
constB.mWorld = XMMatrixTranspose(g_Shapes[i]);
constB.mView = XMMatrixTranspose(g_View);
constB.mProjection = XMMatrixTranspose(g_Projection);
g_pImmediateContext->UpdateSubresource(g_pConstantBufferP, 0, nullptr, &constB, 0, 0);

g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBufferP);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
g_pImmediateContext->DrawIndexed(18, 0, 0);
}

g_pSwapChain->Present(0, 0);

我也在关注常量缓冲区和 HLSL,看看这是否也是一个问题。

请至少有人能给我指出正确的方向,因为这个问题已经困扰我将近 2 个月了(我把它留了这么久是因为我想自己弄清楚,但现在我迫切需要一个解决方案)。

感谢您花时间阅读这篇文章,很抱歉这么长,但我需要尽可能多地获取信息,希望它更容易阅读。

最佳答案

您对 IASetIndexBuffer 和 IASetVertexBuffers 的调用在您的创建例程中,它们需要在您的渲染函数中(在调用相关的 Draw 函数之前,因为它们在绘制之前将这些缓冲区附加到运行时)

它们根本不需要在创建部分(如在 DirectX11 上下文中,例如构建命令和设备,例如:创建资源是分离的)。

你应该在渲染循环中:

// Set vertex buffer and index buffer for your cube
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride,
&offset );

// Set index buffer
g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT,
0 );

g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBuffer);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
g_pImmediateContext->DrawIndexed(36, 0, 0);

在绘制所有金字塔之前:

// Set vertex buffer and index buffer for pyramids as you will draw it 10 times, you can do it once just before the loop as geometry will not change
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride,
&offset );
// Set index buffer
g_pImmediateContext->IASetIndexBuffer(g_pIndexBufferP, DXGI_FORMAT_R16_UINT, 0);


for (int i = 0; i < 10; i++)
{
//Same draw code as before
}

关于c++ - 如何在 DirectX 11 中绘制/渲染不同的形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45256082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com