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 Today, 03:32 PM

#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);



#5132568 Double Dispatch errors

Posted by Tispe on 19 February 2014 - 02:21 AM

Thanks, got it working by moving the class implementation after the declarations.

#define	MsgAddPlayer		1
#define	MsgRmvPlayer		2
#define	MsgPosPlayer		3

struct PlayerData 
{
	DWORD ID;
	float Pos[3];
};

struct MessageBase 
{
	DWORD Type;
	DWORD Size;
};

struct MessageAdd : MessageBase
{
	DWORD ID;
	float Pos[3];
};

struct MessageRemove : MessageBase 
{
	DWORD ID;
};

struct MessagePos : MessageBase 
{
	DWORD ID;
	float Pos[3];
};

struct InstructionBase;
struct InstructionAdd;
struct InstructionRemove;
struct InstructionPos;

class PlayerManager
{
public:
	void Process(InstructionBase& nothing);
	void Process(InstructionAdd& add);
	void Procces(InstructionRemove& remove);
	void Procces(InstructionPos& pos);
//private:
	std::map<DWORD, std::shared_ptr<PlayerData> > PlayersMap;
};

struct InstructionBase 
{
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionAdd : InstructionBase
{
	MessageAdd Data;
	InstructionAdd(DWORD ID, float x, float y, float z)
	{
		Data.Type = MsgAddPlayer;
		Data.ID = ID;
		Data.Pos[0] = x;
		Data.Pos[1] = y;
		Data.Pos[2] = z;
	}
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionRemove : InstructionBase
{
	MessageRemove Data;
	InstructionRemove(DWORD ID)
	{
		Data.Type = MsgRmvPlayer;
		Data.ID = ID;
	}
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

struct InstructionPos : InstructionBase
{
	MessagePos Data;
	InstructionPos(DWORD ID, float x, float y, float z)
	{
		Data.Type = MsgPosPlayer;
		Data.ID = ID;
		Data.Pos[0] = x;
		Data.Pos[1] = y;
		Data.Pos[2] = z;
	}
	virtual void Process(PlayerManager& processer){
		processer.Process(*this);
	}
};

void PlayerManager::Process(InstructionBase& nothing)
{
}

void PlayerManager::Process(InstructionAdd& add)
{
	std::shared_ptr<PlayerData> spNewPlayer(new PlayerData);
	PlayersMap[add.Data.ID] = spNewPlayer;
	spNewPlayer->Pos[0] = add.Data.Pos[0];
	spNewPlayer->Pos[1] = add.Data.Pos[1];
	spNewPlayer->Pos[2] = add.Data.Pos[2];
}

void PlayerManager::Procces(InstructionRemove& remove)
{
	PlayersMap.erase(remove.Data.ID);
}

void PlayerManager::Procces(InstructionPos& pos)
{
	PlayersMap[pos.Data.ID]->Pos[0] = pos.Data.Pos[0];		//x
	PlayersMap[pos.Data.ID]->Pos[1] = pos.Data.Pos[1];		//y
	PlayersMap[pos.Data.ID]->Pos[2] = pos.Data.Pos[2];		//z
}

void GetNewInstructions(std::queue<std::shared_ptr<InstructionBase> > &Instructions)
{
	Instructions.push(std::make_shared<InstructionAdd>(17, 1.0f, 0.0f, 5.0f));
	Instructions.push(std::make_shared<InstructionAdd>(7, 16.0f, 0.0f, 15.0f));
	Instructions.push(std::make_shared<InstructionAdd>(89, -11.0f, 0.0f, 55.0f));
}

//Example
int main(){
	PlayerManager Players;
	std::queue<std::shared_ptr<InstructionBase> > Instructions;

	GetNewInstructions(Instructions);

	while(!Instructions.empty()){
		Instructions.front()->Process(Players);
		Instructions.pop();
	}

	std::cout << Players.PlayersMap[89]->Pos[0] << std::endl;
	std::cout << Players.PlayersMap[89]->Pos[1] << std::endl;
	std::cout << Players.PlayersMap[89]->Pos[2] << std::endl;

	return 0;
}



#5130866 Calling a virtual function, illegal call of non-static member function?

Posted by Tispe on 12 February 2014 - 12:59 PM

In order to completely encapsulate this in a simple class the thread function has to be static. But now the static function can't call a member function.

 

Perhaps this is a viable workaround:

class WorkerThread
{
public:
	WorkerThread(void);
	~WorkerThread(void);

	virtual void ThreadFunction(LPVOID param) = 0;
private:
	HANDLE hThread;
	static DWORD WINAPI ThreadRoutine(LPVOID param);
};
 
WorkerThread::WorkerThread(void)
{
	hThread = CreateThread(NULL, 0, WorkerThread::ThreadRoutine, this, NULL, NULL);
}

DWORD WINAPI WorkerThread::ThreadRoutine(LPVOID param)
{
	static_cast<WorkerThread*>(param)->ThreadFunction(param);
	return 0;
}



#5129561 [DX9] many lights: registers VS Volume Texture

Posted by Tispe on 07 February 2014 - 06:41 AM

I think that the bandwidth usage and overhead of transferring a few kilobytes to the GPU is no problem. You can use Vertex Texture Fetch in the vertex shader to lookup your lights array.

 

Only when you want each light to cast shadows will you notice performance issues.




#5129366 Single tile as background?

Posted by Tispe on 06 February 2014 - 12:33 PM

you set the addressing modes for the sampler, MIRROR or WRAP

device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);

Then you can draw a Quad where the UV addresses goes beyond 1.0f. for example if the vertex has an UV address of 2.0f, you will have the texture repeated two times in the same Quad.




#5128933 DirectX in WS_OVERLAPPED window vs WS_CHILD window - shader renders differently

Posted by Tispe on 05 February 2014 - 12:33 AM

device->GetBackBuffer(...., pSurface);

pSurface->GetDesc(pDesc)

 

Check if pDesc->Width and pDesc->Height is the same as the client area of the window.




#5127393 Has any of the veterans tried to feed animation data into an animation contro...

Posted by Tispe on 30 January 2014 - 12:55 AM

I think it is best to just roll your own animation controller. It is not that hard to do. Animation Tracks has a set of keys for each bone. Just figure out between which two keys you are by using a time variable 0-1, then interpolate those keys for each bone.

 

Blending animations is just as easy.




#5123587 C++ DirectX Renderer Design

Posted by Tispe on 14 January 2014 - 09:31 AM

What functionality do you want from a renderer? Well you want to give it a Scene and render it to the screen right? You also want it to handle the game window so that you can change resolution and toggle windowed mode and fullscreen mode.

 

Another thing you want from the renderer (atleast DX9) is to create textures/surfaces and buffers for you.

 

Here is some of my Dx9Device class:

class Dx9Device
{
public:
	Dx9Device(void);
	~Dx9Device(void);

	bool CreateGameWindowAndInit(HINSTANCE hInstance, int nCmdShow, LPVOID *pInput);
	void ChangeDisplaySettings(DisplaySettings &NewSettings);
	void BuildManagedResources(std::shared_ptr<GameResource> &spResource);
	void Render(GameScene &Scene);
	void GetSettings(DisplaySettings &Settings);

.
.
.
}

The Scene data structure contain all the information necessary to draw one frame to the screen.




#5122311 error C2061: syntax error : identifier 'HINSTANCE'

Posted by Tispe on 09 January 2014 - 12:33 AM

Well, I like it simple. Even if it creates un-needed dependency. I have enough with forward declarations already.




#5122310 Impossible to use instancing with DirectX 9 when D3DCREATE_HARDWARE_VERTEXPRO...

Posted by Tispe on 09 January 2014 - 12:24 AM

Do you SetVertexShader() and SetPixelShader()?

 

 

 


pD3dDevice_->SetFVF(simpleKnobMesh_.Mesh->GetFVF());

 

Do you need this?

 

 

 


simpleKnobMesh_.Mesh->GetVertexBuffer(&g_vertexBufferGeometry);
simpleKnobMesh_.Mesh->GetIndexBuffer(&g_indexBuffer);

Remember to release(), as the internal reference count increases everytime you call Get*.




#5122207 error C2061: syntax error : identifier 'HINSTANCE'

Posted by Tispe on 08 January 2014 - 12:23 PM

Right, the problem was that I did not #include Main.h where all my includes are in Dx9Device.cpp as I did in my original source. Fixed now. Thx.






PARTNERS