我刚刚开始使用OpenGL编码,并尝试运行一个显示立方体旋转的示例。我在Mac OS Pro上使用OS X 10.6上的Xcode。生成的立方体似乎“非常”快速地旋转。我看到在Windows系统上运行相同的示例,并且立方体以适当的速度旋转。为什么不同?
/* Copyright (c) Mark J. Kilgard, 1994. */
/**
* (c) Copyright 1993, 1994, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* US Government Users Restricted Rights
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/*
* 1992 David G Yu -- Silicon Graphics Computer Systems
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GLUT/glut.h>
static int useRGB = 1;
static int useLighting = 1;
static int useFog = 0;
static int useDB = 1;
static int useLogo = 0;
static int useQuads = 1;
static int tick = -1;
static int moving = 1;
#define GREY 0
#define RED 1
#define GREEN 2
#define BLUE 3
#define CYAN 4
#define MAGENTA 5
#define YELLOW 6
#define BLACK 7
static float materialColor[8][4] =
{
{0.8, 0.8, 0.8, 1.0},
{0.8, 0.0, 0.0, 1.0},
{0.0, 0.8, 0.0, 1.0},
{0.0, 0.0, 0.8, 1.0},
{0.0, 0.8, 0.8, 1.0},
{0.8, 0.0, 0.8, 1.0},
{0.8, 0.8, 0.0, 1.0},
{0.0, 0.0, 0.0, 0.6},
};
static float lightPos[4] =
{2.0, 4.0, 2.0, 1.0};
#if 0
static float lightDir[4] =
{-2.0, -4.0, -2.0, 1.0};
#endif
static float lightAmb[4] =
{0.2, 0.2, 0.2, 1.0};
static float lightDiff[4] =
{0.8, 0.8, 0.8, 1.0};
static float lightSpec[4] =
{0.4, 0.4, 0.4, 1.0};
static float groundPlane[4] =
{0.0, 1.0, 0.0, 1.499};
static float backPlane[4] =
{0.0, 0.0, 1.0, 0.899};
static float fogColor[4] =
{0.0, 0.0, 0.0, 0.0};
static float fogIndex[1] =
{0.0};
static unsigned char shadowPattern[128] =
{
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, /* 50% Grey */
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55
};
static unsigned char sgiPattern[128] =
{
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* SGI Logo */
0xff, 0xbd, 0xff, 0x83, 0xff, 0x5a, 0xff, 0xef,
0xfe, 0xdb, 0x7f, 0xef, 0xfd, 0xdb, 0xbf, 0xef,
0xfb, 0xdb, 0xdf, 0xef, 0xf7, 0xdb, 0xef, 0xef,
0xfb, 0xdb, 0xdf, 0xef, 0xfd, 0xdb, 0xbf, 0x83,
0xce, 0xdb, 0x73, 0xff, 0xb7, 0x5a, 0xed, 0xff,
0xbb, 0xdb, 0xdd, 0xc7, 0xbd, 0xdb, 0xbd, 0xbb,
0xbe, 0xbd, 0x7d, 0xbb, 0xbf, 0x7e, 0xfd, 0xb3,
0xbe, 0xe7, 0x7d, 0xbf, 0xbd, 0xdb, 0xbd, 0xbf,
0xbb, 0xbd, 0xdd, 0xbb, 0xb7, 0x7e, 0xed, 0xc7,
0xce, 0xdb, 0x73, 0xff, 0xfd, 0xdb, 0xbf, 0xff,
0xfb, 0xdb, 0xdf, 0x87, 0xf7, 0xdb, 0xef, 0xfb,
0xf7, 0xdb, 0xef, 0xfb, 0xfb, 0xdb, 0xdf, 0xfb,
0xfd, 0xdb, 0xbf, 0xc7, 0xfe, 0xdb, 0x7f, 0xbf,
0xff, 0x5a, 0xff, 0xbf, 0xff, 0xbd, 0xff, 0xc3,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
static float cube_vertexes[6][4][4] =
{
{
{-1.0, -1.0, -1.0, 1.0},
{-1.0, -1.0, 1.0, 1.0},
{-1.0, 1.0, 1.0, 1.0},
{-1.0, 1.0, -1.0, 1.0}},
{
{1.0, 1.0, 1.0, 1.0},
{1.0, -1.0, 1.0, 1.0},
{1.0, -1.0, -1.0, 1.0},
{1.0, 1.0, -1.0, 1.0}},
{
{-1.0, -1.0, -1.0, 1.0},
{1.0, -1.0, -1.0, 1.0},
{1.0, -1.0, 1.0, 1.0},
{-1.0, -1.0, 1.0, 1.0}},
{
{1.0, 1.0, 1.0, 1.0},
{1.0, 1.0, -1.0, 1.0},
{-1.0, 1.0, -1.0, 1.0},
{-1.0, 1.0, 1.0, 1.0}},
{
{-1.0, -1.0, -1.0, 1.0},
{-1.0, 1.0, -1.0, 1.0},
{1.0, 1.0, -1.0, 1.0},
{1.0, -1.0, -1.0, 1.0}},
{
{1.0, 1.0, 1.0, 1.0},
{-1.0, 1.0, 1.0, 1.0},
{-1.0, -1.0, 1.0, 1.0},
{1.0, -1.0, 1.0, 1.0}}
};
static float cube_normals[6][4] =
{
{-1.0, 0.0, 0.0, 0.0},
{1.0, 0.0, 0.0, 0.0},
{0.0, -1.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, -1.0, 0.0},
{0.0, 0.0, 1.0, 0.0}
};
static void
usage(void)
{
printf("\n");
printf("usage: scube [options]\n");
printf("\n");
printf(" display a spinning cube and its shadow\n");
printf("\n");
printf(" Options:\n");
printf(" -geometry window size and location\n");
printf(" -c toggle color index mode\n");
printf(" -l toggle lighting\n");
printf(" -f toggle fog\n");
printf(" -db toggle double buffering\n");
printf(" -logo toggle sgi logo for the shadow pattern\n");
printf(" -quads toggle use of GL_QUADS to draw the checkerboard\n");
printf("\n");
#ifndef EXIT_FAILURE /* should be defined by ANSI C
<stdlib.h> */
#define EXIT_FAILURE 1
#endif
exit(EXIT_FAILURE);
}
void
buildColormap(void)
{
if (useRGB) {
return;
} else {
int mapSize = 1 << glutGet(GLUT_WINDOW_BUFFER_SIZE);
int rampSize = mapSize / 8;
int entry;
int i;
for (entry = 0; entry < mapSize; ++entry) {
int hue = entry / rampSize;
GLfloat val = (entry % rampSize) * (1.0 / (rampSize - 1));
GLfloat red, green, blue;
red = (hue == 0 || hue == 1 || hue == 5 || hue == 6) ? val : 0;
green = (hue == 0 || hue == 2 || hue == 4 || hue == 6) ? val : 0;
blue = (hue == 0 || hue == 3 || hue == 4 || hue == 5) ? val : 0;
glutSetColor(entry, red, green, blue);
}
for (i = 0; i < 8; ++i) {
materialColor[i][0] = i * rampSize + 0.2 * (rampSize - 1);
materialColor[i][1] = i * rampSize + 0.8 * (rampSize - 1);
materialColor[i][2] = i * rampSize + 1.0 * (rampSize - 1);
materialColor[i][3] = 0.0;
}
fogIndex[0] = -0.2 * (rampSize - 1);
}
}
static void
setColor(int c)
{
if (useLighting) {
if (useRGB) {
glMaterialfv(GL_FRONT_AND_BACK,
GL_AMBIENT_AND_DIFFUSE, &materialColor[c][0]);
} else {
glMaterialfv(GL_FRONT_AND_BACK,
GL_COLOR_INDEXES, &materialColor[c][0]);
}
} else {
if (useRGB) {
glColor4fv(&materialColor[c][0]);
} else {
glIndexf(materialColor[c][1]);
}
}
}
static void
drawCube(int color)
{
int i;
setColor(color);
for (i = 0; i < 6; ++i) {
glNormal3fv(&cube_normals[i][0]);
glBegin(GL_POLYGON);
glVertex4fv(&cube_vertexes[i][0][0]);
glVertex4fv(&cube_vertexes[i][1][0]);
glVertex4fv(&cube_vertexes[i][2][0]);
glVertex4fv(&cube_vertexes[i][3][0]);
glEnd();
}
}
static void
drawCheck(int w, int h, int evenColor, int oddColor)
{
static int initialized = 0;
static int usedLighting = 0;
static GLuint checklist = 0;
if (!initialized || (usedLighting != useLighting)) {
static float square_normal[4] =
{0.0, 0.0, 1.0, 0.0};
static float square[4][4];
int i, j;
if (!checklist) {
checklist = glGenLists(1);
}
glNewList(checklist, GL_COMPILE_AND_EXECUTE);
if (useQuads) {
glNormal3fv(square_normal);
glBegin(GL_QUADS);
}
for (j = 0; j < h; ++j) {
for (i = 0; i < w; ++i) {
square[0][0] = -1.0 + 2.0 / w * i;
square[0][1] = -1.0 + 2.0 / h * (j + 1);
square[0][2] = 0.0;
square[0][3] = 1.0;
square[1][0] = -1.0 + 2.0 / w * i;
square[1][1] = -1.0 + 2.0 / h * j;
square[1][2] = 0.0;
square[1][3] = 1.0;
square[2][0] = -1.0 + 2.0 / w * (i + 1);
square[2][1] = -1.0 + 2.0 / h * j;
square[2][2] = 0.0;
square[2][3] = 1.0;
square[3][0] = -1.0 + 2.0 / w * (i + 1);
square[3][1] = -1.0 + 2.0 / h * (j + 1);
square[3][2] = 0.0;
square[3][3] = 1.0;
if ((i & 1) ^ (j & 1)) {
setColor(oddColor);
} else {
setColor(evenColor);
}
if (!useQuads) {
glBegin(GL_POLYGON);
}
glVertex4fv(&square[0][0]);
glVertex4fv(&square[1][0]);
glVertex4fv(&square[2][0]);
glVertex4fv(&square[3][0]);
if (!useQuads) {
glEnd();
}
}
}
if (useQuads) {
glEnd();
}
glEndList();
initialized = 1;
usedLighting = useLighting;
} else {
glCallList(checklist);
}
}
static void
myShadowMatrix(float ground[4], float light[4])
{
float dot;
float shadowMat[4][4];
dot = ground[0] * light[0] +
ground[1] * light[1] +
ground[2] * light[2] +
ground[3] * light[3];
shadowMat[0][0] = dot - light[0] * ground[0];
shadowMat[1][0] = 0.0 - light[0] * ground[1];
shadowMat[2][0] = 0.0 - light[0] * ground[2];
shadowMat[3][0] = 0.0 - light[0] * ground[3];
shadowMat[0][1] = 0.0 - light[1] * ground[0];
shadowMat[1][1] = dot - light[1] * ground[1];
shadowMat[2][1] = 0.0 - light[1] * ground[2];
shadowMat[3][1] = 0.0 - light[1] * ground[3];
shadowMat[0][2] = 0.0 - light[2] * ground[0];
shadowMat[1][2] = 0.0 - light[2] * ground[1];
shadowMat[2][2] = dot - light[2] * ground[2];
shadowMat[3][2] = 0.0 - light[2] * ground[3];
shadowMat[0][3] = 0.0 - light[3] * ground[0];
shadowMat[1][3] = 0.0 - light[3] * ground[1];
shadowMat[2][3] = 0.0 - light[3] * ground[2];
shadowMat[3][3] = dot - light[3] * ground[3];
glMultMatrixf((const GLfloat *) shadowMat);
}
static char *windowNameRGBDB = "shadow cube (OpenGL RGB DB)";
static char *windowNameRGB = "shadow cube (OpenGL RGB)";
static char *windowNameIndexDB = "shadow cube (OpenGL Index DB)";
static char *windowNameIndex = "shadow cube (OpenGL Index)";
void
idle(void)
{
tick++;
if (tick >= 120) {
tick = 0;
}
glutPostRedisplay();
}
/* ARGSUSED1 */
void
keyboard(unsigned char ch, int x, int y)
{
switch (ch) {
case 27: /* escape */
exit(0);
break;
case 'L':
case 'l':
useLighting = !useLighting;
useLighting ? glEnable(GL_LIGHTING) :
glDisable(GL_LIGHTING);
glutPostRedisplay();
break;
case 'F':
case 'f':
useFog = !useFog;
useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
glutPostRedisplay();
break;
case '1':
glFogf(GL_FOG_MODE, GL_LINEAR);
glutPostRedisplay();
break;
case '2':
glFogf(GL_FOG_MODE, GL_EXP);
glutPostRedisplay();
break;
case '3':
glFogf(GL_FOG_MODE, GL_EXP2);
glutPostRedisplay();
break;
case ' ':
if (!moving) {
idle();
glutPostRedisplay();
}
}
}
void
display(void)
{
GLfloat cubeXform[4][4];
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0, -1.5, 0.0);
glRotatef(-90.0, 1, 0, 0);
glScalef(2.0, 2.0, 2.0);
drawCheck(6, 6, BLUE, YELLOW); /* draw ground */
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, 0.0, -0.9);
glScalef(2.0, 2.0, 2.0);
drawCheck(6, 6, BLUE, YELLOW); /* draw back */
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, 0.2, 0.0);
glScalef(0.3, 0.3, 0.3);
glRotatef((360.0 / (30 * 1)) * tick, 1, 0, 0);
glRotatef((360.0 / (30 * 2)) * tick, 0, 1, 0);
glRotatef((360.0 / (30 * 4)) * tick, 0, 0, 1);
glScalef(1.0, 2.0, 1.0);
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) cubeXform);
drawCube(RED); /* draw cube */
glPopMatrix();
glDepthMask(GL_FALSE);
if (useRGB) {
glEnable(GL_BLEND);
} else {
glEnable(GL_POLYGON_STIPPLE);
}
if (useFog) {
glDisable(GL_FOG);
}
glPushMatrix();
myShadowMatrix(groundPlane, lightPos);
glTranslatef(0.0, 0.0, 2.0);
glMultMatrixf((const GLfloat *) cubeXform);
drawCube(BLACK); /* draw ground shadow */
glPopMatrix();
glPushMatrix();
myShadowMatrix(backPlane, lightPos);
glTranslatef(0.0, 0.0, 2.0);
glMultMatrixf((const GLfloat *) cubeXform);
drawCube(BLACK); /* draw back shadow */
glPopMatrix();
glDepthMask(GL_TRUE);
if (useRGB) {
glDisable(GL_BLEND);
} else {
glDisable(GL_POLYGON_STIPPLE);
}
if (useFog) {
glEnable(GL_FOG);
}
if (useDB) {
glutSwapBuffers();
} else {
glFlush();
}
}
void
fog_select(int fog)
{
glFogf(GL_FOG_MODE, fog);
glutPostRedisplay();
}
void
menu_select(int mode)
{
switch (mode) {
case 1:
moving = 1;
glutIdleFunc(idle);
break;
case 2:
moving = 0;
glutIdleFunc(NULL);
break;
case 3:
useFog = !useFog;
useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
glutPostRedisplay();
break;
case 4:
useLighting = !useLighting;
useLighting ? glEnable(GL_LIGHTING) :
glDisable(GL_LIGHTING);
glutPostRedisplay();
break;
case 5:
exit(0);
break;
}
}
void
visible(int state)
{
if (state == GLUT_VISIBLE) {
if (moving)
glutIdleFunc(idle);
} else {
if (moving)
glutIdleFunc(NULL);
}
}
int
main(int argc, char **argv)
{
int width = 350, height = 350;
int i;
char *name;
int fog_menu;
glutInitWindowSize(width, height);
glutInit(&argc, argv);
/* process commmand line args */
for (i = 1; i < argc; ++i) {
if (!strcmp("-c", argv[i])) {
useRGB = !useRGB;
} else if (!strcmp("-l", argv[i])) {
useLighting = !useLighting;
} else if (!strcmp("-f", argv[i])) {
useFog = !useFog;
} else if (!strcmp("-db", argv[i])) {
useDB = !useDB;
} else if (!strcmp("-logo", argv[i])) {
useLogo = !useLogo;
} else if (!strcmp("-quads", argv[i])) {
useQuads = !useQuads;
} else {
usage();
}
}
/* choose visual */
if (useRGB) {
if (useDB) {
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
name = windowNameRGBDB;
} else {
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
name = windowNameRGB;
}
} else {
if (useDB) {
glutInitDisplayMode(GLUT_DOUBLE | GLUT_INDEX | GLUT_DEPTH);
name = windowNameIndexDB;
} else {
glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX | GLUT_DEPTH);
name = windowNameIndex;
}
}
glutCreateWindow(name);
buildColormap();
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
glutVisibilityFunc(visible);
fog_menu = glutCreateMenu(fog_select);
glutAddMenuEntry("Linear fog", GL_LINEAR);
glutAddMenuEntry("Exp fog", GL_EXP);
glutAddMenuEntry("Exp^2 fog", GL_EXP2);
glutCreateMenu(menu_select);
glutAddMenuEntry("Start motion", 1);
glutAddMenuEntry("Stop motion", 2);
glutAddMenuEntry("Toggle fog", 3);
glutAddMenuEntry("Toggle lighting", 4);
glutAddSubMenu("Fog type", fog_menu);
glutAddMenuEntry("Quit", 5);
glutAttachMenu(GLUT_RIGHT_BUTTON);
/* setup context */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -2.0);
glEnable(GL_DEPTH_TEST);
if (useLighting) {
glEnable(GL_LIGHTING);
}
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
#if 0
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDir);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 80);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25);
#endif
glEnable(GL_NORMALIZE);
if (useFog) {
glEnable(GL_FOG);
}
glFogfv(GL_FOG_COLOR, fogColor);
glFogfv(GL_FOG_INDEX, fogIndex);
glFogf(GL_FOG_MODE, GL_EXP);
glFogf(GL_FOG_DENSITY, 0.5);
glFogf(GL_FOG_START, 1.0);
glFogf(GL_FOG_END, 3.0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (useLogo) {
glPolygonStipple((const GLubyte *) sgiPattern);
} else {
glPolygonStipple((const GLubyte *) shadowPattern);
}
glClearColor(0.0, 0.0, 0.0, 1);
glClearIndex(0);
glClearDepth(1);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
谢谢,
阿伦
答案 0 :(得分:5)
我认为问题是代码是1992-1994,它使用tick
变量而不是某些计时器:
void
idle(void)
{
tick++;
if (tick >= 120) {
tick = 0;
}
glutPostRedisplay();
}
这意味着您的现代PC将比旧机器增加tick
快约100倍(甚至更多)。您可能希望用
void
idle(void)
{
tick = (myTimerThatReturnsMillisecondsSince1970() / speedScale) % 120;
glutPostRedisplay();
}