Skip to content

Instantly share code, notes, and snippets.

@KamilChmielewski
Created February 8, 2018 11:00
Show Gist options
  • Save KamilChmielewski/2cefce2312830d7b28f701b96c6177de to your computer and use it in GitHub Desktop.
Save KamilChmielewski/2cefce2312830d7b28f701b96c6177de to your computer and use it in GitHub Desktop.
Year 2 First Semester
#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);
_arenaCageModel = new Model(_pd3dDevice);
_arenaCageModel->LoadModel("OBJ'S/cage.obj");
_arenaCage = new GameObject(XMFLOAT3(0.0f, 0.0f, 0.0f), _arenaCageModel, _pd3dDevice, _pVertexShader, _pPixelShader);
_arenaCage->CreateAndSetSamplerState();
_arenaCage->CreateAndSetTextureDDS(L"OBJ'S/WireFence.dds");
_camera2.SetPosition(XMFLOAT3(0.0f, 0.0f, -3.0f));
//_cameraTest.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);
_cameraTest = new CameraTest(_WindowWidth, _WindowHeight, Eye, At, Up);
// XMStoreFloat4x4(&_cameraTest.Get4X4View(), XMMatrixLookAtLH(Eye, At, Up));
// Initialize the projection matrix
// XMStoreFloat4x4(&_cameraTest.Get4X4Proj(), XMMatrixPerspectiveFovLH(70.0f, _WindowWidth / (FLOAT)_WindowHeight, 0.01f, 100.0f));
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;
}
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, 1024, 768 };
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);
D3D11_BUFFER_DESC perFrame;
ZeroMemory(&perFrame, sizeof(perFrame));
perFrame.Usage = D3D11_USAGE_DEFAULT;
perFrame.ByteWidth = sizeof(cbPerFrame);
perFrame.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
perFrame.CPUAccessFlags = 0;
hr = _pd3dDevice->CreateBuffer(&perFrame, nullptr, &_pfogBuffer);
//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);
D3D11_RASTERIZER_DESC rastDesc;
ZeroMemory(&rastDesc, sizeof(D3D11_RASTERIZER_DESC));
rastDesc.FillMode = D3D11_FILL_SOLID;
rastDesc.CullMode = D3D11_CULL_NONE;
hr = _pd3dDevice->CreateRasterizerState(&rastDesc, &_noCull);
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 (_pfogBuffer) _pfogBuffer->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();
if (_noCull) _noCull->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);
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);
}
//bool initCursor = false;
//
//if ((GetKeyState(VK_LCONTROL) & 0x8000))
// {
//// Make each pixel correspond to a quarter of a degree.
//GetCursorPos(&mLastMousePos);
//SetCursorPos(_WindowWidth/2, _WindowHeight/2);
//horizontalAngle += mouseSpeed * float(1024 / 2 - mLastMousePos.x);
//verticalAngle -= mouseSpeed * float(768 / 2 - mLastMousePos.y);
//
//_camera2.Pitch(horizontalAngle);
//_camera2.RotateY(verticalAngle);
//}
//else if (!(GetKeyState(VK_SHIFT) & 0x8000))
//{
// initCursor = false;
//}
//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();
_cameraTest->UpdateMatrix(t);
}
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);
cbPerFrame cbPF;
cbPF.gFogStart = 15.0f;
cbPF.gFogRange = 175.0f;
cbPF.gFogColor = { 1.0f, 0.0f, 0.0f, 1.0f };
_pImmediateContext->VSSetConstantBuffers(1, 1, &_pfogBuffer);
_pImmediateContext->PSSetConstantBuffers(1, 1, &_pfogBuffer);
//XMMATRIX view = _camera2.GetView();
//XMMATRIX projection = _camera2.GetProj();
XMMATRIX view = _cameraTest->GetView();
XMMATRIX projection = _cameraTest->GetProj();
//
// Update variables
//
ConstantBuffer cb;
// cb.mWorld = XMMatrixTranspose(world);
cb.mView = XMMatrixTranspose(view);
cb.mProjection = XMMatrixTranspose(projection);
//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(_pfogBuffer, 0, nullptr, &cbPF, 0, 0);
_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);
//RasteriseObject2
_gameObjectManager->DrawObjects(_pConstantBuffer, _pImmediateContext, cb);
_pImmediateContext->RSSetState(_noCull);
_arenaCage->Draw(_pConstantBuffer, _pImmediateContext, cb, XMMatrixIdentity());
//_pImmediateContext->UpdateSubresource(_pfogBuffer, 1, nullptr, &cbPF, 0, 0);
//
// 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 "Camera2.h"
#include "CameraTest.h"
#include "Model.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;
ID3D11Buffer* _pfogBuffer;
XMFLOAT4X4 _world;
XMFLOAT4X4 _world2;
XMFLOAT4X4 _view;
XMFLOAT4X4 _projection;
//RenderStates
ID3D11RasterizerState* _wireFrame;
ID3D11RasterizerState* _noCull;
//Camera
Camera2 _camera2;
CameraTest* _cameraTest;
float horizontalAngle = 3.14f;
float verticalAngle = 0.0f;
float mouseSpeed = 0.0005f;
//lighting
DirectionalLight DL;
MaterialStruct Mtrl;
XMFLOAT3 mEyePosW;
//ObjTest* objObject;
float x = 0;
float y = 0;
float z = 0;
GameObjectManager* _gameObjectManager;
GameObject* _arenaCage;
Model* _arenaCageModel;
//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();
};
#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;
}
}
#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 "CameraTest.h"
CameraTest::CameraTest(UINT WindowWidth, UINT WindowHeight, XMVECTOR EYE, XMVECTOR AT, XMVECTOR UP)
{
this->WindowWidth = WindowWidth;
this->WindowHeight = WindowHeight;
_eye = XMFLOAT3(0.0f, 0.0f, -3.0f);
_at = XMFLOAT3(0.0f, 0.0f, 0.0f);
_up = XMFLOAT3(0.0f, 1.0f, 0.0f);
XMStoreFloat4x4(&proj, XMMatrixIdentity());
XMStoreFloat4x4(&view, XMMatrixIdentity());
XMStoreFloat4x4(&view, XMMatrixLookAtLH(XMLoadFloat3(&_eye), XMLoadFloat3(&_at), XMLoadFloat3(&_up)));
XMStoreFloat4x4(&proj, XMMatrixPerspectiveFovLH(70.0f, WindowWidth / (FLOAT)WindowHeight, 0.01f, 1000.0f));
//XMStoreFloat4x4(&view, XMMatrixLookAtLH(EYE, AT, UP));
//XMStoreFloat4x4(&proj, XMMatrixPerspectiveFovLH(70.0f, WindowWidth / (FLOAT)WindowHeight, 0.01f, 100.0f));
position = XMLoadFloat3(&_eye);
}
CameraTest::~CameraTest()
{
}
void CameraTest::SetPosition(XMFLOAT3 & position)
{
this->position = XMLoadFloat3(&_eye);
}
void CameraTest::UpdateMatrix(float t)
{
static float time = t;
float lastTime = time;
float deltaTime = time - lastTime;
time = lastTime;
time = t;
bool initCursor = false;
if ((GetKeyState(VK_SHIFT) & 0x8000))
{
if (!initCursor)
{
SetCursorPos(WindowWidth / 2, WindowHeight / 2);
initCursor = true;
}
GetCursorPos(&mousePos);
SetCursorPos(WindowWidth / 2, WindowHeight / 2);
//Compute new orientation
horizontalAngle += mouseSpeed * float((float)WindowWidth / 2.0f - mousePos.x);
verticalAngle -= mouseSpeed * float((float)WindowHeight / 2.0f - mousePos.y);
XMFLOAT3 direction(cos(verticalAngle)* sin(horizontalAngle), sin(verticalAngle), cos(verticalAngle) * cos(horizontalAngle));
XMVECTOR d = XMLoadFloat3(&direction);
XMFLOAT3 right(sin(horizontalAngle - 3.14f / 2.0f), 0.0f, cos(horizontalAngle - 3.14f / 2.0f));
XMVECTOR r = XMLoadFloat3(&right);
XMVECTOR up = XMVector3Cross(r, d);
if ((GetAsyncKeyState('W') & 0x8000))
{
position += (d * 0.0005 * speed);
}
if (GetAsyncKeyState('Q') & 0x8000)
{
position -= (d * 0.05 * speed);
}
if (GetAsyncKeyState('D') & 0x8000)
{
position += (r * deltaTime * speed);
}
if (GetAsyncKeyState('A') & 0x8000)
{
position -= (r * deltaTime * speed);
}
XMStoreFloat4x4(&view, XMMatrixLookAtLH(position, position + d, up));
// XMStoreFloat4x4(&proj, XMMatrixPerspectiveFovLH(70.0f, WindowWidth / (FLOAT)WindowHeight, 0.01f, 100.0f));
}
else if (!(GetKeyState(VK_SHIFT) & 0x8000))
{
initCursor = false;
}
}
XMMATRIX CameraTest::GetView()
{
return XMLoadFloat4x4(&view);
}
XMMATRIX CameraTest::GetProj()
{
return XMLoadFloat4x4(&proj);
}
XMFLOAT4X4 CameraTest::Get4X4View()
{
return view;
}
XMFLOAT4X4 CameraTest::Get4X4Proj()
{
return proj;
}
#pragma once
#include <Windows.h>
#include <DirectXMath.h>
#include <ostream>
#include <sstream>
#include <iostream>
using namespace DirectX;
class CameraTest
{
private:
POINT mousePos;
XMFLOAT4X4 view;
XMFLOAT4X4 proj;
XMFLOAT3 _eye;
XMFLOAT3 _at;
XMFLOAT3 _up;
XMVECTOR position;
UINT WindowWidth;
UINT WindowHeight;
float horizontalAngle = 3.14f;
float verticalAngle = 0.0f;
float mouseSpeed = 0.0005f;
float initialFoV = 70.0f;
float speed = 3.0f;
public:
CameraTest(UINT WindowWidth, UINT WindowHeight, XMVECTOR EYE, XMVECTOR AT, XMVECTOR UP);
~CameraTest();
void SetPosition(XMFLOAT3& position);
void UpdateMatrix(float t);
XMMATRIX GetView();
XMMATRIX GetProj();
XMFLOAT4X4 Get4X4View();
XMFLOAT4X4 Get4X4Proj();
};
#include "GameObject.h"
GameObject::GameObject(XMFLOAT3& _position, Model* model, ID3D11Device* _pd3dDevice, ID3D11VertexShader* _pVertexShader, ID3D11PixelShader* _pPixelShader)
{
this->_position = _position;
this->_pd3dDevice = _pd3dDevice;
this->_pVertexShader = _pVertexShader;
this->_pPixelShader = _pPixelShader;
this->model = model;
XMStoreFloat4x4(&_world, XMMatrixIdentity());
MaterialStruct Mtrl;
Mtrl.Ambient = XMFLOAT4(0.0f, 1.0f, 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);
material = new Material(Mtrl, this->_pVertexShader, this->_pPixelShader);
}
GameObject::GameObject(XMFLOAT3& _position)
{
this->_position = _position;
model = nullptr;
}
GameObject::~GameObject()
{
}
void GameObject::CreateAndSetSamplerState()
{
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
_pd3dDevice->CreateSamplerState(&sampDesc, &_pSamplerLinear);
}
void GameObject::ModelToLoad(Model * model)
{
this->model = model;
}
void GameObject::CreateAndSetTextureWIC(const wchar_t* filePath)
{
HRESULT hr = CreateWICTextureFromFile(_pd3dDevice, filePath, nullptr, &_pTextureRV, 0);
}
void GameObject::CreateAndSetTextureDDS(const wchar_t * filePath)
{
HRESULT hr = CreateDDSTextureFromFile(_pd3dDevice, filePath, nullptr, &_pTextureRV, 0);
}
void GameObject::Update(float t)
{
XMStoreFloat4x4(&_world, (XMMatrixRotationX(t) * XMMatrixTranslation(0.0f, 1.0f, 25.0f)));
}
void GameObject::Draw(ID3D11Buffer* _pConstantBuffer, ID3D11DeviceContext* _pImmediateContext, ConstantBuffer& cb, XMMATRIX result)
{
if (model == nullptr)
{
return;
}
XMMATRIX world = XMLoadFloat4x4(&_world);
cb.mWorld = XMMatrixTranspose(result);
material->Draw(_pImmediateContext, cb);
_pImmediateContext->PSSetSamplers(0, 1, &_pSamplerLinear);
_pImmediateContext->UpdateSubresource(_pConstantBuffer, 0, nullptr, &cb, 0, 0);
_pImmediateContext->PSSetShaderResources(0, 1, &_pTextureRV);
model->Draw(_pImmediateContext);
}
//enum Type { Type0, Type1 };
//
//void something(Type type)
//{
// array[type];
//
// psSetshader(Array[type]);
//}
#pragma once
#include <DirectXMath.h>
#include "Model.h"
#include "Struct.h"
#include "Material.h"
//Texture loading
#include "WICTextureLoader.h"
#include "DDSTextureLoader.h"
using namespace DirectX;
class GameObject
{
private:
Model* model;
Material* material;
XMFLOAT3 _position;
XMFLOAT4X4 _world;
ID3D11Device* _pd3dDevice;
ID3D11VertexShader* _pVertexShader;
ID3D11PixelShader* _pPixelShader;
ID3D11ShaderResourceView* _pTextureRV = nullptr;
ID3D11SamplerState* _pSamplerLinear = nullptr;
public:
GameObject(XMFLOAT3& _position, Model* model, ID3D11Device* _pd3dDevice, ID3D11VertexShader* _pVertexShader, ID3D11PixelShader* _pPixelShader);
GameObject(XMFLOAT3& _position);
~GameObject();
XMMATRIX GetMatrix() { return XMMatrixIdentity() * XMMatrixTranslation(_position.x, _position.y, _position.z); }
void CreateAndSetSamplerState();
void CreateAndSetTextureWIC(const wchar_t* filePath);
void CreateAndSetTextureDDS(const wchar_t* filePath);
void Update(float t);
void Draw(ID3D11Buffer* _pConstantBuffer, ID3D11DeviceContext* _pImmediateContext, ConstantBuffer& cb, XMMATRIX result);
void ModelToLoad(Model* model);
};
#include "GameObjectManager.h"
GameObjectManager::GameObjectManager(ID3D11Device * _pd3dDevice, ID3D11VertexShader * _pVertexShader, ID3D11PixelShader * _pPixelShader)
{
//Create Models
_shipModel = new Model(_pd3dDevice);
_sphereModel = new Model(_pd3dDevice);
_groundModel = new Model(_pd3dDevice);
//Load Models
_shipModel->LoadModel("OBJ'S/car.obj");
_sphereModel->LoadModel("Sphere.obj");
_groundModel->LoadModel("OBJ'S/flatPlane.obj");
//Create GameObjects
_rootObject = new GameObject(XMFLOAT3(0.0f, 0.0f, 0.0f));
_shipObject = new GameObject(XMFLOAT3(0.0f, 0.0f, 5.0f), _shipModel, _pd3dDevice, _pVertexShader, _pPixelShader);
_sphereObject = new GameObject(XMFLOAT3(5.0f, 0.2f, 10.0f), _sphereModel, _pd3dDevice, _pVertexShader, _pPixelShader);
_groundObject = new GameObject(XMFLOAT3(0.0f, -0.5f, 0.0f), _groundModel, _pd3dDevice, _pVertexShader, _pPixelShader);
//SamplerStates
_shipObject->CreateAndSetSamplerState();
_sphereObject->CreateAndSetSamplerState();
//ObjectTextures
_shipObject->CreateAndSetTextureWIC(L"OBJ'S/Image_earth.jpg");
_sphereObject->CreateAndSetTextureWIC(L"OBJ'S/Ball.jpg");
_groundObject->CreateAndSetTextureWIC(L"OBJ'S/mountinTex.jpg");
rootNode = makeNode(_rootObject);
rootNode->child = makeNode(_shipObject);
rootNode->sibling = makeNode(_sphereObject);
rootNode->sibling->sibling = makeNode(_groundObject);
}
GameObjectManager::~GameObjectManager()
{
}
Node * GameObjectManager::makeNode(GameObject * data)
{
Node* newNode;
newNode = new Node();
newNode->data = data;
newNode->child = nullptr;
newNode->sibling = nullptr;
return newNode;
}
void GameObjectManager::Update()
{
}
void GameObjectManager::DrawObjects(ID3D11Buffer * _pConstantBuffer, ID3D11DeviceContext * _pImmediateContext, ConstantBuffer & cb)
{
preOrderTraverse(rootNode, XMMatrixIdentity(), _pConstantBuffer, _pImmediateContext, cb);
}
void GameObjectManager::preOrderTraverse(Node * object, XMMATRIX & matrix, ID3D11Buffer * _pConstantBuffer, ID3D11DeviceContext * _pImmediateContext, ConstantBuffer & cb)
{
//Matrix multiplication
if (object->sibling != nullptr)
{
preOrderTraverse(object->sibling, matrix, _pConstantBuffer, _pImmediateContext, cb);
}
XMMATRIX result = object->data->GetMatrix() * matrix;
if (object->child != nullptr)
{
preOrderTraverse(object->child, result, _pConstantBuffer, _pImmediateContext, cb);
}
if (object->data)
{
object->data->Draw(_pConstantBuffer, _pImmediateContext, cb, result);
}
}
#pragma once
#include "Struct.h"
#include <DirectXMath.h>
#include "GameObject.h"
#include "Model.h"
using namespace DirectX;
struct Node
{
GameObject* data;
Node* child;
Node* sibling;
};
class GameObjectManager
{
private:
Node* makeNode(GameObject* data);
//Models that are going to be used
Model* _shipModel;
Model* _sphereModel;
Model* _groundModel;
//Objects that are going to be used
GameObject* _rootObject;
GameObject* _shipObject;
GameObject* _sphereObject;
GameObject* _groundObject;
Node* rootNode;
public:
GameObjectManager(ID3D11Device* _pd3dDevice, ID3D11VertexShader* _pVertexShader, ID3D11PixelShader* _pPixelShader);
~GameObjectManager();
void Update();
void DrawObjects(ID3D11Buffer* _pConstantBuffer, ID3D11DeviceContext* _pImmediateContext, ConstantBuffer& cb);
void preOrderTraverse(Node* object, XMMATRIX& matrix, ID3D11Buffer* _pConstantBuffer, ID3D11DeviceContext* _pImmediateContext, ConstantBuffer& cb);
};
#include "Material.h"
Material::Material(MaterialStruct Mtrl, ID3D11VertexShader * _pVertexShader, ID3D11PixelShader * _pPixelShader, ID3D11ShaderResourceView * _pTextureRV)
{
this->Mtrl = Mtrl;
this->_pVertexShader = _pVertexShader;
this->_pPixelShader = _pPixelShader;
this->_pTextureRV = _pTextureRV;
}
Material::Material(MaterialStruct Mtrl, ID3D11VertexShader * _pVertexShader, ID3D11PixelShader * _pPixelShader)
{
this->Mtrl = Mtrl;
this->_pVertexShader = _pVertexShader;
this->_pPixelShader = _pPixelShader;
this->_pTextureRV = nullptr;
}
Material::~Material()
{
}
void Material::Draw(ID3D11DeviceContext * _pImmediateContext, ConstantBuffer & cb)
{
// cb.Mtrl.Ambient = Mtrl.Ambient;
// cb.Mtrl.Diffuse = Mtrl.Diffuse;
cb.Mtrl = Mtrl;
if (_pTextureRV)
{
_pImmediateContext->PSSetShaderResources(0, 1, &_pTextureRV);
}
_pImmediateContext->VSSetShader(_pVertexShader, nullptr, 0);
_pImmediateContext->PSSetShader(_pPixelShader, nullptr, 0);
}
#pragma once
#include <DirectXMath.h>
#include "Struct.h"
using namespace DirectX;
class Material
{
private:
ID3D11VertexShader* _pVertexShader;
ID3D11PixelShader* _pPixelShader;
ID3D11ShaderResourceView* _pTextureRV;
//Struct Used
MaterialStruct Mtrl;
public:
Material(MaterialStruct Mtrl, ID3D11VertexShader* _pVertexShader, ID3D11PixelShader* _pPixelShader, ID3D11ShaderResourceView* _pTextureRV);
Material(MaterialStruct Mtrl, ID3D11VertexShader* _pVertexShader, ID3D11PixelShader* _pPixelShader);
~Material();
void Draw(ID3D11DeviceContext* _pImmediateContext, ConstantBuffer& cb);
};
#include "Model.h"
Model::Model(ID3D11Device * _pd3dDevice)
{
mesh = nullptr;
this->_pd3dDevice = _pd3dDevice;
}
Model::~Model()
{
}
void Model::LoadModel(char * path)
{
mesh = ModelLoader::Load(path, _pd3dDevice);
}
void Model::Draw(ID3D11DeviceContext * _pImmediateContext)
{
if (mesh == nullptr)
{
return;
}
static UINT stride = sizeof(Vertex);
static UINT offset = 0;
_pImmediateContext->IASetVertexBuffers(0, 1, &mesh->_pVertexBuffer, &stride, &offset);
_pImmediateContext->IASetIndexBuffer(mesh->_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
_pImmediateContext->DrawIndexed(mesh->Indices.size(), 0, 0);
}
#pragma once
//Load the Model and Draw the model
#include <d3d11.h>
#include "ModelLoader.h"
#include "Struct.h"
#include <DirectXMath.h>
using namespace DirectX;
class Model
{
private:
Mesh* mesh;
ID3D11Device* _pd3dDevice;
public:
Model(ID3D11Device* _pd3dDevice);
~Model();
void LoadModel(char* path);
void Draw(ID3D11DeviceContext* _pImmediateContext);
};
#include "ModelLoader.h"
#include <map>
using namespace std;
using namespace DirectX;
namespace ModelLoader
{
void LoadVertices(string& buffer);
void LoadFaces(string &buffer);
void LoadTexCoords(string &buffer);
void LoadNormals(string &buffer);
void LoadVB(ID3D11Device * _pd3dDevice, Mesh* mesh);
void LoadIB(ID3D11Device * _pd3dDevice, Mesh* mesh);
//VertexToOutIndex is the data used to find a vertex check weather one already exists or not and then use that and put it into result which will be put into indices
//check pre existing vertex then return result of that index
bool GetSimilarVertexIndex(PackedVertex & packed, std::map<PackedVertex, unsigned short> & VertexToOutIndex, unsigned short & result);
//will get the data loadeded into the readData and index it and store it into the mesh which will be used to draw
void IndexVBO(
std::vector<XMFLOAT3>&out_vertices, std::vector<XMFLOAT3>&out_normals, std::vector<XMFLOAT2>&out_uv,
std::vector<XMFLOAT3>&indexed_vertices, std::vector<XMFLOAT3>&indexed_normals, std::vector<XMFLOAT2>&indexed_uvs,
Mesh& mesh);
std::vector<unsigned short> indices;
unsigned short vertexIndex[3], uvIndex[3], normalIndex[3];
std::vector<unsigned short> vertexIndices, uvIndices, normalIndices; //These indices will be then pushed back into the out_temp
std::vector<XMFLOAT3>temp_vertices;
std::vector<XMFLOAT3>temp_normals;
std::vector<XMFLOAT2>temp_uv;
std::vector<XMFLOAT3>out_vertices;
std::vector<XMFLOAT3>out_normals;
std::vector<XMFLOAT2>out_uv;
std::vector<XMFLOAT3> indexed_vertices;
std::vector<XMFLOAT2> indexed_uvs;
std::vector<XMFLOAT3> indexed_normals;
//make this in the while loop
void LoadVB(ID3D11Device * _pd3dDevice, Mesh* mesh)
{
HRESULT hr;
// Create vertex buffer
// Set vertex buffer
ID3D11Buffer* _pVertexBuffer2;
_pVertexBuffer2 = nullptr;
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = mesh->indexed_vertices.size() * sizeof(Vertex);
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = &mesh->elements[0];
hr = _pd3dDevice->CreateBuffer(&bd, &InitData, &mesh->_pVertexBuffer);
}
void LoadIB(ID3D11Device * _pd3dDevice, Mesh* mesh)
{
HRESULT hr;
ID3D11Buffer* _pIndexBuffer2;
_pIndexBuffer2 = nullptr;
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(unsigned short) * mesh->Indices.size();
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = &mesh->Indices[0];
hr = _pd3dDevice->CreateBuffer(&bd, &InitData, &mesh->_pIndexBuffer);
}
void LoadVertices(string& buffer)
{
if (buffer[0] == 'v' && buffer[1] == ' ')
{
XMFLOAT3 temp3;
float tmpX, tmpY, tmpZ;
sscanf_s(buffer.c_str(), "v %f %f %f", &tmpX, &tmpY, &tmpZ);
temp3.x = tmpX;
temp3.y = tmpY;
temp3.z = tmpZ;
temp_vertices.push_back(temp3);
}
}
void LoadTexCoords(string &buffer)
{
if (buffer[0] == 'v' && buffer[1] == 't')
{
XMFLOAT2 temp2;
float tmpU, tmpV;
sscanf_s(buffer.c_str(), "vt %f %f", &tmpU, &tmpV);
temp2.x = tmpU;
temp2.y = tmpV;
temp_uv.push_back(temp2);
}
}
void LoadNormals(string &buffer)
{
if (buffer[0] == 'v' && buffer[1] == 'n')
{
XMFLOAT3 temp3;
float tmpX, tmpY, tmpZ;
sscanf_s(buffer.c_str(), "vn %f %f %f", &tmpX, &tmpY, &tmpZ);
temp3.x = tmpX;
temp3.y = tmpY;
temp3.z = tmpZ;
temp_normals.push_back(temp3);
}
}
void LoadFaces(string &buffer)
{
if (buffer[0] == 'f' && buffer[1] == ' ')
{
if (sscanf_s(buffer.c_str(), "f %i//%i %i//%i %i//%i", &vertexIndex[0], &normalIndex[0], &vertexIndex[1], &normalIndex[1], &vertexIndex[2], &normalIndex[2]) == 6) //Vertex and normal
{
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
normalIndices.push_back(normalIndex[0]);
normalIndices.push_back(normalIndex[1]);
normalIndices.push_back(normalIndex[2]);
}
if (sscanf_s(buffer.c_str(), "f %i/%i/%i %i/%i/%i %i/%i/%i", &vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2]) == 9) //vertex normal and texture
{
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
normalIndices.push_back(normalIndex[0]);
normalIndices.push_back(normalIndex[1]);
normalIndices.push_back(normalIndex[2]);
uvIndices.push_back(uvIndex[0]);
uvIndices.push_back(uvIndex[1]);
uvIndices.push_back(uvIndex[2]);
}
if (sscanf_s(buffer.c_str(), "f %i/%i %i/%i %i/%i", &vertexIndex[0], &uvIndex[0], &vertexIndex[1], &uvIndex[1], &vertexIndex[2], &uvIndex[2]) == 6) //vertex and texture
{
vertexIndices.push_back(vertexIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
uvIndices.push_back(uvIndex[0]);
uvIndices.push_back(uvIndex[1]);
uvIndices.push_back(uvIndex[2]);
}
}
}
bool GetSimilarVertexIndex(PackedVertex & packed, std::map<PackedVertex, unsigned short> & VertexToOutIndex, unsigned short & result)
{
std::map<PackedVertex, unsigned short>::iterator it = VertexToOutIndex.find(packed);
if (it == VertexToOutIndex.end())
{
return false;
}
else
{
result = it->second;
return true;
}
}
void IndexVBO(
std::vector<XMFLOAT3>&out_vertices, std::vector<XMFLOAT3>&out_normals, std::vector<XMFLOAT2>&out_uv,
std::vector<XMFLOAT3>&indexed_vertices, std::vector<XMFLOAT3>&indexed_normals, std::vector<XMFLOAT2>&indexed_uvs,
Mesh& mesh)
{
std::map<PackedVertex, unsigned short> VertexToOutIndex;
for (unsigned int i = 0; i < out_vertices.size(); i++)
{
PackedVertex packed = { out_vertices[i], out_normals[i], out_uv[i] };
//Try to find a similar index
unsigned short index;
bool found = GetSimilarVertexIndex(packed, VertexToOutIndex, index);
if (found)
{
// A similar vertex is already in the VBO, use it instead !
mesh.Indices.push_back(index);
}
else
{
indexed_vertices.push_back(out_vertices[i]);
indexed_uvs.push_back(out_uv[i]);
indexed_normals.push_back(out_normals[i]);
unsigned short newindex = (unsigned short)indexed_vertices.size() - 1;
mesh.Indices.push_back(newindex);
VertexToOutIndex[packed] = newindex;
}
}
}
Mesh * ModelLoader::Load(char* path, ID3D11Device * _pd3dDevice)
{
Mesh* mesh = new Mesh();
ifstream file;
file.open(path);
string buffer;
if (!file.good())
{
cerr << "Can't open texture file " << path << endl;
return nullptr;
}
while (!file.eof())
{
getline(file, buffer);
if (buffer[0] == '#')
{
continue;
}
else
{
LoadVertices(buffer);
LoadNormals(buffer);
LoadTexCoords(buffer);
LoadFaces(buffer); //* defeferncing
}
}
file.close();
for (unsigned short i = 0; i < vertexIndices.size(); i++)
{
unsigned int vertexIndex = vertexIndices[i];
unsigned int normalIndex = normalIndices[i];
unsigned int uvIndex = uvIndices[i];
XMFLOAT2 faceUV;
XMFLOAT3 faceVertices;
XMFLOAT3 faceNormals;
faceUV = temp_uv[uvIndex - 1];
faceVertices = temp_vertices[vertexIndex - 1];
faceNormals = temp_normals[normalIndex - 1];
out_uv.push_back(faceUV);
out_normals.push_back(faceNormals);
out_vertices.push_back(faceVertices);
}
IndexVBO(out_vertices, out_normals, out_uv, indexed_vertices, indexed_normals, indexed_uvs, *mesh);
for (unsigned int i = 0; i < indexed_vertices.size(); i++)
{
mesh->elements.push_back({ indexed_vertices[i], indexed_normals[i], indexed_uvs[i] });
mesh->indexed_vertices.push_back({ indexed_vertices[i] });
mesh->indexed_normals.push_back({ indexed_normals[i] });
mesh->indexed_uvs.push_back({ indexed_uvs[i] });
}
LoadVB(_pd3dDevice, mesh);
LoadIB(_pd3dDevice, mesh);
temp_vertices.clear();
temp_normals.clear();
temp_uv.clear();
out_vertices.clear();
out_normals.clear();
out_uv.clear();
vertexIndices.clear();
normalIndices.clear();
uvIndices.clear();
return mesh;
}
}
#pragma once
#include "Struct.h"
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <d3d11_1.h>
#include <d3dcompiler.h>
#include <directxmath.h>
namespace ModelLoader
{
Mesh* Load(char* path, ID3D11Device * _pd3dDevice);
};
#pragma once
#include <directxmath.h>
#include <vector>
#include <iostream>
#include <windows.h>
#include <d3dcompiler.h>
#include <d3d11_1.h>
using namespace DirectX;
struct SimpleVertex
{
XMFLOAT3 Pos;
XMFLOAT4 Color;
XMFLOAT3 Normal;
};
struct Vertex
{
XMFLOAT3 Pos;
XMFLOAT3 Normal;
XMFLOAT2 UV;
};
struct Textures
{
float u, v;
};
struct Mesh
{
std::vector<Vertex> elements;
std::vector<unsigned short> Indices;
unsigned short vertexIndex[3], uvIndex[3], normalIndex[3];
std::vector<unsigned short> vertexIndices, uvIndices, normalIndices;
std::vector<XMFLOAT3> indexed_vertices;
std::vector<XMFLOAT2> indexed_uvs;
std::vector<XMFLOAT3> indexed_normals;
ID3D11Buffer* _pVertexBuffer;
ID3D11Buffer* _pIndexBuffer;
};
struct PackedVertex
{
XMFLOAT3 Pos;
XMFLOAT3 Normal;
XMFLOAT2 UV;
//Overloading < function
bool operator <(const PackedVertex that) const { return memcmp((void*)this, (void*)&that, sizeof(PackedVertex)) > 0; } //So if that is greater than this then return true
};
struct DirectionalLight
{
// DirectionalLight() { ZeroMemory(this, sizeof(this)); }
XMFLOAT4 Ambient;
XMFLOAT4 Diffuse;
XMFLOAT4 Specular;
XMFLOAT3 Direction;
float Pad; // Not sure if I need this but I can now have an array of lights if I wanted to?
};
struct MaterialStruct
{
// Material() { ZeroMemory(this, sizeof(this)); }
XMFLOAT4 Ambient;
XMFLOAT4 Diffuse;
XMFLOAT4 Specular;
XMFLOAT4 Reflect;
};
struct ConstantBuffer
{
XMMATRIX mWorld;
XMMATRIX mView;
XMMATRIX mProjection;
DirectionalLight DL;
MaterialStruct Mtrl;
XMFLOAT3 gEyePosW;
};
struct cbPerFrame
{
float gFogStart;
float gFogRange;
XMFLOAT4 gFogColor;
};
enum class RenderLayer : int
{
Opaque = 0,
AlphaTested,
Transparent,
Default
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment