Рендеринг с Directx10

Во время выполнения я ожидаю, что все объекты, которые были успешно созданы и прорисованы в программе во время инициализации, будут менять свои позиции при каждом вызове функции GraphicsClass::Render(). Но ничего не происходит: все цифры (точки в моем случае) стоят на месте, и никакого движения нет.

Я знаю, что общий подход в Directx10 - это использование матриц мира, ракурса и проекций. Но здесь я напрямую изменяю буфер, который затем отправляется объекту ID3D10Device для рисования, потому что мне нужно нарисовать много объектов с их различными траекториями, и каждый объект представлен точкой.

Я подозреваю, что ошибка может быть в методе ColorShaderClass::SetShaderParameters. Итак, я только прикрепил код, который напрямую связан с рендерингом в программе.

graphicsclass.h

class GraphicsClass
{
public:
    GraphicsClass();
    GraphicsClass(const GraphicsClass&);
    ~GraphicsClass();

    bool Initialize(int, int, HWND);
    void Shutdown();
    bool Frame(double time);

private:
    bool Render(double time);

private:
    D3DClass * m_Direct3D;
    CameraClass* m_Camera;
    ModelClass* m_Model;
    ColorShaderClass* m_ColorShader;

    //amount of bodies
    int m_bodies;
};

graphicsclass.cpp

bool GraphicsClass::Render()
{
    // Clear the buffers to begin the scene.
    m_Direct3D->BeginScene(0.5f, 0.5f, 0.5f, 1.0f);

    bool result;

    // Clear the buffers to begin the scene.
    m_Direct3D->BeginScene(0.0f, 0.0f, 0.0f, 1.0f);

    // Generate the view matrix based on the camera's position.
    m_Camera->Render();

    // Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing.
    m_Model->Render(m_Direct3D->GetDevice());

    // Render the model using the color shader.
    result = m_ColorShader->Render(m_Direct3D->GetDevice(), m_Model->GetIndexCount(),m_Model->GetPositions());
    if (!result)
    {
        return false;
    }

    // Present the rendered scene to the screen.
    m_Direct3D->EndScene();
    return true;
}

modelclsss.h

class ModelClass
{
private:
    struct ModelVertex {
        XMFLOAT4 Pos;
    };

public:
    ModelClass(int); //pass number of bodies
    ModelClass(const ModelClass&);
    ~ModelClass();

    bool Initialize(ID3D10Device*);
    void Shutdown();
    void Render(ID3D10Device*);

    int GetIndexCount();
    float * GetPositions();

private:
    bool InitializeBuffers(ID3D10Device*);
    void ShutdownBuffers();
    void RenderBuffers(ID3D10Device*);

private:
    ID3D10Buffer *m_vertexBuffer, *m_indexBuffer;
    int m_vertexCount, m_indexCount;

    float  * m_positions;
    float  * m_velocities;
    NBodySystemGPU * m_bodySystem;
    int m_bodies;
};

modelclass.cpp

void ModelClass::Render(ID3D10Device* device)
{
    //update bodies' positions
    bool result;
    //m_bodySystem->update(0.00001f, m_positions, m_velocities, result);
    for (int i = 0; i < m_bodies; ++i) {
        m_positions[i] += 0.5;
    }
    InitializeBuffers(device);
    // Put the vertex and index buffers on the graphics pipeline to prepare them for drawing.
    RenderBuffers(device);
    return;
}

void ModelClass::RenderBuffers(ID3D10Device* device)
{
    unsigned int stride;
    unsigned int offset;

    // Set vertex buffer stride and offset.
    stride = sizeof(ModelVertex);
    offset = 0;

    // Set the vertex buffer to active in the input assembler so it can be rendered.
    device->IASetVertexBuffers(0, 1, &m_vertexBuffer, &stride, &offset);

    // Set the index buffer to active in the input assembler so it can be rendered.
    device->IASetIndexBuffer(m_indexBuffer, DXGI_FORMAT_R32_UINT, 0);

    // Set the type of primitive that should be rendered from this vertex buffer, in this case triangles.
    device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_POINTLIST);

    return;
}

bool ModelClass::InitializeBuffers(ID3D10Device* device)
{
    unsigned long* indices;
    D3D10_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
    D3D10_SUBRESOURCE_DATA vertexData, indexData;
    HRESULT result;

    // Create the index array.
    indices = new unsigned long[m_bodies];
    if(!indices)
    {
        return false;
    }

    // Load the vertex array with data.
    for (int i = 0; i < m_bodies; ++i) {
        indices[i] = i;
    }

    // Set up the description of the vertex buffer.
    ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
    vertexBufferDesc.Usage = D3D10_USAGE_DYNAMIC;
    vertexBufferDesc.ByteWidth = sizeof(ModelVertex) * m_bodies;
    vertexBufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    vertexBufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
    vertexBufferDesc.MiscFlags = 0;

    // Give the subresource structure a pointer to the vertex data.
    ZeroMemory(&vertexData, sizeof(vertexData));
    vertexData.pSysMem = m_positions;
    vertexData.SysMemPitch = 0;
    vertexData.SysMemSlicePitch = 0;

    // Now finally create the vertex buffer.
    result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);
    if(FAILED(result))
    {
        return false;
    }

    // Set up the description of the index buffer.
    ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc));
    indexBufferDesc.Usage = D3D10_USAGE_DYNAMIC;
    indexBufferDesc.ByteWidth = sizeof(unsigned long) * m_bodies;
    indexBufferDesc.BindFlags = D3D10_BIND_INDEX_BUFFER;
    indexBufferDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
    indexBufferDesc.MiscFlags = 0;

    // Give the subresource structure a pointer to the index data.
    indexData.pSysMem = indices;

    // Create the index buffer.
    result = device->CreateBuffer(&indexBufferDesc, &indexData, &m_indexBuffer);
    if(FAILED(result))
    {
        return false;
    }

    // Release the arrays now that the vertex and index buffers have been created and loaded.

    delete [] indices;
    indices = 0;

    return true;
}

colorshadersclss.h

class ColorShaderClass
{
private:
    struct ColorVertex {
        XMFLOAT4 Pos;
    };

public:
    ColorShaderClass(int); //pass number of bodies
    ColorShaderClass(const ColorShaderClass&);
    ~ColorShaderClass();

    bool Initialize(ID3D10Device*, HWND);
    void Shutdown();
    bool Render(ID3D10Device*, int,float *);

private:
    bool InitializeShader(ID3D10Device*, HWND, WCHAR*, WCHAR*);
    void ShutdownShader();
    void OutputShaderErrorMessage(ID3D10Blob*, HWND, WCHAR*);

    bool SetShaderParameters(ID3D10Device*,float *);
    void RenderShader(ID3D10Device*, int);

private:
    ID3D10VertexShader* m_vertexShader;
    ID3D10PixelShader* m_pixelShader;
    ID3D10InputLayout* m_layout;
    ID3D10Buffer* m_matrixBuffer;

    //Body system 
    int m_bodies;
};

colorshaders.cpp

bool ColorShaderClass::Render(ID3D10Device* device, int indexCount, float * positions)
{
    bool result;

    // Set the shader parameters that it will use for rendering.
    result = SetShaderParameters(device,positions);
    if (!result)
    {
        return false;
    }

    // Now render the prepared buffers with the shader.
    RenderShader(device, indexCount);

    return true;
}

bool ColorShaderClass::SetShaderParameters(ID3D10Device* device, float * positions)
{
    HRESULT result;
    void* mappedResource;

    unsigned int bufferNumber;

    // Lock the constant buffer so it can be written to.
    result = m_matrixBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mappedResource);
    if(FAILED(result))
    {
        return false;
    }

    // Get a pointer to the data in the constant buffer.
    memcpy(mappedResource, positions, 4 * m_bodies * sizeof(float));

    // Unlock the constant buffer.
    m_matrixBuffer->Unmap();

    // Set the position of the constant buffer in the vertex shader.
    bufferNumber = 0;

    // Finally set the constant buffer in the vertex shader with the updated values.
    device->VSSetConstantBuffers(bufferNumber, 1, &m_matrixBuffer);

    return true;
}

void ColorShaderClass::RenderShader(ID3D10Device* device, int indexCount)
{
    // Set the vertex input layout.
    device->IASetInputLayout(m_layout);

    // Set the vertex and pixel shaders that will be used to render the objects.
    device->VSSetShader(m_vertexShader);
    device->PSSetShader(m_pixelShader);

    // Render the objects.
    device->DrawIndexed(indexCount, 0, 0);

    return;
}

color.ps

// Pixel Shader
float4 PS( float4 Pos : SV_POSITION ) : SV_Target
{
    return float4( 1.0f, 1.0f, 1.0f, 1.0f );    // White, with Alpha = 1
}

color.vs

// GLOBALS 
cbuffer MatrixBuffer { 
    float4 updatedPosition;
};

float4 VS( float4 Pos : POSITION ) : SV_POSITION
{
    return Pos;
}

1 ответ

Решение

Когда вы обновляете хранилища значений в float * m_positions;

Вы меняете значения на стороне процессора. Это не фактические значения, хранящиеся в графическом процессоре, которые вы указали при создании m_vertexBuffer

Для этого вам нужно вызвать функцию рендера Initialize(ID3D10Device*, HWND); снова

Там должна быть строка кода, которая выглядит следующим образом:

vertexData.pSysMem = vertices;
vertexData.SysMemPitch = 0;
vertexData.SysMemSlicePitch = 0;

// Now create the vertex buffer.
result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &m_vertexBuffer);

здесь вершины - ваши m_positions + ваш цвет, который я подозреваю.

Это не рекомендуется, но следует делать работу.

Если вы хотите посмотреть дальше, вам нужно создать этот буфер с D3D11_USAGE_DYNAMIC пометить и обновить значение с

D3D11_MAPPED_SUBRESOURCE resource;
d3dDeviceContext->Map( vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource );
memcpy( resource.pData, sourceData, vertexDataSize );
d3dDeviceContext->Unmap( vertexBuffer, 0 );

Посмотрите на: Direct3D C++ API, как обновить буфер вершин?

Я надеюсь, что вы найдете то, что относится к вам. Razterizer - это круто

Другие вопросы по тегам