/************************************************************************** * * 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 #include #include #include #include #include #include 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 pDevice; ComPtr pDeviceContext; ComPtr 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 pDXGIDevice; hr = pDevice->QueryInterface(IID_IDXGIDevice, (void **)&pDXGIDevice); if (FAILED(hr)) { return EXIT_FAILURE; } ComPtr 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 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 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 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 pVertexLayout; hr = pDevice->CreateInputLayout(InputElementDescs, _countof(InputElementDescs), g_VS, sizeof g_VS, &pVertexLayout); if (FAILED(hr)) { return EXIT_FAILURE; } pDeviceContext->IASetInputLayout(pVertexLayout.Get()); ComPtr 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 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 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; }