1.實驗目的:html
理解掌握一個OpenGL程序的常見交互方法。函數
2.實驗內容:oop
(1) 運行示範實驗代碼1,掌握程序鼠標交互方法,嘗試爲其添加鍵盤與菜單控制,實現一樣功能;.net
(2)運行示範實驗代碼2,掌握程序鼠標座標獲取與繪圖方法,嘗試爲其添加繪製直線功能;htm
(3)結合上述兩步,可否實現經過鼠標右鍵菜單切換實現一個簡單的繪圖程序,能夠繪製直線、三角形、正方形等常見圖形?blog
3.實驗原理:事件
要想在OpenGL中處理鼠標事件很是的方便,GLUT已經爲咱們的註冊好了函數,只要咱們提供一個方法。使用函數glutMouseFunc,就能夠幫咱們註冊咱們的函數,這樣當發生鼠標事件時就會自動調用咱們的方法。get
函數的原型是:原型
void glutMouseFunc(void(*func)(int button,int state,int x,int y));it
參數:func:處理鼠標click事件的函數的函數名。
從上面能夠看到,處理鼠標單擊事件的函數,必定有4個參數。第一個參數代表哪一個鼠標鍵被按下或鬆開,這個變量能夠是下面的三個值中的一個:
GLUT_LEFT_BUTTON
GLUT_MIDDLE_BUTTON
GLUT_RIGHT_BUTTON
第二個參數代表,函數被調用發生時,鼠標的狀態,也就是是被按下,或鬆開,可能取值以下:
GLUT_DOWN
GLUT_UP
當函數被調用時,state的值是GLUT_DOWN,那麼程序可能會假定將會有個GLUT_UP事件,甚至鼠標移動到窗口外面,也如此。然而,若是程序調用glutMouseFunc傳遞NULL做爲參數,那麼GLUT將不會改變鼠標的狀態。剩下的兩個參數(x,y)提供了鼠標當前的窗口座標(以左上角爲原點)。
鍵盤相關知識可參考:http://blog.csdn.net/xie_zi/article/details/1911891
菜單相關知識可參考:http://blog.csdn.net/xie_zi/article/details/1963383
4.示範代碼:
(1)鼠標控制旋轉的正方形
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#define DEGREES_TO_RADIANS 3.14159/180.0
static GLfloat spin = 0.0;
GLfloat x = 0.0;
GLfloat y = 0.0;
GLfloat size = 50.0;
GLfloat angle = 2.0;
GLsizei wh = 500, ww = 500;
void square()
{
glBegin(GL_QUADS);
glVertex2f(x,y);
glVertex2f(-y,x);
glVertex2f(-x,-y);
glVertex2f(y,-x);
glEnd();
}
void spinDisplay(void)
{
spin = spin + 2.0;
if (spin > 360.0) spin = spin - 360.0;
x=125.0 * cos(DEGREES_TO_RADIANS*spin);
y=125.0 * sin(DEGREES_TO_RADIANS*spin);
glutPostRedisplay();
}
void mydisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
square();
glutSwapBuffers();
}
void init()
{
glClearColor (0.0, 0.0, 0.0, 1.0);
}
void myreshape(GLint w, GLint h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-w/2, w/2, -h/2, h/2, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
ww = w;
wh = h;
}
void mymouse(GLint button, GLint state, GLint wx, GLint wy)
{
if(button ==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
exit(0);
if(button ==GLUT_LEFT_BUTTON && state == GLUT_DOWN)
glutIdleFunc(spinDisplay);
if(button== GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
glutIdleFunc(NULL);
}
void main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("double");
init();
glutDisplayFunc(mydisplay);
glutReshapeFunc(myreshape);
glutMouseFunc(mymouse);
glutIdleFunc(spinDisplay);
glutMainLoop();
}
(2)鼠標當前位置繪製方框
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
GLfloat x = 0.0;
GLfloat y = 0.0;
GLfloat size = 50.0;
GLsizei wh = 500, ww = 500;
void drawSquare(GLint x, GLint y) {
y = wh-y;
glBegin(GL_POLYGON);
glVertex3f(x + size, y + size, 0);
glVertex3f(x - size, y + size, 0);
glVertex3f(x - size, y - size, 0);
glVertex3f(x + size, y - size, 0);
glEnd();
}
void mydisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
drawSquare(x, y);
glutSwapBuffers();
glutPostRedisplay();
}
void init()
{
glClearColor (0.0, 0.0, 0.0, 1.0);
}
void myreshape(GLint w, GLint h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, w, 0, h, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
ww = w;
wh = h;
}
void mymouse(GLint button, GLint state, GLint wx, GLint wy)
{
if(button ==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
exit(0);
if(button ==GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
x = wx;
y = wy;
}
}
void main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("double");
init();
glutDisplayFunc(mydisplay);
glutReshapeFunc(myreshape);
glutMouseFunc(mymouse);
glutMainLoop();
}
5. 實驗做業:
試比較所給兩個示範代碼的窗口座標系有何不一樣。
分類: CG實驗指導