在2D平台游戏中,我想要可视化我创建的边界框以帮助调试。如何在Visual C ++ 2012中完成此操作?
答案 0 :(得分:2)
首先定义一个简单的顶点结构:
struct Vertex
{
D3DXVECTOR3 position; //a 3D point even in 2D rendering
};
现在您可以创建顶点和索引数组:
Vertex *vertices;
unsigned long *indices = new unsigned long[5];
D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
D3D11_SUBRESOURCE_DATA vertexData, indexData;
//create the vertex array
vertices = new Vertex[5];
if(!vertices)
{
//handle error
}
//load the vertex array with data
vertices[0].position = D3DXVECTOR3(left, top, 0.0f);
vertices[1].position = D3DXVECTOR3(right, top, 0.0f);
vertices[2].position = D3DXVECTOR3(right, bottom, 0.0f);
vertices[3].position = D3DXVECTOR3(left, bottom, 0.0f);
vertices[4].position = D3DXVECTOR3(left, top, 0.0f);
//create the index array
indices = new unsigned long[5];
if(!indices)
{
//handle error
}
//load the index array with data
for(i=0; i<5; i++)
indices[i] = i;
将它们加载到缓冲区中:
ID3D11Buffer *vertexBuffer, *indexBuffer;
HRESULT result;
//set up the description of the dynamic vertex buffer
vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; //enables recreation and movement of vertices
vertexBufferDesc.ByteWidth = sizeof(Vertex) * 5;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; //couples with dynamic
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0;
//give the subresource structure a pointer to the vertex data
vertexData.pSysMem = vertices;
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;
//now create the vertex buffer
result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &vertexBuffer);
if(FAILED(result))
{
//handle error
}
//set up the description of the static index buffer
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(unsigned long) * 5;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
indexBufferDesc.StructureByteStride = 0;
//give the subresource structure a pointer to the index data
indexData.pSysMem = indices;
indexData.SysMemPitch = 0;
indexData.SysMemSlicePitch = 0;
//create the index buffer
result = device->CreateBuffer(&indexBufferDesc, &indexData, &indexBuffer);
if(FAILED(result))
{
//handle error
}
设置要渲染的矩形:
unsigned int stride = sizeof(Vertex);
unsigned int offset = 0;
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
deviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP);
现在使用您选择的着色器进行渲染,记住将orthographic matrix传递给着色器而不是透视矩阵。瞧!长方形。但是你还不能移动它......你必须定义另一个函数来做到这一点:
bool UpdateRectBuffers(ID3D11Buffer *vertexBuffer, ID3D11DeviceContext *deviceContext, float top, float left, float bottom, float right)
{
Vertex *vertices;
D3D11_MAPPED_SUBRESOURCE mappedResource;
VertexType *verticesPtr;
HRESULT result;
//create a temporary vertex array to fill with the updated data
vertices = new Vertex[5];
if(!vertices)
{
return false;
}
vertices[0].position = D3DXVECTOR3(left, top, 0.0f);
vertices[1].position = D3DXVECTOR3(right, top, 0.0f);
vertices[2].position = D3DXVECTOR3(right, bottom, 0.0f);
vertices[3].position = D3DXVECTOR3(left, bottom, 0.0f);
vertices[4].position = D3DXVECTOR3(left, top, 0.0f);
//lock the vertex buffer so it can be written to
result = deviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if(FAILED(result))
{
return false;
}
verticesPtr = (Vertex*)mappedResource.pData;
//copy the data into the vertex buffer
memcpy(verticesPtr, (void*)vertices, (sizeof(Vertex) * 5));
deviceContext->Unmap(vertexBuffer, 0);
delete [] vertices;
vertices = 0;
return true;
}
此代码的依赖项为float top
,float left
,float right
,float left
,ID3D11DeviceContext *deviceContext
和ID3D11Device *device
。
答案 1 :(得分:0)
由于你没有很好地描述你已经能够做到的事情,我的回答是基于一些假设。
所以,我假设
并且不会解释如何做到这一点。
变体1: 绘制边缘不需要任何特殊的东西。 “边缘”(直线)只是长而细的矩形。因此,您需要在边缘应该放置4个薄矩形。
这样你就可以选择粗细,线条的颜色,甚至可以使用纹理(虚线,虚线,粉红色小猫的线条等)或着色效果,如程序着色,平滑,模糊等。无论如何,你可能需要你的游戏线。
变体2: 您可以绘制线条而不是三角形。使用“行列表”基元拓扑,而不是“三角形列表”。 (参见:ID3D11DeviceContext::IASetPrimitiveTopology(),D3D11_PRIMITIVE_TOPOLOGY_LINELIST)。
这样你无法自定义东西。但这更容易。
变体3: 在线框模式下绘制矩形。只需设置光栅化器状态的填充模式。请参阅:ID3D11DeviceContext::RSSetState,D3D11_RASTERIZER_DESC::FillMode,D3D11_FILL_MODE::D3D11_FILL_WIREFRAME
你会得到三角形的边,甚至是那些是矩形对角线的三角形。这样,您既不能设置厚度,也不能设置颜色。但这种方式非常非常简单。
变体4: 使用任何将为您执行变体1的2D绘图库。作为D3DX is obsolete,不建议再使用D3DXLine。您可以尝试DirectX toolkit或网上提供的任何库。 显然你会得到额外的依赖。
如果我的初步假设不正确,那么你不会在这里得到答案。 StackOverflow上没有人会向你解释这些基本的东西。纠正一种情况:
希望它有所帮助!