Jump to content
  • Advertisement
Sign in to follow this  
Tertsi

Point sprite rendering with a vertex buffer in 2D coordinates

This topic is 4979 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a capable 3D rendering particle system set up. But I'm trying to convert it to use 2D coordinates (much like the sprite interface) and I'm having trouble rendering the particles in 2D coordinates with a set screen space particle size. Here is the relevant code which, with changes/additions should do what I want.
struct particlevertex
{
	float X, Y, Z;
	D3DCOLOR colour;
	static const DWORD ParticleFVF;
};
const DWORD particlevertex::ParticleFVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE;


lpdevice->SetRenderState(D3DRS_POINTSIZE, particlesize); // the variable particlesize is usually 2.
// D3DRS_POINTSPRITEENABLE is true and D3DRS_POINTSCALEENABLE is false.
/////////////////////////////

lpdevice->SetTexture(0, particletexture);
lpdevice->SetStreamSource(0, vertexbuffer, 0,sizeof(particlevertex));
lpdevice->SetFVF(particlevertex::ParticleFVF);

particlevertex* vertex = 0;
vertexbuffer->Lock(vboffset * sizeof(particlevertex), VERTEXBUFFERBATCHSIZE * sizeof(particlevertex), (void**)&vertex, vboffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);

// Loops through the alive particles
{
    vertex->X = /*(float 2D Xpos)*/;
    vertex->Y = /*(float 2D Ypos)*/;
    vertex->Z = 0.0f; // Should this be 0 or 1 with 2D?
    vertex->colour = D3DCOLOR_ARGB(A,R,G,B);
    ++vertex;

    if(numberofparticles_in_batch == VERTEXBUFFERBATCHSIZE)
    {
        vertexbuffer->Unlock();
        MGEgfxref->lpdevice->DrawPrimitive(D3DPT_POINTLIST, vboffset, VERTEXBUFFERBATCHSIZE);

// ETC.
}



Also, i'm using mainly the sprite interface in this game so does it set the device textures, stream sources when it flushes() the batched graphics or does it leave those set textures, FVF and streamsource intact when I'm using "d3dxsprite->Begin(D3DXSPRITE_DONOTMODIFY_RENDERSTATE);"?

Share this post


Link to post
Share on other sites
Advertisement
Hi,

Here is my code that I use for this purpose:

Setting up:

VertexXYZRHWCT* vertices = new VertexXYZRHWCT[nVertices];
HRESULT hr = rView->pd3dDevice->CreateVertexBuffer(nVertices * sizeof(VertexXYZRHWCT), 0,
FVF_VertexXYZRHWCT,
D3DPOOL_MANAGED, &m_vertexBuffer
DX9v DX9(NULL));

if (hr != D3D_OK)
return;

CCASSERT(m_vertexBuffer != NULL);
if (m_vertexBuffer == NULL)
return;

void* vbVertices = NULL;
if (FAILED(m_vertexBuffer->Lock(0, nVertices * sizeof(VertexXYZRHWCT), (DX89(BYTE, void) * *) &vbVertices,
0)))
throw CCException("DirectX error in drawing billboard");

for (long i = 0; i < nVertices; i++)
vertices.color = p_pickColor;

vertices[0].pos = D3DXVECTOR3(p_x1 - 0.5f, p_y2 + 0.5f, 0);
vertices[0].rhw = 1.0;
vertices[0].tu = 0.0;
vertices[0].tv = 1.0;
vertices[1].pos = D3DXVECTOR3(p_x2 + 0.5f, p_y2 + 0.5f, 0);
vertices[1].rhw = 1.0;
vertices[1].tu = 1.0;
vertices[1].tv = 1.0;
vertices[2].pos = D3DXVECTOR3(p_x2 + 0.5f, p_y1 - 0.5f, 0);
vertices[2].rhw = 1.0;
vertices[2].tu = 1.0;
vertices[2].tv = 0.0;

vertices[3].pos = D3DXVECTOR3(p_x1 - 0.5f, p_y2 + 0.5f, 0);
vertices[3].rhw = 1.0;
vertices[3].tu = 0.0;
vertices[3].tv = 1.0;
vertices[4].pos = D3DXVECTOR3(p_x2 + 0.5f, p_y1 - 0.5f, 0);
vertices[4].rhw = 1.0;
vertices[4].tu = 1.0;
vertices[4].tv = 0.0;
vertices[5].pos = D3DXVECTOR3(p_x1 - 0.5f, p_y1 - 0.5f, 0);
vertices[5].rhw = 1.0;
vertices[5].tu = 0.0;
vertices[5].tv = 0.0;

memcpy(vbVertices, vertices, nVertices * sizeof(VertexXYZRHWCT));

m_vertexBuffer->Unlock();
delete[] vertices;



Rendering:

CCDXNSP::CD3DStateGuard guard(rView->pd3dDevice);

D3DXMATRIX matOrtho;
D3DXMATRIX matIdentity;

//Setup the orthogonal projection matrix and the default world/view matrix
int width, height;
rView->GetSizeInPixels(width, height);
D3DXMatrixOrthoLH(&matOrtho, (float)width, (float)height, 0.0f, 1.0f);
D3DXMatrixIdentity(&matIdentity);

guard.SetTransform(D3DTS_PROJECTION, &matOrtho);
guard.SetTransform(D3DTS_WORLD, &matIdentity);
guard.SetTransform(D3DTS_VIEW, &matIdentity);

// render
guard.SetFVF(FVF_VertexXYZRHWCT);
rView->pd3dDevice->SetStreamSource(0, m_vertexBuffer DX9v DX9(0), sizeof(VertexXYZRHWCT));
guard.SetRenderState(D3DRS_LIGHTING, FALSE);
guard.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
guard.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
guard.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
guard.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

guard.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
if (m_pTexture != NULL) {
guard.SetTexture(0, m_pTexture);
}

rView->pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
SAFE_RELEASE(m_vertexBuffer);



Sorry for the special things, I have just copy-pasted from our project, you have to adjust it.

I've used these two articles when writing this code, maybe you should read them too:
http://www.andypike.com/tutorials/directx8/011.asp
http://www.gamedev.net/reference/articles/article1972.asp

Peter

Share this post


Link to post
Share on other sites
That code has actually nothing to do with point sprites, but thank you for the effort. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Tertsi
That code has actually nothing to do with point sprites, but thank you for the effort. :)

If you look at the code provided it shows you how to set up an Ortho projection which will give you the 2D coordinates that you want. There's nothing special about Point Sprites in this regard.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!