Skip to content

Instantly share code, notes, and snippets.

@KamilChmielewski
Created January 7, 2018 16:36
Show Gist options
  • Save KamilChmielewski/0cb5b856cc890f544c8ba5c4ea2edd4c to your computer and use it in GitHub Desktop.
Save KamilChmielewski/0cb5b856cc890f544c8ba5c4ea2edd4c to your computer and use it in GitHub Desktop.
as
#include "Application.h"
#include <string>
#include <iostream>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
AllocConsole();
freopen("CONOUT$", "w", stdout);
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Application::Application()
{
_hInst = nullptr;
_hWnd = nullptr;
_driverType = D3D_DRIVER_TYPE_NULL;
_featureLevel = D3D_FEATURE_LEVEL_11_0;
_pd3dDevice = nullptr;
_pImmediateContext = nullptr;
_pSwapChain = nullptr;
_pRenderTargetView = nullptr;
_pVertexShader = nullptr;
_pPixelShader = nullptr;
_pVertexLayout = nullptr;
_pVertexBuffer = nullptr;
_pIndexBuffer = nullptr;
_pConstantBuffer = nullptr;
}
Application::~Application()
{
Cleanup();
}
HRESULT Application::Initialise(HINSTANCE hInstance, int nCmdShow)
{
if (FAILED(InitWindow(hInstance, nCmdShow)))
{
return E_FAIL;
}
RECT rc;
GetClientRect(_hWnd, &rc);
_WindowWidth = rc.right - rc.left;
_WindowHeight = rc.bottom - rc.top;
if (FAILED(InitDevice()))
{
Cleanup();
return E_FAIL;
}
// Initialize the world matrix
XMStoreFloat4x4(&_world, XMMatrixIdentity());
//object 2
XMStoreFloat4x4(&_world2, XMMatrixIdentity());
_gameObjectManager = new GameObjectManager(_pd3dDevice, _pVertexShader, _pPixelShader);
testObject = new GameObject2(XMFLOAT3(0.0f, 1.0f, 25.0f),_pd3dDevice, _pVertexShader, _pPixelShader, _pImmediateContext);
testObject->CreateAndSetSamplerState();
testObject->CreateAndSetTextureWIC();
_camera2.SetPosition(XMFLOAT3(0.0f, 0.0f, -3.0f));
// Initialize the view matrix
// XMVECTOR Eye = XMVectorSet(0.0f, 0.0f, -3.0f, 0.0f);
// XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
// XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
// XMStoreFloat4x4(&_view, XMMatrixLookAtLH(Eye, At, Up));
// Initialize the projection matrix
// XMStoreFloat4x4(&_projection, XMMatrixPerspectiveFovLH(70.0f, _WindowWidth / (FLOAT)_WindowHeight, 0.01f, 100.0f));
camera = new Camera(_WindowWidth, _WindowHeight);
DL.Ambient = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
DL.Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
DL.Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
DL.Direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f);
Mtrl.Ambient = XMFLOAT4(1.0f, 0.2f, 0.2f, 1.0f);
Mtrl.Diffuse = XMFLOAT4(1.0f, 0.2f, 0.2f, 1.0f);
Mtrl.Specular = XMFLOAT4(0.8f, 0.8f, 0.8f, 16.0f);
// mEyePosW = XMFLOAT3(0.0f, 0.0f, 0.0f);
return S_OK;
}
HRESULT Application::InitShadersAndInputLayout()
{
HRESULT hr;
// Compile the vertex shader
ID3DBlob* pVSBlob = nullptr;
hr = CompileShaderFromFile(L"DX11 Framework.fx", "VS", "vs_4_0", &pVSBlob);
if (FAILED(hr))
{
MessageBox(nullptr,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
return hr;
}
// Create the vertex shader
hr = _pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &_pVertexShader);
if (FAILED(hr))
{
pVSBlob->Release();
return hr;
}
// Compile the pixel shader
ID3DBlob* pPSBlob = nullptr;
hr = CompileShaderFromFile(L"DX11 Framework.fx", "PS", "ps_4_0", &pPSBlob);
if (FAILED(hr))
{
MessageBox(nullptr,
L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK);
return hr;
}
// Create the pixel shader
hr = _pd3dDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &_pPixelShader);
pPSBlob->Release();
if (FAILED(hr))
return hr;
// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{ //This data 0,0 hows where the vertex starts
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
//The data 0, 12 shows from which point to draw the colours
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
UINT numElements = ARRAYSIZE(layout);
// Create the input layout
hr = _pd3dDevice->CreateInputLayout(layout, numElements, pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &_pVertexLayout);
pVSBlob->Release();
if (FAILED(hr))
return hr;
// Set the input layout
_pImmediateContext->IASetInputLayout(_pVertexLayout);
return hr;
}
HRESULT Application::InitVertexBuffer()
{
HRESULT hr;
return S_OK;
}
HRESULT Application::InitIndexBuffer()
{
HRESULT hr;
return S_OK;
}
void Application::OnMouseMove(WPARAM btnState, int x, int y)
{
if ((btnState & MK_LBUTTON) != 0)
{
// Make each pixel correspond to a quarter of a degree.
float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));
_camera2.Pitch(dy);
_camera2.RotateY(dx);
}
mLastMousePos.x = x;
mLastMousePos.y = y;
}
HRESULT Application::InitWindow(HINSTANCE hInstance, int nCmdShow)
{
// Register class
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TUTORIAL1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_TUTORIAL1);
if (!RegisterClassEx(&wcex))
return E_FAIL;
// Create window
_hInst = hInstance;
RECT rc = { 0, 0, 800, 800 };
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
_hWnd = CreateWindow(L"TutorialWindowClass", L"DX11 Framework", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, hInstance,
nullptr);
if (!_hWnd)
return E_FAIL;
ShowWindow(_hWnd, nCmdShow);
return S_OK;
}
HRESULT Application::CompileShaderFromFile(WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
{
HRESULT hr = S_OK;
DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined(DEBUG) || defined(_DEBUG)
// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
// Setting this flag improves the shader debugging experience, but still allows
// the shaders to be optimized and to run exactly the way they will run in
// the release configuration of this program.
dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
ID3DBlob* pErrorBlob;
hr = D3DCompileFromFile(szFileName, nullptr, nullptr, szEntryPoint, szShaderModel,
dwShaderFlags, 0, ppBlobOut, &pErrorBlob);
if (FAILED(hr))
{
if (pErrorBlob != nullptr)
OutputDebugStringA((char*)pErrorBlob->GetBufferPointer());
if (pErrorBlob) pErrorBlob->Release();
return hr;
}
if (pErrorBlob) pErrorBlob->Release();
return S_OK;
}
HRESULT Application::InitDevice()
{
HRESULT hr = S_OK;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = _WindowWidth;
sd.BufferDesc.Height = _WindowHeight;
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++)
{
_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain(nullptr, _driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pImmediateContext);
if (SUCCEEDED(hr))
break;
}
if (FAILED(hr))
return hr;
//Create DepthBuffer
D3D11_TEXTURE2D_DESC depthStencilDesc;
depthStencilDesc.Width = _WindowWidth;
depthStencilDesc.Height = _WindowHeight;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
_pd3dDevice->CreateTexture2D(&depthStencilDesc, nullptr, &_depthStencilBuffer);
_pd3dDevice->CreateDepthStencilView(_depthStencilBuffer, nullptr, &_depthStencilView);
// Create a render target view
ID3D11Texture2D* pBackBuffer = nullptr;
hr = _pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
if (FAILED(hr))
return hr;
hr = _pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &_pRenderTargetView);
pBackBuffer->Release();
if (FAILED(hr))
return hr;
_pImmediateContext->OMSetRenderTargets(1, &_pRenderTargetView, _depthStencilView);
// Setup the viewport
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)_WindowWidth;
vp.Height = (FLOAT)_WindowHeight;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
_pImmediateContext->RSSetViewports(1, &vp);
InitShadersAndInputLayout();
InitVertexBuffer();
InitIndexBuffer();
// Set index buffer
// Set primitive topology
_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Create the constant buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBuffer);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = _pd3dDevice->CreateBuffer(&bd, nullptr, &_pConstantBuffer);
//Rasterise
D3D11_RASTERIZER_DESC wfdesc;
ZeroMemory(&wfdesc, sizeof(D3D11_RASTERIZER_DESC));
wfdesc.FillMode = D3D11_FILL_WIREFRAME;
wfdesc.CullMode = D3D11_CULL_NONE;
wfdesc.FrontCounterClockwise = false;
hr = _pd3dDevice->CreateRasterizerState(&wfdesc, &_wireFrame);
bool_Key_P = false;
wireframe_State = false;
if (FAILED(hr))
return hr;
return S_OK;
}
void Application::Cleanup()
{
if (_pImmediateContext) _pImmediateContext->ClearState();
if (_pConstantBuffer) _pConstantBuffer->Release();
if (_pVertexBuffer) _pVertexBuffer->Release();
if (_pIndexBuffer) _pIndexBuffer->Release();
if (_pVertexLayout) _pVertexLayout->Release();
if (_pVertexShader) _pVertexShader->Release();
if (_pPixelShader) _pPixelShader->Release();
if (_pRenderTargetView) _pRenderTargetView->Release();
if (_pSwapChain) _pSwapChain->Release();
if (_pImmediateContext) _pImmediateContext->Release();
if (_pd3dDevice) _pd3dDevice->Release();
if (_wireFrame) _wireFrame->Release();
//depth and stencil buffer
if (_depthStencilView) _depthStencilView->Release();
if (_depthStencilBuffer) _depthStencilBuffer->Release();
}
void Application::Update()
{
// Update our time
static float t = 0.0f;
if (_driverType == D3D_DRIVER_TYPE_REFERENCE)
{
t += (float)XM_PI * 0.0125f;
}
else
{
static DWORD dwTimeStart = 0;
DWORD dwTimeCur = GetTickCount();
if (dwTimeStart == 0)
dwTimeStart = dwTimeCur;
t = (dwTimeCur - dwTimeStart) / 1000.0f;
}
//camera->Update(t);
testObject->Update(t);
if ((GetKeyState('P') & 0x8000) && !bool_Key_P)
{
bool_Key_P = true;
wireframe_State = !wireframe_State;
}
else if (!(GetKeyState('P') & 0x8000) && bool_Key_P)
{
bool_Key_P = false;
}
if (wireframe_State == false)
{
_pImmediateContext->RSSetState(nullptr);
}
else if (wireframe_State == true)
{
_pImmediateContext->RSSetState(_wireFrame);
}
/*
if ((btnState & MK_LBUTTON) != 0)
{
// Make each pixel correspond to a quarter of a degree.
float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));
_camera2.Pitch(dy);
_camera2.RotateY(dx);
}
mLastMousePos.x = x;
mLastMousePos.y = y;
*/
bool initCursor = false;
if ((GetKeyState(VK_SHIFT) & 0X8000))
{
if (!initCursor)
{
SetCursorPos(_WindowWidth / 2, _WindowHeight / 2);
}
GetCursorPos(&mLastMousePos);
float dx = XMConvertToRadians(0.000025f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.000025f*static_cast<float>(y - mLastMousePos.y));
SetCursorPos(_WindowWidth / 2, _WindowHeight / 2);
_camera2.Pitch(dy);
_camera2.RotateY(dx);
}
else if (!(GetKeyState(VK_SHIFT) & 0x8000))
{
initCursor = false;
}
if ((GetKeyState(VK_LCONTROL) & 0x8000))
{
// Make each pixel correspond to a quarter of a degree.
GetCursorPos(&mLastMousePos);
float dx = XMConvertToRadians(0.00000025f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.00000025f*static_cast<float>(y - mLastMousePos.y));
SetCursorPos(mLastMousePos.x, mLastMousePos.y);
_camera2.Pitch(dy);
_camera2.RotateY(dx);
_camera2.UpdateViewMatrix();
}
mLastMousePos.x = x;
mLastMousePos.y = y;
// WPARAM btnState;
// POINT poisition;
// if ((MK_LBUTTON) != 0)
// {
// // Make each pixel correspond to a quarter of a degree.
// float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
// float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));
// _camera2.Pitch(dy);
// _camera2.RotateY(dx);
// }
// mLastMousePos.x = x;
// mLastMousePos.y = y;
//Camera movement
if (GetAsyncKeyState('W') & 0x8000)
_camera2.Walk(0.003f*t);
if (GetAsyncKeyState('S') & 0x8000)
_camera2.Walk(-0.003f*t);
if (GetAsyncKeyState('A') & 0x8000)
_camera2.Strafe(-0.003f*t);
if (GetAsyncKeyState('D') & 0x8000)
_camera2.Strafe(0.003f*t);
_camera2.UpdateViewMatrix();
// mLastMousePos.x = x;
// mLastMousePos.y = y;
//reference
// XMStoreFloat4x4(&_world, (XMMatrixRotationX(t) * XMMatrixTranslation(0.0f, 1.0f, 10.0f)));
}
void Application::Draw()
{
//
// Clear the back buffer
//
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alpha
_pImmediateContext->ClearRenderTargetView(_pRenderTargetView, ClearColor);
_pImmediateContext->ClearDepthStencilView(_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// XMMATRIX world = XMLoadFloat4x4(&_world);
// XMMATRIX view = XMLoadFloat4x4(&_view);
// XMMATRIX projection = XMLoadFloat4x4(&_projection);
XMMATRIX view = _camera2.GetView();
XMMATRIX projection = _camera2.GetProj();
//
// Update variables
//
ConstantBuffer cb;
// cb.mWorld = XMMatrixTranspose(world);
cb.mView = XMMatrixTranspose(view);
cb.mProjection = XMMatrixTranspose(projection);
// camera->Draw(cb);
//light
//Directional Light
cb.DL.Ambient = DL.Ambient;
cb.DL.Diffuse = DL.Diffuse;
cb.DL.Direction = DL.Direction;
cb.DL.Specular = DL.Specular;
//Material
cb.Mtrl.Ambient = Mtrl.Ambient;
cb.Mtrl.Diffuse = Mtrl.Diffuse;
cb.Mtrl.Specular = Mtrl.Specular;
cb.gEyePosW = _camera2.GetPosition3f();
_pImmediateContext->UpdateSubresource(_pConstantBuffer, 0, nullptr, &cb, 0, 0);
//
// Renders a triangle
//
_pImmediateContext->VSSetShader(_pVertexShader, nullptr, 0);
_pImmediateContext->VSSetConstantBuffers(0, 1, &_pConstantBuffer);
_pImmediateContext->PSSetConstantBuffers(0, 1, &_pConstantBuffer);
_pImmediateContext->PSSetShader(_pPixelShader, nullptr, 0);
// world = XMLoadFloat4x4(&_world2);
// cb.mWorld = XMMatrixTranspose(world);
//RasteriseObject2
_gameObjectManager->DrawObjects(_pConstantBuffer, _pImmediateContext, cb);
//testObject->Draw(_pConstantBuffer, _pImmediateContext, cb);
//
// Present our back buffer to our front buffer
//
_pSwapChain->Present(0, 0);
}
#pragma once
#include <windows.h>
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <d3d11_1.h>
#include <d3dcompiler.h>
#include <directxmath.h>
#include <directxcolors.h>
#include "resource.h"
#include "GameObjectManager.h"
#include "GameObject2.h"
#include "Camera.h"
#include "Camera2.h"
#include "Struct.h"
#include <wincon.h>
using namespace DirectX;
// this need to be changed with the input layout
class Application
{
private:
//Microsoft functions
POINT mLastMousePos;
bool bool_Key_P;
bool wireframe_State;
HINSTANCE _hInst;
HWND _hWnd;
D3D_DRIVER_TYPE _driverType;
D3D_FEATURE_LEVEL _featureLevel;
ID3D11Device* _pd3dDevice;
ID3D11DeviceContext* _pImmediateContext;
IDXGISwapChain* _pSwapChain;
ID3D11RenderTargetView* _pRenderTargetView;
ID3D11VertexShader* _pVertexShader;
ID3D11PixelShader* _pPixelShader;
ID3D11InputLayout* _pVertexLayout;
//Depth/Stencil Buffer
ID3D11DepthStencilView* _depthStencilView;
ID3D11Texture2D* _depthStencilBuffer;
ID3D11Buffer* _pVertexBuffer;
ID3D11Buffer* _pIndexBuffer;
ID3D11Buffer* _pConstantBuffer;
XMFLOAT4X4 _world;
XMFLOAT4X4 _world2;
XMFLOAT4X4 _view;
XMFLOAT4X4 _projection;
//RenderStates
ID3D11RasterizerState* _wireFrame;
//Camera
Camera* camera;
Camera2 _camera2;
//lighting
DirectionalLight DL;
MaterialStruct Mtrl;
XMFLOAT3 mEyePosW;
//ObjTest* objObject;
float x = 0;
float y = 0;
float z = 0;
GameObjectManager* _gameObjectManager;
GameObject2* testObject;
//List of all the render Items that I will want to use
// std::vector<std::unique_ptr<GameObject2>> mAllRObjects;
private:
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow);
HRESULT InitDevice();
void Cleanup();
HRESULT CompileShaderFromFile(WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut);
HRESULT InitShadersAndInputLayout();
HRESULT InitVertexBuffer();
HRESULT InitIndexBuffer();
void OnMouseMove(WPARAM btnState, int x, int y);
UINT _WindowHeight;
UINT _WindowWidth;
//cube class
//Cube* cube;
public:
Application();
~Application();
HRESULT Initialise(HINSTANCE hInstance, int nCmdShow);
void Update();
void Draw();
};
#pragma once
#pragma once
#include <DirectXMath.h>
using namespace DirectX;
//IdentityMatrix
static XMFLOAT4X4 Identity4x4()
{
static DirectX::XMFLOAT4X4 I(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
return I;
}
class Camera2
{
private:
XMFLOAT3 _position = { 0.0f, 0.0f, 0.0f };
XMFLOAT3 _right = { 1.0f, 0.0f, 0.0f };
XMFLOAT3 _up = { 0.0f, 0.1f, 0.0f };
XMFLOAT3 _look = { 0.0f, 0.0f, 1.0f };
// Cache frustum properties
float _nearZ = 0.0f;
float _farZ = 0.0f;
float _aspect = 0.0f;
float _fovY = 0.0f;
float _nearWindowHeight = 0.0f;
float _farWindowHeight = 0.0f;
bool _viewDirty = true;
//View/Proj matrices.
XMFLOAT4X4 _view = Identity4x4();
XMFLOAT4X4 _proj = Identity4x4();
public:
Camera2();
~Camera2();
void SetPosition(XMFLOAT3& _position);
void SetLens(float fovY, float aspect, float zn, float zf);
XMFLOAT3 GetPosition3f();
XMMATRIX GetView()const;
XMMATRIX GetProj()const;
//Strafe/Walk
void Strafe(float d); //D for distance
void Walk(float d);
//Rotate the Camera
void Pitch(float angle);
void RotateY(float angle);
//After modifiying the cameras position and orientation, call to rebuild the viewMatrix
void UpdateViewMatrix();
};
#include "Camera2.h"
Camera2::Camera2()
{
SetLens(0.25*XM_PI, 1.0f, 1.0f, 1000.0f);
}
Camera2::~Camera2()
{
}
XMFLOAT3 Camera2::GetPosition3f()
{
return _position;
}
void Camera2::SetPosition(XMFLOAT3 & _position)
{
this->_position = _position;
_viewDirty = true;
}
void Camera2::SetLens(float fovY, float aspect, float zn, float zf)
{
//Cache properties
_fovY = fovY;
_aspect = aspect;
_nearZ = zn;
_farZ = zf;
_nearWindowHeight = 2.0f * _nearZ * tanf(0.5*_fovY);
_farWindowHeight = 2.0f *_farZ * tanf(0.5 * _fovY);
XMMATRIX P = XMMatrixPerspectiveFovLH(_fovY, _aspect, _nearZ, _farZ);
XMStoreFloat4x4(&_proj, P);
}
XMMATRIX Camera2::GetView() const
{
assert(!_viewDirty);
return XMLoadFloat4x4(&_view);
}
XMMATRIX Camera2::GetProj() const
{
return XMLoadFloat4x4(&_proj);
}
void Camera2::Strafe(float d)
{
XMVECTOR s = XMVectorReplicate(d);
XMVECTOR r = XMLoadFloat3(&_right);
XMVECTOR p = XMLoadFloat3(&_position);
XMStoreFloat3(&_position, XMVectorMultiplyAdd(s, r, p));
_viewDirty = true;
}
void Camera2::Walk(float d)
{
XMVECTOR s = XMVectorReplicate(d);
XMVECTOR l = XMLoadFloat3(&_look);
XMVECTOR p = XMLoadFloat3(&_position);
XMStoreFloat3(&_position, XMVectorMultiplyAdd(s, l, p));
_viewDirty = true;
}
void Camera2::Pitch(float angle)
{
XMMATRIX R = XMMatrixRotationAxis(XMLoadFloat3(&_right), angle);
XMStoreFloat3(&_up, XMVector3TransformNormal(XMLoadFloat3(&_up), R));
XMStoreFloat3(&_look, XMVector3TransformNormal(XMLoadFloat3(&_look), R));
_viewDirty = true;
}
void Camera2::RotateY(float angle)
{
XMMATRIX R = XMMatrixRotationY(angle);
XMStoreFloat3(&_right, XMVector3TransformNormal(XMLoadFloat3(&_right), R));
XMStoreFloat3(&_up, XMVector3TransformNormal(XMLoadFloat3(&_up), R));
XMStoreFloat3(&_look, XMVector3TransformNormal(XMLoadFloat3(&_look), R));
_viewDirty = true;
}
void Camera2::UpdateViewMatrix()
{
if (_viewDirty)
{
XMVECTOR R = XMLoadFloat3(&_right);
XMVECTOR U = XMLoadFloat3(&_up);
XMVECTOR L = XMLoadFloat3(&_look);
XMVECTOR P = XMLoadFloat3(&_position);
// Keep camera's axes orthogonal to each other and of unit length.
L = XMVector3Normalize(L);
U = XMVector3Normalize(XMVector3Cross(L, R));
// U, L already ortho-normal, so no need to normalize cross product.
R = XMVector3Cross(U, L);
// Fill in the view matrix entries.
float x = -XMVectorGetX(XMVector3Dot(P, R));
float y = -XMVectorGetX(XMVector3Dot(P, U));
float z = -XMVectorGetX(XMVector3Dot(P, L));
XMStoreFloat3(&_right, R);
XMStoreFloat3(&_up, U);
XMStoreFloat3(&_look, L);
_view(0, 0) = _right.x;
_view(1, 0) = _right.y;
_view(2, 0) = _right.z;
_view(3, 0) = x;
_view(0, 1) = _up.x;
_view(1, 1) = _up.y;
_view(2, 1) = _up.z;
_view(3, 1) = y;
_view(0, 2) = _look.x;
_view(1, 2) = _look.y;
_view(2, 2) = _look.z;
_view(3, 2) = z;
_view(0, 3) = 0.0f;
_view(1, 3) = 0.0f;
_view(2, 3) = 0.0f;
_view(3, 3) = 1.0f;
_viewDirty = false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment