1.32k likes | 1.41k Views
Direct3D11 KickStart. Sz écsi László. Direct3D11 SDK. June 2010 DirectX SDK Visual Studio 2010. GPU pipeline input. vertex bufferek index buffer rajzolási állapot egyes pipelineelemek működési beállításai programozható elemek shader programjai
E N D
Direct3D11 KickStart Szécsi László
Direct3D11 SDK • June 2010 DirectX SDK • Visual Studio 2010
GPU pipeline input • vertexbufferek • index buffer • rajzolási állapot • egyes pipelineelemek működési beállításai • programozható elemek shader programjai • erőforrások – globálismemóriában adatok • globális (uniform) változók • textúrák • adatbufferek csak olvasható
GPU pipeline output • kép • rendertarget • framebuffer • textúra • mélységbuffer (+stencil) • adatbuffer • stream out target • read/write (GpGpu-hoz) • unorderedaccessview
GPU pipeline tessfactor IA VS HS Tess DS IA GS RS PS OM tessfactor SO +mindeki olvashatja a uniform változókat, textúrákat, buffereket
Rajzolási állapot tessfactor IA Tess IA RS OM input layout primitive topology rasterizer state viewport depth-stencil state blend state SO
Alapinterface-ek • ID3D11Device (1 van) • erőforrások létrehozása, felszabadítása • textúra, buffer, shader, stateblock • ID3D11DeviceContext (1 immediate, * deferred) • rajzolási állapot, I/O, shader beállítás • rajzolás • ID3DXEffect (*) • shaderek fordítása, menedzselése • shaderek, rajzolási állapotok beállítása scriptből
ID3D11Device interface metódusok • erőforrások létrehozása • CreateBuffer • CreateTexture2D • erőforrásokhoz nézetek létrehozása • CreateShaderResourceView • CreateRenderTargetView • shaderek és rajzolásiállapot-struktúrák • CreateVertexShader • CreateBlendState
ID3DDeviceContext • bemenetek és kimenetek beállítása • IASetIndexBuffer, IASetVertexBuffers • OMSetRenderTargets • rajzolási állapot beállítása • RSSetState, OMSetBlendState • shaderek, uniform paraméterek beállítása • VSSetShader, PSSetShader • rajzolás • Draw, DrawIndexed, DrawIndexInstanced
DXUT • mint a GLUT • ablakozás, eseménykezelés, callback függvények • csomó minden más • kamera osztályok • userinterface • nem külön lib, hanem forrásban ott van minden Empty projectben alapból
DXUT Callback beállítás DXUTSetCallbackD3D11DeviceAcceptable( IsD3D11DeviceAcceptable ); DXUTSetCallbackD3D11DeviceCreated( OnD3D11CreateDevice ); DXUTSetCallbackD3D11SwapChainResized( OnD3D11ResizedSwapChain ); DXUTSetCallbackD3D11FrameRender( OnD3D11FrameRender ); DXUTSetCallbackD3D11SwapChainReleasing( OnD3D11ReleasingSwapChain ); DXUTSetCallbackD3D11DeviceDestroyed( OnD3D11DestroyDevice );
DXUT init DXUTInit( true, true, NULL ); DXUTSetCursorSettings( true, true ); DXUTCreateWindow( L"KickStart11" ); DXUTCreateDevice( D3D_FEATURE_LEVEL_10_0, true, 640, 480 ); DXUTMainLoop(); // Enter into the DXUT render loop
Empty project • Előző két dián lévő kód már benne lesz • Start Menu/DirectX SDK (June 2010)/DirectX Sample Browser • install EmptyProject11 • project neve: KickStart11
Visual Studio 2010 • KickStart11_2010.sln megnyitása • DirectX 9 támogatás kidobása (opcionális) • delete EmptyProject9.cpp • minden D3D9-et tartalmazó sor törlése a KickStart11.cpp-ből • 9-es libek kidobása a linker inputból
Include és lib könyvtárak beállítása • project properties (ez csak erre a projectre lesz érvényes) • Configurationproperties/c/c++/general/additionalincludedirectories • C:\Program Files\Microsoft DirectX SDK (June 2010)\Include • Configurationproperties/linker/general/additionallibrarydirectories • C:\Program Files\Microsoft DirectX SDK (June 2010)\Lib\x86
Include és lib könyvtárak beállítása • gép alapon (minden projectre érvényes lesz) • viewmenu: propertymanager • propertymanager ablakban • pl. Debug| Win32 • Microsoft.Cpp.Win32.User duplaklikk • VC++ directories alá az előző diákon szereplő könyvtárak beállítása
KickStart11.cppglobáliscallback függvények • eszközesemények • OnD3D11CreateDevice program indul • OnD3D11ResizedSwapChain ablak létrejött • OnD3D11ReleasingSwapChain ablak megszűnt • OnD3D11DestroyDevice program vége • vezérlési események • OnD3D11FrameRender rajzolás • OnFrameMove animáció • MsgProcwindows üzenet
Dxa::Baseinterface • célszerű, hogy a globális callback függvények egy saját objektum metódusait hívják • ott tudjuk megvalósítani a funkciót • nem kell a KickStart11.cpp-be nyúlkálni • ahhoz, hogy a saját objektum könnyen cserélhető legyen, legyen egy ősinterface • minden legyen a Dxanamespace-ben • az ősinterface a Dxa::Base • implementáló osztály Dxa::Sas : publicDxa::Base
#0.0 Dxa.h #pragma once namespace Dxa { class Base { protected: ID3D11Device* device; IDXGISwapChain* swapChain; DXGI_SURFACE_DESC backbufferSurfaceDesc; public: Base(ID3D11Device* device) {this->device = device; swapChain = NULL;} void setSwapChain(IDXGISwapChain* swapChain, const DXGI_SURFACE_DESC* backbufferSurfaceDesc) { this->swapChain = swapChain; this->backbufferSurfaceDesc = *backbufferSurfaceDesc;} virtual ~Base(){} // insert code from slide #0.1 here }; }
#0.1 Dxa.h // insert this into code on slide #0.0 virtual HRESULT createResources() {return S_OK;} virtual HRESULT createSwapChainResources() {return S_OK;} virtual HRESULT releaseResources() {return S_OK;} virtual HRESULT releaseSwapChainResources() {return S_OK;} virtual void animate(double dt, double t){} virtual bool processMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {return false;} virtual void render( ID3D11DeviceContext* context){}
#1.0 KickStart11.cpp #include "DXUT.h“ #include "Dxa.h" Dxa::Base* application;
#1.1 KickStart11.cpp HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext) { application = new Dxa::Base(pd3dDevice); application->createResources(); return S_OK; }
#1.2 KickStart11.cpp HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { application->setSwapChain(pSwapChain, pBackBufferSurfaceDesc); application->createSwapChainResources(); return S_OK; }
#1.3 KickStart11.cpp void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext ) { if(application) application->animate( fElapsedTime, fTime); }
#1.4 KickStart11.cpp void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, float fElapsedTime, void* pUserContext ) { // Clear render target and the depth stencil float ClearColor[4] = { 0.176f, 0.196f, 0.667f, 0.0f }; ID3D11RenderTargetView* pRTV = DXUTGetD3D11RenderTargetView(); ID3D11DepthStencilView* pDSV = DXUTGetD3D11DepthStencilView(); pd3dImmediateContext->ClearRenderTargetView( pRTV, ClearColor ); pd3dImmediateContext->ClearDepthStencilView( pDSV, D3D11_CLEAR_DEPTH, 1.0, 0 ); }
#1.5 KickStart11.cpp void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime, float fElapsedTime, void* pUserContext ) { if(application) application->render( pd3dImmediateContext); }
#1.6 KickStart11.cpp void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext ) { application-> releaseSwapChainResources(); }
#1.7 KickStart11.cpp void CALLBACK OnD3D11DestroyDevice( void* pUserContext ) { application->releaseResources(); delete application; application = NULL; }
#1.8 KickStart11.cpp LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext ) { if(application) application->processMessage( hWnd, uMsg, wParam, lParam); return 0; }
Háromszög rajzolása Dxa::Triangle erőforrás létrehozás/felszabadítás (vertexbuffer), rendertarget törlés, rajzolás
Dxa::Triangle • Dxa::Base nem csinál semmit • származtatunk belőle Dxa::Triangle-t • felüldefiniáljuk a virtuális eseménykezelő metódusokat • createResources • releaseResource • render
#2.0 DxaTriangle.h #pragma once #include "dxa.h" namespace Dxa { class Triangle : public Dxa::Base { public: Triangle(ID3D11Device* device); HRESULT createResources(); HRESULT releaseResources(); void render(ID3D11DeviceContext* context); }; }
#2.1 DxaTriangle.cpp #include "DXUT.h" #include "DxaTriangle.h" Dxa::Triangle::Triangle(ID3D11Device* device) :Base(device) { } HRESULT Dxa::Triangle::createResources() { return S_OK; } HRESULT Dxa::Triangle::releaseResources() { return S_OK; } void Dxa::Triangle::render(ID3D11DeviceContext* context) { }
#2.3 KickStart11.cpp #include "DXUT.h" #include "Dxa.h" Dxa::Base* application; #include "DxaTriangle.h"
#2.4 KickStart11.cpp HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { application = new //Dxa::Base(pd3dDevice); Dxa::Triangle(pd3dDevice); application->createResources(); return S_OK; }
Ezekre lesz szükség vertex buffer = [x, y, z] [x, y, z] [x, y, z, 1] IA VS IA RS PS OM [x, y, z, 1] [x, y, z, 1] marad default pixel shader marad default input layout vertex shader primitive topology
#2.5 DxaTriangle.h class Triangle : public Dxa::Base { ID3D11Buffer* vertexBuffer; ID3D11InputLayout* inputLayout; ID3D11VertexShader* vertexShader; ID3D11PixelShader* pixelShader; public:
#2.6 DxaTriangle.cpp HRESULT Dxa::Triangle::createResources() { D3D11_BUFFER_DESC desc; desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; desc.ByteWidth = sizeof(D3DXVECTOR3) * 3; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; desc.StructureByteStride = sizeof(D3DXVECTOR3); desc.Usage = D3D11_USAGE_IMMUTABLE; D3DXVECTOR3 vertexPositionArray[3] = { D3DXVECTOR3(0, 0, 0.5), D3DXVECTOR3(0, 1, 0.5), D3DXVECTOR3(1, 0, 0.5) }; D3D11_SUBRESOURCE_DATA initData; initData.pSysMem = vertexPositionArray; initData.SysMemPitch = 0; initData.SysMemSlicePitch = 0; device->CreateBuffer(&desc, &initData, &vertexBuffer);
#2.7 DxaTriangle.cpp device->CreateBuffer(&desc, &initData, &vertexBuffer); const char* vertexShaderCode = "float4 vsIdle(float4 pos :POSITION ) :SV_Position{return pos;}"; ID3DBlob* vertexShaderByteCode; D3DX11CompileFromMemory(vertexShaderCode, strlen(vertexShaderCode), NULL, NULL, NULL, "vsIdle", "vs_5_0", 0, 0, NULL, &vertexShaderByteCode, NULL, NULL); device->CreateVertexShader( vertexShaderByteCode->GetBufferPointer(), vertexShaderByteCode->GetBufferSize(), NULL, &vertexShader);
#2.8 DxaTriangle.cpp // insert after #2.7 D3D11_INPUT_ELEMENT_DESC positionElement; positionElement.AlignedByteOffset = 0; positionElement.Format = DXGI_FORMAT_R32G32B32_FLOAT; positionElement.InputSlot = 0; positionElement.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; positionElement.InstanceDataStepRate = 0; positionElement.SemanticIndex = 0; positionElement.SemanticName = "POSITION";
#2.9 DxaTriangle.cpp // insert after #2.8 device->CreateInputLayout( &positionElement, 1, vertexShaderByteCode ->GetBufferPointer(), vertexShaderByteCode ->GetBufferSize(), &inputLayout);
#2.10 DxaTriangle.cpp // insert after #2.9 const char* pixelShaderCode = "float4 psIdle() : SV_Target{return float4(1, 0, 0, 1);}"; ID3DBlob* pixelShaderByteCode; D3DX11CompileFromMemory(pixelShaderCode, strlen(pixelShaderCode), NULL, NULL, NULL, "psIdle", "ps_5_0", 0, 0, NULL, &pixelShaderByteCode, NULL, NULL); device-> CreatePixelShader( pixelShaderByteCode->GetBufferPointer(), pixelShaderByteCode->GetBufferSize(), NULL, &pixelShader);
#2.11 DxaTriangle.cpp HRESULT Dxa::Triangle::releaseResources() { vertexBuffer->Release(); inputLayout->Release(); vertexShader->Release(); pixelShader->Release(); return S_OK; }
#2.12 DxaTriangle.cpp void Dxa::Triangle::render(ID3D11DeviceContext* context) { float clearColor[4] = { 0.9f, 0.7f, 0.1f, 0.0f }; ID3D11RenderTargetView* defaultRtv = DXUTGetD3D11RenderTargetView(); ID3D11DepthStencilView* defaultDsv = DXUTGetD3D11DepthStencilView(); context->ClearRenderTargetView( defaultRtv, clearColor ); context->ClearDepthStencilView( defaultDsv, D3D11_CLEAR_DEPTH, 1.0, 0 );
#2.13 DxaTriangle.cpp // insert after #2.12 unsigned int stride = sizeof(D3DXVECTOR3); unsigned int offset = 0; context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); context->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); context->IASetInputLayout(inputLayout); context->VSSetShader(vertexShader, NULL, 0); context->PSSetShader(pixelShader, NULL, 0); context->Draw(3, 0);
Honnan tudjuk mit kell beállítani? • Start menu • doc