c++ - Particles not oriented to the camera -


i've got simple particle system display particles on screen , move them around x, y , z axis. problem particles not oriented camera.

glrotatef(g_fx, 1.0f, 1.0f, 1.0f);                                       glenable(gl_blend);                                                           glblendfunc(gl_src_alpha, gl_one_minus_src_alpha); glenable(gl_texture_2d); gldisable(gl_depth_test); glbindtexture(gl_texture_2d, texcircle);  glcolor3f (1.0f, 0.0f, 0.0f);  (x = -1; x <= 1; x += 0.25) {     (y = -1; y <= 1; y += 0.25)     {         (z = -1; z <= 1; z += 0.25)         {             glbegin(gl_triangle_strip);                                                 gltexcoord2d(1,1); glvertex3f(x+0.5f,y+0.5f,z);             gltexcoord2d(0,1); glvertex3f(x-0.5f,y+0.5f,z);             gltexcoord2d(1,0); glvertex3f(x+0.5f,y-0.5f,z);             gltexcoord2d(0,0); glvertex3f(x-0.5f,y-0.5f,z);             glend();         }     } }        glenable(gl_depth_test);   gldisable(gl_blend);   

what should change in code?

you have draw particles in plane orthogonal viewport. plane given x-axis , y-axis of current inverse modelview matrix.
corner points of rectangle should calculated in following pseudo code:

x = x-axis of inverse modelview matrix y = y-axis of inverse modelview matrix  tl = (x, y, z) - 0.5 * x + 0.5 * y tr = (x, y, z) + 0.5 * x + 0.5 * y bl = (x, y, z) - 0.5 * x - 0.5 * y br = (x, y, z) + 0.5 * x - 0.5 * y 

note transformation matrix looks this:

( x-axis.x, x-axis.y, x-axis.z, 0 ) ( y-axis.x, y-axis.y, y-axis.z, 0 ) ( z-axis.x, z-axis.y, z-axis.z, 0 ) ( trans.x,  trans.y,  trans.z,  1 ) 

you should use libray glm calculate matirces, if have not used far, can read current modelview matrix glgetfloatv(gl_modelview_matrix, ptr) (see how modelview , projection matrices in opengl?).
draw in plane orthogonal viewport have draw, rectangle aligned axis of inverse view matrix (see inverse matrix). use glm::inverse calculating inverse view matrix, other library appropriate too. see answers stackoverflow question inverting 4x4 matrix.

void inversemat44( const glfloat m[], glfloat im[] ) {     // here can put in function, of other library , calculates inverse 4*4 matrix.     glm::mat4 glm_m = glm::make_mat4(m);     glm::mat4 glm_im = glm::inverse(glm_m);     memcpy( im, glm::value_ptr( glm_im ), 16 * sizeof( glfloat ) ); }  glfloat vm[16], ivm[16]; glgetfloatv(gl_modelview_matrix, vm ); inversemat44( vm, ivm ); 

if view matrix scaled, have normalize axis vectors, or have take in account scale factor in side length of quads:

glfloat scalex = sqrt( ivm[0]*ivm[0] + ivm[1]*ivm[1] + ivm[2]*ivm[2] ); glfloat scaley = sqrt( ivm[4]*ivm[4] + ivm[5]*ivm[5] + ivm[6]*ivm[6] );  glfloat lenx = 0.5f, leny = 0.5f; lenx = lenx / scalex; leny = leny / scaley; 

the drawing of rectangle should somehow this:

glfloat xx = ivm[0] * lenx, xy = ivm[1] * lenx, xz = ivm[2] * lenx; glfloat yx = ivm[4] * leny, yy = ivm[5] * leny, yz = ivm[6] * leny;  glbegin(gl_triangle_strip);                                      gltexcoord2d(1,1); glvertex3f( x + xx + yx, y + xy + yy, z + xz + yz ); gltexcoord2d(0,1); glvertex3f( x - xx + yx, y - xy + yy, z - xz + yz ); gltexcoord2d(1,0); glvertex3f( x + xx - yx, y + xy - yy, z + xz - yz ); gltexcoord2d(0,0); glvertex3f( x - xx - yx, y - xy - yy, z - xz - yz );  glend(); 


see answers following questions:

solution using model view matrix

but more elegant solution use model view matrix achieve billboard effect. first have apply translation model matrix , not mesh, , second have apply inverse view rotation model matrix:

glfloat scalex = sqrt( ivm[0]*ivm[0] + ivm[1]*ivm[1] + ivm[2]*ivm[2] ); glfloat scaley = sqrt( ivm[4]*ivm[4] + ivm[5]*ivm[5] + ivm[6]*ivm[6] ); glfloat scalez = sqrt( ivm[8]*ivm[8] + ivm[9]*ivm[9] + ivm[10]*ivm[10] );  glfloat len = 0.5f; (x = -1; x <= 1; x += 0.25) {     (y = -1; y <= 1; y += 0.25)     {         (z = -1; z <= 1; z += 0.25)         {             glfloat rm[16] = {                 ivm[0]/scalex, ivm[1]/scalex, ivm[2]/scalex,  0.0f,                 ivm[4]/scaley, ivm[5]/scaley, ivm[6]/scaley,  0.0f,                 ivm[8]/scalez, ivm[9]/scalez, ivm[10]/scalez, 0.0f,                 0.0f,          0.0f,          0.0f,           1.0f             };              glpushmatrix();             gltranslated( x, y, z );             glmultmatrixf( rm );              glbegin(gl_triangle_strip);                                                 gltexcoord2d(1,1); glvertex3f(  len,  len, 0.0f );             gltexcoord2d(0,1); glvertex3f( -len,  len, 0.0f );             gltexcoord2d(1,0); glvertex3f(  len, -len, 0.0f );             gltexcoord2d(0,0); glvertex3f( -len, -len, 0.0f );             glend();              glpopmatrix();         }     } } 

note, solution have know current model view matrix , have calculate inverse modelview matrix.

an alternativ function calculating inverse matrix (see inverting 4x4 matrix):

bool inversemat44( const glfloat m[16], glfloat invout[16] ) {     float inv[16], det;     int i;      inv[0]  =  m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] + m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];     inv[4]  = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] - m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];     inv[8]  =  m[4] * m[9]  * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] + m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];     inv[12] = -m[4] * m[9]  * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] - m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];     inv[1]  = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] - m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];     inv[5]  =  m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] + m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];     inv[9]  = -m[0] * m[9]  * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] - m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];     inv[13] =  m[0] * m[9]  * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] + m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];     inv[2]  =  m[1] * m[6]  * m[15] - m[1] * m[7]  * m[14] - m[5] * m[2] * m[15] + m[5] * m[3] * m[14] + m[13] * m[2] * m[7]  - m[13] * m[3] * m[6];     inv[6]  = -m[0] * m[6]  * m[15] + m[0] * m[7]  * m[14] + m[4] * m[2] * m[15] - m[4] * m[3] * m[14] - m[12] * m[2] * m[7]  + m[12] * m[3] * m[6];     inv[10] =  m[0] * m[5]  * m[15] - m[0] * m[7]  * m[13] - m[4] * m[1] * m[15] + m[4] * m[3] * m[13] + m[12] * m[1] * m[7]  - m[12] * m[3] * m[5];     inv[14] = -m[0] * m[5]  * m[14] + m[0] * m[6]  * m[13] + m[4] * m[1] * m[14] - m[4] * m[2] * m[13] - m[12] * m[1] * m[6]  + m[12] * m[2] * m[5];     inv[3]  = -m[1] * m[6]  * m[11] + m[1] * m[7]  * m[10] + m[5] * m[2] * m[11] - m[5] * m[3] * m[10] - m[9]  * m[2] * m[7]  + m[9]  * m[3] * m[6];     inv[7]  =  m[0] * m[6]  * m[11] - m[0] * m[7]  * m[10] - m[4] * m[2] * m[11] + m[4] * m[3] * m[10] + m[8]  * m[2] * m[7]  - m[8]  * m[3] * m[6];     inv[11] = -m[0] * m[5]  * m[11] + m[0] * m[7]  * m[9]  + m[4] * m[1] * m[11] - m[4] * m[3] * m[9]  - m[8]  * m[1] * m[7]  + m[8]  * m[3] * m[5];     inv[15] =  m[0] * m[5]  * m[10] - m[0] * m[6]  * m[9]  - m[4] * m[1] * m[10] + m[4] * m[2] * m[9]  + m[8]  * m[1] * m[6]  - m[8]  * m[2] * m[5];      det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];     if (det == 0) return false;     det = 1.0 / det;      (i = 0; < 16; i++)         invout[i] = inv[i] * det;      return true; } 

Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -