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
Online Last Active Today, 01:16 PM

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

Posted by Tispe on Yesterday, 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
};



#5147726 10-bit Monitors

Posted by Tispe on 17 April 2014 - 02:59 PM

Hello

 

There are new monitors on the market that support 10-bits per channel. But in CAPS I can only find support for D3DFMT_X8R8G8B8 and D3DFMT_R5G6B5.

 

I do not have a 10bit monitor, but if I had one would a 10bit format appear in CAPS?

 

How can DirectX render to 10bit monitors?




#5141126 methods for drawing rain

Posted by Tispe on 21 March 2014 - 04:12 PM


rain falls so fast, the eye can only track it for a split second. so using scrolling or particles to get a "falling" effect are unnecessary. multiple randomly animated textures, or a randomly jittered single texture works just fine.

 

Then why not have a texture atlas of different sized raindrops. And use the ones depending on the viewing angle?




#5138682 Passing Concurreny::concurrent_queue by reference to thread

Posted by Tispe on 13 March 2014 - 07:08 AM

If anyone cares I removed a race condition:

class concurrentIO : public std::enable_shared_from_this<concurrentIO>
{
public:
	shared_ptr<concurrentIO> NoRaceCondition;
	concurrent_queue<string> SendQueue;
	concurrent_queue<string> ReceiveQueue;
};

class Network
{
public:
	Network(void) : Connected(false)
	{
	}
	~Network(void)
	{
		Disconnect();
	}

	void Connect(string server, short port)
	{
		spFIFOs = make_shared<concurrentIO>();
		spFIFOs->NoRaceCondition = spFIFOs;
		thread workerThread = thread(&Network::ThreadRoutine, server, port, spFIFOs.get());
		workerThread.detach();
		Connected = true;
	}
	void Disconnect()
	{
		spFIFOs.reset();
		Connected = false;
	}
	bool Send(string message)
	{
		if(Connected)
		{
			spFIFOs->SendQueue.push(message);
		}

		return Connected;
	}
	bool GetMessage(string &message)
	{
		if(Connected)
		{
			return spFIFOs->ReceiveQueue.try_pop(message);
		}

		return false;
	}

private:
	bool Connected;
	shared_ptr<concurrentIO> spFIFOs;

	static DWORD ThreadRoutine(string server, short port, LPVOID param)
	{
		shared_ptr<concurrentIO> spFIFOs = static_cast<concurrentIO* >(param)->shared_from_this();
		spFIFOs->NoRaceCondition.reset();

		if (enet_initialize () != 0){
			return 1;
		}

		ENetHost* client = NULL;
		client = enet_host_create (NULL, 1, 2, 0, 0);
		if(client == NULL){
			spFIFOs->ReceiveQueue.push(string("An error occurred while trying to create an ENet client host."));
		} else {
			ENetAddress address;
			ENetEvent event;
			ENetPeer *peer = NULL;

			enet_address_set_host(& address, server.c_str());
			address.port = port;

			peer = enet_host_connect(client, & address, 2, 0);    
			if (peer == NULL){
				spFIFOs->ReceiveQueue.push(string("No available peers for initiating an ENet connection."));
			} else {
				if (enet_host_service (client, & event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT){
					spFIFOs->ReceiveQueue.push(string("Connection to server succeeded."));

					bool Quit = false;
					while(!Quit)		
					{
						if(spFIFOs.unique())			//if main side resets its shared pointer to signal Disconnect
						{
							enet_peer_disconnect(peer, 0);
							if(enet_host_service (client, & event, 3000) > 0)
							{
								switch (event.type)
								{
								case ENET_EVENT_TYPE_RECEIVE:
									enet_packet_destroy (event.packet);
									break;
								case ENET_EVENT_TYPE_DISCONNECT:
									spFIFOs->ReceiveQueue.push(string("Disconnection succeeded."));
									continue;
								}
							}
							enet_peer_reset(peer);
							Quit = true;
							continue;
						}

						string SendString;
						while(spFIFOs->SendQueue.try_pop(SendString))
						{
							ENetPacket* packet = enet_packet_create (SendString.c_str(), SendString.length() + 1, ENET_PACKET_FLAG_RELIABLE);
							enet_peer_send(peer, 0, packet);
						}

						if(enet_host_service(client, &event, 0) > 0)
						{
							switch (event.type)
							{
							case ENET_EVENT_TYPE_RECEIVE:
								/*printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
								event.packet -> dataLength,
								event.packet -> data,
								event.peer -> data,
								event.channelID);*/
								spFIFOs->ReceiveQueue.push(string((char*)event.packet->data));
								enet_packet_destroy (event.packet);
								break;
							case ENET_EVENT_TYPE_DISCONNECT:
								spFIFOs->ReceiveQueue.push(string("Disconnected."));
								Quit = true;
							}
						}
					}

				} else {
					enet_peer_reset(peer);
					spFIFOs->ReceiveQueue.push(string("Connection to server failed."));
				}

			}

		}

		spFIFOs->SendQueue.clear();
		if(client) enet_host_destroy(client);
		enet_deinitialize();
		return 0;
	}
};



#5138386 Passing Concurreny::concurrent_queue by reference to thread

Posted by Tispe on 12 March 2014 - 06:56 AM

I think I fixed it.

 

Apperantly, I need to wrap it in std::ref

void Connect(string server, short port)
	{
		workerThread = thread(&Network::ThreadRoutine, server, port, ref(SendQueue), ref(ReceiveQueue));
	}

I have never heard of std::ref before....

 

 

For anyone interested:

class Network
{
public:
	Network(void)
	{
	}
	~Network(void)
	{
		Disconnect();
	}

	void Connect(string server, short port)
	{
		workerThread = thread(&Network::ThreadRoutine, server, port, ref(SendQueue), ref(ReceiveQueue));
		workerThread.detach();
	}
	void Disconnect()
	{
		SendQueue.push(string("..quit"));
	}
	void Send(string message)
	{
		SendQueue.push(message);
	}
	bool GetMessage(string &message)
	{
		return ReceiveQueue.try_pop(message);
	}

private:
	thread workerThread;
	concurrent_queue<string> SendQueue;
	concurrent_queue<string> ReceiveQueue;

	static DWORD ThreadRoutine(string server, short port, concurrent_queue<string> &SendQueue, concurrent_queue<string> &ReceiveQueue)
	{
		if (enet_initialize () != 0){
			return 1;
		}

		ENetHost* client = NULL;
		client = enet_host_create (NULL, 1, 2, 0, 0);
		if(client == NULL){
			ReceiveQueue.push(string("An error occurred while trying to create an ENet client host."));
		} else {
			ENetAddress address;
			ENetEvent event;
			ENetPeer *peer = NULL;

			enet_address_set_host (& address, server.c_str());
			address.port = port;

			peer = enet_host_connect (client, & address, 2, 0);    
			if (peer == NULL){
				ReceiveQueue.push(string("No available peers for initiating an ENet connection."));
			} else {
				if (enet_host_service (client, & event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT){
					ReceiveQueue.push(string("Connection to server succeeded."));
					bool Quit = false;
					while(!Quit)
					{
						string SendString;
						if(SendQueue.try_pop(SendString))
						{
							if(strcmp(SendString.c_str(), "..quit") == 0){
								ReceiveQueue.push(string("Exiting worker thread."));
								Quit = true;
								enet_peer_disconnect(peer, 0);
								if(enet_host_service (client, & event, 3000) > 0)
								{
									switch (event.type)
									{
									case ENET_EVENT_TYPE_RECEIVE:
										enet_packet_destroy (event.packet);
										break;
									case ENET_EVENT_TYPE_DISCONNECT:
										ReceiveQueue.push(string("Disconnection succeeded."));
										continue;
									}
								}

								enet_peer_reset(peer);
								continue;
							} else {
								ENetPacket* packet = enet_packet_create (SendString.c_str(), SendString.length() + 1, ENET_PACKET_FLAG_RELIABLE);
								enet_peer_send (peer, 0, packet);
							}
						}

						if(enet_host_service(client, &event, 1) > 0)
						{
							switch (event.type)
							{
							case ENET_EVENT_TYPE_RECEIVE:
								/*printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
									event.packet -> dataLength,
									event.packet -> data,
									event.peer -> data,
									event.channelID);*/
								ReceiveQueue.push(string((char*)event.packet->data));
								enet_packet_destroy (event.packet);
								break;
							case ENET_EVENT_TYPE_DISCONNECT:
								ReceiveQueue.push(string("Disconnected."));
								Quit = true;
							}
						}
					}

				} else {
					enet_peer_reset (peer);
					ReceiveQueue.push(string("Connection to server failed."));
				}

			}

		}

		SendQueue.clear();
		if(client) enet_host_destroy(client);
		enet_deinitialize();
		return 0;
	}
};




#5138086 Running game Server as a system Service

Posted by Tispe on 11 March 2014 - 06:49 AM

Hi

 

I have a simple server/relay which runs on a Virtual Private Server that I rent for 10$/mo. Sometimes the system may restart abruptly and I have to RDP to the system, and log in in order to start my server application.

 

So I figured that I should rather create a Service, which will run without me having to log in after a system restart.

I am using this tutorial: http://www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus

 

Is this an good idea? Any things to keep in mind?

 

 

 

Also, would setting the priority to RealTime work/benefit for a system Service?

SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);





PARTNERS