Jump to content

  • Log In with Google      Sign In   
  • Create Account

Calling DrawPrimitive Heaps


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 BMW   Members   -  Reputation: 160

Like
0Likes
Like

Posted 09 July 2013 - 05:03 AM

Hi all,

 

In my voxel engine similar to Minecraft, I draw each side of each block separately, like this:

for(unsigned int i = 0; i < BLOCKS_PER_CHUNK; i++)
{
	if(blocks[i].type == BLOCKTYPE_AIR)
		continue;

	if(blocks[i].BackFaceVisible)
	{
		g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, (i * VERTICES_PER_BLOCK) + 4, 2);
	}
	if(blocks[i].FrontFaceVisible)
	{
		g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, (i * VERTICES_PER_BLOCK), 2);
	}
	if(blocks[i].LeftFaceVisible)
	{
		g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, (i * VERTICES_PER_BLOCK) + 8, 2);
	}
	if(blocks[i].RightFaceVisible)
	{
		g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, (i * VERTICES_PER_BLOCK) + 12, 2);
	}
	if(blocks[i].TopFaceVisible)
	{
		g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, (i * VERTICES_PER_BLOCK) + 16, 2);
	}
	if(blocks[i].BottomFaceVisible)
	{
		g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, (i * VERTICES_PER_BLOCK) + 20, 2);
	}
}

Is it a bad idea to call DrawPrimitive so much like this? Should I use an index buffer and just make one call to DrawIndexedPrimitive?


Edited by BMW, 09 July 2013 - 05:04 AM.


Sponsor:

#2 mdias   Members   -  Reputation: 792

Like
1Likes
Like

Posted 09 July 2013 - 01:35 PM

Yes, it's a very bad idea.

 

You should render the whole scene with the minimum possible calls to DrawPrimitive. That is, render various cubes at once if possible otherwise performance will degrade very fast.

 

Reducing DrawPrimitive calls by grouping geometry/materials is called batching. You should find lots of info by google for "geometry batching" and similar terms.



#3 BMW   Members   -  Reputation: 160

Like
0Likes
Like

Posted 09 July 2013 - 09:15 PM

Ok, I will see if I can render an entire chunk using one DrawPrimitive() call. That should help.



#4 Krohm   Crossbones+   -  Reputation: 3129

Like
1Likes
Like

Posted 09 July 2013 - 11:59 PM

You might be much happier doing a DIP call for each block type, so you don't have to mess up to much with shader parameters.

Doing a whole chunk per-DIP is excessive in my opinion and the issues involved in managing the multiple textures have to be carefully considered.

 

edit: oh, I see you're using a texture atlas from the other thread. No problem then, go ahead!


Edited by Krohm, 10 July 2013 - 12:00 AM.


#5 BMW   Members   -  Reputation: 160

Like
1Likes
Like

Posted 10 July 2013 - 12:44 AM

You might be much happier doing a DIP call for each block type, so you don't have to mess up to much with shader parameters.

Doing a whole chunk per-DIP is excessive in my opinion and the issues involved in managing the multiple textures have to be carefully considered.

 

edit: oh, I see you're using a texture atlas from the other thread. No problem then, go ahead!

 

WOW WOWOWOWOWOWOWOWOWOWOWOW

 

Using the inferior method as discussed earlier (heaps of draw primitive calls) = 62FPS.

 

Using new method - 1 DIP call per chunk = 320FPS. THATS IT, THREE HUNDRED AND TWENTY FRAMES PER SECOND. (Considering my laptop has integrated graphics, NOT TOO FOUL!!!!)

 

THIS IS THE BEST DAY OF MY LIFE.

 

THANK YOU EVERYONE.

 

I love game development.

 

EDIT: Is updating the entire index buffer for the chunk every time a block changes a good idea? It seems to run ok.

 

This is how I update index buffer:

void Chunk::UpdateIndices()
{
	void* IB = NULL;

	unsigned int* pIBEntry = NULL;

	PrimitiveCount = 0;

	if(g_pIB->Lock(0, BLOCKS_PER_CHUNK * INDICES_PER_BLOCK * 4, &IB, D3DLOCK_DISCARD) != D3D_OK)
		return;

	pIBEntry = (unsigned int*)IB;

	for(unsigned int i = 0; i < BLOCKS_PER_CHUNK; i++)
	{
		if(blocks[i].type == BLOCKTYPE_AIR)
			continue;

		if(blocks[i].FrontFaceVisible)
		{
			*pIBEntry = i * VERTICES_PER_BLOCK;
			*(pIBEntry + 1) = i * VERTICES_PER_BLOCK + 1;
			*(pIBEntry + 2) = i * VERTICES_PER_BLOCK + 2;
			*(pIBEntry + 3) = i * VERTICES_PER_BLOCK + 1;
			*(pIBEntry + 4) = i * VERTICES_PER_BLOCK + 3;
			*(pIBEntry + 5) = i * VERTICES_PER_BLOCK + 2;
			pIBEntry += 6;
			PrimitiveCount += 2;
		}
		if(blocks[i].BackFaceVisible)
		{
			*pIBEntry = i * VERTICES_PER_BLOCK + 4;
			*(pIBEntry + 1) = i * VERTICES_PER_BLOCK + 4 + 1;
			*(pIBEntry + 2) = i * VERTICES_PER_BLOCK + 4 + 2;
			*(pIBEntry + 3) = i * VERTICES_PER_BLOCK + 4 + 1;
			*(pIBEntry + 4) = i * VERTICES_PER_BLOCK + 4 + 3;
			*(pIBEntry + 5) = i * VERTICES_PER_BLOCK + 4 + 2;
			pIBEntry += 6;
			PrimitiveCount += 2;
		}
		if(blocks[i].LeftFaceVisible)
		{
			*pIBEntry = i * VERTICES_PER_BLOCK + 8;
			*(pIBEntry + 1) = i * VERTICES_PER_BLOCK + 8 + 1;
			*(pIBEntry + 2) = i * VERTICES_PER_BLOCK + 8 + 2;
			*(pIBEntry + 3) = i * VERTICES_PER_BLOCK + 8 + 1;
			*(pIBEntry + 4) = i * VERTICES_PER_BLOCK + 8 + 3;
			*(pIBEntry + 5) = i * VERTICES_PER_BLOCK + 8 + 2;
			pIBEntry += 6;
			PrimitiveCount += 2;
		}
		if(blocks[i].RightFaceVisible)
		{
			*pIBEntry = i * VERTICES_PER_BLOCK + 12;
			*(pIBEntry + 1) = i * VERTICES_PER_BLOCK + 12 + 1;
			*(pIBEntry + 2) = i * VERTICES_PER_BLOCK + 12 + 2;
			*(pIBEntry + 3) = i * VERTICES_PER_BLOCK + 12 + 1;
			*(pIBEntry + 4) = i * VERTICES_PER_BLOCK + 12 + 3;
			*(pIBEntry + 5) = i * VERTICES_PER_BLOCK + 12 + 2;
			pIBEntry += 6;
			PrimitiveCount += 2;
		}
		if(blocks[i].TopFaceVisible)
		{
			*pIBEntry = i * VERTICES_PER_BLOCK + 16;
			*(pIBEntry + 1) = i * VERTICES_PER_BLOCK + 16 + 1;
			*(pIBEntry + 2) = i * VERTICES_PER_BLOCK + 16 + 2;
			*(pIBEntry + 3) = i * VERTICES_PER_BLOCK + 16 + 1;
			*(pIBEntry + 4) = i * VERTICES_PER_BLOCK + 16 + 3;
			*(pIBEntry + 5) = i * VERTICES_PER_BLOCK + 16 + 2;
			pIBEntry += 6;
			PrimitiveCount += 2;
		}
		if(blocks[i].BottomFaceVisible)
		{
			*pIBEntry = i * VERTICES_PER_BLOCK + 20;
			*(pIBEntry + 1) = i * VERTICES_PER_BLOCK + 20 + 1;
			*(pIBEntry + 2) = i * VERTICES_PER_BLOCK + 20 + 2;
			*(pIBEntry + 3) = i * VERTICES_PER_BLOCK + 20 + 1;
			*(pIBEntry + 4) = i * VERTICES_PER_BLOCK + 20 + 3;
			*(pIBEntry + 5) = i * VERTICES_PER_BLOCK + 20 + 2;
			pIBEntry += 6;
			PrimitiveCount += 2;
		}
	}

	g_pIB->Unlock();
}

Edited by BMW, 10 July 2013 - 12:52 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS