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
Post a Comment