| /************************************************************************** |
| * |
| * Copyright 2012-2021 VMware, Inc. |
| * All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to deal |
| * in the Software without restriction, including without limitation the rights |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| * copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| * THE SOFTWARE. |
| * |
| **************************************************************************/ |
| |
| |
| #include <stdio.h> |
| #include <stddef.h> |
| #include <string.h> |
| |
| #include <initguid.h> |
| #include <windows.h> |
| |
| #include <d3d11.h> |
| |
| #include <wrl/client.h> |
| |
| using Microsoft::WRL::ComPtr; |
| |
| #include "tri_vs_4_0.h" |
| #include "tri_ps_4_0.h" |
| |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| HRESULT hr; |
| |
| HINSTANCE hInstance = GetModuleHandle(nullptr); |
| |
| WNDCLASSEX wc = { |
| sizeof(WNDCLASSEX), |
| CS_CLASSDC, |
| DefWindowProc, |
| 0, |
| 0, |
| hInstance, |
| nullptr, |
| nullptr, |
| nullptr, |
| nullptr, |
| "tri", |
| nullptr |
| }; |
| RegisterClassEx(&wc); |
| |
| const int WindowWidth = 250; |
| const int WindowHeight = 250; |
| |
| DWORD dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW | WS_VISIBLE; |
| |
| RECT rect = {0, 0, WindowWidth, WindowHeight}; |
| AdjustWindowRect(&rect, dwStyle, FALSE); |
| |
| HWND hWnd = CreateWindow(wc.lpszClassName, |
| "Simple example using DirectX10", |
| dwStyle, |
| CW_USEDEFAULT, CW_USEDEFAULT, |
| rect.right - rect.left, |
| rect.bottom - rect.top, |
| nullptr, |
| nullptr, |
| hInstance, |
| nullptr); |
| if (!hWnd) { |
| return EXIT_FAILURE; |
| } |
| |
| UINT Flags = 0; |
| hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_NULL, 0, D3D11_CREATE_DEVICE_DEBUG, nullptr, 0, D3D11_SDK_VERSION, nullptr, nullptr, nullptr); |
| if (SUCCEEDED(hr)) { |
| Flags |= D3D11_CREATE_DEVICE_DEBUG; |
| } |
| |
| static const D3D_FEATURE_LEVEL FeatureLevels[] = { |
| D3D_FEATURE_LEVEL_10_0 |
| }; |
| |
| HMODULE hSoftware = LoadLibraryA("d3d10sw.dll"); |
| if (!hSoftware) { |
| return EXIT_FAILURE; |
| } |
| |
| DXGI_SWAP_CHAIN_DESC SwapChainDesc; |
| ZeroMemory(&SwapChainDesc, sizeof SwapChainDesc); |
| SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;; |
| SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; |
| SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; |
| SwapChainDesc.SampleDesc.Quality = 0; |
| SwapChainDesc.SampleDesc.Count = 1; |
| SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; |
| SwapChainDesc.BufferCount = 2; |
| SwapChainDesc.OutputWindow = hWnd; |
| SwapChainDesc.Windowed = true; |
| SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; |
| |
| ComPtr<ID3D11Device> pDevice; |
| ComPtr<ID3D11DeviceContext> pDeviceContext; |
| ComPtr<IDXGISwapChain> pSwapChain; |
| hr = D3D11CreateDeviceAndSwapChain(nullptr, |
| D3D_DRIVER_TYPE_SOFTWARE, |
| hSoftware, |
| Flags, |
| FeatureLevels, |
| _countof(FeatureLevels), |
| D3D11_SDK_VERSION, |
| &SwapChainDesc, |
| &pSwapChain, |
| &pDevice, |
| nullptr, /* pFeatureLevel */ |
| &pDeviceContext); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| ComPtr<IDXGIDevice> pDXGIDevice; |
| hr = pDevice->QueryInterface(IID_IDXGIDevice, (void **)&pDXGIDevice); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| ComPtr<IDXGIAdapter> pAdapter; |
| hr = pDXGIDevice->GetAdapter(&pAdapter); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| DXGI_ADAPTER_DESC Desc; |
| hr = pAdapter->GetDesc(&Desc); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| printf("using %S\n", Desc.Description); |
| |
| ComPtr<ID3D11Texture2D> pBackBuffer; |
| hr = pSwapChain->GetBuffer(0, IID_ID3D11Texture2D, (void **)&pBackBuffer); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| D3D11_RENDER_TARGET_VIEW_DESC RenderTargetViewDesc; |
| ZeroMemory(&RenderTargetViewDesc, sizeof RenderTargetViewDesc); |
| RenderTargetViewDesc.Format = SwapChainDesc.BufferDesc.Format; |
| RenderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; |
| RenderTargetViewDesc.Texture2D.MipSlice = 0; |
| |
| ComPtr<ID3D11RenderTargetView> pRenderTargetView; |
| hr = pDevice->CreateRenderTargetView(pBackBuffer.Get(), &RenderTargetViewDesc, &pRenderTargetView); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| pDeviceContext->OMSetRenderTargets(1, pRenderTargetView.GetAddressOf(), nullptr); |
| |
| |
| const float clearColor[4] = { 0.3f, 0.1f, 0.3f, 1.0f }; |
| pDeviceContext->ClearRenderTargetView(pRenderTargetView.Get(), clearColor); |
| |
| ComPtr<ID3D11VertexShader> pVertexShader; |
| hr = pDevice->CreateVertexShader(g_VS, sizeof g_VS, nullptr, &pVertexShader); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| struct Vertex { |
| float position[4]; |
| float color[4]; |
| }; |
| |
| static const D3D11_INPUT_ELEMENT_DESC InputElementDescs[] = { |
| { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(Vertex, position), D3D11_INPUT_PER_VERTEX_DATA, 0 }, |
| { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(Vertex, color), D3D11_INPUT_PER_VERTEX_DATA, 0 } |
| }; |
| |
| ComPtr<ID3D11InputLayout> pVertexLayout; |
| hr = pDevice->CreateInputLayout(InputElementDescs, |
| _countof(InputElementDescs), |
| g_VS, sizeof g_VS, |
| &pVertexLayout); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| pDeviceContext->IASetInputLayout(pVertexLayout.Get()); |
| |
| ComPtr<ID3D11PixelShader> pPixelShader; |
| hr = pDevice->CreatePixelShader(g_PS, sizeof g_PS, nullptr, &pPixelShader); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| pDeviceContext->VSSetShader(pVertexShader.Get(), nullptr, 0); |
| pDeviceContext->PSSetShader(pPixelShader.Get(), nullptr, 0); |
| |
| static const Vertex vertices[] = { |
| { { -0.9f, -0.9f, 0.5f, 1.0f}, { 0.8f, 0.0f, 0.0f, 0.1f } }, |
| { { 0.9f, -0.9f, 0.5f, 1.0f}, { 0.0f, 0.9f, 0.0f, 0.1f } }, |
| { { 0.0f, 0.9f, 0.5f, 1.0f}, { 0.0f, 0.0f, 0.7f, 0.1f } }, |
| }; |
| |
| D3D11_BUFFER_DESC BufferDesc; |
| ZeroMemory(&BufferDesc, sizeof BufferDesc); |
| BufferDesc.Usage = D3D11_USAGE_DYNAMIC; |
| BufferDesc.ByteWidth = sizeof vertices; |
| BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; |
| BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; |
| BufferDesc.MiscFlags = 0; |
| |
| D3D11_SUBRESOURCE_DATA BufferData; |
| BufferData.pSysMem = vertices; |
| BufferData.SysMemPitch = 0; |
| BufferData.SysMemSlicePitch = 0; |
| |
| ComPtr<ID3D11Buffer> pVertexBuffer; |
| hr = pDevice->CreateBuffer(&BufferDesc, &BufferData, &pVertexBuffer); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| |
| UINT Stride = sizeof(Vertex); |
| UINT Offset = 0; |
| pDeviceContext->IASetVertexBuffers(0, 1, pVertexBuffer.GetAddressOf(), &Stride, &Offset); |
| |
| D3D11_VIEWPORT ViewPort; |
| ViewPort.TopLeftX = 0; |
| ViewPort.TopLeftY = 0; |
| ViewPort.Width = WindowWidth; |
| ViewPort.Height = WindowHeight; |
| ViewPort.MinDepth = 0.0f; |
| ViewPort.MaxDepth = 1.0f; |
| pDeviceContext->RSSetViewports(1, &ViewPort); |
| |
| D3D11_RASTERIZER_DESC RasterizerDesc; |
| ZeroMemory(&RasterizerDesc, sizeof RasterizerDesc); |
| RasterizerDesc.CullMode = D3D11_CULL_NONE; |
| RasterizerDesc.FillMode = D3D11_FILL_SOLID; |
| RasterizerDesc.FrontCounterClockwise = true; |
| RasterizerDesc.DepthClipEnable = true; |
| ComPtr<ID3D11RasterizerState> pRasterizerState; |
| hr = pDevice->CreateRasterizerState(&RasterizerDesc, &pRasterizerState); |
| if (FAILED(hr)) { |
| return EXIT_FAILURE; |
| } |
| pDeviceContext->RSSetState(pRasterizerState.Get()); |
| |
| pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); |
| |
| pDeviceContext->Draw(_countof(vertices), 0); |
| |
| pSwapChain->Present(0, 0); |
| |
| Sleep(1000); |
| |
| ID3D11Buffer *pNullBuffer = nullptr; |
| UINT NullStride = 0; |
| UINT NullOffset = 0; |
| pDeviceContext->IASetVertexBuffers(0, 1, &pNullBuffer, &NullStride, &NullOffset); |
| |
| pDeviceContext->OMSetRenderTargets(0, nullptr, nullptr); |
| |
| pDeviceContext->IASetInputLayout(nullptr); |
| |
| pDeviceContext->VSSetShader(nullptr, nullptr, 0); |
| |
| pDeviceContext->PSSetShader(nullptr, nullptr, 0); |
| |
| pDeviceContext->RSSetState(nullptr); |
| |
| DestroyWindow(hWnd); |
| |
| return EXIT_SUCCESS; |
| } |
| |