Skip to content

Instantly share code, notes, and snippets.

@d7samurai
Last active April 11, 2024 09:53
Show Gist options
  • Save d7samurai/261c69490cce0620d0bfc93003cd1052 to your computer and use it in GitHub Desktop.
Save d7samurai/261c69490cce0620d0bfc93003cd1052 to your computer and use it in GitHub Desktop.
Minimal D3D11

Minimal D3D11

Minimal D3D11 reference implementation: An uncluttered Direct3D 11 setup + basic rendering primer and API familiarizer. Complete, runnable Windows application contained in a single function and laid out in a linear, step-by-step fashion that should be easy to follow from the code alone. ~200 LOC. No modern C++, OOP or (other) obscuring cruft. View on YouTube

hollowcube

Also check out Minimal D3D11 pt2, reconfigured for instanced rendering and with a smaller, tighter, simplified overall code structure, or Minimal D3D11 pt3, with shadowmapping + showcasing a range of alternative setup and rendering techniques.

#pragma comment(lib, "user32")
#pragma comment(lib, "d3d11")
#pragma comment(lib, "d3dcompiler")
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <math.h> // sin, cos
#include "xube.h" // 3d model
///////////////////////////////////////////////////////////////////////////////////////////////////
#define TITLE "Minimal D3D11 by d7samurai"
///////////////////////////////////////////////////////////////////////////////////////////////////
struct float3 { float x, y, z; };
struct matrix { float m[4][4]; };
matrix operator*(const matrix& m1, const matrix& m2);
///////////////////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSA wndclass = { 0, DefWindowProcA, 0, 0, 0, 0, 0, 0, 0, TITLE };
RegisterClassA(&wndclass);
HWND window = CreateWindowExA(0, TITLE, TITLE, WS_POPUP | WS_MAXIMIZE | WS_VISIBLE, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr);
///////////////////////////////////////////////////////////////////////////////////////////////
D3D_FEATURE_LEVEL featurelevels[] = { D3D_FEATURE_LEVEL_11_0 };
DXGI_SWAP_CHAIN_DESC swapchaindesc = {};
swapchaindesc.BufferDesc.Width = 0; // use window width
swapchaindesc.BufferDesc.Height = 0; // use window height
swapchaindesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // can't specify SRGB framebuffer directly when using FLIP model swap effect. see lines 49, 66
swapchaindesc.SampleDesc.Count = 1;
swapchaindesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapchaindesc.BufferCount = 2;
swapchaindesc.OutputWindow = window;
swapchaindesc.Windowed = TRUE;
swapchaindesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
IDXGISwapChain* swapchain;
ID3D11Device* device;
ID3D11DeviceContext* devicecontext;
D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_DEBUG, featurelevels, ARRAYSIZE(featurelevels), D3D11_SDK_VERSION, &swapchaindesc, &swapchain, &device, nullptr, &devicecontext); // D3D11_CREATE_DEVICE_DEBUG is optional, but provides useful d3d11 debug output
swapchain->GetDesc(&swapchaindesc); // update swapchaindesc with actual window size
///////////////////////////////////////////////////////////////////////////////////////////////
ID3D11Texture2D* framebuffer;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&framebuffer); // grab framebuffer from swapchain
D3D11_RENDER_TARGET_VIEW_DESC framebufferRTVdesc = {}; // needed for SRGB framebuffer when using FLIP model swap effect
framebufferRTVdesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
framebufferRTVdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
ID3D11RenderTargetView* framebufferRTV;
device->CreateRenderTargetView(framebuffer, &framebufferRTVdesc, &framebufferRTV);
///////////////////////////////////////////////////////////////////////////////////////////////
D3D11_TEXTURE2D_DESC depthbufferdesc;
framebuffer->GetDesc(&depthbufferdesc); // copy framebuffer properties; they're mostly the same
depthbufferdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthbufferdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
ID3D11Texture2D* depthbuffer;
device->CreateTexture2D(&depthbufferdesc, nullptr, &depthbuffer);
ID3D11DepthStencilView* depthbufferDSV;
device->CreateDepthStencilView(depthbuffer, nullptr, &depthbufferDSV);
///////////////////////////////////////////////////////////////////////////////////////////////
ID3DBlob* vertexshaderCSO;
D3DCompileFromFile(L"gpu.hlsl", nullptr, nullptr, "myvertexshader", "vs_5_0", 0, 0, &vertexshaderCSO, nullptr);
ID3D11VertexShader* vertexshader;
device->CreateVertexShader(vertexshaderCSO->GetBufferPointer(), vertexshaderCSO->GetBufferSize(), nullptr, &vertexshader);
D3D11_INPUT_ELEMENT_DESC inputelementdesc[] = // maps to vertexdata struct in gpu.hlsl via semantic names ("POS", "NOR", "TEX", "COL")
{
{ "POS", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // float3 position
{ "NOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // float3 normal
{ "TEX", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // float2 texcoord
{ "COL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, // float3 color
};
ID3D11InputLayout* inputlayout;
device->CreateInputLayout(inputelementdesc, ARRAYSIZE(inputelementdesc), vertexshaderCSO->GetBufferPointer(), vertexshaderCSO->GetBufferSize(), &inputlayout);
///////////////////////////////////////////////////////////////////////////////////////////////
ID3DBlob* pixelshaderCSO;
D3DCompileFromFile(L"gpu.hlsl", nullptr, nullptr, "mypixelshader", "ps_5_0", 0, 0, &pixelshaderCSO, nullptr);
ID3D11PixelShader* pixelshader;
device->CreatePixelShader(pixelshaderCSO->GetBufferPointer(), pixelshaderCSO->GetBufferSize(), nullptr, &pixelshader);
///////////////////////////////////////////////////////////////////////////////////////////////
D3D11_RASTERIZER_DESC rasterizerdesc = {};
rasterizerdesc.FillMode = D3D11_FILL_SOLID;
rasterizerdesc.CullMode = D3D11_CULL_BACK;
ID3D11RasterizerState* rasterizerstate;
device->CreateRasterizerState(&rasterizerdesc, &rasterizerstate);
///////////////////////////////////////////////////////////////////////////////////////////////
D3D11_SAMPLER_DESC samplerdesc = {};
samplerdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
samplerdesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
samplerdesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
samplerdesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
samplerdesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
ID3D11SamplerState* samplerstate;
device->CreateSamplerState(&samplerdesc, &samplerstate);
///////////////////////////////////////////////////////////////////////////////////////////////
D3D11_DEPTH_STENCIL_DESC depthstencildesc = {};
depthstencildesc.DepthEnable = TRUE;
depthstencildesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthstencildesc.DepthFunc = D3D11_COMPARISON_LESS;
ID3D11DepthStencilState* depthstencilstate;
device->CreateDepthStencilState(&depthstencildesc, &depthstencilstate);
///////////////////////////////////////////////////////////////////////////////////////////////
struct Constants { matrix transform, projection; float3 lightvector; };
D3D11_BUFFER_DESC constantbufferdesc = {};
constantbufferdesc.ByteWidth = sizeof(Constants) + 0xf & 0xfffffff0; // ensure constant buffer size is multiple of 16 bytes
constantbufferdesc.Usage = D3D11_USAGE_DYNAMIC; // will be updated every frame
constantbufferdesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantbufferdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
ID3D11Buffer* constantbuffer;
device->CreateBuffer(&constantbufferdesc, nullptr, &constantbuffer);
///////////////////////////////////////////////////////////////////////////////////////////////
D3D11_TEXTURE2D_DESC texturedesc = {};
texturedesc.Width = TEXTURE_WIDTH; // in xube.h
texturedesc.Height = TEXTURE_HEIGHT; // in xube.h
texturedesc.MipLevels = 1;
texturedesc.ArraySize = 1;
texturedesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; // same as framebuffer(view)
texturedesc.SampleDesc.Count = 1;
texturedesc.Usage = D3D11_USAGE_IMMUTABLE;
texturedesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
D3D11_SUBRESOURCE_DATA textureSRD = {};
textureSRD.pSysMem = texturedata; // in xube.h
textureSRD.SysMemPitch = TEXTURE_WIDTH * sizeof(UINT); // 1 UINT = 4 bytes per pixel, 0xAARRGGBB
ID3D11Texture2D* texture;
device->CreateTexture2D(&texturedesc, &textureSRD, &texture);
ID3D11ShaderResourceView* textureSRV;
device->CreateShaderResourceView(texture, nullptr, &textureSRV);
///////////////////////////////////////////////////////////////////////////////////////////////
D3D11_BUFFER_DESC vertexbufferdesc = {};
vertexbufferdesc.ByteWidth = sizeof(vertexdata); // in xube.h
vertexbufferdesc.Usage = D3D11_USAGE_IMMUTABLE;
vertexbufferdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
D3D11_SUBRESOURCE_DATA vertexbufferSRD = { vertexdata };
ID3D11Buffer* vertexbuffer;
device->CreateBuffer(&vertexbufferdesc, &vertexbufferSRD, &vertexbuffer);
///////////////////////////////////////////////////////////////////////////////////////////////
D3D11_BUFFER_DESC indexbufferdesc = {};
indexbufferdesc.ByteWidth = sizeof(indexdata); // in xube.h
indexbufferdesc.Usage = D3D11_USAGE_IMMUTABLE;
indexbufferdesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
D3D11_SUBRESOURCE_DATA indexbufferSRD = { indexdata };
ID3D11Buffer* indexbuffer;
device->CreateBuffer(&indexbufferdesc, &indexbufferSRD, &indexbuffer);
///////////////////////////////////////////////////////////////////////////////////////////////
FLOAT clearcolor[4] = { 0.025f, 0.025f, 0.025f, 1.0f };
UINT stride = 11 * sizeof(float); // vertex size (11 floats: float3 position, float3 normal, float2 texcoord, float3 color)
UINT offset = 0;
D3D11_VIEWPORT viewport = { 0.0f, 0.0f, (float)swapchaindesc.BufferDesc.Width, (float)swapchaindesc.BufferDesc.Height, 0.0f, 1.0f };
///////////////////////////////////////////////////////////////////////////////////////////////
float w = viewport.Width / viewport.Height; // width (aspect ratio)
float h = 1.0f; // height
float n = 1.0f; // near
float f = 9.0f; // far
float3 modelrotation = { 0.0f, 0.0f, 0.0f };
float3 modelscale = { 1.0f, 1.0f, 1.0f };
float3 modeltranslation = { 0.0f, 0.0f, 4.0f };
///////////////////////////////////////////////////////////////////////////////////////////////
while (true)
{
MSG msg;
while (PeekMessageA(&msg, nullptr, 0, 0, PM_REMOVE))
{
if (msg.message == WM_KEYDOWN) return 0; // PRESS ANY KEY TO EXIT
DispatchMessageA(&msg);
}
///////////////////////////////////////////////////////////////////////////////////////////
matrix rotatex = { 1, 0, 0, 0, 0, (float)cos(modelrotation.x), -(float)sin(modelrotation.x), 0, 0, (float)sin(modelrotation.x), (float)cos(modelrotation.x), 0, 0, 0, 0, 1 };
matrix rotatey = { (float)cos(modelrotation.y), 0, (float)sin(modelrotation.y), 0, 0, 1, 0, 0, -(float)sin(modelrotation.y), 0, (float)cos(modelrotation.y), 0, 0, 0, 0, 1 };
matrix rotatez = { (float)cos(modelrotation.z), -(float)sin(modelrotation.z), 0, 0, (float)sin(modelrotation.z), (float)cos(modelrotation.z), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
matrix scale = { modelscale.x, 0, 0, 0, 0, modelscale.y, 0, 0, 0, 0, modelscale.z, 0, 0, 0, 0, 1 };
matrix translate = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, modeltranslation.x, modeltranslation.y, modeltranslation.z, 1 };
modelrotation.x += 0.005f;
modelrotation.y += 0.009f;
modelrotation.z += 0.001f;
///////////////////////////////////////////////////////////////////////////////////////////
D3D11_MAPPED_SUBRESOURCE constantbufferMSR;
devicecontext->Map(constantbuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &constantbufferMSR); // update constant buffer every frame
{
Constants* constants = (Constants*)constantbufferMSR.pData;
constants->transform = rotatex * rotatey * rotatez * scale * translate;
constants->projection = { 2 * n / w, 0, 0, 0, 0, 2 * n / h, 0, 0, 0, 0, f / (f - n), 1, 0, 0, n * f / (n - f), 0 };
constants->lightvector = { 1.0f, -1.0f, 1.0f };
}
devicecontext->Unmap(constantbuffer, 0);
///////////////////////////////////////////////////////////////////////////////////////////
devicecontext->ClearRenderTargetView(framebufferRTV, clearcolor);
devicecontext->ClearDepthStencilView(depthbufferDSV, D3D11_CLEAR_DEPTH, 1.0f, 0);
devicecontext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
devicecontext->IASetInputLayout(inputlayout);
devicecontext->IASetVertexBuffers(0, 1, &vertexbuffer, &stride, &offset);
devicecontext->IASetIndexBuffer(indexbuffer, DXGI_FORMAT_R32_UINT, 0);
devicecontext->VSSetShader(vertexshader, nullptr, 0);
devicecontext->VSSetConstantBuffers(0, 1, &constantbuffer);
devicecontext->RSSetViewports(1, &viewport);
devicecontext->RSSetState(rasterizerstate);
devicecontext->PSSetShader(pixelshader, nullptr, 0);
devicecontext->PSSetShaderResources(0, 1, &textureSRV);
devicecontext->PSSetSamplers(0, 1, &samplerstate);
devicecontext->OMSetRenderTargets(1, &framebufferRTV, depthbufferDSV);
devicecontext->OMSetDepthStencilState(depthstencilstate, 0);
devicecontext->OMSetBlendState(nullptr, nullptr, 0xffffffff); // use default blend mode (i.e. no blending)
///////////////////////////////////////////////////////////////////////////////////////////
devicecontext->DrawIndexed(ARRAYSIZE(indexdata), 0, 0);
///////////////////////////////////////////////////////////////////////////////////////////
swapchain->Present(1, 0);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
matrix operator*(const matrix& m1, const matrix& m2)
{
return
{
m1.m[0][0] * m2.m[0][0] + m1.m[0][1] * m2.m[1][0] + m1.m[0][2] * m2.m[2][0] + m1.m[0][3] * m2.m[3][0],
m1.m[0][0] * m2.m[0][1] + m1.m[0][1] * m2.m[1][1] + m1.m[0][2] * m2.m[2][1] + m1.m[0][3] * m2.m[3][1],
m1.m[0][0] * m2.m[0][2] + m1.m[0][1] * m2.m[1][2] + m1.m[0][2] * m2.m[2][2] + m1.m[0][3] * m2.m[3][2],
m1.m[0][0] * m2.m[0][3] + m1.m[0][1] * m2.m[1][3] + m1.m[0][2] * m2.m[2][3] + m1.m[0][3] * m2.m[3][3],
m1.m[1][0] * m2.m[0][0] + m1.m[1][1] * m2.m[1][0] + m1.m[1][2] * m2.m[2][0] + m1.m[1][3] * m2.m[3][0],
m1.m[1][0] * m2.m[0][1] + m1.m[1][1] * m2.m[1][1] + m1.m[1][2] * m2.m[2][1] + m1.m[1][3] * m2.m[3][1],
m1.m[1][0] * m2.m[0][2] + m1.m[1][1] * m2.m[1][2] + m1.m[1][2] * m2.m[2][2] + m1.m[1][3] * m2.m[3][2],
m1.m[1][0] * m2.m[0][3] + m1.m[1][1] * m2.m[1][3] + m1.m[1][2] * m2.m[2][3] + m1.m[1][3] * m2.m[3][3],
m1.m[2][0] * m2.m[0][0] + m1.m[2][1] * m2.m[1][0] + m1.m[2][2] * m2.m[2][0] + m1.m[2][3] * m2.m[3][0],
m1.m[2][0] * m2.m[0][1] + m1.m[2][1] * m2.m[1][1] + m1.m[2][2] * m2.m[2][1] + m1.m[2][3] * m2.m[3][1],
m1.m[2][0] * m2.m[0][2] + m1.m[2][1] * m2.m[1][2] + m1.m[2][2] * m2.m[2][2] + m1.m[2][3] * m2.m[3][2],
m1.m[2][0] * m2.m[0][3] + m1.m[2][1] * m2.m[1][3] + m1.m[2][2] * m2.m[2][3] + m1.m[2][3] * m2.m[3][3],
m1.m[3][0] * m2.m[0][0] + m1.m[3][1] * m2.m[1][0] + m1.m[3][2] * m2.m[2][0] + m1.m[3][3] * m2.m[3][0],
m1.m[3][0] * m2.m[0][1] + m1.m[3][1] * m2.m[1][1] + m1.m[3][2] * m2.m[2][1] + m1.m[3][3] * m2.m[3][1],
m1.m[3][0] * m2.m[0][2] + m1.m[3][1] * m2.m[1][2] + m1.m[3][2] * m2.m[2][2] + m1.m[3][3] * m2.m[3][2],
m1.m[3][0] * m2.m[0][3] + m1.m[3][1] * m2.m[1][3] + m1.m[3][2] * m2.m[2][3] + m1.m[3][3] * m2.m[3][3],
};
}
cbuffer constants : register(b0)
{
row_major float4x4 transform;
row_major float4x4 projection;
float3 lightvector;
}
struct vertexdata
{
float3 position : POS;
float3 normal : NOR;
float2 texcoord : TEX;
float3 color : COL;
};
struct pixeldata
{
float4 position : SV_POSITION;
float2 texcoord : TEX;
float4 color : COL;
};
Texture2D mytexture : register(t0);
SamplerState mysampler : register(s0);
pixeldata myvertexshader(vertexdata vertex)
{
float light = clamp(dot(mul(vertex.normal, transform), normalize(-lightvector)), 0.0f, 1.0f) * 0.8f + 0.2f;
pixeldata output;
output.position = mul(float4(vertex.position, 1.0f), mul(transform, projection));
output.texcoord = vertex.texcoord;
output.color = float4(vertex.color * light, 1.0f);
return output;
}
float4 mypixelshader(pixeldata pixel) : SV_TARGET
{
return mytexture.Sample(mysampler, pixel.texcoord) * pixel.color;
}
#define TEXTURE_WIDTH 2
#define TEXTURE_HEIGHT 2
UINT texturedata[] = // 2x2 pixel checkerboard pattern, 0xAARRGGBB
{
0xffffffff, 0xff7f7f7f,
0xff7f7f7f, 0xffffffff,
};
float vertexdata[] = // pos.x, pos.y, pos.z, nor.x, nor.y, nor.z, tex.u, tex.v, col.r, col.g, col.b,
{
-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 0.0f, 0.973f, 0.480f, 0.002f,
1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 10.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, 0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 2.0f, 0.973f, 0.480f, 0.002f,
0.6f, 0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 2.0f, 0.973f, 0.480f, 0.002f,
-0.6f, -0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 8.0f, 0.973f, 0.480f, 0.002f,
0.6f, -0.6f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 8.0f, 0.973f, 0.480f, 0.002f,
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 10.0f, 0.973f, 0.480f, 0.002f,
-0.6f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 2.0f, 10.0f, 0.973f, 0.480f, 0.002f,
0.6f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 8.0f, 10.0f, 0.973f, 0.480f, 0.002f,
1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 10.0f, 10.0f, 0.973f, 0.480f, 0.002f,
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, 1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 10.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.897f, 0.163f, 0.011f,
1.0f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 2.0f, 0.897f, 0.163f, 0.011f,
1.0f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 8.0f, 0.897f, 0.163f, 0.011f,
1.0f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 8.0f, 0.897f, 0.163f, 0.011f,
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 10.0f, 0.897f, 0.163f, 0.011f,
1.0f, -1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 2.0f, 10.0f, 0.897f, 0.163f, 0.011f,
1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 8.0f, 10.0f, 0.897f, 0.163f, 0.011f,
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 10.0f, 10.0f, 0.897f, 0.163f, 0.011f,
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 2.0f, 0.612f, 0.000f, 0.069f,
-0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 2.0f, 0.612f, 0.000f, 0.069f,
0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 8.0f, 0.612f, 0.000f, 0.069f,
-0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 8.0f, 0.612f, 0.000f, 0.069f,
1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10.0f, 0.612f, 0.000f, 0.069f,
0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 10.0f, 0.612f, 0.000f, 0.069f,
-0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 8.0f, 10.0f, 0.612f, 0.000f, 0.069f,
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 10.0f, 10.0f, 0.612f, 0.000f, 0.069f,
-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 10.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 2.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 8.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 8.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 10.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 2.0f, 10.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 8.0f, 10.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 10.0f, 10.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 8.0f, 0.0f, 0.000f, 0.254f, 0.637f,
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 10.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 1.0f, 0.6f, 0.0f, 1.0f, 0.0f, 2.0f, 2.0f, 0.000f, 0.254f, 0.637f,
0.6f, 1.0f, 0.6f, 0.0f, 1.0f, 0.0f, 8.0f, 2.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 1.0f, -0.6f, 0.0f, 1.0f, 0.0f, 2.0f, 8.0f, 0.000f, 0.254f, 0.637f,
0.6f, 1.0f, -0.6f, 0.0f, 1.0f, 0.0f, 8.0f, 8.0f, 0.000f, 0.254f, 0.637f,
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 10.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 2.0f, 10.0f, 0.000f, 0.254f, 0.637f,
0.6f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 8.0f, 10.0f, 0.000f, 0.254f, 0.637f,
1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 10.0f, 10.0f, 0.000f, 0.254f, 0.637f,
-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 2.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 8.0f, 0.0f, 0.001f, 0.447f, 0.067f,
1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 10.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -1.0f, -0.6f, 0.0f, -1.0f, 0.0f, 2.0f, 2.0f, 0.001f, 0.447f, 0.067f,
0.6f, -1.0f, -0.6f, 0.0f, -1.0f, 0.0f, 8.0f, 2.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -1.0f, 0.6f, 0.0f, -1.0f, 0.0f, 2.0f, 8.0f, 0.001f, 0.447f, 0.067f,
0.6f, -1.0f, 0.6f, 0.0f, -1.0f, 0.0f, 8.0f, 8.0f, 0.001f, 0.447f, 0.067f,
-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 10.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 2.0f, 10.0f, 0.001f, 0.447f, 0.067f,
0.6f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 8.0f, 10.0f, 0.001f, 0.447f, 0.067f,
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 10.0f, 10.0f, 0.001f, 0.447f, 0.067f,
-0.6f, 0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, -0.6f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, 0.6f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, -0.6f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, -0.6f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, -0.6f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
-0.6f, 0.6f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, 0.6f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.973f, 0.480f, 0.002f,
1.0f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
1.0f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.897f, 0.163f, 0.011f,
0.6f, 0.6f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, -0.6f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, 0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, -0.6f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, -0.6f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, -0.6f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
0.6f, 0.6f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, 0.6f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.612f, 0.000f, 0.069f,
-1.0f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, -0.6f, 0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, -0.6f, -0.6f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 0.6f, 0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-1.0f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, 0.6f, -0.6f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.127f, 0.116f, 0.408f,
-0.6f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, 1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
0.6f, 0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.000f, 0.254f, 0.637f,
-0.6f, -0.6f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -1.0f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -0.6f, -0.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -1.0f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -0.6f, 0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -0.6f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -1.0f, -0.6f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -1.0f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -0.6f, -0.6f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
-0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -0.6f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
0.6f, -1.0f, 0.6f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.001f, 0.447f, 0.067f,
};
UINT indexdata[] =
{
0, 1, 9, 9, 8, 0, 1, 2, 5, 5, 4, 1, 6, 7, 10, 10, 9, 6, 2, 3, 11, 11, 10, 2,
12, 13, 21, 21, 20, 12, 13, 14, 17, 17, 16, 13, 18, 19, 22, 22, 21, 18, 14, 15, 23, 23, 22, 14,
24, 25, 33, 33, 32, 24, 25, 26, 29, 29, 28, 25, 30, 31, 34, 34, 33, 30, 26, 27, 35, 35, 34, 26,
36, 37, 45, 45, 44, 36, 37, 38, 41, 41, 40, 37, 42, 43, 46, 46, 45, 42, 38, 39, 47, 47, 46, 38,
48, 49, 57, 57, 56, 48, 49, 50, 53, 53, 52, 49, 54, 55, 58, 58, 57, 54, 50, 51, 59, 59, 58, 50,
60, 61, 69, 69, 68, 60, 61, 62, 65, 65, 64, 61, 66, 67, 70, 70, 69, 66, 62, 63, 71, 71, 70, 62,
72, 73, 74, 74, 75, 72, 76, 77, 78, 78, 79, 76, 80, 81, 82, 82, 83, 80, 84, 85, 86, 86, 87, 84,
88, 89, 90, 90, 91, 88, 92, 93, 94, 94, 95, 92, 96, 97, 98, 98, 99, 96, 100, 101, 102, 102, 103, 100,
104, 105, 106, 106, 107, 104, 108, 109, 110, 110, 111, 108, 112, 113, 114, 114, 115, 112, 116, 117, 118, 118, 119, 116,
120, 121, 122, 122, 123, 120, 124, 125, 126, 126, 127, 124, 128, 129, 130, 130, 131, 128, 132, 133, 134, 134, 135, 132,
136, 137, 138, 138, 139, 136, 140, 141, 142, 142, 143, 140, 144, 145, 146, 146, 147, 144, 148, 149, 150, 150, 151, 148,
152, 153, 154, 154, 155, 152, 156, 157, 158, 158, 159, 156, 160, 161, 162, 162, 163, 160, 164, 165, 166, 166, 167, 164,
};
@kevinmoran
Copy link

Getting a weird warning when I compile this. Can't make sense of it, any ideas?

\main.cpp(321): warning C4239: nonstandard extension used: 'argument': conversion from 'matrix' to 'matrix &'
\main.cpp(321): note: A non-const reference may only be bound to an lvalue

Line 321 for reference:
constants->Transform = rotateX * rotateY * rotateZ * scale * translate;

Thanks again for sharing this.

@d7samurai
Copy link
Author

are you compiling with /W4? try /W3. alternatively, change both occurrences of

matrix operator*(matrix& m1, matrix& m2)

to

matrix operator*(const matrix& m1, const matrix& m2)

@kevinmoran
Copy link

kevinmoran commented May 23, 2019

Thanks a million, both of those solutions silence the warning.

@Bl00drav3n
Copy link

If you add #pragma comment(lib, "user32") it compiles for me by just typing cl code.cpp (Visual studio 2019, cl version 19.27.29112). Thanks for sharing the code!

@d7samurai
Copy link
Author

If you add #pragma comment(lib, "user32") it compiles for me by just typing cl code.cpp (Visual studio 2019, cl version 19.27.29112). Thanks for sharing the code!

done :)

@AbdouMechraoui
Copy link

I get the following errors when I try to run this code, I am not sure what I'm missing.

..\directxhello.cpp(31): error C2065: 'wndClassEx': undeclared identifier
..\directxhello.cpp(32): error C2065: 'wndClassEx': undeclared identifier
..\directxhello.cpp(33): error C2065: 'wndClassEx': undeclared identifier
..\directxhello.cpp(35): error C2065: 'wndClassEx': undeclared identifier
..\directxhello.cpp(297): error C2678: binary '*': no operator found which takes a left-hand operand of type 'matrix' (or there is no acceptable conversion)
..\directxhello.cpp(25): note: could be 'matrix operator *(matrix &,matrix &)'

@kevinmoran
Copy link

Is that all the errors the compiler gives? Try changing the matrix operator*() to take const arguments like d7samurai says above (23 May 2019)

@AbdouMechraoui
Copy link

Thanks a lot! That fixes the error in line 25, and 297. The first set of errors in line 33, and 35 still stand, I just started learning about windows api so I am not sure what these errors indicate.

@AbdouMechraoui
Copy link

Changing wndClassEx to wndClassExA in lines 33-35 fixed that error for me.

@d7samurai
Copy link
Author

d7samurai commented Jul 20, 2021

i have now updated the code to state matrix operator*(const matrix& m1, const matrix& m2) in both relevant places to avoid people having to manually do that (i.e. add the consts) in the future. it's just that i never use const myself, so i hesitated to make my original version "impure" in that way ;) ..

i also changed WNDCLASSEX to WNDCLASSEXA on line 31 (the type, not the variable name wndClassEx, as i don't see why that would matter).

@AbdouMechraoui
Copy link

Sure, makes sense :D

@9cento
Copy link

9cento commented Jun 30, 2022

The program runs smoothly in Visual Studio but when I launch the compiled .exe (debug or release makes no difference) nothing happens, how comes? Do you have any tips for me? Thank you.
EDIT: I also tried with "Minimal D3D11 pt2", same thing happened. I'm very puzzled.

@CptBishop89
Copy link

CptBishop89 commented Jul 4, 2022

@boios check the .hlsl file path - L"shaders.hlsl", try to change it to something like - L"D:\Shaders\LineShader.hlsl"; where D:\Shaders\ is a file path to .hlsl source file. It this is not it, try to debug and come back :)

@d7samurai
Copy link
Author

The program runs smoothly in Visual Studio but when I launch the compiled .exe (debug or release makes no difference) nothing happens, how comes? Do you have any tips for me? Thank you. EDIT: I also tried with "Minimal D3D11 pt2", same thing happened. I'm very puzzled.

like @CptBishop89 said, it's most likely due to the program not finding the shaders.hlsl file. an easy fix is to copy shaders.hlsl to the same folder as the .exe

@hkva
Copy link

hkva commented Nov 7, 2022

Thanks for making this. Question: Why set the WS_POPUP window flag?

@d7samurai
Copy link
Author

d7samurai commented Nov 7, 2022

Thanks for making this. Question: Why set the WS_POPUP window flag?

just an easy way to get rid of title bar / window chrome

@gonutz
Copy link

gonutz commented Nov 26, 2023

Thanks for this great snippet, this really helped me get up to speed! :-)
One strange thing, though: when I run the program, then close it, the window disappears but the process keeps running with 100% GPU utilization, according to the Task Manager.
Adding device->Release() at the end of the Winmain fixes this issue for me.

@d7samurai
Copy link
Author

d7samurai commented Nov 26, 2023

when I run the program, then close it, the window disappears but the process keeps running with 100% GPU utilization

how are you closing the window?

@gonutz
Copy link

gonutz commented Dec 2, 2023

when I run the program, then close it, the window disappears but the process keeps running with 100% GPU utilization

how are you closing the window?

Not at all :-)
I just copied your code as is. Maybe a call to CloseWindow might also help, but as I said, device->Release() after the main loop will fix the issue for me.

@d7samurai
Copy link
Author

d7samurai commented Dec 3, 2023

when I run the program, then close it, the window disappears but the process keeps running with 100% GPU utilization

how are you closing the app, i mean. if you close it by pressing a key, then it should end the process normally. it's a minimal example intended to showcase the d3d11 aspect with as little tangential code as possible so it cuts corners on the surrounding app framework.

@gonutz
Copy link

gonutz commented Dec 3, 2023

Oh right, I see. I used Alt+F4, you are right. Thanks!

You might still want to add that one Release line, it fixes the issue and may point people to not forget the clean-up code in their real app.

@d7samurai
Copy link
Author

d7samurai commented Dec 3, 2023

... may point people to not forget the clean-up code in their real app.

you never need to manually clean up / release any resources when exiting an app - that is handled by the operating system (and faster).

the issue in this case is that alt-f4 doesn't exit the process because WM_DESTROY isn't handled. and it isn't handled because it would require a custom WindowProc (in the name of minimalism i simply supply the baseline DefWindowProc), which in turn means adding another function and extra clutter to the code.

device->Release() after the main loop will fix the issue for me.

device->Release() shouldn't have any bearing on the problem (unless causing the app to crash, thus ending the process).

so i'm not sure what's going on for you there, as nothing after the main loop will ever get executed. the only exit condition is on WM_KEYDOWN and that exits the process altogether.

@gonutz
Copy link

gonutz commented Dec 3, 2023

Oh yeah, you are right, I did not notice there was no custom window proc. I am glad I know now, thanks for pointing it out! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment