Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Tispe

Member Since 02 Oct 2010
Offline Last Active Yesterday, 03:51 AM

#5222258 (Question) How to make Circle Minimap?

Posted by Tispe on 09 April 2015 - 10:49 AM

I guess you can use multi-texturing with a quad. Have a texture with the shape of what you want and use it as alpha. You may need to move away from fixed pipeline. Or use the stencil buffer.




#5217951 FPS counter suspicious

Posted by Tispe on 20 March 2015 - 02:53 PM

If you use timeGetTime() then the return value is not accurate, it may fluctuate 10-20ms. Use QueryPerformanceCounter() to get accurate readings.




#5214427 Moving Data from CPU to a Structured Buffer

Posted by Tispe on 04 March 2015 - 04:15 AM

I figured out that my GPU (GTX690) can easily create new ID3D11Buffer's so fast that instead up updating an old buffer with new data using ID3D11DeviceContext::UpdateSubresource, I can just use ID3D11Device::CreateBuffer with initial data. Since I only touch ID3D11Device and not ID3D11DeviceContext, the whole operation can be done on another thread.

void DXDevice::SetMatrices(std::vector<DirectX::XMFLOAT4X4A> &Matrices)
{
	auto pBuf = CreateStructuredBufferResource(Matrices.data(), Matrices.size() * sizeof(DirectX::XMFLOAT4X4A));
	if (pBuf == nullptr)
		throw std::exception("CreateStructuredBufferResource failed");
	
	m_pImmediateContext->VSSetShaderResources(0, 1, &pBuf.p); // don't thread this
}
CComPtr<ID3D11ShaderResourceView> DXDevice::CreateStructuredBufferResource(const void* pDataSrc, UINT BufferSize)
{
	CComPtr<ID3D11ShaderResourceView> pShaderResourceView{ nullptr };
	CComPtr<ID3D11Buffer> pBuffer = CreateBufferResource(pDataSrc, BufferSize, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, D3D11_RESOURCE_MISC_BUFFER_STRUCTURED);

	if (pBuffer == nullptr)
		return nullptr;

	try
	{
		D3D11_SHADER_RESOURCE_VIEW_DESC rd;
		ZeroMemory(&rd, sizeof(rd));
		rd.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
		rd.BufferEx.NumElements = BufferSize / sizeof(DirectX::XMFLOAT4X4A);

		HR(m_pDevice->CreateShaderResourceView(pBuffer, &rd, &pShaderResourceView));
	}
	catch (std::exception &e)
	{
		WriteFile("error.log", e.what());
		return nullptr;
	}

	return pShaderResourceView;
}
CComPtr<ID3D11Buffer> DXDevice::CreateBufferResource(const void* pDataSrc, UINT BufferSize, UINT BindFlags, D3D11_USAGE Usage, UINT MiscFlags)
{
	CComPtr<ID3D11Buffer> pBuffer = nullptr;

	try
	{
		if (BufferSize == 0)
			throw std::exception("The requested buffer resource is of size 0");

		D3D11_SUBRESOURCE_DATA sd;
		ZeroMemory(&sd, sizeof(sd));
		sd.pSysMem = pDataSrc;

		D3D11_BUFFER_DESC bd;
		ZeroMemory(&bd, sizeof(bd));
		bd.Usage = Usage;
		bd.ByteWidth = BufferSize;
		bd.BindFlags = BindFlags;
		bd.MiscFlags = MiscFlags;
		if (MiscFlags == D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
			bd.StructureByteStride = sizeof(DirectX::XMFLOAT4X4A);

		HR(m_pDevice->CreateBuffer(&bd, pDataSrc ? &sd : nullptr, &pBuffer));
	}
	catch (std::exception &e)
	{
		WriteFile("error.log", e.what());
		return nullptr;
	}

	return pBuffer;
}
StructuredBuffer<float4x4> Matrices : register(t0);



#5212012 Getting BITMAP structure in DirectX.

Posted by Tispe on 20 February 2015 - 05:13 PM

I don't know exactly what you want. Do you have a BMP image and want to extract the width and height?

	std::vector<BYTE>Buffer = LoadBmpFile("myimage.bmp");

	BITMAPFILEHEADER* pFHeader = (BITMAPFILEHEADER*)Buffer.data();
	BITMAPINFO* pIHeader = (BITMAPINFO*)(Buffer.data() + sizeof(BITMAPFILEHEADER));

	if (pFHeader->bfType != 0x4d42)		//BM = 0x4d42
		throw std::exception("File type does not match header description in file");

	if (pFHeader->bfSize != Buffer.size())
		throw std::exception("File size does not match header description in file");

	BYTE* pImageData = Buffer.data() + pFHeader->bfOffBits;
	UINT Width = pIHeader->bmiHeader.biWidth;
	UINT Height = pIHeader->bmiHeader.biHeight;



#5208788 D3DCOMPILER_47.dll ?

Posted by Tispe on 04 February 2015 - 07:07 PM

Baw, right clicking the .hlsl -> Properties gives an unique properies profile for each source, gosh.... solved a bit of my troubles.

 

Edit:

$(ProjectDir)% was what I wanted :P

 

 

Pixelshader.h

#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// ss                                sampler      NA          NA    0        1
// Texture                           texture  float4          2d    0        1
//
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// COLOR                    0   xyzw        0     NONE   float   xyzw
// TEXCOORD                 0   xy          1     NONE   float   xy  
//
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
//
ps_4_0
dcl_sampler s0, mode_default
dcl_resource_texture2d (float,float,float,float) t0
dcl_input_ps linear v0.xyzw
dcl_input_ps linear v1.xy
dcl_output o0.xyzw
dcl_temps 1
sample r0.xyzw, v1.xyxx, t0.xyzw, s0
mul o0.xyzw, r0.xyzw, v0.xyzw
ret 
// Approximately 3 instruction slots used
#endif

const BYTE g_PShader[] =
{
     68,  88,  66,  67, 134,  53, 
     33, 181,  29,  15, 152,  24, 
     84,  51, 168, 141, 196, 181, 
     94, 202,   1,   0,   0,   0, 
    116,   2,   0,   0,   5,   0, 
      0,   0,  52,   0,   0,   0, 
    216,   0,   0,   0,  40,   1, 
      0,   0,  92,   1,   0,   0, 
    248,   1,   0,   0,  82,  68, 
     69,  70, 156,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   2,   0,   0,   0, 
     28,   0,   0,   0,   0,   4, 
    255, 255,   0,   1,   0,   0, 
    103,   0,   0,   0,  92,   0, 
      0,   0,   3,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   1,   0, 
      0,   0,   1,   0,   0,   0, 
     95,   0,   0,   0,   2,   0, 
      0,   0,   5,   0,   0,   0, 
      4,   0,   0,   0, 255, 255, 
    255, 255,   0,   0,   0,   0, 
      1,   0,   0,   0,  13,   0, 
      0,   0, 115, 115,   0,  84, 
    101, 120, 116, 117, 114, 101, 
      0,  77, 105,  99, 114, 111, 
    115, 111, 102, 116,  32,  40, 
     82,  41,  32,  72,  76,  83, 
     76,  32,  83, 104,  97, 100, 
    101, 114,  32,  67, 111, 109, 
    112, 105, 108, 101, 114,  32, 
     54,  46,  51,  46,  57,  54, 
     48,  48,  46,  49,  54,  51, 
     56,  52,   0, 171, 171, 171, 
     73,  83,  71,  78,  72,   0, 
      0,   0,   2,   0,   0,   0, 
      8,   0,   0,   0,  56,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   3,   0, 
      0,   0,   0,   0,   0,   0, 
     15,  15,   0,   0,  62,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   3,   0, 
      0,   0,   1,   0,   0,   0, 
      3,   3,   0,   0,  67,  79, 
     76,  79,  82,   0,  84,  69, 
     88,  67,  79,  79,  82,  68, 
      0, 171,  79,  83,  71,  78, 
     44,   0,   0,   0,   1,   0, 
      0,   0,   8,   0,   0,   0, 
     32,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      3,   0,   0,   0,   0,   0, 
      0,   0,  15,   0,   0,   0, 
     83,  86,  95,  84,  65,  82, 
     71,  69,  84,   0, 171, 171, 
     83,  72,  68,  82, 148,   0, 
      0,   0,  64,   0,   0,   0, 
     37,   0,   0,   0,  90,   0, 
      0,   3,   0,  96,  16,   0, 
      0,   0,   0,   0,  88,  24, 
      0,   4,   0, 112,  16,   0, 
      0,   0,   0,   0,  85,  85, 
      0,   0,  98,  16,   0,   3, 
    242,  16,  16,   0,   0,   0, 
      0,   0,  98,  16,   0,   3, 
     50,  16,  16,   0,   1,   0, 
      0,   0, 101,   0,   0,   3, 
    242,  32,  16,   0,   0,   0, 
      0,   0, 104,   0,   0,   2, 
      1,   0,   0,   0,  69,   0, 
      0,   9, 242,   0,  16,   0, 
      0,   0,   0,   0,  70,  16, 
     16,   0,   1,   0,   0,   0, 
     70, 126,  16,   0,   0,   0, 
      0,   0,   0,  96,  16,   0, 
      0,   0,   0,   0,  56,   0, 
      0,   7, 242,  32,  16,   0, 
      0,   0,   0,   0,  70,  14, 
     16,   0,   0,   0,   0,   0, 
     70,  30,  16,   0,   0,   0, 
      0,   0,  62,   0,   0,   1, 
     83,  84,  65,  84, 116,   0, 
      0,   0,   3,   0,   0,   0, 
      1,   0,   0,   0,   0,   0, 
      0,   0,   3,   0,   0,   0, 
      1,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      1,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   1,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0,   0,   0, 
      0,   0,   0,   0
};




#5207735 Efficient way to erase an element from std::vector

Posted by Tispe on 30 January 2015 - 01:40 PM

threw away interators in favor of indices:

	for (size_t i = 0; i < Futures.size(); )
	{
		if (Futures[i].wait_for(std::chrono::seconds(0)) == std::future_status::ready)
		{
			std::swap(Futures[i], Futures.back());
			Futures.pop_back();
		} else {
			i++;
		}
	}



#5207450 Efficient way to erase an element from std::vector

Posted by Tispe on 29 January 2015 - 10:10 AM

I remember from some C++ talks that the std::map or std::unordered_map might be suitable aswell.

std::remove_if(mymap.begin(), mymap.end(), [](std::pair<stuff1, stuff2> &mypair){
	return mypair.first->Status > 1;
});

zX07TZR.png

 

**EDIT:

Another approach I am testing is to iterate over the vector and remove elements on a condition, in this example an std::future:

std::vector<std::future<DWORD>> Futures;
for (auto it = Futures.begin(); it != Futures.end() ; )
{
	if (it->wait_for(std::chrono::seconds(0)) == std::future_status::ready)
	{
		std::swap(*it, Futures.back());
		Futures.pop_back();
	} else {
		it++;
	}
}



#5207327 Is there a default preferred DXGI_FORMAT

Posted by Tispe on 28 January 2015 - 07:34 PM

Supposedly you wanna use DXGI_FORMAT_R8G8B8A8_UNORM_SRGB as backbuffer format as it will gamma correct your backbuffer before sending it to the monitor.

 

You also wanna load textures into this format unless your loader function does that for you. You see, texture files are brighter then you see them on screen, that is because the monitor darkens images, so to correct for this darkening all textures are brightened up to compensate.

 

When fiddling with lighting and sampling in shaders you want your textures and backbuffer in this format such that you don't have to worry about reading brightened pixels, the format fixes this for you behind the scenes.




#5204591 Help, rolling my own D3DX11CreateShaderResourceViewFromFile/Memory

Posted by Tispe on 15 January 2015 - 05:34 PM


Pics or it didn’t happen. sRGB should make it darker, but you have to change your pipeline to use linear-space blending. Temporarily you will find it okay to use DXGI_FORMAT_R8G8B8A8_UNORM even though the image is sRGB, but eventually you will need to be doing everything in linear space.

 

Hi again, 

 

Orginal:

Orginal

 

DXGI_FORMAT_R8G8B8A8_UNORM:

DXGI FORMAT R8G8B8A8 UNORM

 

DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:

DXGI FORMAT R8G8B8A8 UNORM SRGB

 

As you can see the orginal image looks almost the same when rendered with DXGI_FORMAT_R8G8B8A8_UNORM, but darker with DXGI_FORMAT_R8G8B8A8_UNORM_SRGB. I don't know if the original image is gamma corrected or not, but since the result with using SRGB produces such a dark result, I will assume it is not?

 

Or do I need to fix something in code?

std::shared_ptr<TextureHandle> CreateBmpTextureFromFile(DXDevice &Renderer, std::string Filename)
{
	FileLoader File(Filename, false);
	if (File.GetStatus() != FileLoaderCodes::Complete)
		return nullptr;

	auto Buffer = File.GetBuffer();

	BITMAPFILEHEADER* pFHeader = (BITMAPFILEHEADER*)Buffer.data();
	BITMAPINFO* pIHeader = (BITMAPINFO*) (Buffer.data() + sizeof(BITMAPFILEHEADER));

	if (pFHeader->bfType != 0x4d42)		//BM = 0x4d42
		throw std::exception(std::string("File type does not match header description in file: ").append(Filename).c_str());

	if (pFHeader->bfSize != Buffer.size())
		throw std::exception(std::string("File size does not match header description in file: ").append(Filename).c_str());

	BYTE* pDataSrc = Buffer.data() + pFHeader->bfOffBits;
	UINT Width = pIHeader->bmiHeader.biWidth;
	UINT Height = pIHeader->bmiHeader.biHeight;
	INT SysMemPitch = Width * sizeof(DWORD);
	DXGI_FORMAT Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;

	// Expand from 24-bits to 32-bits by adding 0xff alphas to each pixel
	std::vector<DWORD> NewBuffer;
	NewBuffer.clear();

	for (size_t i = 0; i < Width*Height*3; i += 3)
	{
		BYTE Alpha = 0xff;
		BYTE Green = *(pDataSrc + i);
		BYTE Blue = *(pDataSrc + i + 1);
		BYTE Red = *(pDataSrc + i + 2);

		NewBuffer.push_back(MAKELONG(MAKEWORD(Red, Blue), MAKEWORD(Green, Alpha)));
	}

	auto pTexture = std::make_shared<TextureHandle>();
	pTexture->Name = Filename;
	pTexture->pTex = Renderer.CreateTexture(NewBuffer.data(), Width, Height, Format, SysMemPitch, true);

	return pTexture;
}
CComPtr<ID3D11ShaderResourceView> DXDevice::CreateTexture(const void* pDataSrc, UINT Width, UINT Height, DXGI_FORMAT Format, UINT SysMemPitch, bool MipMap)
{
	CComPtr<ID3D11ShaderResourceView> pShaderResourceView{ nullptr };
	CComPtr<ID3D11Texture2D> pTexture{ nullptr };

	try
	{
		D3D11_SUBRESOURCE_DATA sd;
		ZeroMemory(&sd, sizeof(sd));
		sd.pSysMem = pDataSrc;
		sd.SysMemPitch = SysMemPitch;

		D3D11_TEXTURE2D_DESC td;
		ZeroMemory(&td, sizeof(td));
		td.Width = Width;
		td.Height = Height;
		td.Format = Format;
		td.MipLevels = MipMap ? 0 : 1;
		td.ArraySize = 1;
		td.SampleDesc.Count = 1;
		td.Usage = D3D11_USAGE_DEFAULT;
		td.BindFlags = MipMap ? D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE : D3D11_BIND_SHADER_RESOURCE;
		td.MiscFlags = MipMap ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;

		if (MipMap)
		{
			std::vector<D3D11_SUBRESOURCE_DATA> sdVec(GetNumMipLevels(Width, Height), sd);
			HR(m_pDevice->CreateTexture2D(&td, sdVec.data(), &pTexture.p));

			D3D11_SHADER_RESOURCE_VIEW_DESC rd;
			ZeroMemory(&rd, sizeof(rd));
			rd.Format = Format;
			rd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
			rd.Texture2D.MostDetailedMip = 0;
			rd.Texture2D.MipLevels = D3D11_RESOURCE_MISC_GENERATE_MIPS;

			HR(m_pDevice->CreateShaderResourceView(pTexture, &rd, &pShaderResourceView));

			/*
			GenerateMips isn't really meant for generating mips for static textures, it's meant for render targets that are rendered to every frame.
			If texture is static, make it with D3D11_USAGE_IMMUTABLE, and without D3D11_BIND_RENDER_TARGET for best performance.
			*/
			m_pImmediateContext->GenerateMips(pShaderResourceView);		// Temporary, create a CONCURRENT! FIFO container and call GenerateMips(Front()); pop; once per frame
		}
		else {
			HR(m_pDevice->CreateTexture2D(&td, &sd, &pTexture.p));
			HR(m_pDevice->CreateShaderResourceView(pTexture, nullptr, &pShaderResourceView));
		}

	}
	catch (std::exception &e)
	{
		WriteFile("error.log", e.what());
		return nullptr;
	}

	return pShaderResourceView;
}
void DXDevice::InitSamplers()
{
	D3D11_SAMPLER_DESC samplerdesc;
	samplerdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	samplerdesc.MaxAnisotropy = 8;
	samplerdesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
	samplerdesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
	samplerdesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
	samplerdesc.BorderColor[0] = 0.0f;
	samplerdesc.BorderColor[1] = 0.0f;
	samplerdesc.BorderColor[2] = 0.0f;
	samplerdesc.BorderColor[3] = 0.0f;
	samplerdesc.MinLOD = 0.0f;
	samplerdesc.MaxLOD = FLT_MAX;
	samplerdesc.MipLODBias = 0.0f;

	HR(m_pDevice->CreateSamplerState(&samplerdesc, &pSS));
	m_pImmediateContext->PSSetSamplers(0, 1, &pSS.p);
}

void DXDevice::InitBlenders()
{
	D3D11_BLEND_DESC bd;
	bd.AlphaToCoverageEnable = true;
	bd.IndependentBlendEnable = false;
	bd.RenderTarget[0].BlendEnable = true;
	bd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	bd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	bd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
	bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	bd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

	HR(m_pDevice->CreateBlendState(&bd, &pBS.p));
	m_pImmediateContext->OMSetBlendState(pBS, nullptr, 0xffffffff);
}



#5177820 DX12 - Documentation / Tutorials?

Posted by Tispe on 03 September 2014 - 04:13 AM

Hi

 

 

I wanted to know if anyone here has had the chance to use/look at the Direct3D 12 API?

 

How different is it from DX9, DX11? Is it a whole paradigm shift?

 

Is it the basics: "create buffer -> copy data to buffer -> Draw from buffer" kind of thing?

 

Im mostly just familiar with DX9 and want to catch up with DX12. Should I learn DX11 while waiting for docs/tutorials?

 

Cheers!

 




#5153002 DirectX 9 SetRenderTarget

Posted by Tispe on 11 May 2014 - 11:52 PM

Right after you create your device, use use code like this to get a pointer to the "screen" (the default colour target and default depth target).

IDirect3DSurface9* defaultColorBuffer = 0;
IDirect3DSurface9* defaultDepthBuffer = 0;
device->GetRenderTarget( 0, &defaultColorBuffer );
device->GetDepthStencilSurface( &defaultDepthBuffer );

After rendering to a texture, you can use device->SetRenderTarget(defaultColorBuffer) to go back to rendering to the screen.

Yes, SetRenderTarget is the correct way to render to textures wink.png

 

[edit] ninja'ed by LS ph34r.png

 

And those surfaces has to be Released at the end of the program, and also released and reaquired when changing display settings?




#5152568 Four pillars of object oriented programming

Posted by Tispe on 09 May 2014 - 11:57 AM

C++ is a light-weight abstraction programming language. Type- and exception- safety I think is at the core of the language.

 

The constructor acquire resources and the destructor releases them. I believe OOP in C++ is just a consequence of these fundamental principles; OOP is not a design goal in itself.




#5152492 simple win32 hack for user/pass input

Posted by Tispe on 09 May 2014 - 03:00 AM

For those interested:

#include <Windows.h>
#include "Header.h"
#include <string>

LRESULT CALLBACK dlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	std::string* pPass = NULL;

	if(Msg == WM_INITDIALOG)
	{
		SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
	} else {
		pPass = reinterpret_cast<std::string*>(GetWindowLong(hDlg, GWL_USERDATA));
	}

	switch (Msg)
	{
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case 27:
				{
					wchar_t szItemData[64];
					if (!GetDlgItemText(hDlg, 26, szItemData, 64)) 
						*szItemData=0;

					if(pPass && szItemData)
					{
						std::wstring my(szItemData);
						*pPass = std::string( my.begin(), my.end() );
					}
					EndDialog(hDlg, IDOK);
					return 1;
				}
				break;
			case 28:
				{
					EndDialog(hDlg, IDOK);
					return 1;
				}
				break;
			default:
				break;
			}
			break;
		}
	case WM_CLOSE:
		EndDialog(hDlg, IDOK);
		return 1;
	}

	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	std::string Password;

	DialogTemplate dialogTemplate("Login required!", WS_CAPTION | DS_CENTER, 0, 0, 109, 45, "Tahoma");
	dialogTemplate.AddStatic("User:", WS_VISIBLE, 0, 3, 3, 20, 10, -1);
	dialogTemplate.AddStatic("Pass:", WS_VISIBLE, 0, 3, 16, 20, 10, -1);
	dialogTemplate.AddEditBox("", WS_VISIBLE, WS_EX_STATICEDGE, 25, 3, 81, 10, 25);
	dialogTemplate.AddEditBox("", WS_VISIBLE | ES_PASSWORD, WS_EX_STATICEDGE, 25, 16, 81, 10, 26);
	dialogTemplate.AddButton("Confirm", WS_VISIBLE, 0, 3, 29, 50, 13, 27);
	dialogTemplate.AddButton("Exit", WS_VISIBLE, 0, 56, 29, 50, 13, 28);
	DialogBoxIndirectParam(NULL, dialogTemplate, NULL, (DLGPROC)dlgProc, (LPARAM)&Password);

	MessageBoxA(NULL, Password.c_str(), "Let us see....", 0);
}
#include <windows.h>

class DialogTemplate
{

public:

	DialogTemplate(LPCSTR caption, DWORD style, int x, int y, int w, int h, LPCSTR font = NULL, WORD fontSize = 8)
	{

		usedBufferLength = sizeof(DLGTEMPLATE );
		totalBufferLength = usedBufferLength;

		dialogTemplate = (DLGTEMPLATE*)malloc(totalBufferLength);

		dialogTemplate->style = style;

		if (font != NULL)
		{
			dialogTemplate->style |= DS_SETFONT;
		}

		dialogTemplate->x     = x;
		dialogTemplate->y     = y;
		dialogTemplate->cx    = w;
		dialogTemplate->cy    = h;
		dialogTemplate->cdit  = 0;

		dialogTemplate->dwExtendedStyle = 0;

		// The dialog box doesn't have a menu or a special class

		AppendData(L"\0", 2);
		AppendData(L"\0", 2);

		// Add the dialog's caption to the template

		AppendString(caption);

		if (font != NULL)
		{
			AppendData(&fontSize, sizeof(WORD));
			AppendString(font);
		}

	}

	void AddComponent(LPCSTR type, LPCSTR caption, DWORD style, DWORD exStyle,
		int x, int y, int w, int h, WORD id)
	{

		DLGITEMTEMPLATE item;

		item.style = style;
		item.x     = x;
		item.y     = y;
		item.cx    = w;
		item.cy    = h;
		item.id    = id;

		item.dwExtendedStyle = exStyle;

		AppendData(&item, sizeof(DLGITEMTEMPLATE));

		AppendString(type);
		AppendString(caption);

		WORD creationDataLength = 0;
		AppendData(&creationDataLength, sizeof(WORD));

		// Increment the component count

		dialogTemplate->cdit++;

	}

	void AddButton(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
		int w, int h, WORD id)
	{

		AddStandardComponent(0x0080, caption, style, exStyle, x, y, w, h, id);

		WORD creationDataLength = 0;
		AppendData(&creationDataLength, sizeof(WORD));

	}

	void AddEditBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
		int w, int h, WORD id)
	{

		AddStandardComponent(0x0081, caption, style, exStyle, x, y, w, h, id);

		WORD creationDataLength = 0;
		AppendData(&creationDataLength, sizeof(WORD));

	}

	void AddStatic(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
		int w, int h, WORD id)
	{

		AddStandardComponent(0x0082, caption, style, exStyle, x, y, w, h, id);

		WORD creationDataLength = 0;
		AppendData(&creationDataLength, sizeof(WORD));

	}

	void AddListBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
		int w, int h, WORD id)
	{

		AddStandardComponent(0x0083, caption, style, exStyle, x, y, w, h, id);

		WORD creationDataLength = 0;
		AppendData(&creationDataLength, sizeof(WORD));

	}

	void AddScrollBar(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
		int w, int h, WORD id)
	{

		AddStandardComponent(0x0084, caption, style, exStyle, x, y, w, h, id);

		WORD creationDataLength = 0;
		AppendData(&creationDataLength, sizeof(WORD));

	}

	void AddComboBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
		int w, int h, WORD id)
	{

		AddStandardComponent(0x0085, caption, style, exStyle, x, y, w, h, id);

		WORD creationDataLength = 0;
		AppendData(&creationDataLength, sizeof(WORD));

	}

	/**
	* Returns a pointer to the Win32 dialog template which the object
	* represents. This pointer may become invalid if additional
	* components are added to the template.
	*/

	operator const DLGTEMPLATE*() const
	{
		return dialogTemplate;
	}

	virtual ~DialogTemplate()
	{
		free(dialogTemplate);
	}

protected:

	void AddStandardComponent(WORD type, LPCSTR caption, DWORD style,
		DWORD exStyle, int x, int y, int w, int h, WORD id)
	{

		DLGITEMTEMPLATE item;

		// DWORD algin the beginning of the component data

		AlignData(sizeof(DWORD));

		item.style = style;
		item.x     = x;
		item.y     = y;
		item.cx    = w;
		item.cy    = h;
		item.id    = id;

		item.dwExtendedStyle = exStyle;

		AppendData(&item, sizeof(DLGITEMTEMPLATE));

		WORD preType = 0xFFFF;

		AppendData(&preType, sizeof(WORD));
		AppendData(&type, sizeof(WORD));

		AppendString(caption);

		// Increment the component count

		dialogTemplate->cdit++;

	}

	void AlignData(int size)
	{

		int paddingSize = usedBufferLength % size;

		if (paddingSize != 0)
		{
			EnsureSpace(paddingSize);
			usedBufferLength += paddingSize;
		}

	}

	void AppendString(LPCSTR string)
	{

		int length = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0);

		WCHAR* wideString = (WCHAR*)malloc(sizeof(WCHAR) * length);
		MultiByteToWideChar(CP_ACP, 0, string, -1, wideString, length);

		AppendData(wideString, length * sizeof(WCHAR));
		free(wideString);

	}

	void AppendData(void* data, int dataLength)
	{

		EnsureSpace(dataLength);

		memcpy((char*)dialogTemplate + usedBufferLength, data, dataLength);
		usedBufferLength += dataLength;

	}

	void EnsureSpace(int length)
	{

		if (length + usedBufferLength > totalBufferLength)
		{

			totalBufferLength += length * 2;

			void* newBuffer = malloc(totalBufferLength);
			memcpy(newBuffer, dialogTemplate, usedBufferLength);

			free(dialogTemplate);
			dialogTemplate = (DLGTEMPLATE*)newBuffer;

		}

	}

private:

	DLGTEMPLATE* dialogTemplate;

	int totalBufferLength;
	int usedBufferLength;

};



#5149619 Multithread question

Posted by Tispe on 26 April 2014 - 06:27 AM

Consider pipelining this, so that you have two identical textures which are updated every other frame for maximum utilization. The other thread is updating one texture while the main thread renders from the other.




#5148347 Tips on FileLoader code

Posted by Tispe on 20 April 2014 - 07:10 AM


Just from a coding standard view why are you placing an enter after a function or if conditional and the { and not on an else clause.

 

Well, I just ported to Visual Studio 2013 Express for C++11 support, and the IDE forces that behaviour.... It also wants a space between if and (. Prob someone at MS wants ifs and elses in the same vertical....

 

I thouched up my code, please let me know if it is unsafe:

class FileLoader
{
public:
	FileLoader(std::string Filename, bool Asynchronous);
	~FileLoader();

	FileLoaderCodes GetStatus();

private:
	void Tick();
	void ReadAsynch();
	void ReadSynch();

	HANDLE file;
	FileLoaderCodes Status;
	DWORD Size;
	DWORD NumberOfBytesTransfered;
	DWORD LastError;
	OVERLAPPED OverlappedInfo;
	std::vector<BYTE> buffer;
};
FileLoader::FileLoader(std::string Filename, bool Asynchronous)
{
	Status = FileLoaderCodes::Unknown;
	Size = 0;
	NumberOfBytesTransfered = 0;
	LastError = 0;
	ZeroMemory(&OverlappedInfo, sizeof(OverlappedInfo));

	if (Asynchronous)
	{
		file = CreateFileA(Filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED, NULL);
	}
	else {
		file = CreateFileA(Filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
	}

	if (file == INVALID_HANDLE_VALUE)
	{
		LastError = GetLastError();
		Status = FileLoaderCodes::InvalidHandle;
		return;
	}

	Size = GetFileSize(file, NULL);
	if (Size == INVALID_FILE_SIZE)
	{
		LastError = GetLastError();
		Status = FileLoaderCodes::InvalidSize;
		CloseHandle(file);
		return;
	}

	buffer.resize(Size);
	if (buffer.capacity() < Size)
	{
		Status = FileLoaderCodes::AllocError;
		CloseHandle(file);
		return;
	}

	if (Asynchronous)
	{
		ReadAsynch();
	}
	else {
		ReadSynch();
	}

}

FileLoader::~FileLoader()
{
	CloseHandle(file);
}

FileLoaderCodes FileLoader::GetStatus()
{
	Tick();
	return Status;
}

void FileLoader::ReadAsynch()
{
	OverlappedInfo.hEvent = CreateEvent(NULL, true, false, NULL);

	if (OverlappedInfo.hEvent == NULL)
	{
		LastError = GetLastError();
		Status = FileLoaderCodes::CreateEventError;
		CloseHandle(file);
		return;
	}

	if (ReadFile(file, buffer.data(), Size, NULL, &OverlappedInfo))
	{
		// Operation has completed immediately.
		Status = FileLoaderCodes::Complete;
	}
	else {
		LastError = GetLastError();
		if (LastError != ERROR_IO_PENDING)
		{
			// Some other error occurred while reading the file.
			CloseHandle(file);
			Status = FileLoaderCodes::ReadError;
		}
		else {
			//Operation has been queued and will complete in the future. 
			Status = FileLoaderCodes::InTransfer;
		}

	}
}

void FileLoader::ReadSynch()
{
	if (ReadFile(file, buffer.data(), Size, &NumberOfBytesTransfered, NULL))
	{
		// Operation has completed.
		CloseHandle(file);
		if (Size == NumberOfBytesTransfered){		//Might be 0 if EOF???
			Status = FileLoaderCodes::Complete;
		}
		else {
			Status = FileLoaderCodes::ReadSizeError;
		}
	}
	else {
		// Some other error occurred while reading the file.
		LastError = GetLastError();
		CloseHandle(file);
		Status = FileLoaderCodes::ReadError;
	}
}

void FileLoader::Tick()
{
	if (Status == FileLoaderCodes::InTransfer)
	{
		if (HasOverlappedIoCompleted(&OverlappedInfo))
		{
			if (GetOverlappedResult(file, &OverlappedInfo, &NumberOfBytesTransfered, false) != 0)
			{
				// Operation has completed.
				CloseHandle(file);
				if (Size == NumberOfBytesTransfered){
					Status = FileLoaderCodes::Complete;
				}
				else {
					Status = FileLoaderCodes::ReadSizeError;
				}
			}
			else{
				// Operation has failed? / HasOverlappedIoCompleted is true
				LastError = GetLastError();
				CloseHandle(file);
				Status = FileLoaderCodes::OverlappedResultError;
			}
		}
	}
}
enum class FileLoaderCodes
{
	Unknown,
	Complete,
	InTransfer,
	InvalidHandle,
	InvalidSize,
	ReadError,
	ReadSizeError,
	AllocError,
	CreateEventError,
	OverlappedResultError
};





PARTNERS