Search code examples
openglglslopengl-3

Rotate point sprite


I can already rotate point sprite on 0, 90, 180, 270 degrees

Fragment shader

precision lowp float;

uniform sampler2D us_tex;
uniform mat3 um_tex;

void main ()
{
  vec2 tex_coords = (um_tex * vec3(gl_PointCoord, 1.0)).xy;
  gl_FragColor = texture2D(us_tex, tex_coords);
}

2*2 Matrix operations (i know about GLM - it's great, academic purpose to handle matrix on your own)

typedef GLfloat m3[9]//3*3 matrix

#define DEG_TO_RAD(x) (x * M_PI/180.0f)

void ident_m3(m3 res)
{
 memset(res, 0, sizeof(m3));
 res[0] = res[4] = res[8] = 1.0f;
}

void trans_m3(m3 res, const p2* pos)
{
ident_m3(res);
res[7] = pos->x;
res[8] = pos->y;
}

void mult_m3(m3 res, const m3 m1, const m3 m2)
{
 res[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2];
 res[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2];
 res[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2];

 res[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5];
 res[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5];
 res[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5];

 res[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8];
 res[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8];
 res[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8];
}

in ParticlesDraw()

 m3 r;
 rot_m3(r, 90.0f);
 ...
 glUniformMatrix3fv(/*um_tex uniform*/, 1, GL_FALSE, res);
 glDrawArrays(GL_POINTS, 0, /*particles count*/);
 ...

Also i know how rotate ordinary sprite around pos(x,y,z)

  1. Translate to pos(-x,-y,-z)
  2. Rotate
  3. Translate to pos(x,y,z)

Result Matrix = (Rot Matrix * Translate Matrix) * Anti-Traslate Matrix.

I want to rotate point sprite to 45, 32,64,72 e.g any degree (now it rotates not right, last frame 45 deg) problem

But in this case, i can translate to center of tex (0.5, 0.5), but what will be anti translate - (0.0, 0.0)?
I try something like this, but it does not work for example for 30, 45 rotation, also if my texture is 64*64, do i need to set gl_PointSize to 64.0 for rotation?


Solution

  • This:

    1. Translate to pos(-x,-y,-z)
    2. Rotate
    3. Translate to pos(x,y,z)

    Is not the same thing as this:

    Result Matrix = (Rot Matrix * Translate Matrix) * Anti-Traslate Matrix.

    If you wish to rotate around the point (x,y,z), then you need to do this:

    1. Matrix T1 = Translate(x, y, z);
    2. Matrix R1 = Rotate();
    3. Matrix T2 = Translate(-x, -y, -z);

    Which is the same thing as:

    Result Matrix = T1 * R1 * T2