Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Creating a simple 2d engine (C++), best way to create an Sprite class?


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
3 replies to this topic

#1 Joyal   Members   -  Reputation: 137

Like
0Likes
Like

Posted 15 March 2013 - 07:28 AM

Since MS announced that they are not give more support to XNA , for me was an opportunity to start to learn DirectX , so i wanted to learn DX11,

i was following this tutorials 

 

http://www.rastertek.com/tutdx11.html

 

i want to build a simple 2D engine while im learning with basic thing,like render an sprite based on a spritesheet, ,animate it, scale, rotation, flip image

 

I started creating some simple basic structure, 

- Engine Class, this hold the initialization of the Window basically

- RenderManager class, this hold all the DX stuff, initialize it, create the swapchain, store the device , etc

 

So now my next step is create the Sprite class , i wanted to create an method called "Quad2D" inside my RenderManager, so i can use it on my render method in my sprite class

 

//This is not actual code, is just oh i want to approach this
class Sprite{

public void Render(RenderManager *rm){
  
    rm->Quad2D(Texture,Position,Width,Height);

}
}

i have some experience with OpenGL and Directx9 , it was easy to approach this, i just need to create an Array with the vertex, send to the VertexBuffer, bind the Texture, and done, 

 

but because now DX10 and DX11 not used fixed pipeline, and you need create this with more advanced stuff (Shaders),

i stopped in here http://www.rastertek.com/dx11tut11.html , i can see how to render the image and everything, but i was thinking, do i need to create an separate Class just to render a Quad? if so, this is going to compile the shader everytime is used?, well one solution maybe is just declare an static atribute for the ps and vs to share the same compile shader

 

so i want to hear your suggestion, how do you manage your Sprite class? 

 

if it necessary, i can attach my source code, but it doesnt has too much, just open a window

 

Note: i want to know how to do it in DX11, please dont reply, (used DX9,OpenGL,DX10, etc..)


Edited by Joyal, 15 March 2013 - 07:42 AM.


Sponsor:

#2 DgekGD   Members   -  Reputation: 374

Like
1Likes
Like

Posted 15 March 2013 - 12:26 PM

Create separate classes for Shaders, Vertex Buffers etc. 

 

 For example i have the following class for vertex shader:

class VertexShaderDX11
	{
	protected:

		ID3D11VertexShader*	m_pShader;
		InputAssemblerStateDX11*	m_pState;

	public:
		VertexShaderDX11()  { m_pState = new InputAssemblerStateDX11(); }
		~VertexShaderDX11() {	SAFE_RELEASE(m_pShader);
								SAFE_DELETE(m_pState); }

		ABOOL Create(BlobDX11 & shaderbuffer, INPUT_LAYOUT* layout, AUINT8 num,
										 AUINT16 topology);
		AVOID Set() const;
	};

 

Note that it has pointer to the InputAssembler structure (it stores information about Input Assembler stage as for vertex shader you have to have right input topology). 

 

 In your sprite class you can reference shader for rendering and bind it to the pipeline before you render your sprite. Don't recompile shader all the time! Compile it one time and then just have a pointer to an object of your shader class which stores compiled shader.  Multiple sprites can use single shader for rendering just having pointer to it.


Edited by DgekGD, 15 March 2013 - 02:43 PM.


#3 Racoonacoon   Members   -  Reputation: 443

Like
1Likes
Like

Posted 16 March 2013 - 12:32 PM

I'm somewhat curious how your Quad2D method is handling things under the hood. Is it buffering the sprites and then drawing them in all one big draw call, sorting them by texture, or does each call set the texture, vertex buffers, IA Layout, shaders, etc? If it is the latter then it is likely to not be all that efficient. You may want to look into mimicking the way SpriteBatch in XNA handles things. You tell it to Begin() and then you do a number of Draw() calls. When you are finished you say End(), which draws all the sprites in one go. This approach is generally more efficient.

 

As for me, I store all my sprites as points in a dynamic vertex buffer and expand them to quads in the Geometry shader. This makes managing the vertex buffers on the C side much easier.



#4 Joyal   Members   -  Reputation: 137

Like
0Likes
Like

Posted 18 March 2013 - 04:37 AM

@DgekGD , i like your approach because i can use the same VS and PS in differents classes biggrin.png!

 

 

@Racoonacoon well right now i don`t have the implementation made of Quad2D on my current "Engine"(DX11), i wanted to ask before i do it because DX10-11 works different,  but i do have my DX9 version , 

 

void RenderManager::DrawQuad2D (CTexture* texture, Vector2 position, int w, int h)
{

	// position = [0] 
	//
	//  [0]------[2]
	//   |        |
	//   |        |
	//   |        |
	//  [1]------[3]
	
	Vector2 coord_text[4];
	coord_text[0].x = 0.f;	coord_text[0].y = 0.f;
	coord_text[1].x = 0.f;	coord_text[1].y = 1.f;
	coord_text[2].x = 1.f;	coord_text[2].y = 0.f;
	coord_text[3].x = 1.f;	coord_text[3].y = 1.f;
			
	unsigned short indices[6]={0,2,1,1,2,3};
	SCREEN_TEXTURE_VERTEX v[4] =
	{
			{ (float)position.x,	(float)position.y,	0.f,1.f, coord_text[0].x,	coord_text[0].y} //(x,y) sup_esq.
		,	{ (float)position.x,	(float)position.y+h,	0.f,1.f, coord_text[1].x,	coord_text[1].y} //(x,y) inf_esq.
		, 	{ (float)position.x+w,	(float)position.y,	0.f,1.f, coord_text[2].x,	coord_text[2].y} //(x,y) sup_dr.
		,	{ (float)position.x+w,	(float)position.y+h,	0.f,1.f, coord_text[3].x,	coord_text[3].y} //(x,y) inf_dr.
	};

	m_pD3DDevice->SetFVF( SCREEN_TEXTURE_VERTEX::getFlags() );
	m_pD3DDevice->SetTexture(0, texture->GetD3DXTexture() );
	m_pD3DDevice->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST,0, 4, 2,indices,D3DFMT_INDEX16, v, sizeof( SCREEN_TEXTURE_VERTEX ) );
}

 

 

Well i based in your suggestion , i think i will do some sort of XNA's "SpriteBranch", and that class can be instantiated once, and be passed on the "Render" method,  instead of the "RenderManager", 

 

Thank for your greats advice 


Edited by Joyal, 18 March 2013 - 04:39 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