forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Rotating images with the GU?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
gotmilk065



Joined: 28 Nov 2009
Posts: 25

PostPosted: Fri Dec 25, 2009 4:15 pm    Post subject: Rotating images with the GU? Reply with quote

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
View user's profile Send private message
jsharrad



Joined: 20 Oct 2005
Posts: 102

PostPosted: Fri Dec 25, 2009 11:15 pm    Post subject: Reply with quote

use the sceGuRotate functions
Back to top
View user's profile Send private message
gotmilk065



Joined: 28 Nov 2009
Posts: 25

PostPosted: Sat Dec 26, 2009 12:06 am    Post subject: Reply with quote

I tried that but it flips the entire screen.. And at high speeds, is it radians or degrees?
Back to top
View user's profile Send private message
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Sat Dec 26, 2009 1:42 am    Post subject: Reply with quote

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
View user's profile Send private message
gotmilk065



Joined: 28 Nov 2009
Posts: 25

PostPosted: Sat Dec 26, 2009 5:30 am    Post subject: Reply with quote

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
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Sat Dec 26, 2009 6:16 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
gotmilk065



Joined: 28 Nov 2009
Posts: 25

PostPosted: Sat Dec 26, 2009 7:30 am    Post subject: Reply with quote

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
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Sat Dec 26, 2009 8:00 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
gotmilk065



Joined: 28 Nov 2009
Posts: 25

PostPosted: Sat Dec 26, 2009 9:00 am    Post subject: Reply with quote

I'll try that when I get home.

Until then; Merry Christmas!
Back to top
View user's profile Send private message
gotmilk065



Joined: 28 Nov 2009
Posts: 25

PostPosted: Sun Dec 27, 2009 2:41 am    Post subject: Reply with quote

:( 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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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