| #include <windows.h> |
| #include <d3d10.h> |
| #include <d3dx10.h> |
|
| #pragma comment (lib, "d3d10.lib") |
| #pragma comment (lib, "d3dx10.lib") |
| |
| struct BasicVertex { D3DXVECTOR3 Position; D3DXVECTOR4 Color; }; |
| int Width = 640, Height = 480; |
| HWND hWnd; |
| HINSTANCE hInst; |
| D3D10_DRIVER_TYPE D3D_DriverType = D3D10_DRIVER_TYPE_NULL; |
| ID3D10Device* D3D_Device = NULL; |
| IDXGISwapChain* SwapChain = NULL; |
| ID3D10RenderTargetView* RenderTargetView = NULL; |
| ID3D10Effect* Effect = NULL; |
| ID3D10EffectTechnique* Technique = NULL; |
| ID3D10InputLayout* VertexLayout = NULL; |
| ID3D10Buffer* VertexBuffer = NULL; |
| ID3D10Buffer* IndexBuffer = NULL; |
| ID3D10EffectMatrixVariable* WorldVariable = NULL; |
| ID3D10EffectMatrixVariable* ViewVariable = NULL; |
| ID3D10EffectMatrixVariable* ProjectionVariable = NULL; |
| D3DXMATRIX World; |
| D3DXMATRIX View; |
| D3DXMATRIX Projection; |
| |
| LRESULT CALLBACK WndProc( HWND , UINT, WPARAM, LPARAM ); |
| HRESULT InitD3D( void ); |
| void Cleanup( void ); |
| void Render ( void ); |
| |
| int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) |
| { |
| WNDCLASSEX wc; |
| ZeroMemory( &wc, sizeof( WNDCLASSEX ) ); |
| |
| wc.cbSize = sizeof( WNDCLASSEX ); |
| wc.style = CS_HREDRAW | CS_VREDRAW; |
| wc.lpfnWndProc = WndProc; |
| wc.cbClsExtra = 0; |
| wc.cbWndExtra = 0; |
| wc.hInstance = hInstance; |
| wc.hCursor = LoadCursor( NULL, IDC_ARROW ); |
| wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); |
| wc.lpszMenuName = NULL; |
| wc.lpszClassName = TEXT( "Win32Test" ); |
| |
| if( !RegisterClassEx( &wc ) ) |
| { |
| MessageBox( NULL, TEXT( "Unable to register window class." ), TEXT( "Error" ), MB_OK | MB_ICONERROR ); |
| return FALSE; |
| } |
| |
| hInst = hInstance; |
| hWnd = CreateWindowEx( NULL, wc.lpszClassName, TEXT( "Win32 Test" ), WS_OVERLAPPEDWINDOW, |
| CW_USEDEFAULT, CW_USEDEFAULT, Width, Height, NULL, NULL, hInstance, NULL); |
| |
| if( !hWnd ) |
| { |
| MessageBox( NULL, TEXT( "Unable to create window." ), TEXT( "Error" ), MB_OK | MB_ICONERROR ); |
| return FALSE; |
| } |
| |
| ShowWindow( hWnd, nShowCmd ); |
| |
| if( FAILED( InitD3D() ) ) |
| { |
| MessageBox( NULL, TEXT( "Unable to initialize Direct3D 10." ), TEXT( "Error" ), MB_OK | MB_ICONERROR ); |
| return FALSE; |
| } |
| |
| MSG msg = {0}; |
| while( WM_QUIT != msg.message ) |
| { |
| if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) |
| { |
| TranslateMessage( &msg ); |
| DispatchMessage( &msg ); |
| } |
| |
| Render(); |
| } |
| |
| Cleanup(); |
| return msg.wParam; |
| } |
| |
| LRESULT CALLBACK WndProc( HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam ) |
| { |
| PAINTSTRUCT pc; |
| HDC hdc; |
| |
| switch( Message ) |
| { |
| case WM_PAINT: |
| hdc = BeginPaint( hWnd, &pc ); |
| EndPaint( hWnd, &pc ); |
| break; |
| |
| case WM_DESTROY: |
| PostQuitMessage( 0 ); |
| break; |
| |
| default: |
| return DefWindowProc( hWnd, Message, wParam, lParam ); |
| } |
| |
| return 0; |
| } |
| |
| HRESULT InitD3D( void ) |
| { |
| HRESULT Result = S_OK; |
| |
| D3D10_DRIVER_TYPE DriverTypes[ = { D3D10_DRIVER_TYPE_HARDWARE, D3D10_DRIVER_TYPE_REFERENCE, }; |
| UINT numDriverTypes = sizeof( DriverTypes ) / sizeof( DriverTypes[0] ); |
| |
| DXGI_SWAP_CHAIN_DESC sd; |
| ZeroMemory( &sd, sizeof( sd ) ); |
| |
| sd.BufferCount = 1; |
| sd.BufferDesc.Width = Width; |
| sd.BufferDesc.Height = Height; |
| sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; |
| sd.BufferDesc.RefreshRate.Numerator = 60; |
| sd.BufferDesc.RefreshRate.Denominator = 1; |
| sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; |
| sd.OutputWindow = hWnd; |
| sd.SampleDesc.Count = 1; |
| sd.SampleDesc.Quality = 0; |
| sd.Windowed = TRUE; |
| |
| for( UINT DriverTypeIndex = 0; DriverTypeIndex < numDriverTypes; DriverTypeIndex++ ) |
| { |
| D3D_DriverType = DriverTypes[DriverTypeIndex]; |
| Result = D3D10CreateDeviceAndSwapChain( NULL, D3D_DriverType, NULL, D3D10_CREATE_DEVICE_DEBUG, |
| D3D10_SDK_VERSION, &sd, &SwapChain, &D3D_Device ); |
| if( SUCCEEDED( Result ) ) |
| break; |
| } |
| |
| if( FAILED( Result ) ) |
| return Result; |
| |
| ID3D10Texture2D* BackBuffer; |
| Result = SwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&BackBuffer ); |
| if( FAILED( Result ) ) |
| return Result; |
| |
| Result = D3D_Device->CreateRenderTargetView( BackBuffer, NULL, &RenderTargetView ); |
| BackBuffer->Release(); |
| if( FAILED( Result ) ) |
| return Result; |
| |
| D3D_Device->OMSetRenderTargets( 1, &RenderTargetView, NULL ); |
| |
| D3D10_VIEWPORT vp; |
| vp.Width = Width; |
| vp.Height = Height; |
| vp.MinDepth = 0.0f; |
| vp.MaxDepth = 1.0f; |
| vp.TopLeftX = 0; |
| vp.TopLeftY = 0; |
| D3D_Device->RSSetViewports( 1, &vp ); |
| |
| Result = D3DX10CreateEffectFromFile( TEXT( "Basic.fx" ), NULL, NULL, "fx_4_0", D3D10_SHADER_DEBUG, 0, |
| D3D_Device, NULL, NULL, &Effect, NULL, NULL ); |
| |
| if( FAILED( Result ) ) |
| { |
| MessageBox( NULL, TEXT( "The FX file cannot be located." ), TEXT( "Error" ), MB_OK | MB_ICONERROR); |
| return Result; |
| } |
| |
| Technique = Effect->GetTechniqueByName( "Render" ); |
| WorldVariable = Effect->GetVariableByName( "World" )->AsMatrix(); |
| ViewVariable = Effect->GetVariableByName( "View" )->AsMatrix(); |
| ProjectionVariable = Effect->GetVariableByName( "Projection" )->AsMatrix(); |
| |
| D3D10_INPUT_ELEMENT_DESC Layout[ = |
| { |
| { TEXT( "POSITION" ), 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, |
| { TEXT( "COLOR" ), 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }, |
| }; |
| UINT numElements = sizeof( Layout ) / sizeof( Layout[0] ); |
| |
| D3D10_PASS_DESC PassDesc; |
| Technique->GetPassByIndex( 0 )->GetDesc( &PassDesc ); |
| Result = D3D_Device->CreateInputLayout( Layout, numElements, PassDesc.pIAInputSignature, |
| PassDesc.IAInputSignatureSize, &VertexLayout ); |
| if( FAILED( Result ) ) |
| return Result; |
| |
| D3D_Device->IASetInputLayout( VertexLayout ); |
| |
| BasicVertex Vertices[ = |
| { |
| { D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ) }, |
| { D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 1.0f ) }, |
| { D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 1.0f, 1.0f ) }, |
| { D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f ) }, |
| { D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f ) }, |
| { D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f ) }, |
| { D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ) }, |
| { D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) }, |
| }; |
| |
| D3D10_BUFFER_DESC bd; |
| bd.Usage = D3D10_USAGE_DEFAULT; |
| bd.ByteWidth = sizeof( BasicVertex ) * 8; |
| bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; |
| bd.CPUAccessFlags = 0; |
| bd.MiscFlags = 0; |
| |
| D3D10_SUBRESOURCE_DATA InitialData; |
| InitialData.pSysMem = Vertices; |
| InitialData.SysMemPitch = sizeof( Vertices ); |
| InitialData.SysMemSlicePitch = sizeof( Vertices ); |
| Result = D3D_Device->CreateBuffer( &bd, &InitialData, &VertexBuffer ); |
| if( FAILED( Result ) ) |
| return Result; |
| |
| BasicVertex *Data = NULL; |
| if( SUCCEEDED( VertexBuffer->Map( D3D10_MAP_WRITE, 0, reinterpret_cast< void** >( &Data ) ) ) ) |
| { |
| memcpy( Data, VertexArray, sizeof( SimpleVertex ) * 8 ); |
| VertexBuffer->Unmap( ); |
| } |
| |
| UINT Stride = sizeof( BasicVertex ); |
| UINT Offset = 0; |
| D3D_Device->IASetVertexBuffers( 0, 1, &VertexBuffer, &Stride, &Offset ); |
| |
| DWORD Indices[ = |
| { |
| 3,1,0, |
| 2,1,3, |
| |
| 0,5,4, |
| 1,5,0, |
| |
| 3,4,7, |
| 0,4,3, |
| |
| 1,6,5, |
| 2,6,1, |
| |
| 2,7,6, |
| 3,7,2, |
| |
| 6,4,5, |
| 7,4,6, |
| }; |
| bd.Usage = D3D10_USAGE_DEFAULT; |
| bd.ByteWidth = sizeof( DWORD ) * 36; |
| bd.BindFlags = D3D10_BIND_INDEX_BUFFER; |
| bd.CPUAccessFlags = 0; |
| bd.MiscFlags = 0; |
| InitialData.pSysMem = Indices; |
| InitialData.SysMemPitch = sizeof( Indices ); |
| InitialData.SysMemSlicePitch = sizeof( Indices ); |
| Result = D3D_Device->CreateBuffer( &bd, &InitialData, &IndexBuffer ); |
| if( FAILED( Result ) ) |
| return Result; |
| |
| D3D_Device->IASetIndexBuffer( IndexBuffer, DXGI_FORMAT_R32_UINT, 0 ); |
| |
| D3D_Device->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); |
| |
| D3DXMatrixIdentity( &World ); |
| |
| D3DXVECTOR3 Eye( 0.0f, 1.0f, -5.0f ); |
| D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f ); |
| D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f ); |
| D3DXMatrixLookAtLH( &View, &Eye, &At, &Up ); |
| D3DXMatrixPerspectiveFovLH( &Projection, ( float )D3DX_PI * 0.5f, Width / ( FLOAT )Height, 0.1f, 100.0f ); |
| |
| return S_OK; |
| } |
| |
| void Render( void ) |
| { |
| static float t = 0.0f; |
| if( DriverType == D3D10_DRIVER_TYPE_REFERENCE ) |
| { |
| t += (float)D3DX_PI * 0.0125f; |
| } |
| else |
| { |
| static DWORD TimeStart = 0; |
| DWORD TimeCur = GetTickCount(); |
| if( TimeStart == 0 ) |
| TimeStart = TimeCur; |
| t = ( TimeCur - TimeStart ) / 1000.0f; |
| } |
| D3DXMatrixRotationY( &World, t ); |
| |
| float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 0.0f }; |
| D3D_Device->ClearRenderTargetView( RenderTargetView, ClearColor ); |
| |
| WorldVariable->SetMatrix( (float*)&World ); |
| ViewVariable->SetMatrix( (float*)&View ); |
| ProjectionVariable->SetMatrix( (float*)&Projection ); |
| |
| D3D10_TECHNIQUE_DESC TechDesc; |
| Technique->GetDesc( &TechDesc ); |
| for( UINT p = 0; p < TechDesc.Passes; p++ ) |
| { |
| Technique->GetPassByIndex( p )->Apply( 0 ); |
| D3D_Device->DrawIndexed( 36, 0, 0 ); |
| } |
| |
| SwapChain->Present( 0, 0 ); |
| } |
| |
| void Cleanup( void ) |
| { |
| if( D3D_Device ) D3D_Device->ClearState(); |
| if( VertexBuffer ) VertexBuffer->Release(); |
| if( VertexLayout ) VertexLayout->Release(); |
| if( Effect ) Effect->Release(); |
| if( RenderTargetView ) RenderTargetView->Release(); |
| if( SwapChain ) SwapChain->Release(); |
| if( D3D_Device ) D3D_Device->Release(); |
| } |