 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
gotmilk065
Joined: 28 Nov 2009 Posts: 25
|
Posted: Fri Dec 25, 2009 4:15 pm Post subject: Rotating images with the GU? |
|
|
I wanted to enhance my particle engine a bit, and the next step is to rotate the smoke particles for a better effect.
Problem is, everything I see on rotating images is done on the CPU and involves essentially resampling the image! Isn't there a simple command to change the rotation of vertices and textures about to be rendered, and then switch it back when it's done? |
|
| Back to top |
|
 |
jsharrad
Joined: 20 Oct 2005 Posts: 102
|
Posted: Fri Dec 25, 2009 11:15 pm Post subject: |
|
|
| use the sceGuRotate functions |
|
| Back to top |
|
 |
gotmilk065
Joined: 28 Nov 2009 Posts: 25
|
Posted: Sat Dec 26, 2009 12:06 am Post subject: |
|
|
| I tried that but it flips the entire screen.. And at high speeds, is it radians or degrees? |
|
| Back to top |
|
 |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Sat Dec 26, 2009 1:42 am Post subject: |
|
|
Try using the sceGum* functions.
| Code: | sceGumMatrixMode(GU_MODEL); // EDIT
sceGumPushMatrix();
sceGumLoadIdentity();
sceGumRotateZ(angle);
sceGumDrawArray(...);
sceGumPopMatrix(); |
I don't think it'll work with GU_SPRITES, though; use GU_TRIANGLE_FAN or the like.
| gotmilk065 wrote: | | And at high speeds, is it radians or degrees? |
Yes. :) (Just make sure GUM gets it as radians.) _________________ PSP-2000 // CFW: 5.50 GEN-D2 ...and not upgrading until OFW supports homebrew!
(But I did downgrade to 1.50 with TimeMachine...)
"I want you to tell me how the machine makes you feel." |
|
| Back to top |
|
 |
gotmilk065
Joined: 28 Nov 2009 Posts: 25
|
Posted: Sat Dec 26, 2009 5:30 am Post subject: |
|
|
Well here's what's going on in the function, doesn't work :(
| Code: |
int D_DrawParticleBuffered (psp_particle* vertices, particle_t *pparticle, vec3_t up, vec3_t right, float scale, float alpha, float rot) {
sceGumMatrixMode(GU_MODEL); // EDIT
sceGumPushMatrix();
sceGumLoadIdentity();
sceGumRotateZ(rot);
unsigned int color = d_8to24table[static_cast<int>(pparticle->color)];
int i = BufIdx;
vertices[i].first.x = pparticle->org[0] - scale*(up[0] + right[0]);
vertices[i].first.y = pparticle->org[1] - scale*(up[1] + right[1]);
vertices[i].first.z = pparticle->org[2] - scale*(up[2] + right[2]);
vertices[i].first.s = 0.0;
vertices[i].first.t = 0.0;
if (pparticle->alpha)
vertices[i].first.color = GU_RGBA(128, 128, 128, int(alpha));
else
vertices[i].first.color = color;
vertices[i].second.x = pparticle->org[0] + scale*(up[0] + right[0]);
vertices[i].second.y = pparticle->org[1] + scale*(up[1] + right[1]);
vertices[i].second.z = pparticle->org[2] + scale*(up[2] + right[2]);
vertices[i].second.s = 1.0;
vertices[i].second.t = 1.0;
if (pparticle->alpha)
vertices[i].second.color = GU_RGBA(128, 128, 128, int(alpha));
else
vertices[i].second.color = color;
BufIdx++;
if (BufIdx >= BufSize) {
sceGuDrawArray(GU_TRIANGLE_STRIP, GU_VERTEX_32BITF|GU_TEXTURE_32BITF|GU_COLOR_8888, BufSize, 0, vertices);
BufIdx = 0;
BufSize = -1;
sceGumPopMatrix();
return -1;
}
sceGumPopMatrix();
return BufIdx;
}
|
I'm sad that it doesn't work :< |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Sat Dec 26, 2009 6:16 am Post subject: |
|
|
1.) you seem to try to save some vertices for your particles, to build them all as one large triangle-strip and only adding the bottom-left and top-right vertex. This won't work. You need to render each particle as a seperate triangle-strip or triangle-fan with four vertices. The only option is to use GU_SPRITE with two vertices and apply the rotation on the texture coordinates, rather than the vertex coordinates, but you have to make sure that the rotated texture corners won't get clipped inside the sprite.
2.) With your current implementation, you always apply the rotation of the current particle to the model matrix, then undo it (with sceGumPopMatrix). The only time, the rotation will get applied is in the case when your buffer gets filled (BufIdx>=BufSize), in which case only the rotation of the current particle will get applied to the draw (because all others have been undone before the render command got sent).
3.) You rotate all your particle vertices around the world-view Z axis. This is doubtly what you want. You probably want to rotate the particles around their own center, hence you need to translate the vertice positions into object space (or directly set them in object space - ie place vertices relative to the particles center) and translate them back after the rotation. Since sceGum transformation matrix is applied from left to right, you need to do the back-translation *before* the rotation command (ie | Code: | sceGumTranslate(&pos);
sceGumRotateZ(angle); | ). This may sound contra-intuitive, but is logical from a mathematical point of view.
Sample code from triEngine:
| Code: |
sceGumPushMatrix();
sceGumLoadIdentity();
ScePspFVector3 trans;
trans.x = (x + width/2);
trans.y = (y + height/2);
trans.z = 0;
sceGumTranslate( &trans );
sceGumRotateZ( angle*GU_PI/180 );
triVertUV* vertices = (triVertUV*)sceGuGetMemory(4 * sizeof(triVertUV));
vertices[0].u = u0;
vertices[0].v = v0;
vertices[0].x = -(width/2);
vertices[0].y = -(height/2);
vertices[0].z = 0;
vertices[1].u = u0;
vertices[1].v = v1;
vertices[1].x = -(width/2);
vertices[1].y = (height/2);
vertices[1].z = 0;
vertices[2].u = u1;
vertices[2].v = v1;
vertices[2].x = (width/2);
vertices[2].y = (height/2);
vertices[2].z = 0;
vertices[3].u = u1;
vertices[3].v = v0;
vertices[3].x = (width/2);
vertices[3].y = -(height/2);
vertices[3].z = 0;
sceGumDrawArray(GU_TRIANGLE_FAN,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_3D,4,0,vertices);
sceGumPopMatrix();
|
_________________ <Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl |
|
| Back to top |
|
 |
gotmilk065
Joined: 28 Nov 2009 Posts: 25
|
Posted: Sat Dec 26, 2009 7:30 am Post subject: |
|
|
I'm simply not getting this o_o
Your first solution seems simplest, rotate the texture instead of the poly itself, but the whole repeating texture deal if it exceeds the bounds kind of ruins it.
I'm totally lost. Here's my new function, but it's not even displaying the particles at all o.o
| Code: |
sceGumPushMatrix();
sceGumLoadIdentity();
ScePspFVector3 trans;
trans.x = (pparticle->org[0] + scale/2);
trans.y = (pparticle->org[1] + scale/2);
trans.z = (pparticle->org[2] + scale/2);
sceGumTranslate(&trans);
sceGumRotateZ(rot*GU_PI/180);
unsigned int color = d_8to24table[static_cast<int>(pparticle->color)];
struct part_vertex {
float s, t;
unsigned int color;
float x, y, z;
};
part_vertex* const vertices = static_cast<part_vertex*>(sceGuGetMemory(4*sizeof(part_vertex)));
vertices[0].x = -(scale/2);
vertices[0].y = -(scale/2);
vertices[0].z = 0;
vertices[0].s = 0.0;
vertices[0].t = 0.0;
vertices[1].x = -(scale/2);
vertices[1].y = (scale/2);
vertices[1].z = 0;
vertices[1].s = 1.0;
vertices[1].t = 1.0;
vertices[2].x = (scale/2);
vertices[2].y = (scale/2);
vertices[2].z = 0;
vertices[2].s = 1.0;
vertices[2].t = 1.0;
vertices[3].x = (scale/2);
vertices[3].y = -(scale/2);
vertices[3].z = 0;
vertices[3].s = 1.0;
vertices[3].t = 1.0;
if (pparticle->alpha) {
vertices[0].color = GU_RGBA(128, 128, 128, int(pparticle->alpha));
vertices[1].color = GU_RGBA(128, 128, 128, int(pparticle->alpha));
vertices[2].color = GU_RGBA(128, 128, 128, int(pparticle->alpha));
vertices[3].color = GU_RGBA(128, 128, 128, int(pparticle->alpha));
} else {
vertices[0].color = color;
vertices[1].color = color;
vertices[2].color = color;
vertices[3].color = color;
}
sceGuDrawArray(GU_TRIANGLE_FAN, GU_VERTEX_32BITF|GU_TEXTURE_32BITF|GU_COLOR_8888|GU_TRANSFORM_3D, 4, 0, vertices);
sceGumPopMatrix();
|
If I can't get this working, I'll have to say goodbye to rotating particles and just stick with the static ones :( |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Sat Dec 26, 2009 8:00 am Post subject: |
|
|
The only thing that is still wrong now, is that the vertices texture coordinates aren't set correctly, which *might* cause the particles to not appear, depending on the texture used.
This should be correct:
| Code: |
vertices[0].x = -(scale/2);
vertices[0].y = -(scale/2);
vertices[0].z = 0;
vertices[0].s = 0.0;
vertices[0].t = 0.0;
vertices[1].x = -(scale/2);
vertices[1].y = (scale/2);
vertices[1].z = 0;
vertices[1].s = 0.0;
vertices[1].t = 1.0;
vertices[2].x = (scale/2);
vertices[2].y = (scale/2);
vertices[2].z = 0;
vertices[2].s = 1.0;
vertices[2].t = 1.0;
vertices[3].x = (scale/2);
vertices[3].y = -(scale/2);
vertices[3].z = 0;
vertices[3].s = 1.0;
vertices[3].t = 0.0;
|
EDIT: I just remembered that it could also be due to your backface culling order, that the particles don't show. If the above still won't show anything and you are sure your view/projection matrices are correct, try switching vertice[1] and vertice[3] values, so the winding order gets inverted. _________________ <Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl |
|
| Back to top |
|
 |
gotmilk065
Joined: 28 Nov 2009 Posts: 25
|
Posted: Sat Dec 26, 2009 9:00 am Post subject: |
|
|
I'll try that when I get home.
Until then; Merry Christmas! |
|
| Back to top |
|
 |
gotmilk065
Joined: 28 Nov 2009 Posts: 25
|
Posted: Sun Dec 27, 2009 2:41 am Post subject: |
|
|
:( I even did so much as disabling backfacing; they still don't appear.
Just to let you know, the old function did work, the buffered one, but without rotation, and I had something before that worked withou the buffer or the rotation. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|