OpenGL 键盘相机控制
http://www.lighthouse3d.com/opengl/glut/
我已经达到使用键盘实现相机控制的阶段:
http://www.lighthouse3d.com/opengl/glut/index.php?8
在执行高级教程时,它停止工作。我几乎只是复制并粘贴它。当我运行它的代码版本时,它可以工作。我的似乎不起作用。当左右移动时,它应该旋转相机视图;当使用向上和向下键时,它应该向前和向后移动。
我的代码在这里被分解:
我的代码的这一部分使用 init() 渲染场景中的组件,它初始化值等:
void display(void)
{
if (deltaMove)
moveMeFlat(deltaMove);
if (deltaAngle) {
angle += deltaAngle;
orientMe(angle);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture[0]);
RenderSkyDome();
glBindTexture(GL_TEXTURE_2D, NULL);
glutSwapBuffers();
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0f);
glColor3f(0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
LoadTextures("clouds2.bmp", 0);
GenerateDome(600.0f, 5.0f, 5.0f, 1.0f, 1.0f);
snowman_display_list = createDL();
}
这是我的主循环函数:
int main ()
{
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(800, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("Captain Ed's Adventures: Great Wall of China");
init();
//Glut Input Commands
glutIgnoreKeyRepeat(1);
glutSpecialFunc(pressKey);
glutSpecialUpFunc(releaseKey);
glutKeyboardFunc(processNormalKeys);
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape); // This redraws everything on screen when window size is changed.
glutMainLoop();
return 0;
}
这是我调用的输入函数:
void pressKey(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT : deltaAngle = -0.10f;break;
case GLUT_KEY_RIGHT : deltaAngle = 0.10f;break;
case GLUT_KEY_UP : deltaMove = 50;break;
case GLUT_KEY_DOWN : deltaMove = -50;break;
}
}
void releaseKey(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT : if (deltaAngle < 0.0f)
deltaAngle = 0.0f;
break;
case GLUT_KEY_RIGHT : if (deltaAngle > 0.0f)
deltaAngle = 0.0f;
break;
case GLUT_KEY_UP : if (deltaMove > 0)
deltaMove = 0;
break;
case GLUT_KEY_DOWN : if (deltaMove < 0)
deltaMove = 0;
break;
}
}
void processNormalKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
}
相机使用的变量以及应该改变它的函数:
static float angle=0.0,deltaAngle = 0.0,ratio;
static float x=0.0f,y=1.75f,z=5.0f;
static float lx=0.0f,ly=0.0f,lz=-1.0f;
static int deltaMove=0;
void orientMe(float ang) {
lx = sin(ang);
lz = -cos(ang);
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}
void moveMeFlat(int i) {
x = x + i*(lx)*0.1;
z = z + i*(lz)*0.1;
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}
我相信这几乎是我正在处理的所有事情,所以基本上应该发生的是,当我按 UP 键 deltaMove 应该 = 50 时,当发生这种情况时, void display(void) 中的 if 语句应该执行 moveMeFlat (增量移动);我不知道我是否做错了,或者是否有更好的结果......
我可以在相关开关案例中移动“moveMeFlat(deltaMove)”,但这不允许我进行我想要的运动。它似乎可以使用上面教程中的源代码来实现正确的功能,但在我的情况下则不然,所以我的假设是它与显示中的 if 语句有关。
我正在寻找的最终结果是能够通过左右旋转相机来向前和向后工作。我希望能够按前进和向左键并看到相机转向像一款赛车游戏...
I have been following this tutorial series for OpenGL: GLUT:
http://www.lighthouse3d.com/opengl/glut/
I have reached the stage of implementing camera controls using the keyboard:
http://www.lighthouse3d.com/opengl/glut/index.php?8
When doing the advanced tutorial it stops working. I've pretty much just copied and pasted it. When I run its version of the code it works. Mine just doesn't seem to work. It should rotate the camera view when moving left and right and move forward and backwards when using up and down keys.
My code is here broken down:
This part of my code renders components in the scene with init() which initilizes values etc.:
void display(void)
{
if (deltaMove)
moveMeFlat(deltaMove);
if (deltaAngle) {
angle += deltaAngle;
orientMe(angle);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture[0]);
RenderSkyDome();
glBindTexture(GL_TEXTURE_2D, NULL);
glutSwapBuffers();
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0f);
glColor3f(0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
LoadTextures("clouds2.bmp", 0);
GenerateDome(600.0f, 5.0f, 5.0f, 1.0f, 1.0f);
snowman_display_list = createDL();
}
This is my main loop function:
int main ()
{
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(800, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("Captain Ed's Adventures: Great Wall of China");
init();
//Glut Input Commands
glutIgnoreKeyRepeat(1);
glutSpecialFunc(pressKey);
glutSpecialUpFunc(releaseKey);
glutKeyboardFunc(processNormalKeys);
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape); // This redraws everything on screen when window size is changed.
glutMainLoop();
return 0;
}
Here are my input functions which are called:
void pressKey(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT : deltaAngle = -0.10f;break;
case GLUT_KEY_RIGHT : deltaAngle = 0.10f;break;
case GLUT_KEY_UP : deltaMove = 50;break;
case GLUT_KEY_DOWN : deltaMove = -50;break;
}
}
void releaseKey(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT : if (deltaAngle < 0.0f)
deltaAngle = 0.0f;
break;
case GLUT_KEY_RIGHT : if (deltaAngle > 0.0f)
deltaAngle = 0.0f;
break;
case GLUT_KEY_UP : if (deltaMove > 0)
deltaMove = 0;
break;
case GLUT_KEY_DOWN : if (deltaMove < 0)
deltaMove = 0;
break;
}
}
void processNormalKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
}
Variables that get used by the camera and the functions that should change it:
static float angle=0.0,deltaAngle = 0.0,ratio;
static float x=0.0f,y=1.75f,z=5.0f;
static float lx=0.0f,ly=0.0f,lz=-1.0f;
static int deltaMove=0;
void orientMe(float ang) {
lx = sin(ang);
lz = -cos(ang);
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}
void moveMeFlat(int i) {
x = x + i*(lx)*0.1;
z = z + i*(lz)*0.1;
glLoadIdentity();
gluLookAt(x, y, z,
x + lx,y + ly,z + lz,
0.0f,1.0f,0.0f);
}
I believe that's pretty much everything I am working with so basically what should happen is that when I press UP key deltaMove should = 50 and when this happens the if statement in void display(void) should do moveMeFlat(deltaMove); I don't know if I am doing this wrong or if there is a better result....
I can move "moveMeFlat(deltaMove)" within the relevant switch cases but this does not allow me to have the movement that I want. It seems to work using the source code from the tutorials above with the right functionality but not in my case so my assumption is that it's to do with the if statement in display.
The end result I am looking for is to be able to have forwards and backwards working with left and right rotating the camera. I would like to be able to press forward and left key and see the camera swerve left like in a racing game...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试去掉所有全局变量声明前面的 static 。
-http://www.cprogramming.com/tutorial /statickeyword.html
另外,不要这样做:
试试这个:
Try getting rid of static in front of all of your global variable declarations.
-http://www.cprogramming.com/tutorial/statickeyword.html
Also, instead of this:
try this:
当按键发生时 GLUT 是否空闲?我想它并没有闲着。仅当创建窗口且 GLUT 空闲时才会调用您的 display() 函数,这不允许更改您的位置。
我建议添加:
到显示函数的末尾。这将导致每 40 毫秒调用一次显示。
另外,不要将显示注册为空闲函数,否则您将让空闲函数启动许多系列的计时器函数。
PS 我会调用 glFlush();就在交换显示函数中的缓冲区之前。
Is GLUT idle when a key press is occurring? I think it is not idle. Your display() function is only called when the window is created and when GLUT is idle, which doesn't allow your position to be changed.
I suggest adding:
to the end of your display function. This will cause display to be called every 40 milliseconds.
Also, don't register display as the idle function, or you'll have the idle function starting lots of series of timer functions.
P.S. I would call glFlush(); just before swapping the buffers in your display function.