这是写在书openGL SuperBible
代码来创建点屏幕上的弹簧形路径:使用箭头键来旋转refrence系统在OpenGL
#include "stdafx.h"
#include <Windows.h>
#include <gl\glut.h>
#include <gl\GLU.h>
#include <gl\GL.h>
#include <math.h>
// Define a constant for the value of PI
#define GL_PI 3.1415f
void ChangeSize(GLsizei , GLsizei);
void SetupRC();
void RenderScene(void);
int main(int argc, CHAR* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Points Example");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
SetupRC();
glutMainLoop();
return 0;
}
// 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, bottom, 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();
}
// This function does any needed initialization on the rendering context
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);
}
// Called to draw scene
void RenderScene(void)
{
GLfloat x,y,z,angle;
int xRot,yRot; // Storage for coordinates and angles
xRot = 45;
yRot = 45;
// 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);
// Call only once for all remaining points
glBegin(GL_POINTS);
z = -50.0f;
for(angle = 0.0f; angle <= (2.0f*GL_PI)*3.0f; angle += 0.1f)
{
x = 50.0f*sin(angle);
y = 50.0f*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
glutSwapBuffers();
}
其实通过设置xRot = yRot = 45度,我已经达到了这种状态。
但书中也被告知:
当运行这个程序,所有你看到的是一个点的圆圈 因为您最初直接向下看的z轴。要查看效果,请使用箭头键围绕x轴和y轴旋转绘图。
这意味着我们应该使用箭头键来增加或减少xRot和yRot的值。我已经做了一些努力来做到这一点。
1-编写的函数:
void _cdecl keyboard(int key ,int xRot,int yRot)
{
switch (key)
{
case GLUT_KEY_PAGE_UP:
yRot++;
case GLUT_KEY_PAGE_DOWN:
yRot--;
case GLUT_KEY_HOME:
xRot--;
case GLUT_KEY_END:
xRot++;
}
}
2-它的原型在代码的顶部:
void _cdecl keyboard(int,int,int);
3-加入这两行代码的函数RenderScene
体:
GLint key = GLUT_KEY_PAGE_UP;
glutSpecialFunc(keyboard(key,xRot,yRot));
但我不确定它会工作。该代码获取错误:
error C2664: 'glutSpecialFunc' : cannot convert parameter 1 from 'void' to 'void (__cdecl *)(int,int,int)'
,我不知道怎么的xRot
和yRot
更改后的值返回给调用函数,因为编译器不会让我定义Pass by referrence
参数和glutSpecialFunc
参数是一个void函数的指针!
我的问题的编辑部分
作为jblocksom建议我改变了代码是这样的:
1定义,只是主开始前初始化的全局变量:
int xRot = 0;
int yRot = 0;
2-通话主要在某处的glutSpecialFunc
glutSpecialFunc(keyboard);
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
3-改变键盘功能中的代码
void keyboard(int keyParam ,int mx,int my)
{
switch (keyParam)
{
case GLUT_KEY_PAGE_UP:
my++;
case GLUT_KEY_PAGE_DOWN:
my--;
case GLUT_KEY_HOME:
mx--;
case GLUT_KEY_END:
mx++;
}
glutPostRedisplay();
}
没有编译和运行时错误。但它不起作用。我认为这是因为当我呼叫glutSpecialFunc(keyboard)
时,该函数使用鼠标和键盘按钮的坐标作为输入参数,所以任何增量或减量应用于不是xRot
或yRot
的鼠标坐标上,这将用于glRotatef(xRot, 1.0f, 0.0f, 0.0f)
或glRotatef(yRot, 0.0f, 1.0f, 0.0f)
,因此当调用两个后者xRot
和yRot
仍然等于零,并且不会有旋转。 我需要通过xRot
和yRot
函数keyboard
但如何?
即使写功能:
void keyboard(int keyParam ,int mx,int my)
{
switch (keyParam)
{
case GLUT_KEY_PAGE_UP:
yRot++;
case GLUT_KEY_PAGE_DOWN:
yRot--;
case GLUT_KEY_HOME:
xRot--;
case GLUT_KEY_END:
xRot++;
}
glutPostRedisplay();
}
,并调用它的形式glutSpecialFunc(keyboard)
将没有任何区别!
谢谢@jblocksom,但看到我的问题的编辑部分。我希望你能帮助我。 – sepideh