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