在 DirectX 中渲染后看不到我的模型

问题描述 投票:0回答:1

我在使用 DirectX 在打开的窗口中显示模型时遇到问题。

这是我的代码:

struct MatrixBufferType
{
    XMMATRIX worldViewProjection;
};

// Definition der ConstantBuffer-Klasse
template <typename T>
class ConstantBuffer
{
private:
    Microsoft::WRL::ComPtr<ID3D11Buffer> buffer;

public:
    T data;

    ConstantBuffer() : buffer(nullptr), data()
    {
    }

    // Constructor with device pointer
    ConstantBuffer(ID3D11Device* device) : buffer(nullptr), data()
    {
        // Create the buffer
        D3D11_BUFFER_DESC bufferDesc = { sizeof(T), D3D11_USAGE_DEFAULT, D3D11_BIND_CONSTANT_BUFFER, 0, 0, 0 };
        device->CreateBuffer(&bufferDesc, nullptr, buffer.GetAddressOf());
    }

    void ApplyChanges(ID3D11DeviceContext* context)
    {
        // Kopiere die Daten in den Puffer
        context->UpdateSubresource(buffer.Get(), 0, nullptr, &data, 0, 0);
    }

    void SetVSBuffer(ID3D11DeviceContext* context, UINT slot)
    {
        // Setze den Puffer im Vertex-Shader
        context->VSSetConstantBuffers(slot, 1, buffer.GetAddressOf());
    }
};


// Definiere notwendige Datenstrukturen für das Modell
struct Vertex {
    DirectX::XMFLOAT3 Position;

    Vertex(float x = 0.0f, float y = 0.0f, float z = 0.0f)
    :     Position(x, y, z) {}
};


struct Model
{
    std::vector<Vertex> vertices;
    std::vector<unsigned int> indices;
    ID3D11Buffer* vertexBuffer = nullptr;
    ID3D11Buffer* indexBuffer = nullptr;
};

// Function to create a vertex buffer from vertex data
bool CreateVertexBuffer(ID3D11Device* device, const std::vector<Vertex>& vertices, ID3D11Buffer*& vertexBuffer)
{
    D3D11_BUFFER_DESC desc;
    ZeroMemory(&desc, sizeof(desc));
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.ByteWidth = sizeof(Vertex) * vertices.size();
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

    D3D11_SUBRESOURCE_DATA initData;
    ZeroMemory(&initData, sizeof(initData));
    initData.pSysMem = vertices.data();

    HRESULT hr = device->CreateBuffer(&desc, &initData, &vertexBuffer);
    if (FAILED(hr)) {
        // Handle error: failed to create vertex buffer
        return false;
    }

    return true;
}

bool CreateIndexBuffer(ID3D11Device* device, const std::vector<unsigned int>& indices, ID3D11Buffer*& indexBuffer)
{
    D3D11_BUFFER_DESC desc;
    ZeroMemory(&desc, sizeof(desc));
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.ByteWidth = sizeof(unsigned int) * indices.size();
    desc.BindFlags = D3D11_BIND_INDEX_BUFFER;

    D3D11_SUBRESOURCE_DATA initData;
    ZeroMemory(&initData, sizeof(initData));
    initData.pSysMem = indices.data();

    HRESULT hr = device->CreateBuffer(&desc, &initData, &indexBuffer);
    if (FAILED(hr)) {
        // Handle error: failed to create index buffer
        return false;
    }

    return true;
}

// Load model data from file and create vertex and index buffers
Model LoadModel(ID3D11Device* device, const char* absoluteModelFilePath)
{
    Model model;  // Create an empty model

    // Open the model file
    std::ifstream inputFile(absoluteModelFilePath);
    if (!inputFile.is_open()) {
        // Handle error: unable to open file
        std::cerr << "Error: Unable to open file " << absoluteModelFilePath << std::endl;
        return model; // Return empty model
    }

    std::vector<Vertex> vertices;
    std::vector<unsigned int> indices;

    std::string line;
    while (std::getline(inputFile, line))
    {
        std::istringstream iss(line);
        std::string type;
        iss >> type;

        if (type == "v") // Vertex data
        {
            Vertex vertex;
            iss >> vertex.Position.x >> vertex.Position.y >> vertex.Position.z;
            vertices.push_back(vertex);
        }
        else if (type == "f") // Face (index) data
        {
            unsigned int index;
            while (iss >> index)
            {
                // Subtract 1 from index to convert to zero-based indexing
                indices.push_back(index - 1);
            }
        }
    }

    // Close the file
    inputFile.close();

    // Check if vertices and indices are empty
    if (vertices.empty() || indices.empty()) {
        // Handle error: no vertex or index data loaded
        return model; // Return empty model
    }

    // Initialize the model's vertices and indices with the loaded data
    model.vertices = std::move(vertices);
    model.indices = std::move(indices);

    // Create vertex buffer
    if (!CreateVertexBuffer(device, model.vertices, model.vertexBuffer)) {
        // Handle error: failed to create vertex buffer
        return model; // Return empty model
    }

    // Create index buffer
    if (!CreateIndexBuffer(device, model.indices, model.indexBuffer)) {
        // Handle error: failed to create index buffer
        return model; // Return empty model
    }

    // Return the loaded model
    return model;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
    {
        // Handle painting of the window
        // This message is typically handled by calling BeginPaint and EndPaint
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        // Add your painting code here
        EndPaint(hWnd, &ps);
        break;
    }

    case WM_SIZE:
    {
        // Handle resizing of the window
        // This message is sent when the size of the window is changed
        UINT width = LOWORD(lParam);
        UINT height = HIWORD(lParam);
        // Add your resizing code here
        break;
    }

    case WM_KEYDOWN:
    {
        // Handle key down events
        // This message is sent when a key is pressed
        // wParam contains the virtual-key code of the key that was pressed
        // Add your key down handling code here
        break;
    }

    case WM_KEYUP:
    {
        // Handle key up events
        // This message is sent when a key is released
        // wParam contains the virtual-key code of the key that was released
        // Add your key up handling code here
        break;
    }

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;
}

struct Joint
{
    DirectX::XMFLOAT4X4 bindPoseMatrix;   // Bind-Pose-Matrix
    DirectX::XMFLOAT4X4 localMatrix;      // Lokale Transformationsmatrix
    DirectX::XMFLOAT4X4 globalMatrix;    // Globale Transformationsmatrix für den Joint
    int parentIndex;  // Index des Eltern-Joints
};

// Hierarchie der Joints
std::vector<Joint> skeletonHierarchy;

// Beispiel für die Initialisierung der skeletonHierarchy
void InitializeSkeletonHierarchy()
{
    // Initialize root joint
    Joint rootJoint;
    rootJoint.parentIndex = -1;  // Root joint has no parent

    // Initialize other properties of the root joint
    rootJoint.bindPoseMatrix = DirectX::XMFLOAT4X4(); // Identity matrix
    rootJoint.localMatrix = DirectX::XMFLOAT4X4();    // Identity matrix
    rootJoint.globalMatrix = rootJoint.localMatrix;   // Initially same as local matrix

    // Add the root joint to the hierarchy
    skeletonHierarchy.push_back(rootJoint);

    // Add more joints to the hierarchy as needed
    Joint childJoint;
    childJoint.parentIndex = 0;  // Index of the parent joint in the hierarchy (root joint here)

    // Initialize other properties of the child joint
    childJoint.bindPoseMatrix = DirectX::XMFLOAT4X4(); // Initialize as needed
    childJoint.localMatrix = DirectX::XMFLOAT4X4();    // Initialize as needed
    childJoint.globalMatrix = childJoint.localMatrix;   // Initially same as local matrix
    // Add the child joint to the hierarchy
    skeletonHierarchy.push_back(childJoint);

    // Repeat this process for all joints in the hierarchy
}

// Funktion zur Berechnung der globalen Transformationen für alle Joints im Skelett
void UpdateGlobalTransformations(Model& model)
{
    for (size_t i = 0; i < skeletonHierarchy.size(); ++i)
    {
        if (skeletonHierarchy[i].parentIndex != -1)
        {
            // Calculate the global transformation by multiplying with the parent joint's transformation
            DirectX::XMMATRIX parentGlobalMatrix = DirectX::XMLoadFloat4x4(&skeletonHierarchy[skeletonHierarchy[i].parentIndex].globalMatrix);
            DirectX::XMMATRIX localMatrix = DirectX::XMLoadFloat4x4(&skeletonHierarchy[i].localMatrix);

            DirectX::XMMATRIX globalMatrix = localMatrix * parentGlobalMatrix;

            // Update the global matrix back into the hierarchy
            DirectX::XMFLOAT4X4 tempMatrix;
            DirectX::XMStoreFloat4x4(&tempMatrix, globalMatrix);
            skeletonHierarchy[i].globalMatrix = tempMatrix;

            // Update the vertex positions based on the new global transformation
            for (size_t j = 0; j < model.vertices.size(); ++j)
            {
                // Transform the vertex position using the joint's global matrix
                DirectX::XMVECTOR position = DirectX::XMLoadFloat3(&model.vertices[j].Position);
                position = DirectX::XMVector3Transform(position, globalMatrix);
                DirectX::XMStoreFloat3(&model.vertices[j].Position, position);
            }
        }
        else
        {
            // If it's the root joint, its global matrix is the same as its local matrix
            skeletonHierarchy[i].globalMatrix = skeletonHierarchy[i].localMatrix;
        }
    }
}


// Funktion zur Änderung der lokalen Transformationsmatrix eines Joints
void SetLocalTransformationMatrix(int jointIndex, const DirectX::XMFLOAT4X4& newLocalMatrix)
{
    skeletonHierarchy[jointIndex].localMatrix = newLocalMatrix;
}

void CleanupDirectX(IDXGISwapChain* pSwapChain, ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext)
{
    if (pSwapChain) pSwapChain->Release();
    if (pDeviceContext) pDeviceContext->Release();
    if (pDevice) pDevice->Release();
}

ID3D11RenderTargetView* g_pRenderTargetView = nullptr;
ID3D11Device* g_pd3dDevice = nullptr;
ConstantBuffer<MatrixBufferType> g_MatrixConstantBuffer;
ID3D11InputLayout* g_pVertexLayout = nullptr;

HRESULT InitDirectX(HWND hWnd, ID3D11Device** ppDevice, ID3D11DeviceContext** ppDeviceContext, IDXGISwapChain** ppSwapChain, UINT windowWidth, UINT windowHeight)
{
    HRESULT hr = S_OK;

    DXGI_SWAP_CHAIN_DESC sd = {};
    ZeroMemory(&sd, sizeof(sd));
    sd.BufferCount = 2; // Update BufferCount to be within the required range
    sd.BufferDesc.Width = windowWidth;
    sd.BufferDesc.Height = windowHeight;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.Flags = 0;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;
    sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // Use flip-model swap effect


    UINT createDeviceFlags = 0;
#ifdef _DEBUG
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 };
    D3D_FEATURE_LEVEL featureLevel;

    hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevels, ARRAYSIZE(featureLevels),
        D3D11_SDK_VERSION, &sd, ppSwapChain, ppDevice, &featureLevel, ppDeviceContext);
    if (FAILED(hr))
    {
        OutputDebugString(L"DirectX initialization failed!\n");
        return hr;
    }

    // Erstellen Sie die Render-Target-View
    ID3D11Texture2D* pBackBuffer = nullptr;
    hr = (*ppSwapChain)->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer));
    if (SUCCEEDED(hr)) {
        hr = (*ppDevice)->CreateRenderTargetView(pBackBuffer, nullptr, &g_pRenderTargetView);
        pBackBuffer->Release(); // Da die View erstellt wurde, kann der Backbuffer freigegeben werden
        if (FAILED(hr)) {
            return hr; // Fehlerbehandlung, falls das Erstellen der Render-Target-View fehlschlägt
        }
    }

    return hr;
}

HRESULT CompileShaderFromFile(const WCHAR* fileName, LPCSTR entryPoint, LPCSTR shaderModel, ID3DBlob** blobOut)
{
    // Define shader compilation flags
    DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

    // Append debug flag if in debug mode
#ifdef _DEBUG
    shaderFlags |= D3DCOMPILE_DEBUG;
#endif

    // Initialize variables to hold the compiled shader code and error messages
    ID3DBlob* errorBlob = nullptr;
    HRESULT hr = D3DCompileFromFile(fileName, nullptr, nullptr, entryPoint, shaderModel,
        shaderFlags, 0, blobOut, &errorBlob);

    // Check if shader compilation failed
    if (FAILED(hr))
    {
        // If an error blob is available, output the error message
        if (errorBlob)
        {
            OutputDebugStringA(reinterpret_cast<const char*>(errorBlob->GetBufferPointer()));
            errorBlob->Release(); // Release the error blob
        }
        return hr; // Return the error code
    }

    // Check if the compiled shader blob is nullptr
    if (*blobOut == nullptr)
    {
        // Handle the case where the shader compilation succeeded but the blob is nullptr
        OutputDebugString(L"Shader compilation succeeded, but the compiled shader blob is nullptr.\n");
        return E_FAIL; // Return a failure code
    }

    // Release the error blob if it was allocated
    if (errorBlob) errorBlob->Release();

    return S_OK; // Return success code if compilation was successful
}

ID3D11VertexShader* g_pVertexShader = nullptr;
ID3D11PixelShader* g_pPixelShader = nullptr;

HRESULT InitShaders(ID3D11Device* pDevice)
{
    HRESULT hr = S_OK;

    // Vertex Shader
    ID3DBlob* pVertexShaderBlob = nullptr;
    hr = CompileShaderFromFile(L"VertexShader.hlsl", "VSMain", "vs_5_0", &pVertexShaderBlob);
    if (FAILED(hr))
    {
        // Handle shader compilation failure
        return hr;
    }

    hr = pDevice->CreateVertexShader(pVertexShaderBlob->GetBufferPointer(), pVertexShaderBlob->GetBufferSize(), nullptr, &g_pVertexShader);
    if (FAILED(hr))
    {
        // Handle shader creation failure
        pVertexShaderBlob->Release(); // Release the blob before returning
        return hr;
    }

    // Input Layout
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    UINT numElements = ARRAYSIZE(layout);

    hr = pDevice->CreateInputLayout(layout, numElements, pVertexShaderBlob->GetBufferPointer(),
        pVertexShaderBlob->GetBufferSize(), &g_pVertexLayout);
    pVertexShaderBlob->Release(); // Release the blob after creating the input layout
    if (FAILED(hr))
    {
        // Handle input layout creation failure
        return hr;
    }

    // Pixel Shader
    ID3DBlob* pPixelShaderBlob = nullptr;
    hr = CompileShaderFromFile(L"PixelShader.hlsl", "PSMain", "ps_5_0", &pPixelShaderBlob);
    if (FAILED(hr))
    {
        // Handle shader compilation failure
        return hr;
    }

    hr = pDevice->CreatePixelShader(pPixelShaderBlob->GetBufferPointer(), pPixelShaderBlob->GetBufferSize(), nullptr, &g_pPixelShader);
    pPixelShaderBlob->Release();
    if (FAILED(hr))
    {
        // Handle shader creation failure
        return hr;
    }

    return S_OK;
}

void Render(ID3D11DeviceContext* pDeviceContext, Model& model, UINT windowWidth, UINT windowHeight)
{
    // Check if both vertex and index buffers are valid
    if (model.vertexBuffer && model.indexBuffer)
    {
        // Set the primitive topology
        pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        // Set up the viewport
        D3D11_VIEWPORT viewport;
        ZeroMemory(&viewport, sizeof(viewport));
        viewport.TopLeftX = 0;
        viewport.TopLeftY = 0;
        viewport.Width = static_cast<float>(windowWidth);  // Use window width
        viewport.Height = static_cast<float>(windowHeight); // Use window height
        viewport.MinDepth = 0.0f;
        viewport.MaxDepth = 1.0f;

    pDeviceContext->RSSetViewports(1, &viewport);

    // Set the input layout
    pDeviceContext->IASetInputLayout(g_pVertexLayout);

    // Set the vertex buffer
    UINT stride = sizeof(Vertex);
    UINT offset = 0;
    pDeviceContext->IASetVertexBuffers(0, 1, &model.vertexBuffer, &stride, &offset);

    // Set the index buffer
    pDeviceContext->IASetIndexBuffer(model.indexBuffer, DXGI_FORMAT_R32_UINT, 0);


    // Set the Vertex and Pixel Shaders
    pDeviceContext->VSSetShader(g_pVertexShader, nullptr, 0);

    // Set the Pixel Shader
    pDeviceContext->PSSetShader(g_pPixelShader, nullptr, 0);

    // Update view matrix for camera position
    XMFLOAT3 cameraPosition = XMFLOAT3(0.0f, 0.0f, -5.0f); // Adjust camera position as needed
    XMFLOAT3 cameraTarget = XMFLOAT3(0.0f, 0.0f, 0.0f);     // Adjust target position as needed
    XMFLOAT3 cameraUp = XMFLOAT3(0.0f, 1.0f, 0.0f);         // Adjust up vector as needed

    XMMATRIX viewMatrix = XMMatrixLookAtLH(XMLoadFloat3(&cameraPosition), XMLoadFloat3(&cameraTarget), XMLoadFloat3(&cameraUp));

    // Update projection matrix (Ensure it's correctly configured)
    float fovAngleY = XM_PIDIV2;
    float aspectRatio = static_cast<float>(windowWidth) / static_cast<float>(windowHeight);
    float nearZ = 0.1f;
    float farZ = 1000.0f;

    XMMATRIX projectionMatrix = XMMatrixPerspectiveFovLH(fovAngleY, aspectRatio, nearZ, farZ);

    // Combine view and projection matrices
    XMMATRIX viewProjectionMatrix = viewMatrix * projectionMatrix;

    // Adjust the translation and scaling factors as needed
    XMFLOAT3 modelPosition = XMFLOAT3(0.0f, 0.0f, 0.0f); // Position the model at the origin
    XMFLOAT3 modelScale = XMFLOAT3(1.0f, 1.0f, 1.0f); // Scale the model uniformly (no scaling)

    // Create translation and scaling matrices
    XMMATRIX translationMatrix = XMMatrixTranslation(modelPosition.x, modelPosition.y, modelPosition.z);
    XMMATRIX scalingMatrix = XMMatrixScaling(modelScale.x, modelScale.y, modelScale.z);

    // Combine translation, scaling, and other transformations as needed
    XMMATRIX worldMatrix = scalingMatrix * translationMatrix; // Apply scaling first, then translation

    // Set the worldViewProjection matrix in the constant buffer
    g_MatrixConstantBuffer.data.worldViewProjection = XMMatrixTranspose(worldMatrix * viewProjectionMatrix);
    g_MatrixConstantBuffer.ApplyChanges(pDeviceContext);
    g_MatrixConstantBuffer.SetVSBuffer(pDeviceContext, 0);

    if (model.indexBuffer) { // Check if indexBuffer is not nullptr
        D3D11_BUFFER_DESC desc;
        model.indexBuffer->GetDesc(&desc);
        UINT numIndices = desc.ByteWidth / sizeof(unsigned int); // For 32-bit indices

        pDeviceContext->IASetVertexBuffers(0, 1, &model.vertexBuffer, &stride, &offset);

        // Set the Index Buffer
        pDeviceContext->IASetIndexBuffer(model.indexBuffer, DXGI_FORMAT_R32_UINT, 0);

        UpdateGlobalTransformations(model);

        // Iteriere über die Joints und rendere das Modell für jeden Joint
        for (size_t i = 0; i < skeletonHierarchy.size(); ++i)
        {
            // Setze die Welttransformation für jeden Joint
            XMMATRIX worldMatrix = XMLoadFloat4x4(&skeletonHierarchy[i].globalMatrix);
            g_MatrixConstantBuffer.data.worldViewProjection = XMMatrixTranspose(worldMatrix * viewProjectionMatrix);
            g_MatrixConstantBuffer.ApplyChanges(pDeviceContext);
            g_MatrixConstantBuffer.SetVSBuffer(pDeviceContext, 0);

            // Draw the model
            pDeviceContext->DrawIndexed(numIndices, 0, 0);
        }
    }

    }
}

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
    // Initialize variables
    HWND hWnd = nullptr;
    DXGI_SWAP_CHAIN_DESC sd = {};
    HRESULT hr = S_OK;

    // Fensterklasse registrieren
    WNDCLASSEX wc = {};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = L"DirectX11WindowClass";
    RegisterClassEx(&wc);

    // Fenster erstellen
    hWnd = CreateWindowEx(
        0,
        L"DirectX11WindowClass",
        L"DirectX 11 Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 2400, 1800,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
    {
        // Handle window creation failure
        OutputDebugString(L"Failed to create window!\n");
        return E_FAIL;
    }

    // Initialize DXGI_SWAP_CHAIN_DESC after creating the window
    sd = {};
    sd.BufferCount = 2;
    sd.BufferDesc.Width = 2400;
    sd.BufferDesc.Height = 1800;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = hWnd;
    sd.SampleDesc.Count = 1;
    sd.SampleDesc.Quality = 0;
    sd.Windowed = TRUE;

    // Initialisierung von DirectX 11
    ID3D11Device* device = nullptr;
    ID3D11DeviceContext* deviceContext = nullptr;
    IDXGISwapChain* swapChain = nullptr;

    // Initialize DirectX
    hr = InitDirectX(hWnd, &device, &deviceContext, &swapChain, sd.BufferDesc.Width, sd.BufferDesc.Height);
    if (FAILED(hr))
    {
        // Handle DirectX initialization failure
        OutputDebugString(L"DirectX initialization failed!\n");
        return hr;
    }

    g_pd3dDevice = device; // Setze den globalen Zeiger auf das Gerät

    g_MatrixConstantBuffer = ConstantBuffer<MatrixBufferType>(g_pd3dDevice);

    // Initialisierung der Shader
    hr = InitShaders(device);
    if (FAILED(hr)) {
        // Handle shader initialization failure
        OutputDebugString(L"Shader initialization failed!\n");
        CleanupDirectX(swapChain, device, deviceContext);
        return hr;
    }
    else {
        OutputDebugString(L"Shaders initialized successfully.\n");
    }

    // Load the 3D model
    Model myModel = LoadModel(device, "C:/Users/zizoa/Desktop/RTR/ZiZo_Animation/Marsienne_OBJ/Marsienne_Base.obj");
    if (myModel.vertices.empty() || myModel.indices.empty())
    {
        OutputDebugString(L"Failed to load model or model data is empty!\n");
        CleanupDirectX(swapChain, device, deviceContext);
        return E_FAIL; // Indicate model loading failure
    }
    else
    {
        // Output the size of vertices and indices
        std::wstringstream logStream;
        logStream << L"Number of Vertices: " << myModel.vertices.size() << L"\n";
        logStream << L"Number of Indices: " << myModel.indices.size() << L"\n";
        OutputDebugString(logStream.str().c_str());

        OutputDebugString(L"Model loaded successfully.\n");
    }

    // Create vertex buffer
    if (!CreateVertexBuffer(device, myModel.vertices, myModel.vertexBuffer))
    {
        // Handle vertex buffer creation failure
        CleanupDirectX(swapChain, device, deviceContext);
        return E_FAIL;
    }
    else
    {
        OutputDebugString(L"CreateVertexBuffer True.\n");
    }

    // Create index buffer
    if (!CreateIndexBuffer(device, myModel.indices, myModel.indexBuffer))
    {
        // Handle index buffer creation failure
        CleanupDirectX(swapChain, device, deviceContext);
        return E_FAIL;
    }
    else
    {
        OutputDebugString(L"CreateIndexBuffer True.\n");
    }

    // Zeige das Fenster an
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // Nachrichtenverarbeitungsschleife
    MSG msg = {};
    while (true)
    {
        // Peek and process messages
        while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            // Check for quit message
            if (msg.message == WM_QUIT || msg.message == WM_CLOSE)
                return static_cast<int>(msg.wParam); // Return exit code

            // Translate and dispatch the message
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        // Rendering
        if (!CheckForWindowClose())
        {
            // Update global transformations
            UpdateGlobalTransformations(myModel);

            // Clear the back buffer
            deviceContext->ClearRenderTargetView(g_pRenderTargetView, DirectX::Colors::CornflowerBlue);

            // Render the model
            Render(deviceContext, myModel, sd.BufferDesc.Width, sd.BufferDesc.Height);
            UpdateWindow(hWnd);

            // Present the frame
            hr = swapChain->Present(0, 0);
            if (FAILED(hr))
            {
                OutputDebugString(L"Failed to present frame!\n");
                CleanupDirectX(swapChain, device, deviceContext);
                return hr;
            }
        }
        else
        {
            // Handle window close
            break;
        }
    }

    // Cleanup DirectX objects
    CleanupDirectX(swapChain, device, deviceContext);

    return static_cast<int>(msg.wParam);
}

这是控制台返回的内容:

Shaders initialized successfully.
Number of Vertices: 13235
Number of Indices: 16422
Model loaded successfully.
CreateVertexBuffer True.
CreateIndexBuffer True.

我尝试过更改相机位置,但没有成功。有什么想法吗?

c++ winapi visual-c++ directx
1个回答
0
投票

我不确定对象是否被渲染,我还没有深入研究你的 D3D 代码。但我确信,一个可能的问题在于您的查看体积定义和正在渲染的对象。要么您的对象太大而无法包含在查看体积 d 内,要么太小而无法看到。尝试调整观看音量。取顶点缓冲区中指定的坐标的极限,并使用此限制来定义查看体积(正交或透视查看体积)

另一个问题与您指定的相机坐标有关。相机可能会看到某个方向,而您的物体在该方向上不可用。尝试调整相机坐标并检查物体是否可见。

以上建议只是我的猜测。代码中可能存在其他问题。

© www.soinside.com 2019 - 2024. All rights reserved.