Advertisement

Realtime OpenGl

Started by April 07, 2003 10:32 AM
2 comments, last by J__H 21 years, 10 months ago
I need some help with what i understand is a classical problem. I collect signals (realtime) from three gyro sensors and want to make a cube that follows the motion of my gyro sensor package. The trouble i have is to get the right translation between the local coordinate system angles. First i have made a translation from angles to eulerangles. So what i want to feed the openGL function is eulerangles. I use the following code to update the cube angles: glRotatef(Xrotation,1.0f,0.0f,0.0f); glRotatef(Yrotation,0.0f,1.0f,0.0f); glRotatef(Zrotation,0.0f,0.0f,1.0f); This code only works for the Zrotation. When i rotate around Z, the axel will be still while the cube rotate around it. But the other two doesn''t work, X and Y will rotate around the the current position of the cube. Any suggestion what i do wrong... Thanks in advance /JH
The behaviour is right, but unfortunately obviously not what you want. I don''t know what data your gyroscope package outputs, maybe if you explain that a little we''ll be able to come up with a solution.

Sounds like an interesting project though.
Advertisement
I use LabWindows with a I/O card to collect the data, the output from the gyroscope are in volts then i scale the volts to Deg/s and then i make euler calculation that will get rid of the gimbal effect. What i have now is the euler angles and I want to connect them to my cube that i have drawn in openGL.

Did I use the rotate command correct for a local coordinate system? Maybe i somehow clears the matrix so that when the next angle update try to rotate the cube it have forgotten the last position of the cube coordinate system.

At the same time i can ask about textures. I want to paint my cube with a bmp image and it works with the code i write. The trouble is that everytime the cube is updated i load the texture. This of course lead to memory leackage and and reduced performace in terms of sample time. I guess i can do this smarter and only load the texture once, maybe in the init function. But when i do this the texture will mot be visible. So i guess i somewhere clears that memory aswell. Any suggestions how to fix this?

This is some of my code:

void InitOGLControl(void)
{

// Puts the position of the cube in the LabWindows window
OGLSetCtrlAttribute (panelHandle, OGLControlPanel, OGLATTR_PROJECTION_TYPE, OGLVAL_PERSPECTIVE);
OGLSetCtrlAttribute (panelHandle, OGLControlPanel, OGLATTR_VIEW_DIRECTION, OGLVAL_USER_DEFINED);
OGLSetCtrlAttribute (panelHandle, OGLControlPanel, OGLATTR_VIEW_LATITUDE, DFLT_VIEW_LATITUDE);
OGLSetCtrlAttribute (panelHandle, OGLControlPanel, OGLATTR_VIEW_LONGITUDE, DFLT_VIEW_LONGITUDE);
OGLSetCtrlAttribute (panelHandle, OGLControlPanel, OGLATTR_VIEW_CENTERX,DFLT_VIEWPOINT_X);
OGLSetCtrlAttribute (panelHandle, OGLControlPanel, OGLATTR_VIEW_CENTERY,DFLT_VIEWPOINT_Y);
OGLSetCtrlAttribute (panelHandle, OGLControlPanel, OGLATTR_VIEW_CENTERZ,DFLT_VIEWPOINT_Z);
OGLSetCtrlAttribute (panelHandle, OGLControlPanel, OGLATTR_VIEW_DISTANCE,DFLT_VIEW_DISTANCE);

}


void RenderCubeImage(int fastFlag)
{

glPushAttrib(GL_ALL_ATTRIB_BITS);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();

glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_TEXTURE_2D); // Enable texture mapping ( NEW )
glShadeModel(GL_SMOOTH); // Enable smooth shading
glClearDepth(1.0f); // Depth buffer setup
glEnable(GL_DEPTH_TEST); // Enables depth testing
glDepthFunc(GL_LEQUAL); // The type of depth testing to do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations

// LoadGLTextures();

glRotatef(Xrotation,1.0f,0.0f,0.0f);
glRotatef(Zrotation,0.0f,0.0f,1.0f);
glRotatef(Yrotation,0.0f,1.0f,0.0f);

DrawCubeImage(fastFlag);

glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();

}

int DrawCubeImage(int fastFlag)
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLineWidth(4.0);
glBegin(GL_LINES);

// X axel
glColor3f(1.0,0.0,0.0);
glVertex3f(0.0,0.0,0.0);
glVertex3f(5.0,0.0,0.0);

// Y Axel
glColor3f(0.0,0.0,1.0);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,5.0,0.0);

// Z Axel
glColor3f(1.0,1.0,1.0);
glVertex3f(0.0,0.0,0.0);
glVertex3f(0.0,0.0,5.0);

glEnd();
//glFlush();

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]); // Select my texture

glBegin(GL_QUADS);
glColor3f(0.0,1.0,1.0);
// Front face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom left of the texture and quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom right of the texture and quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top right of the texture and quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top left of the texture and quad
// Back face
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom right of the texture and quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top right of the texture and quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top left of the texture and quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom left of the texture and quad
// Top face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top left of the texture and quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom left of the texture and quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom right of the texture and quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top right of the texture and quad
// Bottom face
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top right of the texture and quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top left of the texture and quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom left of the texture and quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom right of the texture and quad
// Right face
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom right of the texture and quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top right of the texture and quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top left of the texture and quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom left of the texture and quad
// Left face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom left of the texture and quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom right of the texture and quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top right of the texture and quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top left of the texture and quad
glEnd();
return true;
}


Hope i can get some help!

Thanks!

/JH
OK, I think I can see what you want, I had a little think and you might be able to solve it this way (you'll need to implement some basic matrix math routines).

First, choose your order, we'll take the z,y,x order you used initially:

glRotatef(Xrotation,1.0f,0.0f,0.0f);
glRotatef(Yrotation,0.0f,1.0f,0.0f);
glRotatef(Zrotation,0.0f,0.0f,1.0f);

Now the first rotation (which is z since thats the way OGL works) should operate on the (0,0,1) axis. The next rotation (y) should actually operate on the (0,1,0) axis *rotated* by the first rotation. The final X rotation should operate on the (1,0,0) axis rotated by both the first two rotations.


      typedef float vector3[3];typedef float matrix4X4[16]; // stored in column-majorvoid mult_matrix(matrix4X4 out,matrix4X4 in1,matrix4X4 in2){  out[0+(0*4)] = (in1[0+(0*4)]*in2[0+(0*4)]) + (in1[0+(1*4)]*in2[1+(0*4)]) + (in1[0+(2*4)]*in2[2+(0*4)]) + (in1[0+(3*4)]*in2[3+(0*4)]);  // etc.}void transform_vector3(vector3 out,matrix4X4 m,vector3 v){  // multiply column vector on the right  vector3 vout;  vout[0] = (m[0+(0*4)]*v[0]) + (m[0+(1*4)]*v[1]) + (m[0+(2*4)]*v[2]) + (m[0+(3*4)]*1.0);  // etc.  out[0] = vout[0];  // etc.}void construct_rotation(float angx,float angy,float angz){  vector3 yaxis;  vector3 xaxis;  vector3 zaxis;  matrix4X4 trans;  zaxis[0] = 0;  zaxis[1] = 0;  zaxis[2] = 1;  yaxis[0] = 0;  yaxis[1] = 1;  yaxis[2] = 0;  xaxis[0] = 1;  xaxis[1] = 0;  xaxis[2] = 0;  glMatrixMode(GL_MODELVIEW);  glLoadIdentity();  glRotatef(angz,zaxis[0],zaxis[1],zaxis[2]);  glGetFloatv(GL_MODELVIEW_MATRIX,trans);  // get the z rotation matrix  transform_vector3(yaxis,trans,yaxis); // rotate the y axis  glRotatef(angy,yaxis[0],yaxis[1],yaxis[2]);  glGetFloatv(GL_MODELVIEW_MATRIX,trans);  // get the z,y rotation   transform_vector3(xaxis,trans,xaxis); // rotate the x axis  glRotatef(angx,xaxis[0],xaxis[1],xaxis[2]);}      


You need to clean it up a bit. Hopefully that should work although you might need to change the axis order (and I might have the math wrong but you can see where I'm going).

About the textures: Theres no reason to load the textures each frame, as long as texture[0] isn't changed. You seem to be pushing all the attributes and not popping them (that might just be an omission in your post tho).



[edited by - JuNC on April 8, 2003 2:41:56 PM]

This topic is closed to new replies.

Advertisement