(OpenGL)旋转对象 [英] (OpenGL) Rotate object

查看:71
本文介绍了(OpenGL)旋转对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个程序,当我单击鼠标按钮时,该程序可以旋转六点星,两个三角形重叠.

I'm making a program that rotates six-point stars with two triangles overlapping when I click the mouse button.

  1. 单击鼠标右键:星空旋转
  2. 单击鼠标中键:星星的颜色变化(白色→蓝色)

我已经应用了代码来旋转矩形,但是当我单击鼠标右键时,它不会旋转并且会跳来跳去.

I've applied the codes to rotate a rectangle, but when I click right mouse button, it doesn't rotate and makes a jump around.

当单击鼠标中键时,颜色更改成功,但是通过旋转星号将其初始化.我想通过旋转时单击中间按钮来旋转颜色已更改的星星.

And when the middle mouse button is clicked, the color changing is successful but it is initialized by rotating the star. I would like to rotate the star with the color changed by clicking the middle button while rotating.

请让我知道是什么问题.

Please let me know what is the problem.

/////////////////////////// Header /////////////////////////////
#include <stdlib.h>
#include <GL/glut.h>

float v1[3] = { 365.0, 465.0, 0.0 };
float v2[3] = { 365.0, 420.0, 0.0 };
float v3[3] = { 400.0, 485.0, 0.0 };
float v4[3] = { 400.0, 400.0, 0.0 };
float v5[3] = { 435.0, 465.0, 0.0 };
float v6[3] = { 435.0, 420.0, 0.0 };

static GLfloat spin = 0.0;

//////////////////////// Functions ////////////////////////////
void init(void) {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
}

void reshape(int w, int h) {
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, 500.0, 0.0, 500.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void spinDisplay(void) {
    spin = spin + 2.0;

    if (spin > 360.0) {
        spin = spin - 360.0;
    }

    glutPostRedisplay();
}

void triangle_1(void) {         /////////// first triangle ///////////
    glColor3f(1.0, 1.0, 1.0);

    glBegin(GL_TRIANGLE_FAN);
    glVertex3fv(v1);
    glVertex3fv(v4);
    glVertex3fv(v5);

    glEnd();
}

void triangle_2(void) {         ///////// second triangle /////////
    glColor3f(1.0, 1.0, 1.0);

    glBegin(GL_TRIANGLE_FAN);
    glVertex3fv(v2);
    glVertex3fv(v3);
    glVertex3fv(v6);

    glEnd();
}

void triangle_1p(void) {       ///// first triangle (color changed) /////
    glColor3f(0.0, 0.0, 1.0);

    glBegin(GL_TRIANGLE_FAN);
    glVertex3fv(v1);
    glVertex3fv(v4);
    glVertex3fv(v5);

    glEnd();
}

void triangle_2p(void) {       ///// second triangle (color changed) /////
    glColor3f(0.0, 1.0, 0.0);

    glBegin(GL_TRIANGLE_FAN);
    glVertex3fv(v2);
    glVertex3fv(v3);
    glVertex3fv(v6);

    glEnd();
}

void display(void) {            ///////// star display /////////
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
    glRotatef(spin, 0.0, 0.0, 1.0);

    triangle_1();
    triangle_2();

    glPopMatrix();

    glutSwapBuffers();
}

void display_p(void) {         ///// star display (color changed) /////
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
    glRotatef(spin, 0.0, 0.0, 1.0);

    triangle_1p();
    triangle_2p();

    glPopMatrix();

    glutSwapBuffers();
}

/////////////////////// Mouse Click ///////////////////////
void mouse(int button, int state, int x, int y) {
    switch (button) {
    case GLUT_LEFT_BUTTON:
        if (state == GLUT_DOWN)
            glutIdleFunc(NULL);
        break;
    case GLUT_MIDDLE_BUTTON:
        if (state == GLUT_DOWN)
            glutIdleFunc(display_p);
        break;
    case GLUT_RIGHT_BUTTON:
        if (state == GLUT_DOWN)
            glutIdleFunc(spinDisplay);
        break;
    default:
        break;
    }
}

//////////////////////////// Main /////////////////////////////
int main(int argc, char **argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(300, 300);
    glutCreateWindow("6-Point Star");

    init();

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMouseFunc(mouse);
    glutMainLoop();

    return 0;
}

推荐答案

当我单击鼠标右键时,它不会旋转并且会跳动

when I click right mouse button, it doesn't rotate and makes a jump around

实际上它不是在跳来跳去,而是绕原点(显示器左下角)旋转.

It actually isn't jumping around, it's rotating around the origin (bottom left corner of the display).

发生这种情况的原因是因为您先旋转然后平移.由于您已将恒星x = 400y = 442.5的位置硬编码到顶点中.如果使星的中心位于0x0(减去400x442.5),那么您会在显示的左下角看到星围绕自身旋转.

The reason this happens if because you're rotating then translating. Since you have hardcoded the star's position of x = 400 and y = 442.5 into your vertices. If you make so that the the center of the star is at 0x0 (subtracting 400x442.5) then you'll see the star is rotating around itself in the bottom left corner of the display.

float v1[3] = { -35.0f,  22.5f, 0.0f };
float v2[3] = { -35.0f, -22.5f, 0.0f };
float v3[3] = {   0.0f,  42.5f, 0.0f };
float v4[3] = {   0.0f, -42.5f, 0.0f };
float v5[3] = {  35.0f,  22.5f, 0.0f };
float v6[3] = {  35.0f, -22.5f, 0.0f };

现在在display()中,您可以在旋转之前进行翻译:

Now in display() you then translate before rotating:

glTranslatef(x, y, 0.0f);
glRotatef(spin, 0.0, 0.0, 1.0);

考虑将float x = 400.0f, y = 442.5f;定义在其他地方.

Considering float x = 400.0f, y = 442.5f; to be defined elsewhere.

现在,您将看到星星回到原处,但围绕自身旋转.

Now you'll see the star back at the same place, but rotating around itself.

我想通过旋转时单击中间按钮来旋转颜色已更改的星星.

I would like to rotate the star with the color changed by clicking the middle button while rotating.

您可以将颜色保留为变量,而不是为每种模式复制所有代码.

Instead of duplicating all your code for each mode, you could keep the colors as variables.

float color1[3] = { 1.0f, 1.0f, 1.0f };
float color2[3] = { 1.0f, 1.0f, 1.0f };

int mode = 1;

现在在GLUT_MIDDLE_BUTTON上的mouse()中,然后在颜色之间切换.

Now in mouse() on GLUT_MIDDLE_BUTTON then you switch around the colors.

case GLUT_MIDDLE_BUTTON:
    if (state == GLUT_DOWN) {
        if (mode == 1) {
            color1[0] = 0.0f, color1[1] = 0.0f, color1[2] = 1.0f;
            color2[0] = 0.0f, color2[1] = 1.0f, color2[2] = 0.0f;
            mode = 2;
        }
        else if (mode == 2) {
            color1[0] = 1.0f, color1[1] = 1.0f, color1[2] = 1.0f;
            color2[0] = 1.0f, color2[1] = 1.0f, color2[2] = 1.0f;
            mode = 1;
        }
    }

然后在triangle_1triangle_2中记住将glColor3f()替换为glColor3fv(color1)glColor3fv(color2).

Then in triangle_1 and triangle_2 remember to replace glColor3f() with glColor3fv(color1) and glColor3fv(color2).

除了所有这些,您还可以在mouse中设置mode并在triangle_1中进行类似的操作(在triangle_2中也是如此):

Instead of all that, you could also just set mode in mouse and do something like this in triangle_1 (also doing likewise in triangle_2):

if (mode == 2)
    glColor3f(0.0, 0.0, 1.0);
else
    glColor3f(1.0, 1.0, 1.0);

选择当然取决于您.

总而言之,现在您应该能够看到恒星围绕自身旋转,并在单击鼠标中键时切换颜色.

All in all, now you should be able to see the star rotating around itself, and toggle the colors when middle mouse button is clicked.

这现在也意味着您可以删除display_ptriangle_1ptriangle_2p.

This now also means that you can delete display_p, triangle_1p and triangle_2p.

这篇关于(OpenGL)旋转对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆