在使用 C++ 在 OpenGL 中移动形状时按时间自动旋转形状

Posted

技术标签:

【中文标题】在使用 C++ 在 OpenGL 中移动形状时按时间自动旋转形状【英文标题】:Auto-Rotating shapes by time while moving them in OpenGL with C++ 【发布时间】:2020-06-11 12:40:10 【问题描述】:

我想让我的形状随时间旋转,同时我可以使用键盘移动它们(左-右、下-上、前-后)我添加了一个名为 timer() 的函数,它应该改变立方体的角度和时间金字塔。 问题是代码在glutPostOverlayRedisplay(); 函数处不断中断,它说:

在 Opengl.exe 中的 0x10004813 (glut32.dll) 处引发异常:0xC0000005: 访问冲突读取位置 0x00000020。

我该如何解决这个问题,为什么会这样? 这是代码:

#include <GL/glut.h>
int object = 0; 
float xLeftRight[] 0, 0 ;
float yDownUp[] 0, 0 ;
float zFrontBack[] 0, 0 ;
float PyramidAngle = 0.0;
float CupeAngle = 0.0;
int t_refresh = 20;//ms 
float degree = 0;
float xscale = 1, yscale = 1, zscale = 1;

void Keyboard(int buttons, int x, int y)

    switch (buttons)
    
    case GLUT_KEY_F1: object = 0; break; 
    case GLUT_KEY_F2: object = 1; break; 
    case GLUT_KEY_LEFT: xLeftRight[object] -= 0.1; break;
    case GLUT_KEY_RIGHT: xLeftRight[object] += 0.1; break;
    case GLUT_KEY_DOWN:  yDownUp[object] -= 0.1; break;
    case GLUT_KEY_UP: yDownUp[object] += 0.1; break;
    case GLUT_KEY_PAGE_UP: zFrontBack[object] -= 0.1; break;
    case GLUT_KEY_PAGE_DOWN: zFrontBack[object] += 0.1; break;
    
    glutPostRedisplay();

void Settings()

    glClearColor(1, 1, 1, 0);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glShadeModel(GL_SMOOTH);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);


void DrawingFunction()//painting

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity(); //reset
    glTranslatef(1.5f, 0.0f, -6.0f); // rotate left and back by time
    glRotatef(PyramidAngle, 1.0f, 1.0f, 0.0f);
    glColor3f(1.0, 0.0, 0.0);
    glScalef(xscale, yscale, zscale);
    glTranslatef(xLeftRight[0], yDownUp[0], zFrontBack[0]); //move the pyramid (if object = 0)

    glBegin(GL_TRIANGLES);
    // front
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(1.0f, -1.0f, 1.0f);
    // right

    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(1.0f, -1.0f, 1.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(1.0f, -1.0f, -1.0f);
    // back

    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(1.0f, -1.0f, -1.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(-1.0f, -1.0f, -1.0f);
    // left

    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glEnd();

    glPopMatrix();
    glPushMatrix();
    glLoadIdentity();//(Reset model-view matrix)
    glTranslatef(-2.0f, 0.0f, -7.0f); // rotate the cube right and back by time
    glRotatef(CupeAngle, 1.0f, 0.0f, 0.0f);
    glTranslatef(xLeftRight[1], yDownUp[1], zFrontBack[1]); //move the cube (if object = 1)                                         
    glBegin(GL_QUADS); //cube

    glColor3f(1.0f, 0.0f, 1.0f); 
    glVertex3f(1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(1.0f, 1.0f, 1.0f);

    glColor3f(1.0f, 0.5f, 0.0f); 
    glVertex3f(1.0f, -1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);

    glColor3f(0.0f, 0.0f, 1.0f); 
    glVertex3f(1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, 1.0f);

    glColor3f(1.0f, 1.0f, 0.0f); 
    glVertex3f(1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(1.0f, 1.0f, -1.0f);

    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);

    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex3f(1.0f, 1.0f, -1.0f);
    glVertex3f(1.0f, 1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);
    glEnd();
    glutSwapBuffers();
    PyramidAngle += 1.0f; //changing the angle
    CupeAngle -= 0.2f;    //changing the angle
    glPopMatrix();

void timer(int value)

    glutPostOverlayRedisplay();
    glutTimerFunc(t_refresh, timer, 0);


void ViewSetting(int x, int y)

    int aspect = x / y;
    glViewport(0, 0, x, y);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, aspect, 0.1, 20);


int main(int argc, char** argv)

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE);
    glutInitWindowPosition(50, 50);
    glutInitWindowSize(800, 600);
    glutCreateWindow("3d shapes");
    glutDisplayFunc(DrawingFunction);
    glutReshapeFunc(ViewSetting);
    glutSpecialFunc(Keyboard);
    Settings();
    glutTimerFunc(0, timer, 0);
    glutMainLoop();
    return 0;

【问题讨论】:

【参考方案1】:

glutPostOverlayRedisplay 将当前窗口的覆盖标记为需要重新显示(参见Overlay Management)。 你必须使用glutPostRedisplay:

void timer(int value)

    glutPostRedisplay();
    glutTimerFunc(t_refresh, timer, 0);

【讨论】:

以上是关于在使用 C++ 在 OpenGL 中移动形状时按时间自动旋转形状的主要内容,如果未能解决你的问题,请参考以下文章

在 OpenGL 中使用箭头键移动一些形状 - 它缩小而不是移动

如何在 C++ 中使用 sdl、opengl 移动相机时修复奇怪的相机旋转

在 OpenGL 中移动 3d 形状

C++ OpenGL,绘制形状返回错误

OpenGL / C++ - 如何在鼠标点击时填充一个点周围的区域?

如何在OpenGL中实现形状的原位旋转和旋转状态下的移动?