i couldn't stuff all my particles now in one large VB coz...,
hello,
well it's because
1. i'd like my particles to have multiple textures(ie, animating),
2. i want it to rotate,
3. each type uses different textures
4. each type too have their own orientation towards the camera
5. different x,y,z sizes
so does that mean, EACH of my particle has it's own World Transformation and SetTexture now? and now i have to use materials too because i can't go for lock/unlock for each of them,
also, i know this is possible but i don't know how, the texture contains a sequence of frames, say 16, so how do i retrieve each of them, method should be very fast though,
many thanks hope you could give me some advice if there's any other way, especially changing the particle's color
[edited by - mickey on December 5, 2002 8:11:04 AM]
hi
I think the best thing to do is to render each particle as a quad (4 vertices), like in the Billboarding SDK sample.
Sort your particles by texture.
You should use one big vertex buffer, that you lock each frame just before you render, fill it with your newly computed vertices, unlock and render it.
you can write something like (pseudo-C++ code):
CParticleList
{
int count;
LPDIRECT3DTEXTURE8 pTex = ...;
YOUR_VERTEX_FORMAT buf[4*count];
void Render(int* pos) {
for (int i=0;i m_pd3dDevice->SetTexture(0, pTex);
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, *pos, 2);
(*pos) += 4;
}
}
};
CParticleSystem:
{
int numTextures;
CParticleList particles[numTextures];
void Render() {
int pos = VertexBufferPosition;
for (int i=0;i particles->Render(&pos);
}
};
Just load your data into the vertex buffer before you render, and you are done. Loading requires that you multiply each vertex by its particle transformation matrix, which can be slow; and that is why current games do not display lots of different particles: it is very expensive.
Again, look at the Billboarding sample code, it will help you with the orientation towards the camera. (in this sample, all the trees are oriented so that they face the camera)
About animating your particles, I suggest using a big texture, containing your 16 frames, and change the vertex texture
coordinates each frame, so that only 1 frame is drawn
Hope this helps
I think the best thing to do is to render each particle as a quad (4 vertices), like in the Billboarding SDK sample.
Sort your particles by texture.
You should use one big vertex buffer, that you lock each frame just before you render, fill it with your newly computed vertices, unlock and render it.
you can write something like (pseudo-C++ code):
CParticleList
{
int count;
LPDIRECT3DTEXTURE8 pTex = ...;
YOUR_VERTEX_FORMAT buf[4*count];
void Render(int* pos) {
for (int i=0;i m_pd3dDevice->SetTexture(0, pTex);
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, *pos, 2);
(*pos) += 4;
}
}
};
CParticleSystem:
{
int numTextures;
CParticleList particles[numTextures];
void Render() {
int pos = VertexBufferPosition;
for (int i=0;i particles->Render(&pos);
}
};
Just load your data into the vertex buffer before you render, and you are done. Loading requires that you multiply each vertex by its particle transformation matrix, which can be slow; and that is why current games do not display lots of different particles: it is very expensive.
Again, look at the Billboarding sample code, it will help you with the orientation towards the camera. (in this sample, all the trees are oriented so that they face the camera)
About animating your particles, I suggest using a big texture, containing your 16 frames, and change the vertex texture
coordinates each frame, so that only 1 frame is drawn
Hope this helps
EDIT :: Should've read Tibo's post - before writing this oh well - this may still be somewhat useful.
Well, particles are usually quite small - can't you have a single texture with more than one particle type in it? If you had a 256x256 texture, you could fit (for example) 4 types of particle, each with 8 frames of animation, each frame 32 x 32 pixels big on that one texture, and then you wouldn't need to change texture for each particle. Of course, if you need more types of particle, or larger particles, or longer animations then you'd have to either use bigger textures (which wouldn't necessarily work on all cards), or split the texture up and SetTexture() for each group of particles.
There are two ways of retreiving a specific part of the texture.
1) Alter the vertices in the vertex buffer, using different texture coordinates.
2) Use a texture transformation matrix to get the card to transform the coords itself.
In the first method you'd need to lock the vertex buffer each frame, and change the texture coordinates (you could also change the colour and position here) - but you would change the coords for every particle at once. Then you'd call DrawPrimitive once to draw every particle.
In the second method you have to group your particles, and set up the texture transform matrix for each group (don't set it for every particle unless).
Hope that helps,
John B
[edited by - JohnBSmall on December 5, 2002 11:20:35 AM]
Well, particles are usually quite small - can't you have a single texture with more than one particle type in it? If you had a 256x256 texture, you could fit (for example) 4 types of particle, each with 8 frames of animation, each frame 32 x 32 pixels big on that one texture, and then you wouldn't need to change texture for each particle. Of course, if you need more types of particle, or larger particles, or longer animations then you'd have to either use bigger textures (which wouldn't necessarily work on all cards), or split the texture up and SetTexture() for each group of particles.
There are two ways of retreiving a specific part of the texture.
1) Alter the vertices in the vertex buffer, using different texture coordinates.
2) Use a texture transformation matrix to get the card to transform the coords itself.
In the first method you'd need to lock the vertex buffer each frame, and change the texture coordinates (you could also change the colour and position here) - but you would change the coords for every particle at once. Then you'd call DrawPrimitive once to draw every particle.
In the second method you have to group your particles, and set up the texture transform matrix for each group (don't set it for every particle unless).
Hope that helps,
John B
[edited by - JohnBSmall on December 5, 2002 11:20:35 AM]
hi,
how do i use the texture transformation to index into the appropriate frame on the texture?
i already tried scaling/rotatino and it works great, but do i use a translation matrix to index? coz it doesn't seem to work?
wish i could still use dx' point sprites though even with all the features i want..,
edit:
okay say i have my quad's tu/tv 0.0f to 1.0f only(covers the entire texture),
then my texture has it's size 128x128 consisting of 16 frames of fires, so that's 32x32, ehm, how do i get row 2 col 2?
thanks!
[edited by - mickey on December 5, 2002 12:45:53 AM]
how do i use the texture transformation to index into the appropriate frame on the texture?
i already tried scaling/rotatino and it works great, but do i use a translation matrix to index? coz it doesn't seem to work?
wish i could still use dx' point sprites though even with all the features i want..,
edit:
okay say i have my quad's tu/tv 0.0f to 1.0f only(covers the entire texture),
then my texture has it's size 128x128 consisting of 16 frames of fires, so that's 32x32, ehm, how do i get row 2 col 2?
thanks!
[edited by - mickey on December 5, 2002 12:45:53 AM]
Use fractional tu/tv coordinates to map to portions of a texture file.
Use this formula:
tu = (1 / texture_file_width) * texture_left_pixel_offset;
tv = (1 / texture_file_height) * texture_top_pixel_offset;
So, in your example, row 2, column 2 would be at left pixel offset 64, top pixel offset 64, and would have a texture file size of 128x128, right? So:
tu = (1 / 128) * 64;
tv = (1 / 128) * 64;
Those would be the texture coordinates of the upper-left corner of the quad.
--Hoozit.
----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.
Use this formula:
tu = (1 / texture_file_width) * texture_left_pixel_offset;
tv = (1 / texture_file_height) * texture_top_pixel_offset;
So, in your example, row 2, column 2 would be at left pixel offset 64, top pixel offset 64, and would have a texture file size of 128x128, right? So:
tu = (1 / 128) * 64;
tv = (1 / 128) * 64;
Those would be the texture coordinates of the upper-left corner of the quad.
--Hoozit.
----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.
hi HoozitWhatzit,
no not that, i''d like to know what kind of matrix i''ll be using if i am to use the texture transformation states, but still thanks for the formulas,
no not that, i''d like to know what kind of matrix i''ll be using if i am to use the texture transformation states, but still thanks for the formulas,
Warning: This may be incorrect, as I don't have the SDK here with me.
If I remember correctly, the texture transform matrix is different from the normal projection, view and world matrices, as it only uses the first 3x3 section of the matrix. Therefore, using the normal D3DXTranslate function to get the matrix will not work (it works for scaling because scaling uses the inner section of the matrix anyway, but for translations it wouldn't work). I can't remember if there is a special utility function to make a texture transform matrix for you, but I don't think there is, so that means you'll need to produce the matrix yourself (probably best to make an inline function to set a texture matrix up given, for example, a rect specifying which section of the texture to use).
Hope that helps,
John B
[edited by - JohnBSmall on December 6, 2002 12:03:44 PM]
If I remember correctly, the texture transform matrix is different from the normal projection, view and world matrices, as it only uses the first 3x3 section of the matrix. Therefore, using the normal D3DXTranslate function to get the matrix will not work (it works for scaling because scaling uses the inner section of the matrix anyway, but for translations it wouldn't work). I can't remember if there is a special utility function to make a texture transform matrix for you, but I don't think there is, so that means you'll need to produce the matrix yourself (probably best to make an inline function to set a texture matrix up given, for example, a rect specifying which section of the texture to use).
Hope that helps,
John B
[edited by - JohnBSmall on December 6, 2002 12:03:44 PM]
DrawPrimitve can render a part of the triangles right?
And you can use matrices BETWEEN the renders.
.lick
[edited by - Pipo DeClown on December 6, 2002 12:06:06 PM]
And you can use matrices BETWEEN the renders.
.lick
[edited by - Pipo DeClown on December 6, 2002 12:06:06 PM]
Exactly, Pipo - no reasons NOT to use one VB so far.
Regards
Thomas Tomiczek
THONA Consulting Ltd.
(Microsoft MVP C#/.NET)
Regards
Thomas Tomiczek
THONA Consulting Ltd.
(Microsoft MVP C#/.NET)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement