OpenGL:如何根据先前转换的结果进行新的转换?

发布于 2024-10-31 04:39:40 字数 1362 浏览 1 评论 0原文

我读过一段像这样旋转立方体的代码(仅关键部分):

static GLfloat theta[] = {0.0,0.0,0.0};
static GLint axis = 2;

void display(void)
{
/* display callback, clear frame buffer and z buffer,
   rotate cube and draw, swap buffers */

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glRotatef(theta[0], 1.0, 0.0, 0.0);
    glRotatef(theta[1], 0.0, 1.0, 0.0);
    glRotatef(theta[2], 0.0, 0.0, 1.0);

 colorcube();

 glFlush();
    glutSwapBuffers();
}

void spinCube()
{

/* Idle callback, spin cube 2 degrees about selected axis */

    theta[axis] += 2.0;
    if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
    /* display(); */
    glutPostRedisplay();
}

void mouse(int btn, int state, int x, int y)
{

/* mouse callback, selects an axis about which to rotate */

    if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0;
    if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1;
    if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2;
}

它在 display 函数外部保留一个变量 theta 来跟踪 角度的改变。每次它都只是重新定义转变 矩阵,那么看起来新的变换是基于 最后一张。

然而,这只是仅旋转的情况。当旋转和 翻译均予以考虑。我发现很难使用类似的方法 将一些变量保留在外部以跟踪转换并重新定义 每次都是矩阵,因为旋转和平移不可互换

我的想法之一是使用glPushMatrixglPopMatrix。但我想知道 这是否是处理此类事情的标准方法。

你能帮忙吗?谢谢。

I have read a code which rotates a cube like this (only the key part):

static GLfloat theta[] = {0.0,0.0,0.0};
static GLint axis = 2;

void display(void)
{
/* display callback, clear frame buffer and z buffer,
   rotate cube and draw, swap buffers */

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glRotatef(theta[0], 1.0, 0.0, 0.0);
    glRotatef(theta[1], 0.0, 1.0, 0.0);
    glRotatef(theta[2], 0.0, 0.0, 1.0);

 colorcube();

 glFlush();
    glutSwapBuffers();
}

void spinCube()
{

/* Idle callback, spin cube 2 degrees about selected axis */

    theta[axis] += 2.0;
    if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
    /* display(); */
    glutPostRedisplay();
}

void mouse(int btn, int state, int x, int y)
{

/* mouse callback, selects an axis about which to rotate */

    if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0;
    if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1;
    if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2;
}

It keeps a variable theta outside the display function to trace the
change of the angle. And every time it just redefines the transformation
matrix then it just looks like the new transformation was based on the
last one.

However, this is just the case for only rotation. When both rotation and
translation are considered. I find it hard to use a similar method which
keeps some variables outside to track transformations and redefines the
matrix every time, since rotation and translation are not interchangeable

One of my ideas is to use glPushMatrix and glPopMatrix. But I wonder
whether this is the standard way to deal with such a thing.

Can you please help? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

菩提树下叶撕阳。 2024-11-07 04:39:40

是的,当您想要更改模型视图矩阵时,这是标准方法,这就是 glPushMatrix()glPopMatrix() 所做的,保存当前的模型视图矩阵堆栈上的矩阵。

假设您有第二个对象,一个球体,它的坐标有不同的变化,为了论证,只是在 OX 轴上平移 -5。

如果您尝试:

//for spehere
glTranslatef(-5.0f,0.0f,0.0f):

drawSphere();

//for cube
glTranslatef(-1.0f,0.0f,0.0f)
glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);

drawCube();

您实际上会将立方体在 Ox 轴上平移 -6.0,而不是 -5.0。

要解决此问题,您只需使用 glPushMatrix()、glPopMatrix()

//for spehere
glPushMatrix();
glTranslatef(-5.0f,0.0f,0.0f):

drawSphere();
glPopMatrix();

//for cube
glPushMatrix();

glTranslatef(-1.0f,0.0f,0.0f)
glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);

drawCube();

glPopMatrix();

通过这种方式,您可以保存原始的模型-视图矩阵,以便您可以对每个对象应用正确的转换。

Yes it's the standard method to go about when you want to change your Model-View Matrix, that's what glPushMatrix() and glPopMatrix() do, saves your current model-view matrix on the matrix stack.

Let's say you have a second object, a sphere, which has different changes for it's coordinates, sake of argument just a translation by -5 on the OX axis.

If you try:

//for spehere
glTranslatef(-5.0f,0.0f,0.0f):

drawSphere();

//for cube
glTranslatef(-1.0f,0.0f,0.0f)
glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);

drawCube();

You will be actually translating your cube by -6.0 on the Ox axis instead of -5.0.

To fix this you just need to use glPushMatrix(), glPopMatrix().

//for spehere
glPushMatrix();
glTranslatef(-5.0f,0.0f,0.0f):

drawSphere();
glPopMatrix();

//for cube
glPushMatrix();

glTranslatef(-1.0f,0.0f,0.0f)
glRotatef(theta[0], 1.0, 0.0, 0.0);
glRotatef(theta[1], 0.0, 1.0, 0.0);
glRotatef(theta[2], 0.0, 0.0, 1.0);

drawCube();

glPopMatrix();

This way you save your original Model-View matrix so you can apply the correct transformations for each object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文