OpenGL – C++ Bài 11: Xử lý sự kiện bàn phím

 

Chào mừng các bạn đến với  chủ đề Học Lập Trình OpenGL Tại blog: Phát triển phần mềm 123-az

Trong bài số 10, tôi đã giới thiệu đến các bạn cách bắt sự kiện khi click chuột và move chuột.

Và chúng ta đã thực hành được một demo kết hợp giữa việc click chuột và move chuột để quay camera xung quanh vật.

Và điều này giúp chúng ta có thể nhìn được vật theo nhiều hướng.

Trong bài này tôi sẽ hướng dẫn các bạn bắt sự kiện khi bấm một phím trên bàn phím.

I. Lý thuyết cơ bản.
1. Bắt sự kiện của các phím chức năng như Left Right Up Down, F1-F12…

+ Viết một hàm OnSpecialKeyDown như sau:

//phattrienphanmem123az.com
void OnSpecialKeyDown(int key, int xx, int yy) 
{
 switch (key)
 {
   case GLUT_KEY_LEFT:
   //Todo
    break;
    case GLUT_KEY_RIGHT:
    //Todo
    break;
    case GLUT_KEY_UP:

    //Todo
    break;
    case GLUT_KEY_DOWN:
    //Todo
    break;
}

+ Trong hàm Main chúng gọi hàm OnSpecialKeyDown như sau:

glutSpecialFunc(OnSpecialKeyDown);

Hàm OnSpecialKeyDown ở trên chỉ có thể nhận được một số phim trên keyboard như sau:

+ 12 phim F đi từ F1-F12

+ 4 Phim : Up Down Left Right

+ Phim: Insert/End/Page Down-Up/ Home

2. Bắt sự kiện của các ký tự A B C…

+ Viết một hàm OnKeyDown như sau:

void OnKeyDown(unsigned char ch, int x, int y)
{
  switch (ch)
  {
   case 'A' :
     break;
   case 'a':
     break;
   default:
     break;
}
}

Trong hàm main chúng ta gọi hàm OnKeyDown như sau:

glutKeyboardFunc(OnKeyDown);

Ngoài ra các bạn có thể thêm sự kiện cho 2 hai hàm nhả phím bấm như sau:

glutSpecialUpFunc(releaseKey);

glutKeyboardUpFunc(OnKeyUp);

Hãy cùng xem video thực hành tôi sẽ nói rõ hơn.

 

II. Thực hành OpenGL Bắt sự kiện bàn phím.

Chúng ta cùng thực hành bài toán với các yêu cầu sau.

+ Click vào phím up và down thì cameraltiến lại gần hoặc lùi dần ra xa.

+ Khi click vào phím right và left thì.

+ Có thể dịch camera sang bên trái hoặc bên phải.

+ Có thể camera đứng im, nhưng nó tự quay quanh mình nó 1 góc anpha.

Note: camera quay quanh mình nó khác với camera quanh xung quanh vật.

=> CAM quay quanh mình nó thì nó sẽ nhìn được mọi hướng, sẽ có lúc nó ko nhìn vào vật mà nhìn sang vật khác.

=> CAM quanh vật (như bài số 10, bắt sự kiện Mouse) thì CAM luôn nhìn thấy vật và nhìn ở các góc cạnh, các hướng khác nhau.

Full code:

#include <gl\glut.h>

float g_x = 0.0f;
float g_z = 30.0f;


void OnKeyUp(unsigned char ch, int x, int y)
{
  switch (ch) 
  {
  case 'A' :
    break;
  case 'a':
    break;
  default:
    break;
  }
}

void OnKeyDown(unsigned char ch, int x, int y)
{
  switch (ch) 
  {
  case 'A' :
    break;
  case 'a':
    break;
  default:
    break;
  }
}

void OnSpecialKeyDown(int key, int x, int y)
{
    switch (key) 
    {
    case GLUT_KEY_UP:
        g_z -= 0.2;
        break;
    case GLUT_KEY_DOWN:
        g_z += 0.2;
        break;
    case GLUT_KEY_LEFT:
        g_x -= 0.2;
        break;
    case GLUT_KEY_RIGHT:
        g_x += 0.2;
        break;
    default:
        break;
    }
}

void OnSpecialKeyUp(int key, int x, int y)
{
    switch (key) 
    {
    case GLUT_KEY_LEFT :
        break;
    case GLUT_KEY_RIGHT:
        break;
    default:
        break;
    }
}

void ReShape(int width, int height)
{
  if (height == 0)
  {
    height = 1;
  }

  glViewport(0, 0, width, height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  float ratio = 0.0;
  if (width > height)
     ratio = (float)width/height;
  else
    ratio = (float)height/width;

  gluPerspective(45.0, ratio, 1.0, 40.0);
  glMatrixMode(GL_MODELVIEW);

}

void DrawCoordinate()
{
  glDisable(GL_LIGHTING);
  glBegin(GL_LINES);
  glColor3f(1.0, 0.0, 0.0);
  glVertex3f(-100.0, 0.0, 0.0);
  glVertex3f(100.0, 0.0, 0.0);
  glEnd();

  glBegin(GL_LINES);
  glColor3f(0.0, 1.0, 0.0);
  glVertex3f(0.0, -100.0, 0.0);
  glVertex3f(0.0, 100.0, 0.0);
  glEnd();

  glBegin(GL_LINES);
  glColor3f(0.0, 0.0, 1.0);
  glVertex3f(0.0, 0.0, -100.0);
  glVertex3f(0.0, 0.0, 100.0);
  glEnd();

  glEnable(GL_LIGHTING);
}

void RenderScene()
{
  glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  gluLookAt(g_x, 1.0f, g_z,
            0.0, 0.0f,  0.0,
            0.0f, 1.0f,  0.0f);

  DrawCoordinate();
  glPushMatrix();
  glutSolidTeapot(10.0);
  glPopMatrix();
  
  glFlush();
  glutPostRedisplay();
}


void Init()
{
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_DEPTH_TEST);

  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);

  GLfloat light_pos [] = {0.0, 0.0, 1.0, 0.0};
  glLightfv(GL_LIGHT0, GL_POSITION, light_pos);

  GLfloat ambient [] = {1.0, 1.0, 1.0, 1.0};
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);

  GLfloat diff_use [] = {0.1, 0.2, 0.3, 1.0};
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff_use);

  GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);

  GLfloat shininess = 50.0f;
  glMateriali(GL_FRONT, GL_SHININESS, shininess);

}

void main()
{
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  glutInitWindowSize(640, 480);
  glutInitWindowPosition(100, 100);
  glutCreateWindow("Opengl Study");

  Init();
  glutReshapeFunc(ReShape);
  glutDisplayFunc(RenderScene);
  glutIdleFunc(RenderScene);
  glutKeyboardFunc(OnKeyDown);
  glutKeyboardUpFunc(OnKeyUp);
  glutSpecialFunc(OnSpecialKeyDown);
  glutSpecialUpFunc(OnSpecialKeyUp);

  // here are the new entries
  glutIgnoreKeyRepeat(1);

  glutMainLoop();

  return;
}

 

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.