ID3DX10Sprite & ID3DX10Font batching

Started by
5 comments, last by Fallonsnest 14 years, 10 months ago
Im working on a new gui system fully running on sprites instead of using a dynamic vertex buffer for my gui images. Im using the same sprite for both rendering images and text. - Begin sprite - Draw background image - Draw button1 image - Draw button1 text - Draw button2 image - Draw button2 text - End sprite for the images im using the 'DrawSpritesBuffered' method. now the text only seem to show up when i flush the sprite first. Is this normal behavior and what would be best workaround? 1) Use different sprite for the fonts 2) Make the gui draw all images, flush and then draw all text (require loop 2x trough control list)
Advertisement
Quote:Original post by Fallonsnest
Im working on a new gui system fully running on sprites instead of using a dynamic vertex buffer for my gui images.

Im using the same sprite for both rendering images and text.

- Begin sprite
- Draw background image
- Draw button1 image
- Draw button1 text
- Draw button2 image
- Draw button2 text
- End sprite

for the images im using the 'DrawSpritesBuffered' method.
now the text only seem to show up when i flush the sprite first.

Is this normal behavior and what would be best workaround?
1) Use different sprite for the fonts
2) Make the gui draw all images, flush and then draw all text (require loop 2x trough control list)


It is normal behaviour, the font object does not reset their state. When I still used these objects i used the first solution.

Take a look into my blog, i've anyway posted 2 articles regarding the remake of these 2 interfaces to have more control over them.
Thanks for the reply.

I found the reasson/fix the issue last night.
The reasson i had to flush the sprite was simply because i was using D3DX10_SPRITE_SORT_TEXTURE flag on the sprite Begin() call.

Now reading your blog cleared out some points for me.
I fully agree that using vertex buffer make the 2D rendering system more flexible as u can use/support custom shaders for it wich is a great advantage.

U state 3 different ways to use the vertex/index buffers. Before implement the sprite class i was using the first method like the DXUT gui system does. Update the vertices inside the vertex buffer for each gui element been drawed.

Now i have some questions about the 3the way.
Did u create 1 vertex buffer that contain a quad and is scaled/translated for each call to define its positioning or did u add a vertex buffer for each element u draw to the screen?

About using the shader, can u show the begin() code?

for example, does the begin code call the pass->apply() method or do u apply the pass for each draw call? When u call the apply only in the begin method, doesnt this give problems for shaders using multiple passes?
Quote:Original post by Fallonsnest
Thanks for the reply.

I found the reasson/fix the issue last night.
The reasson i had to flush the sprite was simply because i was using D3DX10_SPRITE_SORT_TEXTURE flag on the sprite Begin() call.

Now reading your blog cleared out some points for me.
I fully agree that using vertex buffer make the 2D rendering system more flexible as u can use/support custom shaders for it wich is a great advantage.

U state 3 different ways to use the vertex/index buffers. Before implement the sprite class i was using the first method like the DXUT gui system does. Update the vertices inside the vertex buffer for each gui element been drawed.

Now i have some questions about the 3the way.
Did u create 1 vertex buffer that contain a quad and is scaled/translated for each call to define its positioning or did u add a vertex buffer for each element u draw to the screen?

About using the shader, can u show the begin() code?

for example, does the begin code call the pass->apply() method or do u apply the pass for each draw call? When u call the apply only in the begin method, doesnt this give problems for shaders using multiple passes?


I have a single quad and it is scaled/translated/rotated(you can rotate the quad in one axis) for each call to define its positioning.

The begin call set the InputAssembler (InputLayout, PrimitiveTopology, VertexBuffer) and do a first apply of the effect.

The draw call before drawing actually update the constant buffer with the world*View*Projection matrix (you can get the constant buffer at load time of the app via the effects framework and use UpdateSubResource or Map/UnMap to update it) and set the texture via the device function to set shader resources.

The end call in the case of DirectX10 does not do anything (in DX9 close the effect)

Yes, but I do not support multiple pass in the quad sprite system, its pretty much useless with actual HLSL, it was mostly used in the past when the instruction limit was pretty tight. (It is still used when you need the result of the first operation as a pass for the second operation (pretty much only for postprocessing))
But anyway adding support to it will be easy (even thought more costly in terms of CPU power because of the multiple effect.apply())
Great, thanks for the info.
hmm, need some help on the shaders. Changed my code to use a single vertex buffer and a shader. I can scale/position/rotate the image trough the world matrix, but now trying to add a projection matrix (as the sprite class does)

This is my vertex setup
// Setup the verticesVERTEX_GUI vertices[] ={	{ D3DXVECTOR3( -1.0f,  1.0f, 0.5f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 0.0f ) },	{ D3DXVECTOR3(  1.0f,  1.0f, 0.5f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 0.0f ) },	{ D3DXVECTOR3( -1.0f, -1.0f, 0.5f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },	{ D3DXVECTOR3(  1.0f, -1.0f, 0.5f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 1.0f, 1.0f ) },};



This is my vertex shader
VS_OUTPUT VS( float3 vPos : POSITION, float4 Dif : COLOR, float2 vTexCoord0 : TEXCOORD ){	VS_OUTPUT Output;	Output.Pos = float4( vPos, 1.0f );	Output.Pos = mul( Output.Pos, g_World );	//Output.Pos = mul( Output.Pos, g_Projection );	Output.Dif = Dif;	Output.Tex = vTexCoord0;	return Output;}


Now when i try to set the projection matrix, using D3DXMatrixOrthoOffCenterLH method, the image disapear offscreen :(
Any sugestions how i should use the projection matrix on the shader?

For example, when u use, 1/1/1 scaling, 0/0/0 translation, the images is nicely rendered in the center of the screen, filling the entire screen.
now when i set my translation to 1/0/0 the images starts at the center of the screen while with the sprite and its projection matrix u can use the real coordinates to position the image.

So for example, i want the image to start at pixel offset 10/10, i could set my translation matrix to 10/10/0. Now i need to set it to screenwidth / 10 without using a projection matrix
never mind, fixed the problem

// Setup the gui dimensionsD3DXMATRIX matProjection;D3DXMatrixOrthoOffCenterLH( &matProjection, 0.0f, 800.0f, 0.0f, 600.0f, -1.0f, 1.0f );// Position and scale the imageD3DXMatrixScaling( &matScaling, 400.0f, 300.0f, 1.0f );D3DXMatrixTranslation( &matTranslation, 400.0f, 300.0f, 0.1f );


It works a bit different as the sprite as i need to scale half screensize and position the image in the middle of the screen to have a background rendering.

This topic is closed to new replies.

Advertisement