Can't see my Model after rendering in DirectX

59 Views Asked by At

I'm having troubles with displaying my Model in an opened window using DirectX.

This is my code:

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);
}

This is what the console is returning:

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

I've tried changing the cameraPosition, but I got no luck. Any Ideas?

1

There are 1 best solutions below

0
Rajesh On

I am not sure about the Object being rendered as such I haven't digged deep into your D3D code. But I am sure, a possible issue lies with your Viewing Volume definitions and Object being rendered. Either your object is too big to contain inside Viewing Volume d or it is too small enough to see. Trying adjusting Viewing Volume. Take the extreme limits of coordinates specified in the Vertex buffer and use this limits for defining the Viewing Volume(Ortho or Perspective Viewing Volume)

Another issue is with respect to the camera coordinates you specified. Possibility that camera is seeing at a direction, where your object is not available. Try adjusting camera coordinates and check whether the object is visible.

Above suggestions are just my guess. There can be other issues in the code.