alien_fx_fiend

DirectX Spinning Multi-colored Cube *FINAL RELEASE*

Nov 12th, 2024 (edited)
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.02 KB | Source Code | 0 0
  1. ==++ Here's the full source code for (file 1/1) "Spinning Cube.cpp"::++==
  2. #include <windows.h>
  3. #include <d3d11.h>
  4. #include <d3dcompiler.h>
  5. #include <directxmath.h>
  6. #include <directxcolors.h>
  7. #include "resource.h"  // Add this with your other includes
  8.  
  9. using namespace DirectX;
  10.  
  11. // Link required libraries
  12. #pragma comment(lib, "d3d11.lib")
  13. #pragma comment(lib, "d3dcompiler.lib")
  14.  
  15. //int GetSystemMetrics(int nIndex);
  16.  
  17. RECT GetDesktopResolution()
  18. {
  19.    RECT desktop;
  20.    const HWND hDesktop = GetDesktopWindow();
  21.    GetWindowRect(hDesktop, &desktop);
  22.    return desktop;
  23. }
  24.  
  25. // Global declarations
  26. IDXGISwapChain* swapchain;
  27. ID3D11Device* dev;
  28. ID3D11DeviceContext* devcon;
  29. ID3D11RenderTargetView* backbuffer;
  30. ID3D11VertexShader* pVS;
  31. ID3D11PixelShader* pPS;
  32. ID3D11Buffer* pVBuffer;
  33. ID3D11Buffer* pIBuffer;
  34. ID3D11Buffer* pCBuffer;
  35. ID3D11InputLayout* pLayout;
  36. ID3D11DepthStencilView* depthStencilView;
  37. ID3D11Texture2D* depthStencilBuffer;
  38. ID3D11RasterizerState* rasterState;
  39. HWND hwnd;  // Declare hwnd as a global variable
  40.  
  41. // Vertex structure
  42. struct VERTEX {
  43.    XMFLOAT3 Position;
  44.    XMFLOAT4 Color;
  45. };
  46.  
  47. // Constant buffer structure
  48. struct ConstantBuffer {
  49.    XMMATRIX mWorld;
  50.    XMMATRIX mView;
  51.    XMMATRIX mProjection;
  52. };
  53.  
  54. // Vertex Shader
  55. const char* vsSource = R"(
  56. cbuffer ConstantBuffer : register(b0) {
  57.    matrix World;
  58.    matrix View;
  59.    matrix Projection;
  60. };
  61.  
  62. struct VS_INPUT {
  63.    float3 Position : POSITION;
  64.    float4 Color : COLOR;
  65. };
  66.  
  67. struct PS_INPUT {
  68.    float4 Position : SV_POSITION;
  69.    float4 Color : COLOR;
  70. };
  71.  
  72. PS_INPUT main(VS_INPUT input) {
  73.    PS_INPUT output;
  74.    float4 pos = float4(input.Position, 1.0f);
  75.    
  76.    // Transform the position
  77.    pos = mul(pos, World);
  78.    pos = mul(pos, View);
  79.    pos = mul(pos, Projection);
  80.    
  81.    output.Position = pos;
  82.    output.Color = input.Color;
  83.    return output;
  84. })";
  85.  
  86. // Pixel Shader
  87. const char* psSource = R"(
  88. struct PS_INPUT {
  89.    float4 Pos : SV_POSITION;
  90.    float4 Color : COLOR;
  91. };
  92.  
  93. float4 main(PS_INPUT input) : SV_Target {
  94.    return input.Color;
  95. })";
  96.  
  97. // Helper function for error checking
  98. void CheckError(HRESULT hr, const char* message) {
  99.    if (FAILED(hr)) {
  100.        MessageBoxA(NULL, message, "Error", MB_OK);
  101.        exit(1);
  102.    }
  103. }
  104.  
  105. // Function prototypes
  106. LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  107. void InitD3D(HWND hWnd);
  108. void CleanD3D(void);
  109. void RenderFrame(void);
  110. void InitGraphics(void);
  111. void InitPipeline(void);
  112.  
  113. // Indices for the cube (12 triangles x 3 indices)
  114. DWORD indices[] = {
  115.    0, 1, 2, 0, 2, 3, // Front face
  116.    4, 6, 5, 4, 7, 6, // Back face
  117.    0, 4, 1, 1, 4, 5, // Left face
  118.    2, 7, 3, 2, 6, 7, // Right face
  119.    0, 3, 4, 3, 7, 4, // Top face
  120.    1, 5, 2, 2, 5, 6  // Bottom face
  121. };
  122.  
  123. // WinMain
  124. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  125. {
  126.    WNDCLASSEX wc = { 0 };
  127.    wc.cbSize = sizeof(WNDCLASSEX);
  128.    wc.style = CS_HREDRAW | CS_VREDRAW;
  129.    wc.lpfnWndProc = WindowProc;
  130.    wc.hInstance = hInstance;
  131.    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
  132.    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  133.    wc.lpszClassName = L"WindowClass";
  134.    RegisterClassEx(&wc);
  135.  
  136.    // Define the size of your window
  137.    const int WindowWidth = 800;
  138.    const int WindowHeight = 600;
  139.  
  140.    // Get the desktop resolution
  141.    RECT desktop = GetDesktopResolution();
  142.  
  143.    // Calculate the position for a centered window
  144.    int posX = (desktop.right - WindowWidth) / 2;
  145.    int posY = (desktop.bottom - WindowHeight) / 2;
  146.  
  147.    // Create the window with the calculated position
  148.    HWND hWnd = CreateWindowEx(
  149.        0,
  150.        L"WindowClass",
  151.        L"DirectX Rotating Cube",
  152.        WS_OVERLAPPEDWINDOW,
  153.        posX, posY,  // Positioned at the center
  154.        WindowWidth, WindowHeight,
  155.        NULL,
  156.        NULL,
  157.        hInstance,
  158.        NULL
  159.    );
  160.  
  161.    if (!hWnd) return 0;
  162.  
  163.    ShowWindow(hWnd, nCmdShow);
  164.    InitD3D(hWnd);
  165.  
  166.    MSG msg = { 0 };
  167.    while (TRUE)
  168.    {
  169.        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  170.        {
  171.            TranslateMessage(&msg);
  172.            DispatchMessage(&msg);
  173.            if (msg.message == WM_QUIT)
  174.                break;
  175.        }
  176.        RenderFrame();
  177.    }
  178.  
  179.    CleanD3D();
  180.    return msg.wParam;
  181. }
  182.  
  183. // Initialize Direct3D
  184. void InitD3D(HWND hWnd)
  185. {
  186.    // Create swap chain
  187.    DXGI_SWAP_CHAIN_DESC scd = { 0 };
  188.    scd.BufferCount = 1;
  189.    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  190.    scd.BufferDesc.Width = 800;
  191.    scd.BufferDesc.Height = 600;
  192.    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  193.    scd.OutputWindow = hWnd;
  194.    scd.SampleDesc.Count = 4;
  195.    scd.Windowed = TRUE;
  196.    scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
  197.  
  198.    HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
  199.        NULL, 0, D3D11_SDK_VERSION, &scd, &swapchain, &dev, NULL, &devcon);
  200.    CheckError(hr, "Failed to create device and swapchain");
  201.  
  202.    // Create render target view
  203.    ID3D11Texture2D* pBackBuffer;
  204.    hr = swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
  205.    CheckError(hr, "Failed to get back buffer");
  206.  
  207.    hr = dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
  208.    CheckError(hr, "Failed to create render target view");
  209.    pBackBuffer->Release();
  210.  
  211.    // Create depth stencil texture
  212.    D3D11_TEXTURE2D_DESC descDepth = {};
  213.    descDepth.Width = 800;
  214.    descDepth.Height = 600;
  215.    descDepth.MipLevels = 1;
  216.    descDepth.ArraySize = 1;
  217.    descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  218.    descDepth.SampleDesc.Count = 4;
  219.    descDepth.SampleDesc.Quality = 0;
  220.    descDepth.Usage = D3D11_USAGE_DEFAULT;
  221.    descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  222.  
  223.    hr = dev->CreateTexture2D(&descDepth, NULL, &depthStencilBuffer);
  224.    CheckError(hr, "Failed to create depth stencil buffer");
  225.  
  226.    // Create depth stencil view
  227.    D3D11_DEPTH_STENCIL_VIEW_DESC descDSV = {};
  228.    descDSV.Format = descDepth.Format;
  229.    descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
  230.  
  231.    hr = dev->CreateDepthStencilView(depthStencilBuffer, &descDSV, &depthStencilView);
  232.    CheckError(hr, "Failed to create depth stencil view");
  233.  
  234.    devcon->OMSetRenderTargets(1, &backbuffer, depthStencilView);
  235.  
  236.    // Create depth stencil state
  237.    D3D11_DEPTH_STENCIL_DESC depthStencilDesc = {};
  238.    depthStencilDesc.DepthEnable = TRUE;
  239.    depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
  240.    depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
  241.    depthStencilDesc.StencilEnable = FALSE;
  242.  
  243.    ID3D11DepthStencilState* depthStencilState;
  244.    hr = dev->CreateDepthStencilState(&depthStencilDesc, &depthStencilState);
  245.    CheckError(hr, "Failed to create depth stencil state");
  246.    devcon->OMSetDepthStencilState(depthStencilState, 1);
  247.    depthStencilState->Release();
  248.  
  249.    // Create rasterizer state
  250.    D3D11_RASTERIZER_DESC rasterDesc = {};
  251.    rasterDesc.AntialiasedLineEnable = TRUE;
  252.    rasterDesc.CullMode = D3D11_CULL_BACK;
  253.    rasterDesc.DepthClipEnable = TRUE;
  254.    rasterDesc.FillMode = D3D11_FILL_SOLID;
  255.    rasterDesc.FrontCounterClockwise = FALSE;
  256.    rasterDesc.MultisampleEnable = TRUE;
  257.    rasterDesc.ScissorEnable = FALSE;
  258.    rasterDesc.DepthBias = 0;
  259.    rasterDesc.DepthBiasClamp = 0.0f;
  260.    rasterDesc.SlopeScaledDepthBias = 0.0f;
  261.  
  262.    hr = dev->CreateRasterizerState(&rasterDesc, &rasterState);
  263.    CheckError(hr, "Failed to create rasterizer state");
  264.    devcon->RSSetState(rasterState);
  265.  
  266.    // Set the viewport
  267.    D3D11_VIEWPORT viewport = { 0 };
  268.    viewport.TopLeftX = 0;
  269.    viewport.TopLeftY = 0;
  270.    viewport.Width = 800;
  271.    viewport.Height = 600;
  272.    viewport.MinDepth = 0.0f;
  273.    viewport.MaxDepth = 1.0f;
  274.    devcon->RSSetViewports(1, &viewport);
  275.  
  276.    InitPipeline();
  277.    InitGraphics();
  278. }
  279.  
  280. // Initialize graphics
  281. void InitGraphics() {
  282.    // Define the cube vertices with more distinct positions and colors
  283.    VERTEX vertices[] = {
  284.        {XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)}, // Front top left
  285.        {XMFLOAT3(0.5f, 0.5f, -0.5f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f)},  // Front top right
  286.        {XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)},   // Back top right
  287.        {XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)},  // Back top left
  288.        {XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f)}, // Front bottom left
  289.        {XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)},  // Front bottom right
  290.        {XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f)},   // Back bottom right
  291.        {XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f)}   // Back bottom left
  292.    };
  293.  
  294.    // Create vertex buffer
  295.    D3D11_BUFFER_DESC bd = {};
  296.    bd.Usage = D3D11_USAGE_DEFAULT;
  297.    bd.ByteWidth = sizeof(vertices);
  298.    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
  299.    bd.CPUAccessFlags = 0;
  300.  
  301.    D3D11_SUBRESOURCE_DATA initData = {};
  302.    initData.pSysMem = vertices;
  303.  
  304.    HRESULT hr = dev->CreateBuffer(&bd, &initData, &pVBuffer);
  305.    CheckError(hr, "Failed to create vertex buffer");
  306.  
  307.    // Create index buffer
  308.    D3D11_BUFFER_DESC ibd = {};
  309.    ibd.Usage = D3D11_USAGE_DEFAULT;
  310.    ibd.ByteWidth = sizeof(indices);
  311.    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
  312.    ibd.CPUAccessFlags = 0;
  313.  
  314.    D3D11_SUBRESOURCE_DATA indexData = {};
  315.    indexData.pSysMem = indices;
  316.  
  317.    hr = dev->CreateBuffer(&ibd, &indexData, &pIBuffer);
  318.    CheckError(hr, "Failed to create index buffer");
  319.  
  320.    // Create constant buffer
  321.    D3D11_BUFFER_DESC cbd = {};
  322.    cbd.Usage = D3D11_USAGE_DEFAULT;
  323.    cbd.ByteWidth = sizeof(ConstantBuffer);
  324.    cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
  325.    cbd.CPUAccessFlags = 0;
  326.  
  327.    hr = dev->CreateBuffer(&cbd, nullptr, &pCBuffer);
  328.    CheckError(hr, "Failed to create constant buffer");
  329. }
  330.  
  331. // Initialize pipeline
  332. void InitPipeline() {
  333.    ID3DBlob* VS, * PS, * error;
  334.  
  335.    // Compile shaders
  336.    HRESULT hr = D3DCompile(vsSource, strlen(vsSource), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &VS, &error);
  337.    if (FAILED(hr)) {
  338.        if (error) {
  339.            MessageBoxA(NULL, (char*)error->GetBufferPointer(), "Error", MB_OK);
  340.            error->Release();
  341.        }
  342.        exit(1);
  343.    }
  344.  
  345.    hr = D3DCompile(psSource, strlen(psSource), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &PS, &error);
  346.    if (FAILED(hr)) {
  347.        if (error) {
  348.            MessageBoxA(NULL, (char*)error->GetBufferPointer(), "Error", MB_OK);
  349.            error->Release();
  350.        }
  351.        exit(1);
  352.    }
  353.  
  354.    // Create shader objects
  355.    hr = dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
  356.    CheckError(hr, "Failed to create vertex shader");
  357.  
  358.    hr = dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
  359.    CheckError(hr, "Failed to create pixel shader");
  360.  
  361.    // Set shaders
  362.    devcon->VSSetShader(pVS, 0, 0);
  363.    devcon->PSSetShader(pPS, 0, 0);
  364.  
  365.    // Create input layout
  366.    // Create input layout
  367.    D3D11_INPUT_ELEMENT_DESC ied[] = {
  368.    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
  369.    {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
  370.    };
  371.  
  372.    hr = dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout);
  373.    CheckError(hr, "Failed to create input layout");
  374.    devcon->IASetInputLayout(pLayout);
  375.  
  376.    VS->Release();
  377.    PS->Release();
  378. }
  379.  
  380. // Render frame
  381. void RenderFrame() {
  382.    static float angle = 0.0f;
  383.    angle += 0.01f;
  384.  
  385.    // Clear render target and depth buffer
  386.    //float color[4] = { 0.0f, 0.2f, 0.4f, 1.0f }; // Dark blue background
  387.    /*
  388.    // Clear render target and depth buffer
  389.    float color[4] = { 0.0f, 0.2f, 0.4f, 1.0f }; // Dark blue background
  390.    devcon->ClearRenderTargetView(backbuffer, color);
  391.    devcon->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
  392.    */
  393.    /*
  394.    // Clear render target and depth buffer to white
  395.    float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; // White background
  396.    devcon->ClearRenderTargetView(backbuffer, color);
  397.    devcon->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
  398.    */
  399.    
  400.    // Clear render target and depth buffer to white
  401.    float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; // White background
  402.    devcon->ClearRenderTargetView(backbuffer, color);
  403.    devcon->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
  404.    
  405.    devcon->ClearRenderTargetView(backbuffer, color);
  406.    devcon->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
  407.  
  408.    // Update constant buffer
  409.    ConstantBuffer cb;
  410.    XMMATRIX world = XMMatrixRotationY(angle);
  411.    XMVECTOR Eye = XMVectorSet(0.0f, 1.0f, -5.0f, 0.0f);
  412.    XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
  413.    XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
  414.    XMMATRIX view = XMMatrixLookAtLH(Eye, At, Up);
  415.    XMMATRIX projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, 800.0f / 600.0f, 0.01f, 100.0f);
  416.  
  417.    cb.mWorld = XMMatrixTranspose(world);
  418.    cb.mView = XMMatrixTranspose(view);
  419.    cb.mProjection = XMMatrixTranspose(projection);
  420.  
  421.    devcon->UpdateSubresource(pCBuffer, 0, nullptr, &cb, 0, 0);
  422.    devcon->VSSetConstantBuffers(0, 1, &pCBuffer);
  423.  
  424.    // Set vertex buffer
  425.    UINT stride = sizeof(VERTEX);
  426.    UINT offset = 0;
  427.    devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);
  428.    devcon->IASetIndexBuffer(pIBuffer, DXGI_FORMAT_R32_UINT, 0);
  429.    devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  430.  
  431.    // Draw the cube
  432.    devcon->DrawIndexed(36, 0, 0);
  433.  
  434.    // Present the frame
  435.    swapchain->Present(0, 0);
  436. }
  437.  
  438. // Clean up D3D objects
  439. void CleanD3D() {
  440.    if (rasterState) rasterState->Release();
  441.    if (depthStencilView) depthStencilView->Release();
  442.    if (depthStencilBuffer) depthStencilBuffer->Release();
  443.    if (backbuffer) backbuffer->Release();
  444.    if (swapchain) swapchain->Release();
  445.    if (pCBuffer) pCBuffer->Release();
  446.    if (pIBuffer) pIBuffer->Release();
  447.    if (pVBuffer) pVBuffer->Release();
  448.    if (pLayout) pLayout->Release();
  449.    if (pVS) pVS->Release();
  450.    if (pPS) pPS->Release();
  451.    if (devcon) devcon->Release();
  452.    if (dev) dev->Release();
  453. }
  454.  
  455. // Window procedure
  456. LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
  457.    switch (message) {
  458.    case WM_DESTROY:
  459.        PostQuitMessage(0);
  460.        return 0;
  461.    case WM_KEYDOWN:
  462.        if (wParam == VK_ESCAPE) {
  463.            PostQuitMessage(0);
  464.            return 0;
  465.        }
  466.        else if (wParam == VK_F1) {
  467.            MessageBox(hwnd, TEXT("DirectX Spinning Multi-colored Cube (Useful for studying DX Hooks) Programmed in C++ Win32 API (472 lines of code) by Entisoft Software (c) Evans Thorpemorton"), TEXT("Information"), MB_OK | MB_ICONINFORMATION);
  468.            return 0;
  469.        }
  470.        break;
  471.    }
  472.    return DefWindowProc(hWnd, message, wParam, lParam);
  473. }
Add Comment
Please, Sign In to add comment