DirectX - oyungelistirici.org
Transkript
DirectX - oyungelistirici.org
DirectX Uluslararası Bilgisayar Enstitüsü Ege Üniversitesi Ahmet Bilgili & Serkan Ergun DirectX iş hattı DirectX 9 için http://www.xmission.com/~legalize/book/preview/poster/pipeline-9.0.png Input-Assembler Stage – Üçgenleri, doğruları ve köşeleri sağlamakla görevlidir. Vertex-Shader Stage – Vertex başında transformasyonlar ve vertex başına ışıklandırma gibi işlemler yapılır. Rasterizer Stage- Primitivleri kesmek, gereksiz gördüklerini ayıklamak, hangilerinin pixel shader tarafından işleneceğini işlemekle yükümlüdür. Pixel-Shader Stage – İnterpolasyona uğratılmış veriyi alır ve her piksel başına işlem yapar. Output-Merger Stage – Pixel shader’dan çıkan verileri derinlik, stencil gibi işlemlerden geçirerek son şeklini verir. The Direct3D 10 programmable pipeline DirectX iş hattı İş hattı sonuçlarının ekrana yansıtılması DirectX giriş (DirectX 9) Ana pencerenin oluşturulması INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) { // Register the window class. WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, "Direct3D Tutorial", NULL }; RegisterClassEx( &wc ); // Create the application's window. HWND hWnd = CreateWindow( "Direct3D Tutorial", "Direct3D Tutorial 01: CreateDevice", WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL ); init(hWnd); // The message loop. MSG msg; while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } } } DirectX giriş (DirectX 9) Direct3D aygıtının ilklendirilmesi // global değişkenler IDirect3DDevice9 *g_pd3dDevice = NULL; IDirect3D9 * g_pD3D = NULL; DWORD init( HWND hWnd) { if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ))); } DirectX giriş (DirectX 9) Win32 Mesaj döngüsü LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_DESTROY: PostQuitMessage( 0 ); return 0; case WM_PAINT: Render(); ValidateRect( hWnd, NULL ); return 0; } return DefWindowProc( hWnd, msg, wParam, lParam ); } DirectX giriş (DirectX 9) Görüntü hesaplama void Render() { // Clear the back buffer to a blue color g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 ); // Begin the scene g_pd3dDevice->BeginScene(); // Hesaplama burada olur // End the scene g_pd3dDevice->EndScene(); g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); } DirectX giriş (DirectX 9) Pencere kapatılması durumunda kontroller VOID Cleanup() { if( g_pd3dDevice != NULL) g_pd3dDevice->Release(); if( g_pD3D != NULL) g_pD3D->Release(); } DirectX örnek(DirectX 9) Görüntü hesaplama //----------------------------------------------------------------------------// GLOBALS //----------------------------------------------------------------------------HWND g_hWnd = NULL; // pencere handle’ı LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; LPDIRECT3DVERTEXBUFFER9 g_pPointList_VB = NULL; // vertex buffer göstericileri LPDIRECT3DVERTEXBUFFER9 g_pLineStrip_VB = NULL; LPDIRECT3DVERTEXBUFFER9 g_pLineList_VB = NULL; LPDIRECT3DVERTEXBUFFER9 g_pTriangleList_VB = NULL; LPDIRECT3DVERTEXBUFFER9 g_pTriangleStrip_VB = NULL; LPDIRECT3DVERTEXBUFFER9 g_pTriangleFan_VB = NULL; #define D3DFVF_MY_VERTEX ( D3DFVF_XYZ | D3DFVF_DIFFUSE ) // DirectX köşe tanımı // Köşe tanımı struct Vertex { float x, y, z; // Noktanın pozisyonu DWORD color; // Noktanın rengi }; bool g_bRenderInWireFrame = false; D3DPRIMITIVETYPE g_currentPrimitive = D3DPT_TRIANGLEFAN; DirectX örnek(DirectX 9) Vertex buffer için köşeler Vertex g_pointList[] = { { 0.0f, 0.0f, 0.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, { 0.5f, 0.0f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ) }, {-0.5f, 0.0f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ) }, { 0.0f,-0.5f, 0.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 0.0, 1.0 ) }, { 0.0f, 0.5f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 1.0, 1.0 ) }, }; Vertex g_lineList[] = { {-1.0f, 0.0f, 0.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, // Line #1 { 0.0f, 1.0f, 0.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, { 0.5f, 1.0f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ) }, // Line #2 { 0.5f, -1.0f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ) }, { 1.0f, -0.5f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ) }, // Line #3 {-1.0f, -0.5f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ) }, }; Vertex g_lineStrip[] = { { 0.5f, 0.5f, 0.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, { 1.0f, 0.0f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ) }, { 0.0f,-1.0f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ) }, {-1.0f, 0.0f, 0.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 0.0, 1.0 ) }, { 0.0f, 0.0f, 0.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 1.0, 1.0 ) }, { 0.0f, 1.0f, 0.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, }; DirectX örnek(DirectX 9) Direct3D aygıtının ilklendirilmesi void init( void ) { g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ); D3DDISPLAYMODE d3ddm; g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = d3ddm.Format; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ); g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); D3DXMATRIX mProjection; D3DXMatrixPerspectiveFovLH( &mProjection, D3DXToRadian( 45.0f ), 1.0f, 1.0f, 100.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &mProjection ); …….. …….. …….. DirectX örnek(DirectX 9) Vertex buffer’ların oluşturulması void init( void ) { …….. …….. …….. Vertex *pVertices = NULL; // Point List g_pd3dDevice->CreateVertexBuffer( 5*sizeof(Vertex), 0, D3DFVF_MY_VERTEX, D3DPOOL_DEFAULT, &g_pPointList_VB, NULL ); pVertices = NULL; g_pPointList_VB->Lock( 0, sizeof(g_pointList), (void**)&pVertices, 0 ); memcpy( pVertices, g_pointList, sizeof(g_pointList) ); g_pPointList_VB->Unlock(); // Line List g_pd3dDevice->CreateVertexBuffer( 6*sizeof(Vertex), 0, D3DFVF_MY_VERTEX, D3DPOOL_DEFAULT, &g_pLineList_VB, NULL ); pVertices = NULL; g_pLineList_VB->Lock( 0, sizeof(g_lineList), (void**)&pVertices, 0 ); memcpy( pVertices, g_lineList, sizeof(g_lineList) ); g_pLineList_VB->Unlock(); // Line Strip g_pd3dDevice->CreateVertexBuffer( 6*sizeof(Vertex), 0, D3DFVF_MY_VERTEX,D3DPOOL_DEFAULT, &g_pLineStrip_VB, NULL ); pVertices = NULL; g_pLineStrip_VB->Lock( 0, sizeof(g_lineStrip), (void**)&pVertices, 0 ); memcpy( pVertices, g_lineStrip, sizeof(g_lineStrip) ); g_pLineStrip_VB->Unlock(); …….. …….. …….. DirectX örnek(DirectX 9) Vertex buffer’ların oluşturulması void init( void ) { …….. …….. …….. // Triangle List g_pd3dDevice->CreateVertexBuffer( 6*sizeof(Vertex), 0, D3DFVF_MY_VERTEX, D3DPOOL_DEFAULT, &g_pTriangleList_VB,NULL ); pVertices = NULL; g_pTriangleList_VB->Lock( 0, sizeof(g_triangleList), (void**)&pVertices, 0 ); memcpy( pVertices, g_triangleList, sizeof(g_triangleList) ); g_pTriangleList_VB->Unlock(); // Triangle Strip g_pd3dDevice->CreateVertexBuffer( 8*sizeof(Vertex), 0, D3DFVF_MY_VERTEX, D3DPOOL_DEFAULT, &g_pTriangleStrip_VB, NULL ); pVertices = NULL; g_pTriangleStrip_VB->Lock( 0, sizeof(g_triangleStrip), (void**)&pVertices, 0 ); memcpy( pVertices, g_triangleStrip, sizeof(g_triangleStrip) ); g_pTriangleStrip_VB->Unlock(); // Triangle Fan g_pd3dDevice->CreateVertexBuffer( 6*sizeof(Vertex), 0, D3DFVF_MY_VERTEX, D3DPOOL_DEFAULT, &g_pTriangleFan_VB, NULL ); pVertices = NULL; g_pTriangleFan_VB->Lock( 0, sizeof(g_triangleFan), (void**)&pVertices, 0 ); memcpy( pVertices, g_triangleFan, sizeof(g_triangleFan) ); g_pTriangleFan_VB->Unlock(); } DirectX örnek(DirectX 9) Hesaplama void render( void ) { g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0 ); g_pd3dDevice->BeginScene(); D3DXMATRIX mWorld; D3DXMatrixTranslation( &mWorld, 0.0f, 0.0f, 5.0f ); g_pd3dDevice->SetTransform( D3DTS_WORLD, &mWorld ); switch( g_currentPrimitive ) { case D3DPT_POINTLIST: g_pd3dDevice->SetStreamSource( 0, g_pPointList_VB, 0, sizeof(Vertex) ); g_pd3dDevice->SetFVF( D3DFVF_MY_VERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 5 ); break; case D3DPT_LINELIST: g_pd3dDevice->SetStreamSource( 0, g_pLineList_VB, 0, sizeof(Vertex) ); g_pd3dDevice->SetFVF( D3DFVF_MY_VERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, 3); break; case D3DPT_LINESTRIP: g_pd3dDevice->SetStreamSource( 0, g_pLineStrip_VB, 0, sizeof(Vertex) ); g_pd3dDevice->SetFVF( D3DFVF_MY_VERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_LINESTRIP, 0, 5); break; ……. ……. DirectX örnek(DirectX 9) Hesaplama void render( void ) { …….. …….. …….. case D3DPT_TRIANGLELIST: g_pd3dDevice->SetStreamSource( 0, g_pTriangleList_VB, 0, sizeof(Vertex) ); g_pd3dDevice->SetFVF( D3DFVF_MY_VERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 ); break; case D3DPT_TRIANGLESTRIP: g_pd3dDevice->SetStreamSource( 0, g_pTriangleStrip_VB, 0, sizeof(Vertex) ); g_pd3dDevice->SetFVF( D3DFVF_MY_VERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 6 ); break; case D3DPT_TRIANGLEFAN: g_pd3dDevice->SetStreamSource( 0, g_pTriangleFan_VB, 0, sizeof(Vertex) ); g_pd3dDevice->SetFVF( D3DFVF_MY_VERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 4 ); break; default: break; } g_pd3dDevice->EndScene(); g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); } DirectX örnek(DirectX 9) Pencere kapatılması durumunda kontroller void shutDown( void ) { if( g_pPointList_VB != NULL ) g_pPointList_VB->Release(); if( g_pLineList_VB != NULL ) g_pLineList_VB->Release(); if( g_pLineStrip_VB != NULL ) g_pLineStrip_VB->Release(); if( g_pTriangleList_VB != NULL ) g_pTriangleList_VB->Release(); if( g_pTriangleStrip_VB != NULL ) g_pTriangleStrip_VB->Release(); if( g_pTriangleFan_VB != NULL ) g_pTriangleFan_VB->Release(); if( g_pd3dDevice != NULL ) g_pd3dDevice->Release(); if( g_pD3D != NULL ) g_pD3D->Release(); } DirectX örnek(DirectX 9) Mesaj döngüsü LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { …… …… switch( msg ) { case WM_KEYDOWN { switch( wParam ) { case VK_ESCAPE: PostQuitMessage(0); break; case VK_F1: { if( g_currentPrimitive == D3DPT_POINTLIST ) g_currentPrimitive = D3DPT_LINELIST; else if( g_currentPrimitive == D3DPT_LINELIST ) g_currentPrimitive = D3DPT_LINESTRIP; else if( g_currentPrimitive == D3DPT_LINESTRIP ) g_currentPrimitive = D3DPT_TRIANGLELIST; else if( g_currentPrimitive == D3DPT_TRIANGLELIST ) g_currentPrimitive = D3DPT_TRIANGLESTRIP; else if( g_currentPrimitive == D3DPT_TRIANGLESTRIP ) g_currentPrimitive = D3DPT_TRIANGLEFAN; else if( g_currentPrimitive == D3DPT_TRIANGLEFAN ) g_currentPrimitive = D3DPT_POINTLIST; } break; case VK_F2: g_bRenderInWireFrame = !g_bRenderInWireFrame; if( g_bRenderInWireFrame == true ) g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME ); else g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); } } break; Teşekkürler