利用OpenGL绘制按钮

 通过OpenGL自己绘制按钮,菜单,可以自己贴图,可以自己构建很炫的GUI。我这里只是做了一个最原始的模型, 没有增加贴图。

程序实现思路:通过正交变换绘制出按钮cube, 然后重置投影视图矩阵,转入场景绘制。具体在display函数里。

主要想想说一下几个细节问题:

1,正交投影的坐标系原点位于左下角, 而透视投影坐标系原点位于窗口中心。

2,mouse函数参数x,y分别是鼠标的坐标,鼠标的坐标系是:窗口左上角为原点。所以在验证鼠标是否在按钮上时,必须先进行坐标变换。

3,按钮被按下时,增加了反馈:按钮会被缩小为glScalef(0.9, 0.9, 1.0);

运行效果,按了白色小按钮,线框cube会旋转个角度。

下面是基于glut+OpenGL的程序源码:

#include #include #include #include #include // //global float g_fWidth = 500; float g_fHeight = 500; float g_fDepth = 100; float g_fAngle = .0; struct Button{ float m_fPosX; //表示在正交投影坐标系(左下角为坐标原点)的坐标, float m_fPosY; float m_fWidth; //屏幕像素单位 float m_fHeight; bool m_bPressed; void Render() { glPushMatrix(); { //将中心位于原点的cube移动到使cube左下角坐标为m_fPosX,m_fPosY的位置 //必须考虑cube的自身长宽 glTranslatef(m_fPosX+m_fWidth/2, m_fPosY+m_fHeight/2, -2.0); //-2.0只是为了按钮可见 if( m_bPressed ) { //double scaleAmt = 10.0 * sin( (double)rand() ); //double scaleAmt = sin( (double)rand() ); glScalef(0.9, 0.9, 1.0); } //cube中心位于原点 glScalef (m_fWidth, m_fHeight, 5.0); glutSolidCube(1.0); } } bool OnMouseDown(int mousex, int mousey) { //鼠标的位置:mousex,mousey坐标系是原点位于左上角 //必须将mousey变换到原点位于左下角的坐标系中 mousey = g_fHeight-mousey; if( mousex > m_fPosX && mousex < m_fPosX+m_fWidth && mousey > m_fPosY && mousey < m_fPosY+m_fHeight ) { printf("button is pressed .... /n"); m_bPressed = true; return true; } return false; } void OnMouseUp() { m_bPressed = false; } }; Button* pBtn; void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); pBtn = new Button; pBtn->m_bPressed = false; pBtn->m_fPosX = 40; pBtn->m_fPosY = 480; pBtn->m_fWidth = 60; pBtn->m_fHeight = 20; printf("**********button pos: 40/t480/n"); } void display(void) { glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, g_fWidth, 0, g_fHeight, 0, g_fDepth); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); pBtn->Render(); // 绘制cube物体, glMatrixMode (GL_PROJECTION); //回复原有的设置 glLoadIdentity (); gluPerspective(60,1.0,1.5,20); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); /* viewing transformation */ gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotatef(g_fAngle, 0.0, 1.0, 0.0); glScalef (1.0, 2.0, 1.0); /* modeling transformation */ glutWireCube (1.0); //glFlush(); glutSwapBuffers(); } void reshape (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(60,1.0,1.5,20); glMatrixMode (GL_MODELVIEW); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } void mouse(int button, int state, int x, int y) { if(button==GLUT_LEFT_BUTTON) switch(state) { case GLUT_DOWN: //左键按下: printf("Mouse pos : %d/t%d/n", x, 500-y); if( pBtn->OnMouseDown(x, y) ) g_fAngle += 2.0; break; case GLUT_UP: pBtn->OnMouseUp(); break; } glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMouseFunc( mouse ); glutMainLoop(); return 0; }

你可能感兴趣的:(OpenGL,OpenGL技术专栏)