为什么这个 C++ / OpenGL 程序 运行 两次?
Why does this C++ / OpenGL program run twice?
完成大部分课程后,他们 spring 高年级学习 C++。叹。所以我在水下尝试学习它和 OpenGL,后者是 class.
的实际主题
请问,为什么这个东西运行两次?这个作业已经上交并评分了,所以我找不到任何好的 OpenGL 在线指南。感谢您的任何想法。
#ifdef __APPLE__
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#else
#include <GL/glut.h>
#endif
#include <stdlib.h>
int width = 800, height = 600;
float xmin = -(width / 2), ymin = -(height / 2), xmax = width / 2, ymax = height / 2;
GLubyte bitmap[72] = { 0x00, 0x00, 0x00,
0x40, 0x00, 0x02,
0x20, 0x00, 0x04,
0x10, 0x38, 0x08,
0x09, 0x63, 0x10,
0x06, 0x00, 0xA0,
0x08, 0x00, 0x20,
0x10, 0x00, 0x10,
0x10, 0x00, 0x10,
0x10, 0x00, 0x08,
0x20, 0x00, 0x08,
0x20, 0x10, 0x08,
0x20, 0x18, 0x08,
0x10, 0x14, 0x08,
0x10, 0x12, 0x10,
0x10, 0x11, 0x10,
0x08, 0x10, 0x20,
0x04, 0x10, 0x40,
0x01, 0x87, 0x00,
0x00, 0x78, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
void init(void) {
// Set display-window color to white.
glClearColor(0.0, 0.0, 1.0, 0.0);
// Set projection parameters.
glMatrixMode(GL_PROJECTION);
gluOrtho2D(xmin,xmax,ymin,ymax);
// Clear display window.
glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers();
}
// Windows redraw function
void winReshapeFcn(GLint newWidth, GLint newHeight) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-(GLdouble)width / 2, (GLdouble)width / 2, -(GLdouble)height / 2, (GLdouble)height / 2);
glClear(GL_COLOR_BUFFER_BIT);
}
void drawText() {
int x = (int) xmin + 20, y = (int) ymax - 20, count = 0;
char what [] = { 'R', 'e', 'c', 't', 'a', 'n', 'g', 'l', 'e', 's' };
float color = 1.0;
glRasterPos2i(x, y);
do {
glColor3f(color,color,color);
color = color - 0.1;
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, what[count]);
y = y - 20;
glRasterPos2i(x, y);
count = count + 1;
} while (count <= 9);
}
void drawRectangles() {
int h = (int) ymax, x1 = -h, y1 = h, x2 = h, y2 = -h, count = 0, delta, factor = 5;
do {
glBegin(GL_LINES);
glVertex2i(x1,h);
glVertex2i(h,y1);
glVertex2i(h,y1);
glVertex2i(x2,-h);
glVertex2i(x2,-h);
glVertex2i(-h,y2);
glVertex2i(-h,y2);
glVertex2i(x1,h);
glEnd();
h = h - factor; delta = factor * count;
x1 = -h + delta; y1 = h - delta; x2 = h - delta; y2 = -h + delta;
count = count + 1;
} while (x1 < h);
}
void drawBitmaps() {
int count = 0;
GLfloat xorigin = xmin + (xmax - ymax) / 2.0;
// Needed for reading from memory. 1 indicates byte alignment
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Center the bitmap image
glRasterPos2i(0, 0);
do {
glBitmap(24.0, 24.0, xorigin, ymax, 0.0, 24.0, bitmap);
count = count + 24;
Sleep(150);
glutSwapBuffers();
} while ((count < width) && (count < height));
}
void displayFunction(void) {
// Clear display window.
glClear(GL_COLOR_BUFFER_BIT);
// Set graphic objects color to Red or change for your choice
drawText();
glColor3f(1.0, 1.0, 0.0);
drawRectangles();
drawBitmaps();
// Execute OpenGL functions
glFlush();
}
void main(int argc, char** argv) {
// Initialize GLUT.
glutInit(&argc, argv);
// Set display mode.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// Set top-left display-window position.
glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH) - width) / 2, (glutGet(GLUT_SCREEN_HEIGHT) - height) / 2);
// Set display-window width and height.
glutInitWindowSize(width, height);
// Create display window.
glutCreateWindow("Michael Powers - Homework 2");
// Execute initialization procedure.
init();
// Send graphics to display window.
glutDisplayFunc(displayFunction);
// Window reshape call
glutReshapeFunc(winReshapeFcn);
// Display everything and wait.
glutMainLoop();
}
每次需要再次渲染图形时,都会调用 GLUT 显示函数 displayFunction
。在真正的 OpenGL 应用程序中,它将被持续调用,由计时器控制。这里它在 window 打开时被调用一次。但是根据 OS,它可能会被调用多次,例如,如果 window 因为它被激活而需要刷新。
在代码中,动画在 displayFunction()
执行期间由 Sleep(150)
和 glutSwapBuffers()
控制。因此应用程序在动画期间阻塞,但由于 glutSwapBuffers()
次调用,图形仍然显示。
通常显示函数应该快速执行(永远不要 block/wait),最后只调用一次 glFlush()
和 glutSwapBuffers()
。
更好的实现方式是:动画的状态(即时钟图标的数量)存储在全局变量 int state = 0
中。 displayFunction()
总是不等待地绘制那个数量的时钟,然后退出。在开始主循环之前,timer 被注册到 glutTimerFunc
,具有递增 state
的函数,然后调用 glutPostRedisplay()
。这会安排 GLUT 调用显示功能。然后应用程序在动画期间也保持响应,并且可以通过关闭 window.
退出
完成大部分课程后,他们 spring 高年级学习 C++。叹。所以我在水下尝试学习它和 OpenGL,后者是 class.
的实际主题请问,为什么这个东西运行两次?这个作业已经上交并评分了,所以我找不到任何好的 OpenGL 在线指南。感谢您的任何想法。
#ifdef __APPLE__
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#else
#include <GL/glut.h>
#endif
#include <stdlib.h>
int width = 800, height = 600;
float xmin = -(width / 2), ymin = -(height / 2), xmax = width / 2, ymax = height / 2;
GLubyte bitmap[72] = { 0x00, 0x00, 0x00,
0x40, 0x00, 0x02,
0x20, 0x00, 0x04,
0x10, 0x38, 0x08,
0x09, 0x63, 0x10,
0x06, 0x00, 0xA0,
0x08, 0x00, 0x20,
0x10, 0x00, 0x10,
0x10, 0x00, 0x10,
0x10, 0x00, 0x08,
0x20, 0x00, 0x08,
0x20, 0x10, 0x08,
0x20, 0x18, 0x08,
0x10, 0x14, 0x08,
0x10, 0x12, 0x10,
0x10, 0x11, 0x10,
0x08, 0x10, 0x20,
0x04, 0x10, 0x40,
0x01, 0x87, 0x00,
0x00, 0x78, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00,
0x00, 0x00, 0x00
};
void init(void) {
// Set display-window color to white.
glClearColor(0.0, 0.0, 1.0, 0.0);
// Set projection parameters.
glMatrixMode(GL_PROJECTION);
gluOrtho2D(xmin,xmax,ymin,ymax);
// Clear display window.
glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers();
}
// Windows redraw function
void winReshapeFcn(GLint newWidth, GLint newHeight) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-(GLdouble)width / 2, (GLdouble)width / 2, -(GLdouble)height / 2, (GLdouble)height / 2);
glClear(GL_COLOR_BUFFER_BIT);
}
void drawText() {
int x = (int) xmin + 20, y = (int) ymax - 20, count = 0;
char what [] = { 'R', 'e', 'c', 't', 'a', 'n', 'g', 'l', 'e', 's' };
float color = 1.0;
glRasterPos2i(x, y);
do {
glColor3f(color,color,color);
color = color - 0.1;
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, what[count]);
y = y - 20;
glRasterPos2i(x, y);
count = count + 1;
} while (count <= 9);
}
void drawRectangles() {
int h = (int) ymax, x1 = -h, y1 = h, x2 = h, y2 = -h, count = 0, delta, factor = 5;
do {
glBegin(GL_LINES);
glVertex2i(x1,h);
glVertex2i(h,y1);
glVertex2i(h,y1);
glVertex2i(x2,-h);
glVertex2i(x2,-h);
glVertex2i(-h,y2);
glVertex2i(-h,y2);
glVertex2i(x1,h);
glEnd();
h = h - factor; delta = factor * count;
x1 = -h + delta; y1 = h - delta; x2 = h - delta; y2 = -h + delta;
count = count + 1;
} while (x1 < h);
}
void drawBitmaps() {
int count = 0;
GLfloat xorigin = xmin + (xmax - ymax) / 2.0;
// Needed for reading from memory. 1 indicates byte alignment
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Center the bitmap image
glRasterPos2i(0, 0);
do {
glBitmap(24.0, 24.0, xorigin, ymax, 0.0, 24.0, bitmap);
count = count + 24;
Sleep(150);
glutSwapBuffers();
} while ((count < width) && (count < height));
}
void displayFunction(void) {
// Clear display window.
glClear(GL_COLOR_BUFFER_BIT);
// Set graphic objects color to Red or change for your choice
drawText();
glColor3f(1.0, 1.0, 0.0);
drawRectangles();
drawBitmaps();
// Execute OpenGL functions
glFlush();
}
void main(int argc, char** argv) {
// Initialize GLUT.
glutInit(&argc, argv);
// Set display mode.
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// Set top-left display-window position.
glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH) - width) / 2, (glutGet(GLUT_SCREEN_HEIGHT) - height) / 2);
// Set display-window width and height.
glutInitWindowSize(width, height);
// Create display window.
glutCreateWindow("Michael Powers - Homework 2");
// Execute initialization procedure.
init();
// Send graphics to display window.
glutDisplayFunc(displayFunction);
// Window reshape call
glutReshapeFunc(winReshapeFcn);
// Display everything and wait.
glutMainLoop();
}
每次需要再次渲染图形时,都会调用 GLUT 显示函数 displayFunction
。在真正的 OpenGL 应用程序中,它将被持续调用,由计时器控制。这里它在 window 打开时被调用一次。但是根据 OS,它可能会被调用多次,例如,如果 window 因为它被激活而需要刷新。
在代码中,动画在 displayFunction()
执行期间由 Sleep(150)
和 glutSwapBuffers()
控制。因此应用程序在动画期间阻塞,但由于 glutSwapBuffers()
次调用,图形仍然显示。
通常显示函数应该快速执行(永远不要 block/wait),最后只调用一次 glFlush()
和 glutSwapBuffers()
。
更好的实现方式是:动画的状态(即时钟图标的数量)存储在全局变量 int state = 0
中。 displayFunction()
总是不等待地绘制那个数量的时钟,然后退出。在开始主循环之前,timer 被注册到 glutTimerFunc
,具有递增 state
的函数,然后调用 glutPostRedisplay()
。这会安排 GLUT 调用显示功能。然后应用程序在动画期间也保持响应,并且可以通过关闭 window.