freeglut 键盘问题

Posted

技术标签:

【中文标题】freeglut 键盘问题【英文标题】:freeglut Keyboard Issues 【发布时间】:2014-07-21 00:45:55 【问题描述】:

问题是当我按下键盘棒上的“shift”其他键时。这是我正在使用的代码(原始代码归功于 Nghia Ho)

#include <GL/freeglut.h>
#include <iostream>
#include <cmath>

#include "Camera.h"

using namespace std;

void Display();
void Reshape (int w, int h);
void Keyboard(unsigned char key, int x, int y);
void KeyboardUp(unsigned char key, int x, int y);
void MouseMotion(int x, int y);
void Mouse(int button, int state, int x, int y);
void Timer(int value);
void Idle();

void Grid();

Camera g_camera;
bool g_key[256];
bool g_shift_down = false;
bool g_fps_mode = false;
int g_viewport_width = 0;
int g_viewport_height = 0;
bool g_mouse_left_down = false;
bool g_mouse_right_down = false;

// Movement settings
const float g_translation_speed = 0.05;
const float g_rotation_speed = M_PI/180*0.2;

int main (int argc, char **argv) 
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutCreateWindow("FPS demo by Nghia Ho - Hit SPACEBAR to toggle FPS mode");

    glutIgnoreKeyRepeat(1);

    glutDisplayFunc(Display);
    glutIdleFunc(Display);
    glutReshapeFunc(Reshape);
    glutMouseFunc(Mouse);
    glutMotionFunc(MouseMotion);
    glutPassiveMotionFunc(MouseMotion);
    glutKeyboardFunc(Keyboard);
    glutKeyboardUpFunc(KeyboardUp);
    glutIdleFunc(Idle);

    glutTimerFunc(1, Timer, 0);
    glutMainLoop();

    return 0;


void Grid()

    glPushMatrix();
    glColor3f(1,1,1);

    for(int i=-50; i < 50; i++) 
        glBegin(GL_LINES);
        glVertex3f(i, 0, -50);
        glVertex3f(i, 0, 50);
        glEnd();
    

    for(int i=-50; i < 50; i++) 
        glBegin(GL_LINES);
        glVertex3f(-50, 0, i);
        glVertex3f(50, 0, i);
        glEnd();
    

    glPopMatrix();


void Display (void) 
    glClearColor (0.0,0.0,0.0,1.0); //clear the screen to black
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the color buffer and the depth buffer
    glLoadIdentity();

    g_camera.Refresh();

    glColor3f(0,1,0);

    glutWireTeapot(0.5);
    Grid();

    glutSwapBuffers(); //swap the buffers


void Reshape (int w, int h) 
    g_viewport_width = w;
    g_viewport_height = h;

    glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport to the current window specifications
    glMatrixMode (GL_PROJECTION); //set the matrix to projection

    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1 , 100.0); //set the perspective (angle of sight, width, height, ,depth)
    glMatrixMode (GL_MODELVIEW); //set the matrix back to model


void Keyboard(unsigned char key, int x, int y)

    if(key == 27) 
        exit(0);
    

    if(key == ' ') 
        g_fps_mode = !g_fps_mode;

        if(g_fps_mode) 
            glutSetCursor(GLUT_CURSOR_NONE);
            glutWarpPointer(g_viewport_width/2, g_viewport_height/2);
        
        else 
            glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
        
    

    if(glutGetModifiers() == GLUT_ACTIVE_SHIFT) 
        g_shift_down = true;
    
    else 
        g_shift_down = false;
    

    g_key[key] = true;


void KeyboardUp(unsigned char key, int x, int y)

    g_key[key] = false;


void Timer(int value)

    if(g_fps_mode) 
        if(g_key['w'] || g_key['W']) 
            g_camera.Move(g_translation_speed);
        
        else if(g_key['s'] || g_key['S']) 
            g_camera.Move(-g_translation_speed);
        
        else if(g_key['a'] || g_key['A']) 
            g_camera.Strafe(g_translation_speed);
        
        else if(g_key['d'] || g_key['D']) 
            g_camera.Strafe(-g_translation_speed);
        
        else if(g_mouse_left_down) 
            g_camera.Fly(-g_translation_speed);
        
        else if(g_mouse_right_down) 
            g_camera.Fly(g_translation_speed);
        
    

    glutTimerFunc(1, Timer, 0);


void Idle()

    Display();


void Mouse(int button, int state, int x, int y)

    if(state == GLUT_DOWN) 
        if(button == GLUT_LEFT_BUTTON) 
            g_mouse_left_down = true;
        
        else if(button == GLUT_RIGHT_BUTTON) 
            g_mouse_right_down = true;
        
    
    else if(state == GLUT_UP) 
        if(button == GLUT_LEFT_BUTTON) 
            g_mouse_left_down = false;
        
        else if(button == GLUT_RIGHT_BUTTON) 
            g_mouse_right_down = false;
        
    


void MouseMotion(int x, int y)

    // This variable is hack to stop glutWarpPointer from triggering an event callback to Mouse(...)
    // This avoids it being called recursively and hanging up the event loop
    static bool just_warped = false;

    if(just_warped) 
        just_warped = false;
        return;
    

    if(g_fps_mode) 
        int dx = x - g_viewport_width/2;
        int dy = y - g_viewport_height/2;

        if(dx) 
            g_camera.RotateYaw(g_rotation_speed*dx);
        

        if(dy) 
            g_camera.RotatePitch(g_rotation_speed*dy);
        

        glutWarpPointer(g_viewport_width/2, g_viewport_height/2);

        just_warped = true;
    

奇怪的是当我按任何其他键时它第一次修复它但它没有修复它第二次 非常感谢!

【问题讨论】:

通常对于堆栈溢出,最好制作一个简单的(超级基本)示例,看看问题是否仍然存在。它也使跟随变得更容易。 我记下了,谢谢 :) 【参考方案1】:

问题是,GLUT 键盘函数没有给你键码,即按下哪个键和修饰符的数字表示,而是字符码,即由此产生的字母形式。当然,大写字符的字符代码与其对应的小写字符不同。并且按住 shift 当然会改变大小写。

实际上,GLUT 并不是特别适合您想要的输入类型。使用 GLFW 或 SDL 执行此操作要简单得多。但是,在您的特定情况下,有一个简单的解决方案:只需将所有传入的字符代码转换为小写,然后在“按键”数组中进行索引:

#include <ctype.h> /* for tolower */

/* ... */

void Keyboard(unsigned char key, int x, int y)

    key = tolower(key); /* <--- */

    if(key == 27) 
        exit(0);
    

    if(key == ' ') 
        g_fps_mode = !g_fps_mode;

        if(g_fps_mode) 
            glutSetCursor(GLUT_CURSOR_NONE);
            glutWarpPointer(g_viewport_width/2, g_viewport_height/2);
        
        else 
            glutSetCursor(GLUT_CURSOR_LEFT_ARROW);
        
    

    if(glutGetModifiers() == GLUT_ACTIVE_SHIFT) 
        g_shift_down = true;
    
    else 
        g_shift_down = false;
    

    g_key[key] = true;

【讨论】:

以上是关于freeglut 键盘问题的主要内容,如果未能解决你的问题,请参考以下文章

freeglut.dll 丢失

在没有 IDE 的情况下使用 freeglut

如何检测与 C++、OpenGL 和 freeglut 的冲突?

切换到 freeglut 后线条不渲染

如何检查鼠标是不是在 freeglut 的三角形区域内单击?

使用 freeglut 保持纵横比和比例独立于窗口大小