我正在自学如何使用 OpenGL 创建图形,并且我有一个基本的螺旋脚本+旋转。Y 轴旋转是基于计时器功能自动进行的,但我注意到当我在窗口内移动鼠标时,它的旋转速度似乎比预期的快。有人可以查看我的脚本并告诉我是什么导致了计时器功能的加速吗?
#include <Windows.h>
#include <glut.h>
#include <stdio.h>
#include <math.h>
// Change viewing volume and viewport. Called when window is resized
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat nRange = 100.0f;
//Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, buttom, top, near, far)
if (w<= h)
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
//Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//Define a constant for pi
#define GL_PI 3.1415f
// This function does all the initialization
void SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
// Set drawing color to green
glColor3f(0.0f, 1.0f, 0.0f);
}
// Test declaration of rotation angle
GLfloat xRot = 0;
GLfloat yRot = 0;
// Modifiable variables for the eccentricity
GLfloat xMod = 50.0f;
GLfloat yMod = 50.0f;
// Called to draw scene
void RenderScene(void)
{
GLfloat x,y,z,angle; // Storage for coordinates and angles
GLfloat sizes[2]; // Store supported point size range
GLfloat step; // Store point size increments
GLfloat curSize; //Store current point size
// Get supported point size range and step size
glGetFloatv(GL_POINT_SIZE_RANGE, sizes);
glGetFloatv(GL_POINT_SIZE_GRANULARITY, &step);
//Set the initial point size
curSize = sizes[0];
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT);
// Save matrix state and do the rotation
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
// specify point size before primitive is specified
glPointSize(curSize);
//Call only once for remaining points
glBegin(GL_LINE_STRIP);
//Set beginning z coordinate
z = -50.0f;
//Loop around in a circle three times
for (angle = 0.0f; angle <= (2.0f*GL_PI)*3.0f; angle += 0.1f)
{
// Calculate x and y values on the circle (the major and minor axis)
x = xMod*sin(angle);
y = yMod*cos(angle);
// Specify the point and move the z value up a little
glVertex3f(x, y, z);
z += 0.5f;
}
// Done drawing points
glEnd();
// Restore transformations
glPopMatrix();
//Flush drawing commands
glFlush();
}
// Modifier Code
void CircleController (int key, int x, int y)
{
switch (key)
{
case 27 : break;
case 100 :
(yRot -= 5.0f); ; break;
case 102 :
(yRot += 5.0f); ; break;
case 101 :
(xRot -= 5.0f); ; break;
case 103 :
(xRot += 5.0f); ; break;
glutDisplayFunc(RenderScene);
}
}
void MouseHandler (int button, int state, int x, int y)
{
// Holder variable assigned to overcome printf limitation and prevent double- printing due to MouseUp function call
GLfloat Holder = xMod;
// Increases size, and decreases timer speed by increasing the amount of time needed.
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
xMod+= 5.0f;
}
// Decreases size, and increases timer speed by decreasing the amount of time needed.
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
xMod-= 5.0f ;
}
if (Holder != xMod)
printf("%d \n", Holder);
}
void TimerFunction(int value)
{
//Call the arrow key function
glutSpecialFunc(CircleController);
//Call the Mouseclick Modifier function
glutMouseFunc(MouseHandler);
if (xRot < 360)
(xRot += 1.0f);
else
(xRot = 0.0f);
// Redraw the scene with new coordinates
glutPostRedisplay();
glutTimerFunc(1.6666f, TimerFunction, 1);
}
void main(void)
{
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutCreateWindow("Drawing Lines");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutTimerFunc(1.6666f, TimerFunction, 1);
SetupRC();
glutMainLoop();
}