OpenGL: 绘制按钮

来源:互联网 发布:淘宝开店电话 编辑:程序博客网 时间:2024/06/07 07:03

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

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

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

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

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

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

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

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

#include <windows.h>#include <cstdio>#include <cstdlib>#include <GL/glut.h>#include <cmath>#include <ctime>#pragma comment(lib,"glut32.lib")#pragma comment(lib,"glu32.lib")#pragma comment(lib,"opengl32.lib")////////////////////////////////////////////////////globalfloat 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);}glPopMatrix();}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;if (g_fAngle > 360){g_fAngle -= 360;}}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;}

运行效果如下:


0 0
原创粉丝点击