Skip to content

Instantly share code, notes, and snippets.

@PirosB3
Created November 4, 2013 11:43
Show Gist options
  • Save PirosB3/7301411 to your computer and use it in GitHub Desktop.
Save PirosB3/7301411 to your computer and use it in GitHub Desktop.
Game shit
//**************************************************************************//
// Start of an OBJ loader. By no means an end. This just creates //
// triangles. //
// //
// Look for the Nigel style comments, like these, for the bits you need to //
// look at. //
//**************************************************************************//
//**************************************************************************//
// Modifications to the MS sample code is copyright of Dr Nigel Barlow, //
// lecturer in computing, University of Plymouth, UK. //
// email: [email protected]. //
// //
// You may use, modify and distribute this (rather cack-handed in places) //
// code subject to the following conditions: //
// //
// 1: You may not use it, or sell it, or use it in any adapted form for //
// financial gain, without my written premission. //
// //
// 2: You must not remove the copyright messages. //
// //
// 3: You should correct at least 10% of the typig abd spekking errirs. //
//**************************************************************************//
//--------------------------------------------------------------------------------------
// File: Tutorial07 - Textures and Constant buffers.cpp
//
// This application demonstrates texturing
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include <windows.h>
#include <regex>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dcompiler.h>
#include <xnamath.h>
#include <fstream> // Files. The ones without ".h" are the new (not
#include <string> // so new now) standard library headers.
#include <sstream>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <functional>
#include <cctype>
#include <vector>
#include <stdio.h>
#include "resource.h"
struct FaceItem {
XMFLOAT3 *vertex;
XMFLOAT2 *vertexTexture;
XMFLOAT3 *vertexNormal;
};
struct Face {
FaceItem x;
FaceItem y;
FaceItem z;
};
// DEFINE GROUP
class Group {
public:
Group(const char *name);
void addVectorType(const char *type, float *matches);
void addFaceType(FaceItem *faces);
private:
const char *name;
std::vector<XMFLOAT3> vectors;
std::vector<XMFLOAT3> vectorNormals;
std::vector<XMFLOAT2> vectorTextures;
std::vector<Face> faces;
};
Group::Group(const char *name) {
this->name = name;
};
//**************************************************************************//
// Nothing is easy in DirectX. Before we can even create a single vertex, //
// we need to define what it looks like. //
// //
// The data types seems to be inhereted from XNA. //
// An XMFLOAT3 is a float containing 3 numbers, an x, y, x position here. //
// An XMFLOAT4 is a float containing 4 values, an RGBA colour. Not that //
// alpha effects work without additional effort. //
//**************************************************************************//
struct SimpleVertex
{
XMFLOAT3 Pos; //Why not a float4? See the shader strucrure. Any thoughts? Nigel
XMFLOAT3 VecNormal;
XMFLOAT2 TexUV;
};
//**************************************************************************//
// A sort of mesh subset, basically an array of vertices and indexes. //
//**************************************************************************//
struct SortOfMeshSubset
{
SimpleVertex *vertices;
USHORT *indexes;
USHORT numVertices;
USHORT numIndices;
};
int g_numIndices = 0; // Need to record the number of indices
// for drawing mesh.
//**************************************************************************//
// Light vector never moves; and colour never changes. I have done it . //
// this way to show how constant buffers can be used so that you don't //
// upsate stuff you don't need to. //
// Beware of constant buffers that aren't in multiples of 16 bytes.. //
//**************************************************************************//
struct CBNeverChanges
{
XMFLOAT4 materialColour;
XMVECTOR vecLight; // Must be 4, we only use the first 3.
};
struct CBChangeOnResize
{
XMMATRIX matProjection;
};
//**************************************************************************//
// Note we do it properly here and pass the WVP matrix, rather than world, //
// view and projection matrices separately. //
// //
// We still need the world matrix to transform the normal vectors. //
//**************************************************************************//
struct CBChangesEveryFrame
{
XMMATRIX matWorld;
XMMATRIX matWorldViewProjection;
};
//**************************************************************************//
// Global Variables. There are many global variables here (we aren't OO //
// yet. I doubt Roy Tucker (Comp Sci students will know him) will //
// approve pf this either. Sorry, Roy. //
//**************************************************************************//
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device* g_pd3dDevice = NULL;
ID3D11DeviceContext* g_pImmediateContext = NULL;
IDXGISwapChain* g_pSwapChain = NULL;
ID3D11RenderTargetView* g_pRenderTargetView = NULL;
ID3D11Texture2D* g_pDepthStencil = NULL;
ID3D11DepthStencilView* g_pDepthStencilView = NULL;
ID3D11VertexShader* g_pVertexShader = NULL;
ID3D11PixelShader* g_pPixelShader = NULL;
ID3D11InputLayout* g_pVertexLayout = NULL;
ID3D11Buffer* g_pVertexBuffer = NULL;
ID3D11Buffer* g_pIndexBuffer = NULL;
ID3D11SamplerState* g_pSamplerLinear = NULL;
XMMATRIX g_MatProjection;
//**************************************************************************//
// The texture; just one here. //
//**************************************************************************//
ID3D11ShaderResourceView *g_pTextureResourceView = NULL;
//**************************************************************************//
// Now a global instance of each constant buffer. //
//**************************************************************************//
ID3D11Buffer *g_pCBNeverChanges = NULL;
ID3D11Buffer *g_pCBChangeOnResize = NULL;
ID3D11Buffer *g_pCBChangesEveryFrame = NULL;
//**************************************************************************//
// Forward declarations. //
// //
// If you are not used to "C" you will find that functions (or methods in //
// "C++" must have templates defined in advance. It is usual to define the //
// prototypes in a header file, but we'll put them here for now to keep //
// things simple. //
//**************************************************************************//
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDevice();
void CleanupDevice();
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
void Render();
void charStrToWideChar(WCHAR *dest, char *source);
void XMFLOAT3normalise(XMFLOAT3 *toNormalise);
SortOfMeshSubset *LoadMesh(LPSTR filename);
//**************************************************************************//
// A Windows program always kicks off in WinMain. //
// Initializes everything and goes into a message processing //
// loop. Idle time is used to render the scene. //
// //
// In other words, run the computer flat out. Is this good? //
//**************************************************************************//
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );
if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;
if( FAILED( InitDevice() ) )
{
CleanupDevice();
return 0;
}
//**************************************************************************//
// Main Windoze message loop. //
// //
// Gamers will see this as a game loop, though you will find something like //
// this main loop deep within any Windows application. //
//**************************************************************************//
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
CleanupDevice();
return ( int )msg.wParam;
}
//--------------------------------------------------------------------------------------
// Register class and create window
//--------------------------------------------------------------------------------------
HRESULT 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 = NULL;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );
if( !RegisterClassEx( &wcex ) )
return E_FAIL;
// Create window
g_hInst = hInstance;
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 11 Tutorial 7", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
NULL );
if( !g_hWnd )
return E_FAIL;
ShowWindow( g_hWnd, nCmdShow );
return S_OK;
}
//**************************************************************************//
// Compile the shader file. These files aren't pre-compiled (well, not //
// here, and are compiled on he fly). //
//**************************************************************************//
HRESULT CompileShaderFromFile( WCHAR* szFileName, // File Name
LPCSTR szEntryPoint, // Namee of shader
LPCSTR szShaderModel, // Shader model
ID3DBlob** ppBlobOut ) // Blob returned
{
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 = D3DX11CompileFromFile( szFileName, NULL, NULL, szEntryPoint, szShaderModel,
dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL );
if( FAILED(hr) )
{
WCHAR errorCharsW[200];
if( pErrorBlob != NULL )
{
charStrToWideChar(errorCharsW, (char *)pErrorBlob->GetBufferPointer());
MessageBox( 0, errorCharsW, L"Error", 0 );
}
}
if( pErrorBlob ) pErrorBlob->Release();
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDevice()
{
HRESULT hr = S_OK;
RECT rc;
GetClientRect( g_hWnd, &rc );
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
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 = width;
sd.BufferDesc.Height = height;
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 = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
if( SUCCEEDED( hr ) )
break;
}
if( FAILED( hr ) )
return hr;
// Create a render target view
ID3D11Texture2D* pBackBuffer = NULL;
hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );
if( FAILED( hr ) )
return hr;
hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED( hr ) )
return hr;
// Create depth stencil texture
D3D11_TEXTURE2D_DESC descDepth;
ZeroMemory( &descDepth, sizeof(descDepth) );
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
descDepth.SampleDesc.Count = 1;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
hr = g_pd3dDevice->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil );
if( FAILED( hr ) )
return hr;
// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
ZeroMemory( &descDSV, sizeof(descDSV) );
descDSV.Format = descDepth.Format;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView );
if( FAILED( hr ) )
return hr;
g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, g_pDepthStencilView );
// Setup the viewport
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports( 1, &vp );
//**********************************************************************//
// Compile the shader file. These files aren't pre-compiled (well, not //
// here, and are compiles on he fly). //
// //
// This is DirectX11, but what shader model do you see here? //
// Change to shader model 5 in Babbage209 and it should still work. //
//**********************************************************************//
ID3DBlob* pVSBlob = NULL;
hr = CompileShaderFromFile( L"Start of OBJ loader VS.hlsl", "VS_obj", "vs_4_0", &pVSBlob );
if( FAILED( hr ) )
{
MessageBox( NULL,
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 = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );
if( FAILED( hr ) )
{
pVSBlob->Release();
return hr;
}
//**********************************************************************//
// Create the pixel shader. //
//**********************************************************************//
ID3DBlob* pPSBlob = NULL;
hr = CompileShaderFromFile( L"Start of OBJ loader PS.hlsl", "PS_TexturesNoLighting", "ps_4_0", &pPSBlob );
if( FAILED( hr ) )
{
MessageBox( NULL,
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;
}
hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );
pPSBlob->Release();
if( FAILED( hr ) )
return hr;
//**********************************************************************//
// Define the input layout. I won't go too much into this except that //
// the vertex defined here MUST be consistent with the vertex shader //
// input you use in your shader file and the constand buffer structure //
// at the top of this module. //
// //
// Here a vertex has a position a normal vector (used for lighting) and //
// a single texture UV coordinate. //
//**********************************************************************//
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "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 = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &g_pVertexLayout );
pVSBlob->Release();
if( FAILED( hr ) )
return hr;
// Set the input layout
g_pImmediateContext->IASetInputLayout( g_pVertexLayout );
//**************************************************************************//
// Load the obj mesh, NOT COMPLETE. //
//**************************************************************************//
SortOfMeshSubset *sortOfMesh = LoadMesh("Media\\Cup\\Cup.obj");
//**************************************************************************//
// Create the vertex buffer. //
//**************************************************************************//
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * sortOfMesh->numVertices; //From sortOfMesh
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = sortOfMesh->vertices; //From sortOfMesh
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) )
return hr;
// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
//**************************************************************************//
// Now define some triangles. That's all DirectX allows us to draw. This //
// is called an index buffer, and it indexes the vertices to make triangles.//
// //
// This is called an index buffer. //
//**************************************************************************//
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( USHORT ) * sortOfMesh->numIndices; //From sortOfMesh
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
InitData.pSysMem = sortOfMesh->indexes; //From sortOfMesh
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
if( FAILED( hr ) )
return hr;
g_numIndices = sortOfMesh->numIndices;
// Set index buffer
g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );
// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
//**************************************************************************//
// Can this be true? Nigel is caught cleaning up after himself. Once the //
// vertex and index buffers are created, this structure is no longer needed.//
//**************************************************************************//
delete sortOfMesh->indexes; // Delete the two arrays.
delete sortOfMesh->vertices;
delete sortOfMesh; // Then delete sortOfMesh
//**************************************************************************//
// Create the 3 constant buffers. //
//**************************************************************************//
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(CBNeverChanges);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pCBNeverChanges );
if( FAILED( hr ) )
return hr;
bd.ByteWidth = sizeof(CBChangeOnResize);
hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pCBChangeOnResize );
if( FAILED( hr ) )
return hr;
bd.ByteWidth = sizeof(CBChangesEveryFrame);
hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pCBChangesEveryFrame );
if( FAILED( hr ) )
return hr;
//**************************************************************************//
// Load the texture into "ordinary" RAM. //
//**************************************************************************//
hr = D3DX11CreateShaderResourceViewFromFile( g_pd3dDevice,
L"Media\\woodtexture.jpg",
NULL, NULL,
&g_pTextureResourceView, // This is returned.
NULL );
if( FAILED( hr ) )
return hr;
//**************************************************************************//
// Put the texture in shader (video) memory. As there is only one texture, //
// we can do this only once. Try to minimise the number of times you put //
// textures into video memory, there is quite an overhead in doing so. //
//**************************************************************************//
g_pImmediateContext->PSSetShaderResources( 0, 1, &g_pTextureResourceView );
// Create the sample state
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;
hr = g_pd3dDevice->CreateSamplerState( &sampDesc, &g_pSamplerLinear );
if( FAILED( hr ) )
return hr;
//**************************************************************************//
// Update the constant buffer for stuff (the light vector and material //
// colour in this case) that never change. This is faster; don't update //
// stuff if you don't have to. //
//**************************************************************************//
CBNeverChanges cbNeverChanges;
cbNeverChanges.materialColour = XMFLOAT4(1, 1, 1, 1); //Alpha does nothing.
cbNeverChanges.vecLight = XMVectorSet(1, 1, -2, 0); //4th value unused.
cbNeverChanges.vecLight = XMVector3Normalize(cbNeverChanges.vecLight);
g_pImmediateContext->UpdateSubresource( g_pCBNeverChanges,
0, NULL,
&cbNeverChanges,
0, 0 );
//**************************************************************************//
// Creatre the projection matrix. Generally you will only want to create //
// this matrix once and then forget it. //
//**************************************************************************//
g_MatProjection = XMMatrixPerspectiveFovLH( XM_PIDIV4, // Field of view (pi / 4 radians, or 45 degrees
width / (FLOAT)height, // Aspect ratio.
0.01f, // Near clipping plane.
100.0f ); // Far clipping plane.
CBChangeOnResize cbChangesOnResize;
cbChangesOnResize.matProjection = XMMatrixTranspose( g_MatProjection );
g_pImmediateContext->UpdateSubresource( g_pCBChangeOnResize, 0, NULL, &cbChangesOnResize, 0, 0 );
return S_OK;
}
//--------------------------------------------------------------------------------------
// Clean up the objects we've created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{
if( g_pImmediateContext ) g_pImmediateContext->ClearState();
if( g_pSamplerLinear ) g_pSamplerLinear->Release();
if( g_pTextureResourceView ) g_pTextureResourceView->Release();
if( g_pCBNeverChanges ) g_pCBNeverChanges->Release();
if( g_pCBChangeOnResize ) g_pCBChangeOnResize->Release();
if( g_pCBChangesEveryFrame ) g_pCBChangesEveryFrame->Release();
if( g_pVertexBuffer ) g_pVertexBuffer->Release();
if( g_pIndexBuffer ) g_pIndexBuffer->Release();
if( g_pVertexLayout ) g_pVertexLayout->Release();
if( g_pVertexShader ) g_pVertexShader->Release();
if( g_pPixelShader ) g_pPixelShader->Release();
if( g_pDepthStencil ) g_pDepthStencil->Release();
if( g_pDepthStencilView ) g_pDepthStencilView->Release();
if( g_pRenderTargetView ) g_pRenderTargetView->Release();
if( g_pSwapChain ) g_pSwapChain->Release();
if( g_pImmediateContext ) g_pImmediateContext->Release();
if( g_pd3dDevice ) g_pd3dDevice->Release();
}
//--------------------------------------------------------------------------------------
// Called every time the application receives a message
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
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;
}
//--------------------------------------------------------------------------------------
// Render a frame
//--------------------------------------------------------------------------------------
void Render()
{
//**************************************************************************//
// Update our time. This block is supposed to make the movement frame rate //
// independent, as the frame rate we get depends of the performance of our //
// computer. We may even be in reference (software emulation) mode, which //
// is painfully slow. //
//**************************************************************************//
static float t = 0.0f;
if( g_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;
}
// Rotate cube around the origin
XMMATRIX matCubeWorld = XMMatrixRotationY( t );
//
// Clear the back buffer
//
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha
g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
//
// Clear the depth buffer to 1.0 (max depth)
//
g_pImmediateContext->ClearDepthStencilView( g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );
//**************************************************************************//
// Initialize the view matrix. What you do to the viewer matrix moves the //
// viewer, or course. //
// //
// The viewer matrix is created every frame here, which looks silly as the //
// viewer never moves. However in general your viewer does move. //
//**************************************************************************//
XMVECTOR Eye = XMVectorSet( 0.0f, 1.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 );
XMMATRIX matView = XMMatrixLookAtLH( Eye, // The eye, or viewer's position.
At, // The look at point.
Up ); // Which way is up.
XMMATRIX matWVP = matCubeWorld * matView * g_MatProjection;
//
// Update variables that change once per frame
//
CBChangesEveryFrame cb;
cb.matWorld = XMMatrixTranspose( matCubeWorld );
cb.matWorldViewProjection = XMMatrixTranspose( matWVP);
g_pImmediateContext->UpdateSubresource( g_pCBChangesEveryFrame, 0, NULL, &cb, 0, 0 );
//
// Render the cube
//
g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
g_pImmediateContext->PSSetConstantBuffers( 0, 1, &g_pCBNeverChanges ); //Note this one belongs to the pixel shader.
g_pImmediateContext->VSSetConstantBuffers( 0, 1, &g_pCBChangeOnResize ); // Paremeter 1 relates to pisition in
g_pImmediateContext->VSSetConstantBuffers( 1, 1, &g_pCBChangesEveryFrame ); // constant buffers.
g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
g_pImmediateContext->PSSetConstantBuffers( 2, 1, &g_pCBChangesEveryFrame );
g_pImmediateContext->PSSetSamplers( 0, 1, &g_pSamplerLinear );
g_pImmediateContext->DrawIndexed( g_numIndices, 0, 0 );
//
// Present our back buffer to our front buffer
//
g_pSwapChain->Present( 0, 0 );
}
//**************************************************************************//
// Convert an old chracter (char *) string to a WCHAR * string. There must//
// be something built into Visual Studio to do this for me, but I can't //
// find it - Nigel. //
//**************************************************************************//
void charStrToWideChar(WCHAR *dest, char *source)
{
int length = strlen(source);
for (int i = 0; i <= length; i++)
dest[i] = (WCHAR) source[i];
}
//**************************************************************************//
// Normalise an XMFLOAT3 as if it were a vector, i.e. return a vector of //
// unit magnitude. By Nigel. //
//**************************************************************************//
void XMFLOAT3normalise(XMFLOAT3 *toNormalise)
{
float magnitude = (toNormalise->x * toNormalise->x
+ toNormalise->y * toNormalise->y
+ toNormalise->z * toNormalise->z);
magnitude = sqrt(magnitude);
toNormalise->x /= magnitude;
toNormalise->y /= magnitude;
toNormalise->z /= magnitude;
}
//**************************************************************************//
// A couple of functions to trim the start and and of a C++ string, which //
// strangely doesn't have a trim() method. //
// //
// I nicked them from the Internet, which is why they are incomprehensible. //
//**************************************************************************//
std::wstring TrimStart(std::wstring s)
{
s.erase(s.begin(), std::find_if(s.begin(),
s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
std::wstring TrimEnd(std::wstring s)
{
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
//**************************************************************************//
// A simple structure to hold a single vertex. //
//**************************************************************************//
struct VertexXYZ
{
float x, y, z;
};
//**************************************************************************//
// Load the obj file into an array. Everything here is wide (unicode) //
//strings, hence the "w"s on the front of everything. //
// //
// However, my sample does not: //
// Read normal vectors. //
// Read texture UV coordinates //
// Read the materials (the lighting properties) from the associated ".mtl" //
// file //
// Create any textures (which are indicated in the associated ".mtl" file) //
// Handle meshes with subsets (meshes within meshes or groups in ".obj" //
// jargon) //
// //
// ...And only works with meshes in exactly the right format. //
//**************************************************************************//
std::string evaluateInstruction(std::wstring *line) {
std::string str(line->begin(), line->end());
std::regex e("^\w+");
std::cmatch m;
std::regex_match("g fuckoff", m, e);
int size = m.size();
if (size == 0){
return "FUCK";
} else {
return m.str(0);
}
}
SortOfMeshSubset *LoadMesh(LPSTR filename)
{
std::wifstream fileStream;
std::wstring line;
std::vector<Group*> groups;
Group *currentGroup;
fileStream.open(filename);
bool isOpen = fileStream.is_open(); //debugging only.
while(std::getline(fileStream, line))
{
line = TrimStart(line);
std::string instructionType = evaluateInstruction(&line);
// check if it is a vectory type
/*
bool isVectorType = ((line.compare(0, 2, L"v ") == 0) || (line.compare(0, 3, L"vn ") == 0) || (line.compare(0, 3, L"vt ") == 0));
if (isVectorType) {
} else if(line.compare(0, 2, L"g ") == 0) {
if (currentGroup) {
groups.push_back(currentGroup);
}
currentGroup = new Group("Hello");
}*/
}
return NULL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment