【发布时间】:2016-01-30 12:50:59
【问题描述】:
我试图使用 Directx 11 创建具有用户定义坐标的三角形绘图:
void triangle(float anchorx, float anchory, float x1, float y1, float x2, float y2, XMFLOAT4 _color)
{
XMMATRIX scale;
XMMATRIX translate;
XMMATRIX world;
simplevertex framevertices[3] = { XMFLOAT3(anchorx, ui::height - anchory, 1.0f), XMFLOAT2(0.0f, 0.0f),
XMFLOAT3(x1, ui::height - y1, 1.0f), XMFLOAT2(1.0f, 0.0f),
XMFLOAT3(x2, ui::height - y2, 1.0f), XMFLOAT2(1.0f, 1.0f) };
world = XMMatrixIdentity();
dx11::generalcb.world = XMMatrixTranspose(world);// XMMatrixIdentity();
dx11::generalcb.fillcolor = _color;
dx11::generalcb.projection = XMMatrixOrthographicOffCenterLH( 0.0f, ui::width, 0.0f, ui::height, 0.01f, 100.0f );
// copy the vertices into the buffer
D3D11_MAPPED_SUBRESOURCE ms;
dx11::context->Map(dx11::vertexbuffers::trianglevertexbuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
memcpy(ms.pData, framevertices, sizeof(simplevertex) * 3);
dx11::context->Unmap(dx11::vertexbuffers::trianglevertexbuffer, NULL);
dx11::context->VSSetShader(dx11::shaders::simplevertexshader, NULL, 0);
dx11::context->IASetVertexBuffers(0, 1, &dx11::vertexbuffers::trianglevertexbuffer, &dx11::verticestride, &dx11::verticeoffset);
dx11::context->IASetInputLayout(dx11::shaders::simplevertexshaderlayout);
dx11::context->PSSetShader(dx11::shaders::panelpixelshader, NULL, 0);
dx11::context->UpdateSubresource(dx11::general_cb, 0, NULL, &dx11::generalcb, 0, 0);
dx11::context->IASetIndexBuffer(dx11::indexbuffers::triangleindexbuffer, DXGI_FORMAT_R16_UINT, 0);
dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
dx11::context->DrawIndexed(4, 0, 0);
//dx11::context->Draw(3, 0);
};
填充pos.y数据时Y轴上的减法:
XMFLOAT3(anchorx, ui::height - anchory, 1.0f)
XMFLOAT3(x1, ui::height - y1, 1.0f)
XMFLOAT3(x2, ui::height - y2, 1.0f)
我的正交投影将坐标零设置到屏幕的左下角,因此我从窗口高度减去传递的 Y 坐标以获得在 y 轴上的正确位置。不确定它是否会影响我的问题,因为它适用于所有其他基元(矩形、纹理、填充矩形、线条和圆形)。
索引缓冲区中定义的索引顺序:
unsigned short triangleindices[6] = { 0, 1, 2, 0, 2, 3 };
我实际上是使用这个索引缓冲区来渲染矩形,所以它被创建来渲染形成一个四边形的 2 个三角形,没有费心去创建单独的三角形索引缓冲区
Trianglevertexbuffer 包含数组 4 的 simplevertex:
//A VERTEX STRUCT
struct simplevertex
{
XMFLOAT3 pos; // pixel coordintes
XMFLOAT2 uv; // corresponding point color coordinates in texture
};
我没有在上面的函数中使用 UV 数据,只是用随机数据填充它们,因为颜色数据是通过常量缓冲区传递的。如您所见,我还只将 3 个第一个数组数据 memcpy 到三角形的顶点缓冲区只需要 3 个。
顶点着色器:
// SIMPLE VERTEX SHADER
cbuffer buffer : register(b0) // constant buffer, set up as 0 in set constant buffers command
{
matrix world; // world matrix
matrix projection; // projection matrix, is orthographic for now
float4 bordercolor;
float4 fillcolor;
float blendindex;
};
// simple vertex shader
float4 main(float4 input : POSITION) : SV_POSITION
{
float4 output = (float4)0; // setting variable fields to zero, may be skipped?
output = mul(input, world); // multiplying vertex shader output by world matrix passed in the constant buffer
output = mul(output, projection); // multiplying on by projection passed in the constant buffer (2d for now), resulting in final output data(.pos)
return output;
}
像素着色器:
// SIMPLE PIXEL SHADER RETURNING COLOR PASSED IN CONSTNT BUFFER
cbuffer buffer : register(b0) // constant buffer, set up as 0 in set constant buffers command
{
matrix world; // world matrix
matrix projection; // projection matrix, is orthographic for now
float4 bordercolor;
float4 fillcolor;
float blendindex;
};
// pixel shader returning preset color in constant buffer
float4 main(float4 input : SV_POSITION) : SV_Target
{
return fillcolor; // and we just return the color passed to constant buffer
}
函数中使用的布局:
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 };
在那里,我在渲染周期中创建了下一行:
if (ui::keys[VK_F1]) tools::triangle(700, 100, 400, 300, 850, 700, colors::blue);
if (ui::keys[VK_F2]) tools::triangle(400, 300, 700, 100, 850, 700, colors::blue);
if (ui::keys[VK_F3]) tools::triangle(700, 100, 850, 700, 400, 300, colors::blue);
if (ui::keys[VK_F4]) tools::triangle(850, 700, 400, 300, 700, 100, colors::blue);
if (ui::keys[VK_F5]) tools::triangle(850, 700, 700, 100, 400, 300, colors::blue);
if (ui::keys[VK_F6]) tools::triangle(400, 300, 850, 700, 700, 100, colors::blue);
这个设置的目的是实现任何随机顺序的坐标形成一个用于渲染的三角形,但这实际上是这个问题的重点——我没有得到这个三角形在某些坐标变化处渲染,所以我得出结论它来自 TOPOLOGY,正如你现在看到的那样:
dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
dx11::context->DrawIndexed(4, 0, 0);
这是绘制所有三角形的唯一组合,但老实说,我不明白它是如何发生的,据我所知,STRIP 拓扑与 context->Draw 函数一起使用,而 LIST 与索引缓冲区设置一起使用。接下来尝试:
dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
dx11::context->DrawIndexed(4, 0, 0);
未绘制三角形 F1、F5、F6。好的,接下来:
dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
//dx11::context->DrawIndexed(4, 0, 0);
dx11::context->Draw(3, 0);
同样的故事,F1、F5 和 F6 不渲染。
我无法理解正在发生的事情,您可能会发现代码有点原始,但我只想知道为什么我只有结合 STRIP 拓扑和 DrawIndexed 函数才能得到工作结果。我希望我提供了足够的信息,如果没有,对不起,我会按需更正。谢谢:)
【问题讨论】:
标签: c++ directx directx-11