PDA

View Full Version : Question regarding the glRotated



tyyu
04-07-2001, 10:14 PM
Dear All:

I have a question regarding how to
use the glRotate in the application.
It should be a simple question, but
I have no idea how to handle it.

Let say I have a 3D Axis drawn in
the OpenGL Window. It is located at
the Origin (0,0,0). I would like this
axis be rotated with X axis ONLY when
I press F1 key, and rotated with Y axis
ONLY when I press F2 key, and rotated with
Z axis with F3 key. So what I have is
doing something like:

switch(key)
{
case F1_KEY:
m_xrotate += 1;
brea;
case F2_KEY:
m_yrotate += 1;
brea;
case F3_KEY:
m_zrotate += 1;
brea;
}

And in the plot routine, I have

glRotated(m_xrotate, 1.0, 0.0, 0.0);
glRotated(m_yrotate, 0.0, 1.0, 0.0);
glRotated(m_zrotate, 0.0, 0.0, 1.0);

In the first beginning, it seems ok.
ie, when I press F1, it did rotate with
X axis, then press F2, it did rotate with
respect to Y axis, same as F3 key. However,
if I keep on trying, say try F1 again, it
did not rotate with X axis, it looks like
the whole 3D axis is rotating. If I try
F2 key again, same thing happen! The Y
axis does not stand still, instead, it
look like the whole axis is rotating!

How can I adjust my application so that
no matter when I press the F1 key (or F2,F3),
it always rotate the X ONLY (means, the X axis stand
still)(or Y ONLY or Z Only)?

Thanks.

Robert Yu tyyu@ksts.seed.net.tw

ShadowGL
04-07-2001, 10:40 PM
Greetings,

I don't really know what the problem is, because you just posted a fraction of your source code.
However, I suppose that you forgot to "reset" the coordinate system with glLoadIdentity() .
Everytime, you press one of the Keys you mentioned, the new Modelview Matrix is set up by the matrix given by "glRotatef"
If you don't "reset" the Modelview Matrix by glLoadIdentity, it is multiplied with the glRotate matrix AND the current Modelview Matrix .
This could cause undesired effects in your program.

I hope this helps,

ShadowGL

Example:

//...

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glRotatef(xRotate, 1.0f, 0.0f, 0.0f);

//...


[This message has been edited by ShadowGL (edited 04-08-2001).]

tyyu
04-08-2001, 04:53 AM
Thanks for the explaination.
Let me list the part of the source code
to show the problem.

I use the VC6.0 under Window 2000,
and in the project, I have some routines
in CXXView, they are:

void CGLSample4View::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

GLsizei width, height;
GLdouble aspect;

width = cx;
height = cy;

if (cy==0)
aspect = (GLdouble)width;
else
aspect = (GLdouble)width/(GLdouble)height;

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glDrawBuffer(GL_BACK);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}

void CGLSample4View::OnPaint()
{
CPaintDC dc(this); // device context for painting

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

CGLSample4Doc* pDoc = GetDocument();
pDoc->RenderScene();

SwapBuffers(dc.m_ps.hdc);
}

void CGLSample4View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CView::OnKeyDown(nChar, nRepCnt, nFlags);
CGLSample4Doc* pDoc = GetDocument();

switch (nChar)
{
case VK_F1:
pDoc->m_xRotate -= 1; //Change the rotation in X only
break;
case VK_F2:
pDoc->m_yRotate -= 1;//Change the rotation in Y only
break;
case VK_F3:
pDoc->m_zRotate -= 1;//Change the rotation in Z only
break;
}
InvalidateRect(NULL,FALSE);
}

And in the CXXDoc file, I have the followings:

CGLSample4Doc::CGLSample4Doc()
{
m_xRotate = 0;
m_yRotate = 0;
m_zRotate = 0;
}

void CGLSample4Doc::RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
glTranslated(0.0, 0.0, -8.0);

//****** The Real Rotation in 3 Axis
glRotated(m_xRotate, 1.0, 0.0, 0.0);
glRotated(m_yRotate, 0.0, 1.0, 0.0);
glRotated(m_zRotate, 0.0, 0.0, 1.0);

glDisable(GL_LIGHTING);
glLineWidth(3.0f);
glColor3f(1.0f,0.0f,0.0f); //X
glBegin(GL_LINES);
glVertex3f(0.0f,0.0f,0.001f);
glVertex3f(20.0f,0.0f,0.001f);
glEnd();

glColor3f(0.0f,1.0f,0.0f);//Y
glBegin(GL_LINES);
glVertex3f(0.0f,0.0f,0.001f);
glVertex3f(0.0f,20.0f,0.001f);
glEnd();

glColor3f(0.0f,0.0f,1.0f);//Z
glBegin(GL_LINES);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(0.0f,0.0f,20.0f);
glEnd();

glLineWidth(1.0);
glPopMatrix();

}


Ok, so in the previous routine, you see there
are three rotation statements:

glRotated(m_xRotate, 1.0, 0.0, 0.0);
glRotated(m_yRotate, 0.0, 1.0, 0.0);
glRotated(m_zRotate, 0.0, 0.0, 1.0);

And when I press F1, only m_xRotate will be decreasted,
the m_yRotate & m_zRotate keep unchanged when F1 is pressed.
So it suppose the axis will be rotated with respect to X axis?
It somehow does not work right (when I press F1 --> F2 -->F3
and then F3-->F2 or F1, somehow the axis rotate entirly).
What is the problem (I mean when the m_xRoate is changed only,
should the entire axis rotate with X only? What is the bug,
and how to solve? Thanks.

EricK
04-09-2001, 08:50 AM
I did not look at your code real hard but it looks like you need to zero out m_{x,y,z}rotate. I mean it sounds like you want a key press to increment (or decrement) only one rotation angle but how/when does it get reset to zero?

coredump
04-09-2001, 09:21 AM
this seems like a hot topic lately. when you rotate around the x-axis, the y and z axes no longer point in their original directions. pushing/popping each rotation is one of many ways to correct this problem. search the forums for "rotate" and you'll find a plethora of suggestions.

b

EricK
04-09-2001, 10:56 AM
Originally posted by tyyu:
(I mean when the m_xRoate is changed only,
should the entire axis rotate with X only? What is the bug,
and how to solve? Thanks.

To follow up on my previous post....
The answer to your question is no.
The only time the rotation will be about the x-axis only is when m_yRotate and m_zRotate are zero. I believe the only time you set them to zero is in the constructor, which, I assume, is only called once. In addition the "x-axis" is the local axis, not the global, as the previous post pointed out.