D3DXCreateLine - Need help rendering faster

Started by
7 comments, last by kdmiller3 13 years ago
I am currently drawing a 64x64 grid across my screen, as of right now I am using D3DXCreateLine to do this, but... the way I am doing this I am taking a significant performance hit for doing something this trivial, I was wondering if anyone either
a) had some tips to improve on what I am doing
b ) have a better way of drawing a single pixel grid

I was trying to find a way to render my grid to some off screen surface and just do the equivalent of a BLT from old direct draw, but I couldn't find any good way of doing this...

Basically what im doing right now is drawing my horizontal and vertical line at the same time each with its own draw call, even if there was a way to store all of this into a large buffer and just call it each frame, that would be ever better, your help is greatly appreciated!

EDIT: im using Dx9

Here is my code for drawing the lines:


void GraphicsWrapper::DrawGridOverLay2() //draws a grid over our tilemap
{
int ToolBarSize = 27; //this is the size in pixels of our windows toolbar
D3DXVECTOR2 points[2];
ID3DXLine *line;
D3DXCreateLine( d3dDevice, &line );
line->SetWidth( (float) 1 );
line->SetPattern( 0xffffffff );



for (int x=0;x<TilesOnScreenX;x++)
{
for (int y=0;y<TilesOnScreenY;y++)
{

line->Begin();
points[0] = D3DXVECTOR2( (float)x*TILE_HEIGHT, (float)0 + ToolBarSize );
points[1] = D3DXVECTOR2((float) x*TILE_WIDTH, (float)(TilesOnScreenY * TILE_HEIGHT) + ToolBarSize);

line->End();
line->Draw( points, 2, 0xFFFFFFFF );

line->Begin();
points[0] = D3DXVECTOR2( (float)0, (float)y*TILE_HEIGHT+ToolBarSize );
points[1] = D3DXVECTOR2((float) TILE_WIDTH*TilesOnScreenX, (float)(y * TILE_HEIGHT) + ToolBarSize );

line->End();
line->Draw( points, 2, 0xFFFFFFFF );
}
}



line->Release();


}
Advertisement
Simply draw bigger lines... if you want a 9x9 grid, with your code you are drawing 200 lines. However you can simply draw 20 lines, if draw each one with the size of 10 because they are all collinear...

Simply draw bigger lines... if you want a 9x9 grid, with your code you are drawing 200 lines. However you can simply draw 20 lines, if draw each one with the size of 10 because they are all collinear...


Ugh I can't believe I didn't think about that, thanks.. that should help a ton =p
For some reason I was thinking it was doing 20 lines without really looking at it, thanks a ton!

Edit: 10x increase in rendering speed, thanks!
Store all the data in a VBO and the draw it in one call. Should increase speed a lot.

Store all the data in a VBO and the draw it in one call. Should increase speed a lot.


I will check it out, VBO mostly came up with OpenGL results, in Directx would it be considered a Static Vertex Buffer?
Yes in DX they are called vertex buffers. VBO is vertex buffer object so they are pretty much the same thing.
While this isn't the best way to do it, you can generate your points all at once and submit them with DrawPrimitiveUP:

void GraphicsWrapper::DrawGridOverLay2() //draws a grid over our tilemap
{
int ToolBarSize = 27; //this is the size in pixels of our windows toolbar

D3DXVECTOR4 *points = (D3DXVECTOR4 *)_alloca((TilesOnScreenX * 2 + TilesOnScreenY * 2) * sizeof(D3DXVECTOR4));
size_t index = 0;

float x0(0);
float x1(x0 + TilesOnScreenX * TILE_WIDTH);
float y0(ToolBarSize);
float y1(y0 + TilesOnScreenY * TILE_HEIGHT);

for (int ix = 0; ix < TilesOnScreenX; ix++)
{
float x(x0 + ix * TILE_WIDTH);
points[index++] = D3DXVECTOR4(x, y0, 0, 1);
points[index++] = D3DXVECTOR4(x, y1, 0, 1);
}

for (int iy = 0; iy < TilesOnScreenY; iy++)
{
float y(y0 + iy * TILE_HEIGHT);
points[index++] = D3DXVECTOR4(x0, y, 0, 1);
points[index++] = D3DXVECTOR4(x1, y, 0, 1);
}

d3dDevice->SetFVF(D3DFVF_XYZRHW);
d3dDevice->DrawPrimitiveUP(D3DPT_LINELIST, index / 2, points, sizeof(D3DXVECTOR4));
}

I can't guarantee that this is exactly correct, so use at your own risk. :)

If the dimensions of the grid never change, you're better off creating a static vertex buffer once at initialization and then drawing from it with SetStreamSource and DrawPrimitive. It wouldn't make much difference for this kind of light-duty rendering, but it's still a good habit to develop.
Thanks kdmiller3, Yeah the dimensions never change, its actually a overlay grid for a map editor, I can spare the performance loss (at least at this point still).
I am going to check into static vertex buffers though because my actual game could be greatly improved by them.
As long as the vertex format is the same, you can add geometry from any number of models to a single vertex buffer and use the appropriate start vertex value with DrawPrimitive or DrawIndexedPrimitive. You can do the same thing with the index buffer and use the appropriate start index value with DrawIndexedPrimitive. If all your models have the same vertex format and you know the total size, you could have one static vertex buffer and one static index buffer for all the geometry in your game. That can be hard to arrange, though, so most of the time it's easier to create one VB and one IB per model file since you can compute its size at load time. If your model file has multiple geometry chunks (i.e. it's hierarchical or has multiple materials), you can still fit all of those into a single VB and IB.

This topic is closed to new replies.

Advertisement