Не удается привязать индексный буфер directx 11.
I have rendered 3d objects numerous times before in DirectX but this time encountered a strange problem, on which I wasted a day figuring out and still have nothing. I have a DX11 Context in which I load 3d models from obj files. I had to make a skybox and figured out that a good starting point would be to try to render a cube and then proceed further. My graphics pipeline draws many things, so unless I purposefully unbind the index shader, it will remain bound. If I try to render the cube with my cube’s index buffer bound, it doesn’t work. But if I don’t bind the index buffer it uses the previously bound buffer (as far as I can make out) and renders the vertices weirdly as expected. I must be missing something major here. I have spent hours and hours and still couldn’t solve the problem. I would be grateful if someone could help…
PS: я использую эти странные индексы только для тестирования, так как предполагал, что они вызывают проблему.
Что я уже пробовал:
Вот этот код:
void SkyBox::CreateShader(Vertex * verts, size_t size_of_verts, WORD* indices, size_t size_of_indices) { // Shader Compilation ID3D10Blob* VS = nullptr; ID3D10Blob* PS = nullptr; ID3D10Blob* ErrMSG = nullptr; D3DX11CompileFromFile("SkyShader.shader", 0, 0, "SKYMAP_VS", "vs_4_0", 0, 0, 0, &VS, &ErrMSG, 0); D3DX11CompileFromFile("SkyShader.shader", 0, 0, "SKYMAP_PS", "ps_4_0", 0, 0, 0, &PS, &ErrMSG, 0); char* p = new char[100]; // encapsulate both shaders into shader objects if (!ErrMSG && VS && PS) { pRenderer->GetDevice()->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), nullptr, &pVertexShader); pRenderer->GetDevice()->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), nullptr, &pPixelShader); } else { ELOG("The Shader file cannot be compiled. Please run this executable from the directory that contains the Shader file."); exit(1); } D3D11_INPUT_ELEMENT_DESC IED[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE(IED); pRenderer->GetDevice()->CreateInputLayout(IED, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout); // Vertex Buffer D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_DYNAMIC; bd.ByteWidth = size_of_verts; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = verts; pRenderer->GetDevice()->CreateBuffer(&bd, &InitData, OUT &pVBuffer); // creating the buffer // Index Buffer ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = size_of_indices; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = indices; pRenderer->GetDevice()->CreateBuffer(&bd, &InitData, OUT &pIBuffer); } SkyBox::SkyBox() { } SkyBox::SkyBox(CRenderer * pRenderer) : pRenderer(pRenderer) { } void SkyBox::CreateTri() { Vertex verts[] { {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f}, {-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 0.0f} }; WORD indices[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, }; CubeMesh Cube; Cube.CreateMesh(); CreateShader(verts, sizeof(Vertex) * 36, indices, sizeof(WORD) * 36); } void SkyBox::Render() { const UINT vStride = sizeof(Vertex); const UINT vOffset = 0; pRenderer->GetDeviceContext()->VSSetShader(pVertexShader, 0, 0); pRenderer->GetDeviceContext()->PSSetShader(pPixelShader, 0, 0); pRenderer->GetDeviceContext()->IASetInputLayout(pLayout); pRenderer->GetDeviceContext()->IASetVertexBuffers(0, 1, &pVBuffer, &vStride, &vOffset); pRenderer->GetDeviceContext()->IASetIndexBuffer(pIBuffer, DXGI_FORMAT_R16_UINT, 0); pRenderer->GetDeviceContext()->DrawIndexed(36, 0, 0); }
Функция рендеринга вызывается в разделе перед заменой буферов
Shao Voon Wong
Ваш вершинный и пиксельный шейдер-это один и тот же файл! Для меня они обычно находятся в отдельном файле.
Shao Voon Wong
Ваши показатели просто смешные. Обычно индексов больше, чем вершин. Вершина не должна повторяться, иначе она разрушает цель использования индексов. Индексы должны быть в этом паттерне.
0, 1, 2,
0, 2, 3,
1, 4, 5,
1, 5, 2, ...
Поскольку ваши вершины-это вся модель, вы должны отказаться от индексов и вызвать Draw(), а не DrawIndexed(). В этом случае не отправляйте свои индексы в контекст DX.
Member 14131869
я знаю, это было просто для проверки. и как ни странно, даже Draw() не работает.
Shao Voon Wong
Попробуйте сначала нарисовать треугольник без нормали.