Codice:
#include "Application.h"
/* Costruttore */
Application::Application()
{
cam = new Camera();
}
/* Distruttore */
Application::~Application()
{
if(pDevice){ pDevice->ClearState(); }
if(pSwapChain){ pSwapChain->Release(); }
if(pRenderTargetView){ pRenderTargetView->Release(); }
if(pDepthStencilView){ pDepthStencilView->Release(); }
if(pVertexBuffer){ pVertexBuffer->Release(); }
if(pVertexLayout){ pVertexLayout->Release(); }
if(pEffect){ pEffect->Release(); }
if(pDevice){ pDevice->Release(); }
if(cam){ delete cam; }
}
/* Gestione dei messaggi di windows */
LRESULT CALLBACK Application::WndProc( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
{
switch(message){
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_UP:
cam->MoveUp();
break;
case VK_DOWN:
cam->MoveDown();
break;
case VK_LEFT:
cam->MoveLeft();
break;
case VK_RIGHT:
cam->MoveRight();
break;
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
break;
}
return DefWindowProc(hWnd,message,wParam,lParam);
}
/* Crea la finestra Win32 */
bool Application::CreateD3DWindow(int width, int height)
{
this->width = width;
this->height = height;
// Create A Window Class Structure
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(wc));
wc.cbSize = sizeof(wc);
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "GPORG";
wc.style = CS_HREDRAW | CS_VREDRAW;
// Register Window Class
RegisterClassEx(&wc);
// Create Window
hWnd = CreateWindowEx(0,
"GPORG", "GameProgrammer.org Direct3D 10 Tutorial",
WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, width, height,
NULL,NULL,wc.hInstance,0);
return true;
}
/* Inizializza le Directx10 */
bool Application::Initialize()
{
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory( &swapChainDesc, sizeof(swapChainDesc) );
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Windowed = TRUE;
if( FAILED( D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL,
0, D3D10_SDK_VERSION, &swapChainDesc, &pSwapChain, &pDevice ) ) )
{
if( FAILED( D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL,
0, D3D10_SDK_VERSION, &swapChainDesc, &pSwapChain, &pDevice ) ) )
{
MBError("Failed to create device and swap chain.");
return false;
}
}
if(InitRenderTargetView() == false){ return false; }
if(InitDepthStencilView(width, height) == false){ return false; }
pDevice->OMSetRenderTargets( 1, &pRenderTargetView, pDepthStencilView );
D3D10_VIEWPORT vp = {0, 0, width, height, 0, 1};
pDevice->RSSetViewports( 1, &vp );
if(InitEffect() == false){ return false; }
if(InitVertexBuffer() == false){ return false; }
//Setta il Vertex Buffer
UINT stride = sizeof(COLORED_VERTEX);
UINT offset = 0;
pDevice->IASetVertexBuffers(0, 1, &pVertexBuffer, &stride, &offset);
//Setta la Topology delle primitive
pDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
cam->Init(pEffect);
return true;
}
/* Inizializza l'effetto [shader] */
bool Application::InitEffect()
{
//Crea lo Shader (Effect)
HRESULT res;
ID3D10Blob* error;
D3DX10CreateEffectFromFile("./shader.fx", NULL, NULL, "fx_4_0", D3D10_SHADER_ENABLE_STRICTNESS,
0, pDevice, NULL, NULL, &pEffect, &error, &res);
if(FAILED(res))
{
MBError((char*)error->GetBufferPointer());
return false;
}
//Ottieni la tecnica
pTechnique = pEffect->GetTechniqueByName("Render");
return true;
}
/* Crea il Vertex Buffer */
bool Application::InitVertexBuffer()
{
//Definisci l'InputLayout (Rimpiazzamento del VertexDeclaration per D3D9)
D3D10_INPUT_ELEMENT_DESC elementDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = sizeof(elementDesc) / sizeof(elementDesc[0]);
//Crea l'inputLayout
D3D10_PASS_DESC PassDesc;
pTechnique->GetPassByIndex(0)->GetDesc(&PassDesc);
if(FAILED(pDevice->CreateInputLayout(elementDesc, numElements, PassDesc.pIAInputSignature,
PassDesc.IAInputSignatureSize, &pVertexLayout)))
{
MBError("Errore nella creazione dell Vertex Layout");
return false;
}
//Setta l'Input Layout
pDevice->IASetInputLayout(pVertexLayout);
//Crea il Vertex Buffer
COLORED_VERTEX pVertices[4];
pVertices[0].Position = D3DXVECTOR3( -1.0f, -1.0f, 0.0f); //L - B
pVertices[0].Color = 0xffff0000; //Red
pVertices[1].Position = D3DXVECTOR3( -1.0f, 1.0f, 0.0f); //L - T
pVertices[1].Color = 0xff00ff00; //Green
pVertices[2].Position = D3DXVECTOR3( 1.0f, -1.0f, 0.0f); //R - B
pVertices[2].Color = 0xff0000ff; //Blue
pVertices[3].Position = D3DXVECTOR3( 1.0f, 1.0f, 0.0f); //R - T
pVertices[3].Color = 0xffffffff; //White
//Crea il Descrittore del Buffer
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = sizeof(COLORED_VERTEX) * 4;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitData;
InitData.pSysMem = &pVertices;
//Finalmente creiamo il Vertex Buffer
if(FAILED(pDevice->CreateBuffer(&bd, &InitData, &pVertexBuffer)))
{
MBError("Impossibile creare il Vertex Buffer");
return false;
}
return true;
}
/* Inizializza il Render Target */
bool Application::InitRenderTargetView()
{
ID3D10Texture2D *pBackBuffer;
if( FAILED( pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), (LPVOID*)&pBackBuffer ) ) )
{
MBError("Failed to create back buffer.");
return false;
}
if(FAILED( pDevice->CreateRenderTargetView( pBackBuffer, NULL, &pRenderTargetView )))
{
MBError("Failed to create render target view.");
return false;
}
pBackBuffer->Release();
return true;
}
/* Inizializza il Depth Buffer */
bool Application::InitDepthStencilView(int w, int h)
{
D3D10_TEXTURE2D_DESC descDepth;
descDepth.Width = w;
descDepth.Height = h;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D32_FLOAT;
descDepth.SampleDesc.Count = 1;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D10_USAGE_DEFAULT;
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
ID3D10Texture2D* depthBuffer;
if(FAILED(pDevice->CreateTexture2D(&descDepth, NULL, &depthBuffer)))
{
MBError("Failed to create the depth Buffer");
return false;
}
D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;
descDSV.Format = descDepth.Format;
descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
if(FAILED(pDevice->CreateDepthStencilView(depthBuffer, &descDSV, &pDepthStencilView)))
{
MBError("Failed to create Depth Stencil View");
return false;
}
depthBuffer->Release();
return true;
}
/* Renderizza a schermo */
void Application::Render(float deltaTime)
{
cam->Update(deltaTime);
pDevice->ClearRenderTargetView( pRenderTargetView, D3DXVECTOR4(0.2f, 0.2f, 0.5f, 1) );
pDevice->ClearDepthStencilView( pDepthStencilView, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, 1.0f, 0);
//Renderizza il Quadrato
D3D10_TECHNIQUE_DESC techDesc;
pTechnique->GetDesc(&techDesc);
for(UINT p = 0; p < techDesc.Passes; ++p)
{
pTechnique->GetPassByIndex(p)->Apply(0);
pDevice->Draw(4, 0);
}
pSwapChain->Present( 0, 0 );
}
/* Loop principale */
void Application::MainLoop()
{
MSG msg;
long prevTime = GetTickCount(), curTime = GetTickCount();
while(true)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message==WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else{
Render((curTime-prevTime)/1000.f);
prevTime = curTime;
curTime = GetTickCount();
}
}
}
come posso risolvere?