Пример #1
0
int main(int argc, char* argv[])
{
	std::cout << "VoxelAO by Kevin Ortegren, 2015" << std::endl;
	bool running = true;

	//Setup SDL window
	SDL_SysWMinfo info;

	HWND handle;
	
	if (SDL_Init(SDL_INIT_TIMER) != 0)
	{
		std::cerr << "SDL_Init failed: " << SDL_GetError() << std::endl;
	}

	window = SDL_CreateWindow("VoxelAO", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE );

	//Must init info struct with SDL version info, see documentation for explanation
	SDL_VERSION(&info.version);

	//If succeeded, init d3d11 and other things
	if (SDL_GetWindowWMInfo(window, &info))
	{
		handle = info.info.win.window;
	}
	else
	{
		std::cerr << "Failed to get WMInfo: " << SDL_GetError() << std::endl;
		running = false;
	}
	
	InitD3D(handle);

	SetupAntTweakBar();

	timer = new D3D11Timer(device, context);

	{
		ID3DBlob* vsblob,* psblob, *gsblob;
		ID3DBlob* errblob = nullptr;
		UINT flags = 0;

#ifndef _DEBUG // IF NOT DEBUG
		flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3;
#endif 
	
		//Create shaders
		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/simple.vertex", nullptr, nullptr, "main", "vs_5_0", flags, 0, &vsblob, nullptr));

		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/simple.pixel", nullptr, nullptr, "main", "ps_5_0", flags, 0, &psblob, nullptr));

		CHECKDX(device->CreateVertexShader(vsblob->GetBufferPointer(), vsblob->GetBufferSize(), nullptr, &VS));
		CHECKDX(device->CreatePixelShader(psblob->GetBufferPointer(), psblob->GetBufferSize(), nullptr, &PS));

		D3D11_INPUT_ELEMENT_DESC ied[] =
		{
			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
		};

		CHECKDX(device->CreateInputLayout(ied, 3, vsblob->GetBufferPointer(), vsblob->GetBufferSize(), &layout));

		//Full screen quad shader
		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/fsq.vertex", nullptr, nullptr, "main", "vs_5_0", flags, 0, &vsblob, nullptr));
		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/fsq.pixel", nullptr, nullptr, "main", "ps_5_0", flags, 0, &psblob, &errblob));

		CHECKDX(device->CreateVertexShader(vsblob->GetBufferPointer(), vsblob->GetBufferSize(), nullptr, &fsqVS));
		CHECKDX(device->CreatePixelShader(psblob->GetBufferPointer(), psblob->GetBufferSize(), nullptr, &fsqPS));

		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/fsq_only_AO.pixel", nullptr, nullptr, "main", "ps_5_0", flags, 0, &psblob, &errblob));
		CHECKDX(device->CreatePixelShader(psblob->GetBufferPointer(), psblob->GetBufferSize(), nullptr, &fsqOcclusionPS));

		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/fsq_no_AO.pixel", nullptr, nullptr, "main", "ps_5_0", flags, 0, &psblob, &errblob));
		CHECKDX(device->CreatePixelShader(psblob->GetBufferPointer(), psblob->GetBufferSize(), nullptr, &fsqNOOcclusionPS));
		
		D3D11_INPUT_ELEMENT_DESC iedfsq[] =
		{
			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
		};

		CHECKDX(device->CreateInputLayout(iedfsq, 1, vsblob->GetBufferPointer(), vsblob->GetBufferSize(), &fsqlayout));

		//Create voxelizer shaders
		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/voxelizing.vertex", nullptr, nullptr, "main", "vs_5_0", flags, 0, &vsblob, &errblob));

		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/voxelizing.geometry", nullptr, nullptr, "main", "gs_5_0", flags, 0, &gsblob, &errblob));

		CHECKDX(D3DCompileFromFile(L"../../Assets/Shaders/voxelizing.pixel", nullptr, nullptr, "main", "ps_5_0", flags, 0, &psblob, &errblob));

		CHECKDX(device->CreateVertexShader(vsblob->GetBufferPointer(), vsblob->GetBufferSize(), nullptr, &voxelVS));
		CHECKDX(device->CreateGeometryShader(gsblob->GetBufferPointer(), gsblob->GetBufferSize(), nullptr, &voxelGS));
		CHECKDX(device->CreatePixelShader(psblob->GetBufferPointer(), psblob->GetBufferSize(), nullptr, &voxelPS));

		D3D11_INPUT_ELEMENT_DESC iedvox[] =
		{
			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }
		};

		CHECKDX(device->CreateInputLayout(ied, 3, vsblob->GetBufferPointer(), vsblob->GetBufferSize(), &voxelLayout));

		vsblob->Release();
		gsblob->Release();
		psblob->Release();

	}

	{
		OBJLoader objLoader;

		mesh = objLoader.LoadBIN("../../Assets/Models/sponza.bin");
	}

	//Camera 
	camera.SetLens((float)M_PI_4, NEARZ, FARZ, WINDOW_WIDTH, WINDOW_HEIGHT);


	{
		//Init primitive spritebatch from DirectXTK
		primitiveBatch = new DirectX::PrimitiveBatch<DirectX::VertexPositionColor>(context, 65536, (size_t)(65536/3));
		basicEffect = new DirectX::BasicEffect(device);
	
		basicEffect->SetProjection(XMLoadFloat4x4(&camera.GetCamData().projMat));

		basicEffect->SetVertexColorEnabled(true);

		void const* shaderByteCode;
		size_t byteCodeLength;

		basicEffect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);

		CHECKDX(device->CreateInputLayout(DirectX::VertexPositionColor::InputElements,
			DirectX::VertexPositionColor::InputElementCount,
			shaderByteCode, byteCodeLength,
			&basicInputLayout));


		D3D11_BUFFER_DESC cbDesc;
		cbDesc.ByteWidth = sizeof(CameraData);
		cbDesc.Usage = D3D11_USAGE_DYNAMIC;
		cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
		cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
		cbDesc.MiscFlags = 0;
		cbDesc.StructureByteStride = 0;

		CHECKDX(device->CreateBuffer(&cbDesc, nullptr, &camConstBuffer));


		D3D11_BUFFER_DESC cbkernelDesc;
		cbkernelDesc.ByteWidth = sizeof(SampleKernelOptions);
		cbkernelDesc.Usage					= D3D11_USAGE_DYNAMIC;
		cbkernelDesc.BindFlags				= D3D11_BIND_CONSTANT_BUFFER;
		cbkernelDesc.CPUAccessFlags			= D3D11_CPU_ACCESS_WRITE;
		cbkernelDesc.MiscFlags				= 0;
		cbkernelDesc.StructureByteStride	= 0;

		CHECKDX(device->CreateBuffer(&cbkernelDesc, nullptr, &sampleConstBuffer));

		D3D11_BUFFER_DESC cbvoxelDesc;
		cbvoxelDesc.ByteWidth = sizeof(VoxelOptions);
		cbvoxelDesc.Usage = D3D11_USAGE_DYNAMIC;
		cbvoxelDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
		cbvoxelDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
		cbvoxelDesc.MiscFlags = 0;
		cbvoxelDesc.StructureByteStride = 0;

		CHECKDX(device->CreateBuffer(&cbvoxelDesc, nullptr, &voxelOptionConstBuffer));

		//Set up sampler state
		D3D11_SAMPLER_DESC samplerDesc;
		ZeroMemory(&samplerDesc, sizeof(samplerDesc));
		samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
		samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
		samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
		samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
		samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
		samplerDesc.MinLOD = 0;
		samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

		CHECKDX(device->CreateSamplerState(&samplerDesc, &linearSamplerState));

		//Rasterizer state
		D3D11_RASTERIZER_DESC RSdesc;
		ZeroMemory(&RSdesc, sizeof(RSdesc));
		RSdesc.FillMode = D3D11_FILL_SOLID;
		RSdesc.CullMode = D3D11_CULL_NONE;
		RSdesc.DepthClipEnable = TRUE;

		CHECKDX(device->CreateRasterizerState(&RSdesc, &RSStateSolid));

		RSdesc.FillMode = D3D11_FILL_WIREFRAME;
		CHECKDX(device->CreateRasterizerState(&RSdesc, &RSStateWireframe));
	}

	//Init voxel structure and GPU resources
	{
		voxelMatrix = Matrix::CreateOrthographic(VOXEL_STRUCTURE_WIDTH, VOXEL_STRUCTURE_WIDTH, 0.0f, VOXEL_STRUCTURE_WIDTH);
		voxelViewProjMatrix[0] = Matrix::CreateLookAt(Vector3(-VOXEL_STRUCTURE_WIDTH/2, 0, 0), Vector3(0, 0, 0), Vector3(0, 1, 0)) * voxelMatrix;
		voxelViewProjMatrix[1] = Matrix::CreateLookAt(Vector3(0, -VOXEL_STRUCTURE_WIDTH / 2, 0), Vector3(0, 0, 0), Vector3(1, 0, 0)) * voxelMatrix;
		voxelViewProjMatrix[2] = Matrix::CreateLookAt(Vector3(0, 0, -VOXEL_STRUCTURE_WIDTH / 2), Vector3(0, 0, 0), Vector3(0, 1, 0)) * voxelMatrix;

		D3D11_BUFFER_DESC voxmatbuffdesc;
		voxmatbuffdesc.ByteWidth = 3 * sizeof(Matrix);
		voxmatbuffdesc.Usage = D3D11_USAGE_IMMUTABLE;
		voxmatbuffdesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
		voxmatbuffdesc.CPUAccessFlags = 0;
		voxmatbuffdesc.MiscFlags = 0;
		voxmatbuffdesc.StructureByteStride = 0;

		D3D11_SUBRESOURCE_DATA voxmatdata;
		voxmatdata.pSysMem = &voxelViewProjMatrix[0];
		voxmatdata.SysMemPitch = 3 * sizeof(Matrix);
		voxmatdata.SysMemSlicePitch = 0;

		CHECKDX(device->CreateBuffer(&voxmatbuffdesc, &voxmatdata, &voxelMatBuffer));

		//	CreateVoxelBuffers();

		D3D11_BLEND_DESC blendDesc = { 0 };

		CHECKDX(device->CreateBlendState(&blendDesc, &voxelBlendState));

	}

	RebuildKernel();

	//RenderTarget clear color
	float clearColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };

	//Timer
	uint32 oldTime, currentTime;
	float dt;
	uint32 frames = 0;
	float collectedTime = 0.0f;
	float collectedAOTime = 0.0f;
	float collectedVoxelTime = 0.0f;

	currentTime = SDL_GetTicks();

	while (running)
	{
		oldTime = currentTime;
		currentTime = SDL_GetTicks();
		dt = (currentTime - oldTime) / 1000.0f;
		collectedTime += dt;
		++frames;
		if (collectedTime >= 1.0f)
		{
			collectedTime -= 1.0f;
			FPS = frames;

			AOTime = collectedAOTime / (float)frames;
			voxelTime = collectedVoxelTime / (float)frames;

			collectedAOTime = 0.0f;
			collectedVoxelTime = 0.0f;
			frames = 0;
		}
		running = HandleEvents();

		const Uint8* keystate = SDL_GetKeyboardState(NULL);

		//Check keys and move camera
		if (keystate[SDL_SCANCODE_A])
			camera.StrafeLeft(dt);
		if (keystate[SDL_SCANCODE_D])
			camera.StrafeRight(dt);
		if (keystate[SDL_SCANCODE_W])
			camera.MoveForward(dt);
		if (keystate[SDL_SCANCODE_S])
			camera.MoveBackward(dt);
		if (keystate[SDL_SCANCODE_LSHIFT])
			camera.MoveDown(dt);
		if (keystate[SDL_SCANCODE_SPACE])
			camera.MoveUp(dt);

		camera.Update();

		D3D11_MAPPED_SUBRESOURCE camResource;
		CHECKDX(context->Map(camConstBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &camResource));
		memcpy(camResource.pData, &camera.GetCamData(), sizeof(CameraData));
		context->Unmap(camConstBuffer, 0);


		if (sampleOptions.sizeX != prevSampleOptions.sizeX || sampleOptions.sizeY != prevSampleOptions.sizeY)
		{
			prevSampleOptions.sizeX = sampleOptions.sizeX;
			prevSampleOptions.sizeY = sampleOptions.sizeY;

			RebuildKernel();
		}

		D3D11_MAPPED_SUBRESOURCE kernelResource;
		CHECKDX(context->Map(sampleConstBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &kernelResource));
		memcpy(kernelResource.pData, &sampleOptions, sizeof(SampleKernelOptions));
		context->Unmap(sampleConstBuffer, 0);

		if (voxelRes != prevVoxelRes)
		{
			prevVoxelRes = voxelRes;

			switch (voxelRes)
			{
			case _64:
				numVoxels = 64;
				break;
			case _128:
				numVoxels = 128;
				break;
			case _256:
				numVoxels = 256;
				break;
			case _512:
				numVoxels = 512;
				break;
			case _1024:
				numVoxels = 1024;
				break;
			default:
				break;
			}

			voxelOptions.count = numVoxels;
			voxelOptions.width = VOXEL_STRUCTURE_WIDTH / (float)numVoxels;

			voxelElementCount = numVoxels * numVoxels * (numVoxels / 32);

#ifdef ENABLE_VOXELDRAW
			delete[] voxelCPUstructure;
			voxelCPUstructure = new uint32[voxelElementCount];
#endif

			CreateVoxelBuffers();

			D3D11_MAPPED_SUBRESOURCE voxelResource;
			CHECKDX(context->Map(voxelOptionConstBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &voxelResource));
			memcpy(voxelResource.pData, &voxelOptions, sizeof(VoxelOptions));
			context->Unmap(voxelOptionConstBuffer, 0);
		}



		///////////////////////
		//Voxelize step
		///////////////////////
		ID3D11RenderTargetView* RT = voxelVoidRT.GetRenderTargetView();
		context->OMSetRenderTargetsAndUnorderedAccessViews(1, &RT, 0, 1, 1, &voxelUAV, nullptr);
		context->OMSetBlendState(voxelBlendState, nullptr, 0xffffffff);
		context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

		//Copy a null buffer to clear voxel structure. Needs to be done if having dynamic geometry
		//context->CopyResource(voxelStructure, voxelClearBuffer);

		D3D11_VIEWPORT voxviewPort;
		ZeroMemory(&voxviewPort, sizeof(D3D11_VIEWPORT));

		voxviewPort.TopLeftX = 0;
		voxviewPort.TopLeftY = 0;
		voxviewPort.MinDepth = 0.0f;
		voxviewPort.MaxDepth = 1.0f;
		voxviewPort.Width = (float)numVoxels;
		voxviewPort.Height = (float)numVoxels;

		context->RSSetViewports(1, &voxviewPort);

		context->VSSetShader(voxelVS, 0, 0);
		context->GSSetShader(voxelGS, 0, 0);
		context->PSSetShader(voxelPS, 0, 0);
		context->PSSetConstantBuffers(1, 1, &voxelOptionConstBuffer);
		context->IASetInputLayout(voxelLayout);
		context->GSSetConstantBuffers(0, 1, &voxelMatBuffer);
		context->GSSetConstantBuffers(1, 1, &voxelOptionConstBuffer);
		context->RSSetState(RSStateSolid);

		timer->Start();
		mesh->Apply();
		mesh->Draw();
		timer->Stop();

		collectedVoxelTime += (float)timer->GetTime();

#ifdef ENABLE_VOXELDRAW
		if (enableDebugDraw)
		{
			context->CopyResource(voxelStagingStructure, voxelStructure);

			D3D11_MAPPED_SUBRESOURCE mapData;
			if (context->Map(voxelStagingStructure, 0, D3D11_MAP_READ, 0, &mapData) == S_OK)
			{
				memcpy(voxelCPUstructure, mapData.pData, voxelElementCount * sizeof(uint32));
				context->Unmap(voxelStagingStructure, 0);
			}
		}
#endif

		/////////////////////////////
		//G-buffer pass
		/////////////////////////////
		//Clear RTs before drawing
		colorRT.Clear();
		normalRT.Clear();
		positionRT.Clear();
		context->ClearRenderTargetView(backBuffer, clearColor);
		context->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

		//Set Gbuffer RTs
		ID3D11RenderTargetView* RTs[] = { colorRT.GetRenderTargetView(), normalRT.GetRenderTargetView(), positionRT.GetRenderTargetView() };
		ID3D11RenderTargetView* RTzero[] = { 0, 0, 0 };
		context->OMSetRenderTargets(3, RTs, depthStencilView);
		context->OMSetBlendState(nullptr, nullptr, 0xffffffff);

		//Set shaders
		D3D11_VIEWPORT viewPort;
		ZeroMemory(&viewPort, sizeof(D3D11_VIEWPORT));

		viewPort.TopLeftX = 0;
		viewPort.TopLeftY = 0;
		viewPort.MinDepth = 0.0f;
		viewPort.MaxDepth = 1.0f;
		viewPort.Width = WINDOW_WIDTH;
		viewPort.Height = WINDOW_HEIGHT;

		context->RSSetViewports(1, &viewPort);

		context->VSSetShader(VS, 0, 0);
		context->GSSetShader(nullptr, 0, 0);
		context->PSSetShader(PS, 0, 0);
		context->IASetInputLayout(layout);
		context->PSSetSamplers(0, 1, &linearSamplerState);
		context->VSSetConstantBuffers(0, 1, &camConstBuffer);
		context->RSSetState(RSStateSolid);

		//Draw geometry
		mesh->Apply();
		mesh->DrawIndexed();

		context->OMSetRenderTargets(3, RTzero, 0);

		/////////////////////////////
		//Draw to backbuffer, AO pass
		/////////////////////////////
		context->OMSetRenderTargets(1, &backBuffer, 0);

		context->VSSetShader(fsqVS, 0, 0);
		switch (drawMode)
		{
		case DRAW_NORMAL:
			context->PSSetShader(fsqPS, 0, 0);
			break;
		case DRAW_NO_AO:
			context->PSSetShader(fsqNOOcclusionPS, 0, 0);
			break;
		case DRAW_AO_ONLY:
			context->PSSetShader(fsqOcclusionPS, 0, 0);
			break;
		default:
			break;
		}
		
		context->IASetInputLayout(fsqlayout);
		colorRT.PSSetSRV(0);
		normalRT.PSSetSRV(1);
		positionRT.PSSetSRV(2);
		context->PSSetShaderResources(3, 1, &depthBufferView); 
		context->PSSetShaderResources(4, 1, &voxelSRV);
		context->PSSetConstantBuffers(0, 1, &voxelSampleKernel);
		context->PSSetConstantBuffers(1, 1, &sampleConstBuffer);
		context->PSSetConstantBuffers(2, 1, &voxelOptionConstBuffer);
		context->RSSetState(RSStateSolid);

		timer->Start();
		context->DrawInstanced(3, 1, 0, 0);
		timer->Stop();

		collectedAOTime += (float)timer->GetTime();


		//Unbind depth from input
		ID3D11ShaderResourceView* SRVzero[] = { 0 };
		context->PSSetShaderResources(3, 1, SRVzero);

		//Set up some things for DXTK, to draw some lines or other primitives
		context->OMSetRenderTargets(1, &backBuffer, depthStencilView);

		basicEffect->SetView(XMLoadFloat4x4(&camera.GetCamData().viewMat));
		basicEffect->Apply(context);
		context->IASetInputLayout(basicInputLayout);

		voxelCounter = 0;
		if(enableDebugDraw)
			DrawVoxels(primitiveBatch);
		
		if(enableDrawKernel)
			DrawKernel(primitiveBatch);
		
		TwRefreshBar(antbar);
		TwDraw();

		swapChain->Present(0, 0);

		//Unbind all resources
		context->PSSetShaderResources(0, 1, SRVzero);
		context->PSSetShaderResources(1, 1, SRVzero);
		context->PSSetShaderResources(2, 1, SRVzero);
		context->PSSetShaderResources(3, 1, SRVzero);
		context->PSSetShaderResources(4, 1, SRVzero);
	}

	std::cout << "Exiting program!" << std::endl;

	//Cleanup
	delete primitiveBatch;
	delete basicEffect;
	delete timer;

#ifdef ENABLE_VOXELDRAW
	delete[] voxelCPUstructure;
#endif

	depthStencilView->Release();
	RSStateSolid->Release();
	RSStateWireframe->Release();
	voxelBlendState->Release();
	voxelStagingStructure->Release();
	voxelSampleKernel->Release();
	voxelClearBuffer->Release();
	voxelSRV->Release();
	fsqVS->Release();
	fsqPS->Release();
	fsqOcclusionPS->Release();
	fsqNOOcclusionPS->Release();
	camConstBuffer->Release();
	sampleConstBuffer->Release();
	voxelOptionConstBuffer->Release();
	depthBufferView->Release();
	layout->Release();
	fsqlayout->Release();
	voxelLayout->Release();
	linearSamplerState->Release();
	VS->Release();
	PS->Release();
	voxelVS->Release();
	voxelGS->Release();
	voxelPS->Release();
	voxelStructure->Release();
	voxelUAV->Release();
	voxelMatBuffer->Release();
	swapChain->Release();
	backBuffer->Release();
	device->Release();
	context->Release();
	basicInputLayout->Release();
	SDL_DestroyWindow(window);

	return 0;
}