The order of vertices only matters for the backface culling that DirectX does. The default behavior is that the face of a primitive with the vertices in clockwise order are drawn, while the back of that face (which, if it were to be drawn, would have the same vertices, but in counter-clockwise order) is not drawn.
In the case of a triangle strip it gets a bit funky because the second vertex is used in a clockwise fashion for the first triangle but in a counter-clockwise fashion for the second triangle.
You also have your first three vertices in clockwise order, so I'm not sure why DirectX regards that differently, and maybe my backface culling theory doesn't hold water in this case. Maybe there are some other specifics to triangle strips that require such a specific vertex order. In any case, I'm glad it worked out for you.
Drawing Shape on top of Sprites
The winding order of vertices is relative to your camera. Your original code's vertices are in clockwise order only if your camera looks along +Z. If it looks along -Z, then they're in anti-clockwise order.
What is the FVF / vertex declaration you're using for your vertex struct?
You could also just disable backface culling when drawing your 2D, by calling SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE).
That method for drawing quads looks fine to me, although some performance improvements would be:
1. Make sure the vertex buffer is allocated as dynamic (You have the D3DUSAGE_DYNAMIC flag set when creating it). Dynamic vertex buffers are much faster to update.
2. If you're drawing multiple rectangles, draw as many as possible in one go. That means creating a vertex buffer large enough for a "lot" of vertices (say 1024 verts or so), filling it with all the rectangles, then drawing them all in a single DrawPrimtive() call. That requires...
3. Use an index buffer. That way you can do the above (render all rectangles in one draw call), by rendering the rectangles as an indexed triangle list instead of a series of short triangle strip. That way the GPU's vertex cache can kick in, and it should be quicker than rendering triangle strips.
3b. The index buffer can be static and can be pre-filled - the order of vertices will never change, no matter how many rectangles you draw.
ID3DXSprite internally performs all of the above optimisations, so if you do that you'll get performance at least as good as ID3DXSprite.
What is the FVF / vertex declaration you're using for your vertex struct?
You could also just disable backface culling when drawing your 2D, by calling SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE).
That method for drawing quads looks fine to me, although some performance improvements would be:
1. Make sure the vertex buffer is allocated as dynamic (You have the D3DUSAGE_DYNAMIC flag set when creating it). Dynamic vertex buffers are much faster to update.
2. If you're drawing multiple rectangles, draw as many as possible in one go. That means creating a vertex buffer large enough for a "lot" of vertices (say 1024 verts or so), filling it with all the rectangles, then drawing them all in a single DrawPrimtive() call. That requires...
3. Use an index buffer. That way you can do the above (render all rectangles in one draw call), by rendering the rectangles as an indexed triangle list instead of a series of short triangle strip. That way the GPU's vertex cache can kick in, and it should be quicker than rendering triangle strips.
3b. The index buffer can be static and can be pre-filled - the order of vertices will never change, no matter how many rectangles you draw.
ID3DXSprite internally performs all of the above optimisations, so if you do that you'll get performance at least as good as ID3DXSprite.
One final question. I am drawing this rectangle on top of my sprites now. Is there any way to get the red to fade into a transparency as opposed to black which it is currently fading to?
I'd prefer a solid red with probably 40-60% opacity if that's possible in this situation.
I'd prefer a solid red with probably 40-60% opacity if that's possible in this situation.
I'm using DirectX 8, so there may be a better way to do this in newer versions, but here's how I do it:
Turn on alpha blending:
SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
then bind the alpha component of the of the vertices to that of the texture (if applicable):
SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
then set the alpha component of the vertices of the quad to whatever transparancy I need:
myDrawVertices[].diffuse & 0x00FFFFFF;
myDrawVertices[].diffuse | alpha; //where alpha is between 0 and 255
The texture part might not be relevant for you in this case. I just set it up this way in case I decide to use textured quads.
Turn on alpha blending:
SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
then bind the alpha component of the of the vertices to that of the texture (if applicable):
SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
then set the alpha component of the vertices of the quad to whatever transparancy I need:
myDrawVertices[].diffuse & 0x00FFFFFF;
myDrawVertices[].diffuse | alpha; //where alpha is between 0 and 255
The texture part might not be relevant for you in this case. I just set it up this way in case I decide to use textured quads.
Whoops. The alpha part should be:
myDrawVertices[].diffuse & 0x00FFFFFF;
alpha = alpha << 24; //where the original alpha was between 0 and 255
myDrawVertices[].diffuse | alpha;
Also, you can turn alpha blending on and off during a frame (using SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE/FALSE)). I've read that it's a pretty expensive operation, so I would only turn it on while drawing your transparent item(s).
myDrawVertices[].diffuse & 0x00FFFFFF;
alpha = alpha << 24; //where the original alpha was between 0 and 255
myDrawVertices[].diffuse | alpha;
Also, you can turn alpha blending on and off during a frame (using SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE/FALSE)). I've read that it's a pretty expensive operation, so I would only turn it on while drawing your transparent item(s).
Ah, I had set those render settings before but had turned them off when I was trying to figure out why my sprites were all tranlucent.
That gives me a fade from top heading to the bottom when the bottom being transparent it seems. How can I get this to not have a gradient effect but rather be solid but semi transparent? The values I am passing for my colors when defining my vertices:
The value for the A of the ARGB color doesn't seem to affect the transparency at all. Any idea what I'm doing wrong?
*edit*
I wanted to add my settings just in case I was setting them wrong:
[Edited by - nlraley on October 26, 2010 3:10:26 PM]
That gives me a fade from top heading to the bottom when the bottom being transparent it seems. How can I get this to not have a gradient effect but rather be solid but semi transparent? The values I am passing for my colors when defining my vertices:
Vertex vertices[] = { {Data->Zones.i->dxPosition[0].X, Data->Zones.i->dxPosition[0].Y, 0.0f, 0.0f, 0, 0, 0xff0000ff}, {Data->Zones.i->dxPosition[1].X, Data->Zones.i->dxPosition[1].Y, 0.0f, 0.0f, 1, 0, 0xff0000ff}, {Data->Zones.i->dxPosition[2].X, Data->Zones.i->dxPosition[2].Y, 0.0f, 0.0f, 0, 1, 0xff0000ff}, {Data->Zones.i->dxPosition[3].X, Data->Zones.i->dxPosition[3].Y, 0.0f, 0.0f, 1, 1, 0xff0000ff} };
The value for the A of the ARGB color doesn't seem to affect the transparency at all. Any idea what I'm doing wrong?
*edit*
I wanted to add my settings just in case I was setting them wrong:
if (FAILED(hr = d3d9Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE))) return hr; if (FAILED(hr = d3d9Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA))) return hr; if (FAILED(hr = d3d9Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA))) return hr; if (FAILED(hr = d3d9Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE))) return hr;
[Edited by - nlraley on October 26, 2010 3:10:26 PM]
Quote:Original post by Evil Steve
The winding order of vertices is relative to your camera. Your original code's vertices are in clockwise order only if your camera looks along +Z. If it looks along -Z, then they're in anti-clockwise order.
What is the FVF / vertex declaration you're using for your vertex struct?
You could also just disable backface culling when drawing your 2D, by calling SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE).
That method for drawing quads looks fine to me, although some performance improvements would be:
1. Make sure the vertex buffer is allocated as dynamic (You have the D3DUSAGE_DYNAMIC flag set when creating it). Dynamic vertex buffers are much faster to update.
2. If you're drawing multiple rectangles, draw as many as possible in one go. That means creating a vertex buffer large enough for a "lot" of vertices (say 1024 verts or so), filling it with all the rectangles, then drawing them all in a single DrawPrimtive() call. That requires...
3. Use an index buffer. That way you can do the above (render all rectangles in one draw call), by rendering the rectangles as an indexed triangle list instead of a series of short triangle strip. That way the GPU's vertex cache can kick in, and it should be quicker than rendering triangle strips.
3b. The index buffer can be static and can be pre-filled - the order of vertices will never change, no matter how many rectangles you draw.
ID3DXSprite internally performs all of the above optimisations, so if you do that you'll get performance at least as good as ID3DXSprite.
Do you have an example of how this is done by chance steve?
Quote:Original post by nlraleyNot really. What part? It should all be straightforward just following the DirectX docs.
Do you have an example of how this is done by chance steve?
Quote:Original post by nlraley
Creating the indexed triangle list.
Untested:
#define MAX_RECTS 1024 // Maximum number of rectangles that can be drawnLPDIRECT3DINDEXBUFFER9 pIndexBuffer = NULL;// At init time:// Create the index buffer with 6*MAX_RECTS indices in it (3 per triangle, 2 triangles per rect)HRESULT hResult = d3d9Device->CreateIndexBuffer(sizeof(WORD)*MAX_RECTS*6, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &pIndexBuffer, NULL);if(FAILED(hResult)){ // Error, abort}// Fill the index buffer with indices. Assume vertices are always added in order:// top left, top right, bottom left, bottom rightWORD* pIndices;hResult = pIndexBuffer->Lock(0, 0, (void**)&pIndices, 0);if(FAILED(hResult)){ // Error, abort}for(int i=0; i<MAX_RECTS; ++i){ // First triangle (top left, top right, bottom left) *pIndices++ = i*4; *pIndices++ = i*4 + 1; *pIndices++ = i*4 + 2; // Second triangle (top right, bottom right, bottom left) *pIndices++ = i*4 + 1; *pIndices++ = i*4 + 3; *pIndices++ = i*4 + 2;}pIndexBuffer->Unlock();// At render time:// Fill vertex buffer with all the rectangles you want to draw (Add vertices in// the same order as you have already)// Set the index buffer as the index sourced3d9Device->SetIndices(pIndexBuffer);// Draw num_rectangles as an indexed triangle list:d3d9Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, num_rectangles*4, 0, num_rectangles*2);
And at shutdown time, remember to Release() pIndexBuffer.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement