Download - Direct3D11 KickStart
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
• erőforrások – globális memóriában adatok– globális (uniform) változók– textúrák– adatbufferek
csak olvasható
GPU pipeline output
• kép– render target• frame buffer• textúra
– mélységbuffer (+stencil)• adatbuffer– stream out target
• read/write (GpGpu-hoz)– unordered access view
GPU pipeline
IA VS HS DS GS PS OMRSTess
tessfactor
tessfactor
IA
SO+mindeki olvashatja a uniform változókat, textúrákat, buffereket
Rajzolási állapot
IA OMRSTess
tessfactor
IA
SO
input layout
primitivetopology
rasterizerstate
depth-stencilstate
blendstate
viewport
Alapinterface-ek
• ID3D11Device (1 van)– erőforrások létrehozása, felszabadítása• textúra, buffer, shader, state block
• 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– user interface
• 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 ren der 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)– Configuration properties/c/c++/general/additional
include directories• C:\Program Files\Microsoft DirectX SDK (June 2010)\
Include– Configuration properties/linker/general/additional
library directories• 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)• view menu: property manager• property manager 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
Itt tartunk – üres ablak
KickStart11.cppglobális callback 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ó– MsgProc windows üzenet
Dxa::Base interface
• 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 Dxa namespace-ben– az ősinterface a Dxa::Base– implementáló osztály Dxa::Sas : public Dxa::Base
Dxa.h#pragma oncenamespace 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.0
Dxa.h// insert this into code on slide #0.0virtual 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){}
#0.1
KickStart11.cpp#include "DXUT.h“#include "Dxa.h"Dxa::Base* application;
#1.0
KickStart11.cppHRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) {application = new Dxa::Base(pd3dDevice);application->createResources();return S_OK;
}
#1.1
KickStart11.cppHRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{application->setSwapChain(pSwapChain,pBackBufferSurfaceDesc);application->createSwapChainResources();return S_OK;
}
#1.2
KickStart11.cppvoid CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{if(application)
application->animate(fElapsedTime, fTime);
}
#1.3
KickStart11.cppvoid 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.4
KickStart11.cppvoid CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext,
double fTime, float fElapsedTime, void* pUserContext )
{if(application)application->render(pd3dImmediateContext);
}
#1.5
KickStart11.cppvoid CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext )
{application->
releaseSwapChainResources();}
#1.6
KickStart11.cppvoid CALLBACK OnD3D11DestroyDevice( void* pUserContext )
{application->releaseResources();delete application;application = NULL;
}
#1.7
KickStart11.cppLRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
{if(application)application->processMessage(hWnd, uMsg, wParam, lParam);return 0;
}
#1.8
Itt tartunk
Háromszög rajzolása
Dxa::Triangleerőforrás létrehozás/felszabadítás (vertex
buffer), render target 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
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.0
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.1
KickStart11.cpp#include "DXUT.h"#include "Dxa.h"Dxa::Base* application;#include "DxaTriangle.h"
#2.3
KickStart11.cppHRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
application = new //Dxa::Base(pd3dDevice);Dxa::Triangle(pd3dDevice);
application->createResources(); return S_OK;}
#2.4
Itt tartunk
Ezekre lesz szükség
IA VS PS OMRSIA
vertexbuffer
inputlayout
vertexshader
pixelshader
primitivetopology
maraddefault
maraddefault
= [x, y, z]
[x, y, z]
[x, y, z, 1]
[x, y, z, 1]
[x, y, z, 1]
DxaTriangle.hclass Triangle :public Dxa::Base{ID3D11Buffer* vertexBuffer;ID3D11InputLayout* inputLayout;ID3D11VertexShader* vertexShader;ID3D11PixelShader* pixelShader;
public:
#2.5
DxaTriangle.cppHRESULT 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.6
DxaTriangle.cppdevice->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.7
DxaTriangle.cpp// insert after #2.7D3D11_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.8
DxaTriangle.cpp// insert after #2.8device->CreateInputLayout(&positionElement, 1, vertexShaderByteCode
->GetBufferPointer(), vertexShaderByteCode
->GetBufferSize(), &inputLayout);
#2.9
DxaTriangle.cpp// insert after #2.9const 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.10
DxaTriangle.cppHRESULT Dxa::Triangle::releaseResources()
{vertexBuffer->Release();inputLayout->Release();vertexShader->Release();pixelShader->Release();return S_OK;
}
#2.11
DxaTriangle.cppvoid 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.12
DxaTriangle.cpp// insert after #2.12unsigned 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);
#2.13
Háromszög kész
Honnan tudjuk mit kell beállítani?
• Start menu• doc
Visual Studio 2010 tippek
• bepastelt kódhoz:– formáz: kijelöl, Ctrl+K, Ctrl+F
• általában kódoláshoz– kódieg.: eleje begépel, aztán Ctrl+space– metódus paraméterlistája• kurzor a zárójelek közé v. nyitó zárójel után• ctrl+alt+space
Effect framework
Dxa::TriangleWithFxshaderek kényelmesebb kezelése
Effects11
• forráskódban elérhető• egyszerűsíti a shaderek fordítását, rajzolási
állapot beállítását– pass: egy ilyen beállítóscript– technique: pass gyűjtemény– group: technique gyűjtemény
• erőforrások, uniform paraméterek átadása– globális változók
ID3DX11Effect interface
• ID3DXEffectVariable gyűjtemény– scalar, vector, matrix– shaderResourceView (pl. textúra)
• ID3DXEffectGroup– ID3DXEffectTechnique• ID3DXEffectPass
– shader programok beállítása– rasterizer, blend, depthstencil állapot beállítása
• mindezek egy .fx fileban– HLSL shader kódok
Effect framework beépítése a projektünkbe• 1. lehetőség– forrás lefordítása– <dxsdk dir>/Samples/C++/Effects11– kapott lib file belinkelése
• 2. lehetőség (bele akarunk hekkelni esetleg)– forrás bemásolása a KickStart11 könyvtárba– project hozzáadása a KickStart11 solutionhöz
Effect11 project beépítése
• copy– c:\Program Files (x86)\Microsoft DirectX SDK (June
2010)\Samples\C++\Effects11\– d:\Education\KickStart\D3D11\KickStart11\
• solution/add/existing project– KickStart11/Effects11/Effects11_2010.vcxproj
• KickStart11 project properties– common properties– add new reference: Effects 11
Effect11 include könyvtár
• KickStart11 project properties– configuration properties/c++/additional include
directories• Effects11\Inc
Effect fileok
• hozzunk létre egy ‘fx’ alkönyvtárat a KickStart11-en belül
• abba egy idle.fx file– add new item/utility/text file
fx/idle.fxfloat4 vsIdle(float4 pos : POSITION) : SV_Position {
return pos;}float4 psIdle() : SV_Target{
return float4(0, 1, 0, 1);}technique11 idle{
pass idle{SetVertexShader ( CompileShader( vs_5_0, vsIdle() ) );SetPixelShader( CompileShader( ps_5_0, psIdle() ) );}
}
#3.0
Új osztály: Dxa::TriangleWithFx
• DxaTriangle.h, DxaTriangle.cpp tartalma bemásolva a DxaTriangleWithFx.h, ill. cpp-be
• Minden Triangle TriangleWithFx-re cserélve
KickStart.cppDxa::Base* application;#include "DxaTriangle.h"#include "DxaTriangleWithFx.h"
#4.0
KickStart11.cppHRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
application = new //Dxa::Base(pd3dDevice);//Dxa::Triangle(pd3dDevice);Dxa::TriangleWithFx(pd3dDevice);application->createResources();
return S_OK;}
#4.1
DxaTriangleWithFx.h#pragma once#include "dxa.h"#include "d3dx11effect.h"
#4.2
DxaTriangleWithFx.hID3D11VertexShader* vertexShader;ID3D11PixelShader* pixelShader;
ID3DX11Effect* effect;
public:TriangleWithFx(ID3D11Device* device);
#4.3
DxaTriangleWithFx.cppconst 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);
#4.4
DxaTriangleWithFx.cppdevice->CreateInputLayout(&positionElement, 1, vertexShaderByteCode->GetBufferPointer(), vertexShaderByteCode->GetBufferSize(), &inputLayout);
#4.5
DxaTriangleWithFx.cppconst 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);
#4.6
DxaTriangleWithFx.cppHRESULT Dxa::TriangleWithFx::createResources(){
ID3DBlob* compiledEffect = NULL;D3DX11CompileFromFileW( L"fx/idle.fx", NULL, NULL, NULL, "fx_5_0", 0, 0, NULL, &compiledEffect, NULL, NULL);
D3DX11CreateEffectFromMemory( compiledEffect->GetBufferPointer(), compiledEffect->GetBufferSize(),0, device, &effect);
#4.7
DxaTriangleWithFx.cpp// append to createResourcesD3DX11_PASS_DESC idlePassDesc;effect->GetTechniqueByName("idle")->GetPassByName("idle")->GetDesc(&idlePassDesc);
device->CreateInputLayout(&positionElement, 1, idlePassDesc.pIAInputSignature, idlePassDesc.IAInputSignatureSize, &inputLayout);
#4.8
DxaTriangleWithFx.cppHRESULT Dxa::TriangleWithFx::releaseResources()
{effect->Release();vertexBuffer->Release();inputLayout->Release();vertexShader->Release();pixelShader->Release();
#4.9
DxaTriangleWithFx.cppcontext->VSSetShader(vertexShader, NULL, 0);
context->PSSetShader(pixelShader, NULL, 0);
effect->GetTechniqueByName("idle")->GetPassByName("idle")->Apply(0, context);
context->Draw(3, 0);
#4.10
Effect framework háromszög kész
Mesh + kamera
Dxa::MeshCammesh osztály, kamera,
transzformációk, advanced effect
Mesh osztály
• dx11-ben nincs– játékfejlesztők írnak maguknak úgyis
• DXUT-ban van– CDXUTSDKMesh– csak sdkmesh formátumot tud betölteni– túl bonyolult most nekünk
• Saját Mesh osztály– vertex buffer, index buffer, vertex elements– saját formátum (.dgb) + konverter (dgbMaker)
.dgb formátum
• bináris• vertex element descriptor• vertex buffer binárisan• index buffer binárisan• ennyi– nincs attribútum tábla– nincsenek anyagok– nincsenek textúrák– nincsenek submeshek
Mesh osztály használataclass Mesh{ID3D11Buffer* vertexBuffer;ID3D11Buffer* indexBuffer;. . . // code deleted from herepublic:static HRESULT createMeshFromFile(const char* dgbFilename, ID3D11Device* device, Mesh** mesh);
~Mesh();HRESULT createInputLayout(ID3D11Device* device, D3DX11_PASS_DESC* passDesc, ID3D11InputLayout** inputLayout);
void draw(ID3D11DeviceContext* context);};
Új effect file: fx/basic.fx
• transzformációkat végrehajtó vertex shader– be: modell pos, model normal, tex– ki: képernyő pos, világ pos, világ normal, tex– trafó mátrixok uniform paraméterek• kamerától fog majd függeni az érték
• primitív árnyalást számoló pixel shader– ne legyen egyszínű– normal.z abszolútértéke a szín– (függőleges irányfény)
fx/basic.fxfloat4x4 modelMatrix;float4x4 modelMatrixInverse;float4x4 modelViewProjMatrix;
#5.0
fx/basic.fxstruct IaosTrafo{ float4 pos : POSITION; float3 normal : NORMAL; float2 tex : TEXCOORD;};
struct VsosTrafo{ float4 pos : SV_POSITION; float4 worldPos : WORLDPOS; float3 normal : NORMAL; float2 tex : TEXCOORD;};
#5.1
fx/basic.fxVsosTrafo vsTrafo(IaosTrafo input){VsosTrafo output = (VsosTrafo)0;output.pos = mul(input.pos,modelViewProjMatrix);output.worldPos = mul(input.pos,modelMatrix);output.normal = mul(modelMatrixInverse,float4(input.normal.xyz, 0.0));output.tex = input.tex;return output;
}
#5.2
fx/basic.fxVsosTrafo vsTrafo(IaosTrafo input){VsosTrafo output = (VsosTrafo)0;output.pos = mul(input.pos,modelViewProjMatrix);output.worldPos = mul(input.pos,modelMatrix);output.normal = mul(modelMatrixInverse,float4(input.normal.xyz, 0.0));output.tex = input.tex;return output;
}
#5.3
fx/basic.fxfloat4 psBasic(VsosTrafo input) : SV_Target
{ return abs(saturate(input.normal).y);
}
#5.2
fx/basic.fxtechnique11 basic{pass basic{
SetVertexShader ( CompileShader(vs_5_0, vsTrafo() ) );
SetPixelShader( CompileShader(ps_5_0, psBasic() ) );
}}
#5.3
Új osztály: Dxa::MeshCam
• DxaMeshCam.h• DxaMeshCam.cpp
KickStart.cpp#include "DxaTriangle.h#include "DxaTriangleWithFx.h"#include "DxaMeshCam.h"Dxa::Base* application;
#6.0
KickStart11.cppHRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{application = new //Dxa::Base(pd3dDevice);//Dxa::Triangle(pd3dDevice);//Dxa::TriangleWithFx(pd3dDevice);Dxa::MeshCam(pd3dDevice);application->createResources();
return S_OK;}
#6.1
DxaMeshCam.h#pragma once#include "dxa.h"#include "Mesh.h“#include "DXUTCamera.h"
namespace Dxa {class MeshCam : public Dxa::Base{ // insert code from #6.3 herepublic:
MeshCam(ID3D11Device* device);HRESULT createResources();HRESULT releaseResources();HRESULT createSwapChainResources();HRESULT releaseSwapChainResources();void animate(double dt, double t);bool processMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);void render(ID3D11DeviceContext* context);
};}
#6.2
DxaMeshCam.hclass MeshCam :public Dxa::Base{// insert into code on #6.2ID3DX11Effect* effect;CFirstPersonCamera camera;Mesh* mesh;ID3D11InputLayout* inputLayout;
#6.3
DxaMeshCam.cppDxa::MeshCam::MeshCam(ID3D11Device* device)
:Dxa::Base(device){camera.SetViewParams( &D3DXVECTOR3(0, 3, -10), &D3DXVECTOR3(0, 3, 0) );
}
#6.4
DxaMeshCam.cppHRESULT Dxa::MeshCam::createResources() {ID3DBlob* compiledEffect = NULL;ID3DBlob* compilationErrors = NULL;HRESULT hr = D3DX11CompileFromFileW( L"fx/basic.fx", NULL, NULL,
NULL,"fx_5_0", 0, 0, NULL, &compiledEffect, &compilationErrors, NULL);
if(hr != S_OK) {if(compilationErrors != NULL)MessageBoxA( NULL, (LPSTR)compilationErrors->GetBufferPointer(),"Failed to create effect from file!", MB_OK);elseMessageBoxA( NULL, "File cound not be opened","Failed to create effect from file!",MB_OK);exit(-1);}
// insert next slides here return S_OK; }
#6.5
DxaMeshCam.cpp// insert after #6.5hr = D3DX11CreateEffectFromMemory(compiledEffect->GetBufferPointer(), compiledEffect->GetBufferSize(),0, device, &effect);
if(hr != S_OK){MessageBoxA( NULL, "CreateEffectFromMemory failed","Failed to create effect from file!", MB_OK);exit(-1);
}
#6.6
DxaMeshCam.cpp// insert after #6.6mesh = NULL;Mesh::createMeshFromFile("media/bigbunny.dgb", device, &mesh);
if(mesh == NULL){MessageBoxA( NULL, "Mesh could not be loaded.","Failed to create mesh from file!", MB_OK);exit(-1);
}
#6.7
DxaMeshCam.cpp// insert after #6.7D3DX11_PASS_DESC basicPassDesc;effect->GetTechniqueByName("basic")->GetPassByName("basic")->GetDesc(&basicPassDesc);
mesh->createInputLayout(device, &basicPassDesc, &inputLayout);
#6.8
DxaMeshCam.cppHRESULT Dxa::MeshCam::releaseResources()
{effect->Release();inputLayout->Release();delete mesh;return S_OK;
}
#6.9
DxaMeshCam.cppHRESULT Dxa::MeshCam::
createSwapChainResources(){camera.SetProjParams(1.58, (float)
backbufferSurfaceDesc.Width / backbufferSurfaceDesc.Height, 0.1, 1000 );
return S_OK;}
#6.10
DxaMeshCam.cppHRESULT Dxa::MeshCam::releaseSwapChainResources()
{ return S_OK;
}
#6.11
DxaMeshCam.cppvoid Dxa::MeshCam::animate(double dt, double t)
{camera.FrameMove(dt);
}bool Dxa::MeshCam::processMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{return camera.HandleMessages(hWnd, uMsg, wParam, lParam);
}
#6.12
DxaMeshCam.cppvoid Dxa::MeshCam::render(ID3D11DeviceContext* context)
{float clearColor[4] = { 0.3f, 0.2f, 0.9f, 0.0f };ID3D11RenderTargetView* defaultRtv = DXUTGetD3D11RenderTargetView();ID3D11DepthStencilView* defaultDsv = DXUTGetD3D11DepthStencilView();context->ClearRenderTargetView( defaultRtv, clearColor );context->ClearDepthStencilView( defaultDsv, D3D11_CLEAR_DEPTH, 1.0, 0 );// insert next slides here
}
#6.13
DxaMeshCam.cppD3DXMATRIX modelMatrix, modelMatrixInverse;
D3DXMatrixIdentity(&modelMatrix);D3DXMatrixInverse(&modelMatrixInverse, NULL, &modelMatrix);
D3DXMATRIX viewMatrix = *camera.GetViewMatrix();
D3DXMATRIX projMatrix = *camera.GetProjMatrix();
D3DXMATRIX modelViewProjMatrix = modelMatrix * viewMatrix * projMatrix;
#6.14
DxaMeshCam.cppcontext->IASetInputLayout(inputLayout);
effect->GetTechniqueByName("basic")->GetPassByName("basic")->Apply(0, context);
mesh->draw(context);
#6.16
Itt tartunk – mozgó kamerával
Textúrázás
Dxa::Textured
Új osztály: Dxa::Textured
• Dxa::MeshCam lemásolva• MeshCam -> Textured search&replace• basic.fx helyett textured.fx betöltése
fx/textured.fx#include technique11 basic
Texture2D kdTexture;
SamplerState linearSampler{Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap;};
#7.0
fx/textured.fxfloat4 psTextured(VsosTrafo input) : SV_Target{return abs(saturate(input.normal).y) * kdTexture.Sample(linearSampler, input.tex);
}
technique11 textured{pass textured{SetVertexShader ( CompileShader( vs_5_0, vsTrafo() ) );SetPixelShader( CompileShader( ps_5_0, psTextured() ) );}
}
#7.1
KickStart11.cpp#include "DxaTextured.h"
#8.0
KickStart11.cppnew//Dxa::MeshCam(pd3dDevice);Dxa::Textured(pd3dDevice);
#8.1
DxaTextured.hclass Textured :public Dxa::Base{ID3D11ShaderResourceView* kdTextureSrv;
#8.2
DxaTextured.cppHRESULT Dxa::Textured::createResources(){. . .
D3DX11CreateShaderResourceViewFromFile( device, L"Media/uvGrid.jpg", NULL,
NULL, &kdTextureSrv, NULL);
return S_OK;}
#8.3
DxaTextured.cppHRESULT Dxa::Textured::releaseResources()
{kdTextureSrv->Release();
#8.4
InputLayout
• átírhatnánk az input layoutot hogy a textured|textured pass-t alapján jöjjön létre– most a basic|basic alapján van– de a kettőben tökugyanaz a VS
DxaTextured.cppD3DX11_PASS_DESC basicPassDesc;effect->GetTechniqueByName("textured")->GetPassByName("textured")->GetDesc(&basicPassDesc);
mesh->createInputLayout(device, &basicPassDesc, &inputLayout);
#8.5
DxaTextured.cppeffect->GetVariableByName("kdTexture")->AsShaderResource()->SetResource(kdTextureSrv);
context->IASetInputLayout(inputLayout);
effect->GetTechniqueByName("textured")->GetPassByName("textured")->Apply(0, context);
mesh->draw(context);
#8.6
Kész – textúrázott nyúl
Environment mapping
Dxa::EnvMapped
Szokásos lépések
• DxaTextured -> DxaEnvMapped• KickStart.cpp-be include és példány létrehozás• textured.fx helyett envmapped.fx• textured|textured pass helyett– envmapped technique• background pass• envmapped pass
fx/envmapped.fx#include "textured.fx"
float3 eyePos;TextureCube envTexture;
float4 psEnvMapped(VsosTrafo input) : SV_Target{
float3 viewDir = normalize(input.worldPos - eyePos);float3 reflectionDir = reflect(viewDir, input.normal);return 0.5 * envTexture.Sample(linearSampler, reflectionDir) + 0.5 * kdTexture.Sample(linearSampler, input.tex);
}
technique11 envmapped{
pass envmapped{SetVertexShader ( CompileShader( vs_5_0, vsTrafo() ) );SetPixelShader( CompileShader( ps_5_0, psEnvMapped() ) );}
}
#9.0
DxaEnvMapped.hclass EnvMapped :public Dxa::Base{ID3D11ShaderResourceView* envTextureSrv;
#10.0
DxaEnvMapped.cpp// createResources
D3DX11CreateShaderResourceViewFromFile( device, L"Media/cloudyNoon.dds", NULL, NULL, &envTextureSrv, NULL);return S_OK;
}
// releaseResourcesenvTextureSrv->Release();
#10.1
DxaEnvMapped.cppeffect->GetVariableByName("eyePos")->AsVector()->SetFloatVector((float*)camera.GetEyePt());
effect->GetVariableByName("envTexture")->AsShaderResource()->SetResource(envTextureSrv);
effect->GetVariableByName("kdTexture")->AsShaderResource()->SetResource(kdTextureSrv);
context->IASetInputLayout(inputLayout);effect->GetTechniqueByName("envmapped")->GetPassByName("envmapped")->Apply(0, context);
mesh->draw(context);
#10.2
Env map tükröződés kész
Látsszon a környezet a háttérben
• full-viewport quad– új mesh– Mesh::createQuad
• minden pixel olyan színű amilyen irányban látszik– vsQuad– psBackground– envmapped|background pass
• backgroundInputLayout
fx/envmapped.fxstruct IaosQuad{float4 pos: POSITION;float2 tex: TEXCOORD0;
};
struct VsosQuad{float4 pos: SV_POSITION;float2 tex: TEXCOORD0;float3 viewDir: TEXCOORD1;
};
#11.0
fx/envmapped.fxfloat4x4 eyeViewProjMatrixInverse;
VsosQuad vsQuad(IaosQuad input){VsosQuad output = (VsosQuad)0;
output.pos = input.pos; float4 hWorldPosMinusEye = mul(input.pos, eyeViewProjMatrixInverse);
hWorldPosMinusEye /= hWorldPosMinusEye.w; output.viewDir = hWorldPosMinusEye.xyz;output.tex = input.tex;
return output;};
#11.1
fx/envmapped.fxtechnique11 envmapped{
pass envmapped{SetVertexShader ( CompileShader( vs_5_0, vsTrafo() ) );SetPixelShader( CompileShader( ps_5_0, psEnvMapped() ) );}pass background{SetVertexShader ( CompileShader( vs_5_0, vsQuad() ) );SetPixelShader( CompileShader( ps_5_0, psBackground() ) );}
}
#11.1
DxaEnvMapped.hclass EnvMapped :public Dxa::Base{Mesh* backgroundQuad;ID3D11InputLayout* backgroundInputLayout;
#12.3
DxaEnvMapped.cpp//createResourcesMesh::createQuad(device, &backgroundQuad);
D3DX11_PASS_DESC backgroundPassDesc;effect->GetTechniqueByName("envmapped")->GetPassByName("background")->GetDesc(&backgroundPassDesc);
backgroundQuad->createInputLayout(device, &backgroundPassDesc, &backgroundInputLayout);
#12.4
DxaEnvMapped.cppHRESULT Dxa::EnvMapped::releaseResources()
{delete backgroundQuad;backgroundInputLayout->Release();
#12.5
DxaEnvMapped.cpp// renderD3DXMATRIX eyeMatrix;D3DXMatrixTranslation(&eyeMatrix, camera.GetEyePt()->x,
camera.GetEyePt()->y, camera.GetEyePt()->z);D3DXMATRIX eyeViewProjMatrix = eyeMatrix * viewMatrix *
projMatrix;D3DXMATRIX eyeViewProjMatrixInverse;D3DXMatrixInverse(
&eyeViewProjMatrixInverse, NULL, &eyeViewProjMatrix);effect->
GetVariableByName("eyeViewProjMatrixInverse")->AsMatrix()->SetMatrix((float*)&eyeViewProjMatrixInverse);
#12.6
DxaEnvMapped.cpp//rendercontext->
IASetInputLayout(backgroundInputLayout);
effect->GetTechniqueByName("envmapped")->GetPassByName("background")->Apply(0, context);
backgroundQuad->draw(context);
#12.7
Environment map kész
Folyt. köv.
• GUI• Asset import• Instancing• Render to texture• Geometry shader• Stream output• Tessellator