1/************************************************************************** 2 * 3 * Copyright 2012-2021 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 * 24 **************************************************************************/ 25 26 27#include <stdio.h> 28#include <stddef.h> 29#include <string.h> 30 31#include <initguid.h> 32#include <windows.h> 33 34#include <d3d11.h> 35 36#include <wrl/client.h> 37 38using Microsoft::WRL::ComPtr; 39 40#include "tri_vs_4_0.h" 41#include "tri_ps_4_0.h" 42 43 44int 45main(int argc, char *argv[]) 46{ 47 HRESULT hr; 48 49 HINSTANCE hInstance = GetModuleHandle(nullptr); 50 51 WNDCLASSEX wc = { 52 sizeof(WNDCLASSEX), 53 CS_CLASSDC, 54 DefWindowProc, 55 0, 56 0, 57 hInstance, 58 nullptr, 59 nullptr, 60 nullptr, 61 nullptr, 62 "tri", 63 nullptr 64 }; 65 RegisterClassEx(&wc); 66 67 const int WindowWidth = 250; 68 const int WindowHeight = 250; 69 70 DWORD dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW | WS_VISIBLE; 71 72 RECT rect = {0, 0, WindowWidth, WindowHeight}; 73 AdjustWindowRect(&rect, dwStyle, FALSE); 74 75 HWND hWnd = CreateWindow(wc.lpszClassName, 76 "Simple example using DirectX10", 77 dwStyle, 78 CW_USEDEFAULT, CW_USEDEFAULT, 79 rect.right - rect.left, 80 rect.bottom - rect.top, 81 nullptr, 82 nullptr, 83 hInstance, 84 nullptr); 85 if (!hWnd) { 86 return EXIT_FAILURE; 87 } 88 89 UINT Flags = 0; 90 hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_NULL, 0, D3D11_CREATE_DEVICE_DEBUG, nullptr, 0, D3D11_SDK_VERSION, nullptr, nullptr, nullptr); 91 if (SUCCEEDED(hr)) { 92 Flags |= D3D11_CREATE_DEVICE_DEBUG; 93 } 94 95 static const D3D_FEATURE_LEVEL FeatureLevels[] = { 96 D3D_FEATURE_LEVEL_10_0 97 }; 98 99 HMODULE hSoftware = LoadLibraryA("d3d10sw.dll"); 100 if (!hSoftware) { 101 return EXIT_FAILURE; 102 } 103 104 DXGI_SWAP_CHAIN_DESC SwapChainDesc; 105 ZeroMemory(&SwapChainDesc, sizeof SwapChainDesc); 106 SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;; 107 SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; 108 SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; 109 SwapChainDesc.SampleDesc.Quality = 0; 110 SwapChainDesc.SampleDesc.Count = 1; 111 SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; 112 SwapChainDesc.BufferCount = 2; 113 SwapChainDesc.OutputWindow = hWnd; 114 SwapChainDesc.Windowed = true; 115 SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 116 117 ComPtr<ID3D11Device> pDevice; 118 ComPtr<ID3D11DeviceContext> pDeviceContext; 119 ComPtr<IDXGISwapChain> pSwapChain; 120 hr = D3D11CreateDeviceAndSwapChain(nullptr, 121 D3D_DRIVER_TYPE_SOFTWARE, 122 hSoftware, 123 Flags, 124 FeatureLevels, 125 _countof(FeatureLevels), 126 D3D11_SDK_VERSION, 127 &SwapChainDesc, 128 &pSwapChain, 129 &pDevice, 130 nullptr, /* pFeatureLevel */ 131 &pDeviceContext); 132 if (FAILED(hr)) { 133 return EXIT_FAILURE; 134 } 135 136 ComPtr<IDXGIDevice> pDXGIDevice; 137 hr = pDevice->QueryInterface(IID_IDXGIDevice, (void **)&pDXGIDevice); 138 if (FAILED(hr)) { 139 return EXIT_FAILURE; 140 } 141 142 ComPtr<IDXGIAdapter> pAdapter; 143 hr = pDXGIDevice->GetAdapter(&pAdapter); 144 if (FAILED(hr)) { 145 return EXIT_FAILURE; 146 } 147 148 DXGI_ADAPTER_DESC Desc; 149 hr = pAdapter->GetDesc(&Desc); 150 if (FAILED(hr)) { 151 return EXIT_FAILURE; 152 } 153 154 printf("using %S\n", Desc.Description); 155 156 ComPtr<ID3D11Texture2D> pBackBuffer; 157 hr = pSwapChain->GetBuffer(0, IID_ID3D11Texture2D, (void **)&pBackBuffer); 158 if (FAILED(hr)) { 159 return EXIT_FAILURE; 160 } 161 162 D3D11_RENDER_TARGET_VIEW_DESC RenderTargetViewDesc; 163 ZeroMemory(&RenderTargetViewDesc, sizeof RenderTargetViewDesc); 164 RenderTargetViewDesc.Format = SwapChainDesc.BufferDesc.Format; 165 RenderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 166 RenderTargetViewDesc.Texture2D.MipSlice = 0; 167 168 ComPtr<ID3D11RenderTargetView> pRenderTargetView; 169 hr = pDevice->CreateRenderTargetView(pBackBuffer.Get(), &RenderTargetViewDesc, &pRenderTargetView); 170 if (FAILED(hr)) { 171 return EXIT_FAILURE; 172 } 173 174 pDeviceContext->OMSetRenderTargets(1, pRenderTargetView.GetAddressOf(), nullptr); 175 176 177 const float clearColor[4] = { 0.3f, 0.1f, 0.3f, 1.0f }; 178 pDeviceContext->ClearRenderTargetView(pRenderTargetView.Get(), clearColor); 179 180 ComPtr<ID3D11VertexShader> pVertexShader; 181 hr = pDevice->CreateVertexShader(g_VS, sizeof g_VS, nullptr, &pVertexShader); 182 if (FAILED(hr)) { 183 return EXIT_FAILURE; 184 } 185 186 struct Vertex { 187 float position[4]; 188 float color[4]; 189 }; 190 191 static const D3D11_INPUT_ELEMENT_DESC InputElementDescs[] = { 192 { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(Vertex, position), D3D11_INPUT_PER_VERTEX_DATA, 0 }, 193 { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, offsetof(Vertex, color), D3D11_INPUT_PER_VERTEX_DATA, 0 } 194 }; 195 196 ComPtr<ID3D11InputLayout> pVertexLayout; 197 hr = pDevice->CreateInputLayout(InputElementDescs, 198 _countof(InputElementDescs), 199 g_VS, sizeof g_VS, 200 &pVertexLayout); 201 if (FAILED(hr)) { 202 return EXIT_FAILURE; 203 } 204 205 pDeviceContext->IASetInputLayout(pVertexLayout.Get()); 206 207 ComPtr<ID3D11PixelShader> pPixelShader; 208 hr = pDevice->CreatePixelShader(g_PS, sizeof g_PS, nullptr, &pPixelShader); 209 if (FAILED(hr)) { 210 return EXIT_FAILURE; 211 } 212 213 pDeviceContext->VSSetShader(pVertexShader.Get(), nullptr, 0); 214 pDeviceContext->PSSetShader(pPixelShader.Get(), nullptr, 0); 215 216 static const Vertex vertices[] = { 217 { { -0.9f, -0.9f, 0.5f, 1.0f}, { 0.8f, 0.0f, 0.0f, 0.1f } }, 218 { { 0.9f, -0.9f, 0.5f, 1.0f}, { 0.0f, 0.9f, 0.0f, 0.1f } }, 219 { { 0.0f, 0.9f, 0.5f, 1.0f}, { 0.0f, 0.0f, 0.7f, 0.1f } }, 220 }; 221 222 D3D11_BUFFER_DESC BufferDesc; 223 ZeroMemory(&BufferDesc, sizeof BufferDesc); 224 BufferDesc.Usage = D3D11_USAGE_DYNAMIC; 225 BufferDesc.ByteWidth = sizeof vertices; 226 BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 227 BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; 228 BufferDesc.MiscFlags = 0; 229 230 D3D11_SUBRESOURCE_DATA BufferData; 231 BufferData.pSysMem = vertices; 232 BufferData.SysMemPitch = 0; 233 BufferData.SysMemSlicePitch = 0; 234 235 ComPtr<ID3D11Buffer> pVertexBuffer; 236 hr = pDevice->CreateBuffer(&BufferDesc, &BufferData, &pVertexBuffer); 237 if (FAILED(hr)) { 238 return EXIT_FAILURE; 239 } 240 241 UINT Stride = sizeof(Vertex); 242 UINT Offset = 0; 243 pDeviceContext->IASetVertexBuffers(0, 1, pVertexBuffer.GetAddressOf(), &Stride, &Offset); 244 245 D3D11_VIEWPORT ViewPort; 246 ViewPort.TopLeftX = 0; 247 ViewPort.TopLeftY = 0; 248 ViewPort.Width = WindowWidth; 249 ViewPort.Height = WindowHeight; 250 ViewPort.MinDepth = 0.0f; 251 ViewPort.MaxDepth = 1.0f; 252 pDeviceContext->RSSetViewports(1, &ViewPort); 253 254 D3D11_RASTERIZER_DESC RasterizerDesc; 255 ZeroMemory(&RasterizerDesc, sizeof RasterizerDesc); 256 RasterizerDesc.CullMode = D3D11_CULL_NONE; 257 RasterizerDesc.FillMode = D3D11_FILL_SOLID; 258 RasterizerDesc.FrontCounterClockwise = true; 259 RasterizerDesc.DepthClipEnable = true; 260 ComPtr<ID3D11RasterizerState> pRasterizerState; 261 hr = pDevice->CreateRasterizerState(&RasterizerDesc, &pRasterizerState); 262 if (FAILED(hr)) { 263 return EXIT_FAILURE; 264 } 265 pDeviceContext->RSSetState(pRasterizerState.Get()); 266 267 pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); 268 269 pDeviceContext->Draw(_countof(vertices), 0); 270 271 pSwapChain->Present(0, 0); 272 273 Sleep(1000); 274 275 ID3D11Buffer *pNullBuffer = nullptr; 276 UINT NullStride = 0; 277 UINT NullOffset = 0; 278 pDeviceContext->IASetVertexBuffers(0, 1, &pNullBuffer, &NullStride, &NullOffset); 279 280 pDeviceContext->OMSetRenderTargets(0, nullptr, nullptr); 281 282 pDeviceContext->IASetInputLayout(nullptr); 283 284 pDeviceContext->VSSetShader(nullptr, nullptr, 0); 285 286 pDeviceContext->PSSetShader(nullptr, nullptr, 0); 287 288 pDeviceContext->RSSetState(nullptr); 289 290 DestroyWindow(hWnd); 291 292 return EXIT_SUCCESS; 293} 294 295