#include <Windows.h>
#include <D3D11.h>
#include <D3DX11.h>
struct SimpleVertex
{
float pos[3];
float col[4];
};
IDXGISwapChain *pSwapChain = NULL;
ID3D11Device *pDevice = NULL;
ID3D11DeviceContext *pImediateContext = NULL;
ID3D11RenderTargetView *pRenderTargetView = NULL;
ID3D11Buffer *pVertexBuffer = NULL;
ID3D11Buffer *pIndexBuffer = NULL;
ID3D11VertexShader *pVertexShader = NULL;
ID3D11InputLayout *pLayout = NULL;
ID3D11PixelShader *pPixelShader = NULL;
ID3D11RasterizerState *pRasterizerState = NULL;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//void EnumAdapters();
bool InitD3D(HWND hwnd)
{
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(DXGI_SWAP_CHAIN_DESC));
sd.BufferCount = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.Height = 480;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Width = 640;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hwnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = true;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
D3D_FEATURE_LEVEL reqFeat = D3D_FEATURE_LEVEL_10_0;
UINT numLevels = 1;
D3D_FEATURE_LEVEL featSupported;
HRESULT hr;
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &reqFeat, numLevels, D3D11_SDK_VERSION, &sd, &pSwapChain, &pDevice, &featSupported, &pImediateContext);
if(FAILED(hr))
return false;
ID3D11Texture2D *pBackBuffer = NULL;
hr = pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *)&pBackBuffer);
if(FAILED(hr))
return false;
pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView);
pImediateContext->OMSetRenderTargets(1, &pRenderTargetView, NULL);
pBackBuffer->Release();
D3D11_VIEWPORT vp;
vp.Height = 480;
vp.MaxDepth = 1.0f;
vp.MinDepth = 0.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
vp.Width = 640;
pImediateContext->RSSetViewports(1, &vp);
SimpleVertex verts[3] = {
{
{
0, 0.5f, 0.5f
},
{
0, 0, 0.5f, 1.0f
}
},
{
{
0.5f, -0.5f, 0.5f
},
{
0.5f, 0, 0, 1.0f
}
},
{
{
-0.5f, -0.5f, 0.5f
},
{
0, 0.5f, 0, 1.0f
}
}
};
D3D11_BUFFER_DESC vb_desc;
ZeroMemory(&vb_desc, sizeof(D3D11_BUFFER_DESC));
vb_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vb_desc.ByteWidth = sizeof(SimpleVertex) * 3;
vb_desc.CPUAccessFlags = 0;
vb_desc.MiscFlags = 0;
vb_desc.Usage = D3D11_USAGE_DEFAULT;
D3D11_SUBRESOURCE_DATA init_data;
ZeroMemory(&init_data, sizeof(D3D11_SUBRESOURCE_DATA));
init_data.pSysMem = verts;
hr = pDevice->CreateBuffer(&vb_desc, &init_data, &pVertexBuffer);
if(FAILED(hr))
return false;
unsigned int indexes[] = {
2, 1, 0
};
D3D11_BUFFER_DESC ib_desc;
ZeroMemory(&ib_desc, sizeof(D3D11_BUFFER_DESC));
ib_desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
ib_desc.ByteWidth = sizeof(unsigned int) * 3;
ib_desc.CPUAccessFlags = 0;
ib_desc.MiscFlags = 0;
ib_desc.Usage = D3D11_USAGE_DEFAULT;
ZeroMemory(&init_data, sizeof(D3D11_SUBRESOURCE_DATA));
init_data.pSysMem = indexes;
hr = pDevice->CreateBuffer(&ib_desc, &init_data, &pIndexBuffer);
if(FAILED(hr))
return false;
UINT strides = 0;
UINT offsets = 0;
pImediateContext->IASetVertexBuffers(0, 1, &pVertexBuffer, &strides, &offsets);
pImediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
ID3D10Blob *pBlob;
ID3D10Blob *pErrorBlob;
hr = D3DX11CompileFromFile(L"simple.hlsl", NULL, NULL, "vs_main", "vs_4_0", D3D10_SHADER_DEBUG, NULL, NULL, &pBlob, &pErrorBlob, NULL);
if(FAILED(hr))
{
return false;
}
if(pErrorBlob != NULL)
{
pErrorBlob->Release();
pErrorBlob = NULL;
}
hr = pDevice->CreateVertexShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), NULL, &pVertexShader);
if(FAILED(hr))
{
return false;
}
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
},
{
"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0
}
};
UINT numelems = sizeof(layout)/sizeof(layout[0]);
hr = pDevice->CreateInputLayout(layout, numelems, pBlob->GetBufferPointer(), pBlob->GetBufferSize(), &pLayout);
pBlob->Release();
pBlob = NULL;
if(FAILED(hr))
return false;
hr = D3DX11CompileFromFile(L"simple.hlsl", NULL, NULL, "ps_main", "ps_4_0", D3D10_SHADER_DEBUG, NULL, NULL, &pBlob, &pErrorBlob, NULL);
if(FAILED(hr))
{
return false;
}
if(pErrorBlob != NULL)
{
pErrorBlob->Release();
pErrorBlob = NULL;
}
hr = pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), NULL, &pPixelShader);
if(FAILED(hr))
return false;
pBlob->Release();
pBlob = NULL;
pImediateContext->IASetInputLayout(pLayout);
pImediateContext->VSSetShader(pVertexShader, NULL, 0);
pImediateContext->PSSetShader(pPixelShader, NULL, 0);
return true;
}
void Render()
{
float clearColor[] = {0,0,1,1};
pImediateContext->ClearRenderTargetView(pRenderTargetView, clearColor);
pImediateContext->DrawIndexed(3, 0, 0);
pSwapChain->Present(0,0);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
WNDCLASSEX wndclass;
ZeroMemory(&wndclass, sizeof(WNDCLASSEX));
wndclass.cbClsExtra = 0;
wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = L"dx11test";
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wndclass);
HWND hwnd = CreateWindow(L"dx11test",L"Test D3D11", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, (HWND)GetDesktopWindow(), NULL, hInstance, NULL);
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
if(!InitD3D(hwnd))
MessageBox(hwnd, L"There was an error while trying to start D3D!", L"Error", MB_OK);
//EnumAdapters();
MSG msg;
ZeroMemory(&msg, sizeof(MSG));
while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
Render();
}
}
UnregisterClass(L"dx11test", hInstance);
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
if(wParam == VK_ESCAPE)
{
DestroyWindow(hwnd);
return 0;
}
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}