【问题标题】:Entire object rotates整个物体旋转
【发布时间】:2026-01-11 19:30:02
【问题描述】:

此代码的想法是让风车状结构旋转,问题是整个对象旋转而不是风车风扇本身(不仅仅是红色三角形)。这是代码(我用按键控制速度)

  #include <windows.h>  // for MS Windows
  #include <GL/glut.h>  // GLUT, include glu.h and gl.h

  float angle = 0.00002f;  
  int refreshMills = 30;

  void initGL() {
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque
  }

  void Timer(int value) {
        glutPostRedisplay();      // Post re-paint request to activate display()
        glutTimerFunc(refreshMills, Timer, 0); // next Timer call milliseconds later
  }

  void display() {
        glClear(GL_COLOR_BUFFER_BIT);
        glBegin(GL_TRIANGLES);
              glColor3f(1.0f, 0.0f, 0.0f)
              glVertex2f(0.0f, 0.0f);
              glVertex2f(-0.4f, 0.2f);
              glVertex2f(-0.2f, 0.4f);
              glColor3f(1.0f, 0.0f, 0.0f);
              glVertex2f(0.0f, 0.0f);
              glVertex2f(0.4f, -0.2f);
              glVertex2f(0.2f, -0.4f);
              glColor3f(1.0f, 0.0f, 0.0f);
              glVertex2f(0.0f, 0.0f);
              glVertex2f(-0.4f, -0.2f)
              glVertex2f(-0.2f, -0.4f);
              glColor3f(1.0f, 0.0f, 0.0f);
              glVertex2f(0.0f, 0.0f);
              glVertex2f(0.4f, 0.2f);    
              glVertex2f(0.2f, 0.4f);
        glEnd();

        glRotatef(angle, 0.0f, 0.0f, 1.0f); 
        angle=angle+0.000002f;
        glutPostRedisplay();
        glBegin(GL_TRIANGLES);
              glColor3f(1.0f, 1.0f, 1.0f);
              glVertex2f(0.0f, 0.0f);
              glVertex2f(-0.4f, -0.6f);
              glVertex2f(0.4f,  -0.6f);
        glEnd();
        glFlush();
        glutSwapBuffers();
  }

  void keyboard(unsigned char key, int x, int y) {
        switch (key) {
        case 'a':{      
              angle+=1;
              glutPostRedisplay();
        }

        case 's':
              angle+=2;
        glutPostRedisplay();

        case 'd':      
              angle+=3 
        glutPostRedisplay();

        case 'f':    
              angle=0;
        }
  }

  }

  int main(int argc, char** argv) {
        glutInit(&argc, argv);          // Initialize GLUTx
        glutCreateWindow("Windmill");  // Create window with the given title
        glutInitWindowSize(320, 320);   // Set the window's initial width & height
        glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
        glutDisplayFunc(display);
        glutTimerFunc(0, Timer, 0);
        glutSpecialFunc(specialKeys);
        glutKeyboardFunc(keyboard);
        initGL();                       // Our own OpenGL initialization
        glutMainLoop();                 // Enter the event-processing loop

        return 0;
  }

【问题讨论】:

    标签: opengl freeglut


    【解决方案1】:

    您需要在此处实现某种层次结构(通常是场景图),使用变换矩阵进行变换。

    基本上,创建一个具有自己的变换矩阵的“风车”对象。然后创建一个拥有自己的“风车风扇”对象。使风扇成为父级的子级。转换基本上向下传播。改造风车,然后改造风车风扇。

    Post on Scene Graphs

    您可能还想查看 * 的游戏开发部分。这些问题在这里通常不会张开双臂。

    【讨论】:

    • 引自那篇文章:“2D 场景图:如果您的内容足够复杂并且您的对象有许多子组件没有严格固定到较大的身体。否则,正如其他人所提到的,这可能是矫枉过正。”
    【解决方案2】:

    在尝试绘制新框架之前,您需要清除转换。所以,在glClear 函数后面加上一个glLoadIdentity()

      void display() {
        glClear(GL_COLOR_BUFFER_BIT);
        glLoadIdentity(); //  <-- put it here
        glBegin(GL_TRIANGLES);
        ...
    

    【讨论】:

      【解决方案3】:

      您需要在绘制旋转对象之前调用glRotate。在此之前,您需要使用glPushMatrix 将当前模型视图矩阵推入堆栈,然后使用glPopMatrix 将其弹出,然后再绘制风车的其余部分。

      一旦您有了更复杂的场景,您可能会考虑使用场景图。请注意,glRotate 等矩阵函数现已弃用。您可能会考虑切换到例如尽快glm。

      【讨论】:

        【解决方案4】:

        试试这个:

        #include <GL/glut.h>  // GLUT, include glu.h and gl.h
        
        void Timer(int value) 
        {
            glutPostRedisplay();      // Post re-paint request to activate display()
            glutTimerFunc(16, Timer, 0); // next Timer call milliseconds later
        }
        
        float rate = 1.0f;  
        void keyboard(unsigned char key, int x, int y) 
        {
            switch (key) 
            {
            case 'a':
                rate=2;
                break;
            case 's':
                rate=3;
                break;
            case 'd':      
                rate=4;
                break;
            case 'f':    
                rate=0;
                break;
            }
            glutPostRedisplay();
        }
        
        float angle = 0.0f;
        void display() 
        {
            glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
            glMatrixMode( GL_PROJECTION );
            glLoadIdentity();
        
            glMatrixMode( GL_MODELVIEW );
            glLoadIdentity();
        
            // base    
            glPushMatrix();
                glBegin(GL_TRIANGLES);
                    glColor3f(1.0f, 1.0f, 1.0f);
                    glVertex2f(0.0f, 0.0f);
                    glVertex2f(-0.4f, -0.6f);
                    glVertex2f(0.4f,  -0.6f);
                glEnd();
            glPopMatrix();
        
            // prop
            glPushMatrix();
                glRotatef(angle, 0.0f, 0.0f, 1.0f); 
                angle=angle+rate;
                glBegin(GL_TRIANGLES);
                    glColor3f(1.0f, 0.0f, 0.0f);
                    glVertex2f(0.0f, 0.0f);
                    glVertex2f(-0.4f, 0.2f);
                    glVertex2f(-0.2f, 0.4f);
                    glColor3f(1.0f, 0.0f, 0.0f);
                    glVertex2f(0.0f, 0.0f);
                    glVertex2f(0.4f, -0.2f);
                    glVertex2f(0.2f, -0.4f);
                    glColor3f(1.0f, 0.0f, 0.0f);
                    glVertex2f(0.0f, 0.0f);
                    glVertex2f(-0.4f, -0.2f);
                    glVertex2f(-0.2f, -0.4f);
                    glColor3f(1.0f, 0.0f, 0.0f);
                    glVertex2f(0.0f, 0.0f);
                    glVertex2f(0.4f, 0.2f);    
                    glVertex2f(0.2f, 0.4f);
                glEnd();
            glPopMatrix();
        
            glutSwapBuffers();
        }
        
        int main(int argc, char** argv) 
        {
            glutInit(&argc, argv);          // Initialize GLUTx
            glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
            glutInitWindowSize(320, 320);   // Set the window's initial width & height
            glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
            glutCreateWindow("Windmill");  // Create window with the given title
            glutDisplayFunc(display);
            glutTimerFunc(0, Timer, 0);
            glutKeyboardFunc(keyboard);
            glutMainLoop();                 // Enter the event-processing loop
            return 0;
        }
        

        【讨论】:

        • 非常感谢,感谢您的帮助
        • 在*上,说谢谢的方式就是接受答案。