OpenGL 绘制按钮

分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

通过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")

//////////////////////////////////////////////////
//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);
		}
		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;
}

运行效果如下:

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

猜你喜欢

转载自www.cnblogs.com/sownchz/p/10504227.html