opengl动画_OpenGL学习笔记(十一)为OpenGL添加UI界面

b7f9c3031e9d2c393f5fe0280296ec7d.png

本文为学习OpenGL的学习笔记,如有书写和理解错误还请大佬扶正;

文章为OpenGL配置UI界面,使用的是GLUI;使用GLUI必须先配置GLUT;

一,配置GLUT与GLUI

参考文章

从零开始OpenGL-- 一、 环境配置​www.cnblogs.com
d2b328600ec317a93f487b99e4cfe2b1.png

参考文章内为VS2017配置GLUT写的很清楚,网上配置基本都是一样,这里不再进行记录;

参考文章内关于GLUI部分配置,会有一些报错(参考文章下有大佬给出解决方案),但依然(太菜)在配置过程中造成一定麻烦,所以在这里记录一下;

1,下载GLUI,并解压

https://github.com/libglui/glui​github.com

399521522d8b866506bdd7529dce5638.png
下载,解压

2,打开glui.sln文件(路径:glui-2.37msvc),弹出解决方案,无需更改,点击确定

3526e39a44ec34f8bc6b696531e86fb0.png

3,重新定位解决方案,点击确定

859bf489cd2b694070d0f1fb8be0c2de.png

4,右键点击解决方案,点击批生成,选择前四个,点击生成

2363feee840870b31f6c4615c2b6b7fd.png

生成失败(-..-)(文章使用的GLUI为2.37版本,参考文章为2.36所以会多一种报错)

5af3f1e0f94aa8bd0900ce920c24bd07.png

5,解决错误

打开_gluidll library项目的"属性页"对话框,更改左上角配置为所有配置

单击"链接器"文件夹,单击"高级"属性页,将映像具有安全异常处理程序 改为 /SAFESEH:NO ,然后点击应用。

bd57ff94dc2ffd737ea240f3ee0a6fec.png
参考文章这里只对当前配置进行更改,要对所有配置更改

继续点击批生成->重新生成

f4f1ab81d9a31cdf8ff52520ed183260.png
生成成功

同样对于案例项目也进行相应的更改(example1-6)

cefef179ba7a3fcc3212ef2670433c61.png

手动为Release配置和ReleaseGLUDIDL配置L附加依赖库

其中Release配置库为glui32.lib

31872c6394041bca8ec8d7c92366a127.png

ReleaseGLUDIDLL配置库为glui32dll.lib

2092c2752186b910dbc46ccae98d4c82.png

点击批生成,生成剩余的项目

254fdeb9708ce75ddcd0fa185ed2318c.png

生成成功

2d12913b6d24ae1d5abd93c820b9774e.png

剩下的配置与参考文章一致,就不在记录了(可以把相关的库和.h文件放到自己定义的文件夹内,方便移植一些);

生成的6个Demo原文件(glui-2.37msvc)与执行文件(glui-2.37msvcbin)很有参考价值;

二,实践GLUT与GLUI

1,GLUT

官方文档:

GLUT API, version 3​www.opengl.org

前文记录一直使用GLFW库进行相应窗口创建与管理,GLUT也能实现同样的功能,方法很相似;

4507eee24695c7b7a55bfb0ed5c59f83.png
实现效果

实现代码

#include <gl/glut.h>
#include<gl/gl.h>
#include<gl/GLU.h>

void SceneRendering()
{
	//清除颜色缓冲区,并将颜色设置为ClearColor
	glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	//渲染四边形
	glBegin(GL_POLYGON);
	    //顶点颜色/顶点位置
		glColor3f(1.0, 0.0, 0.0);
		glVertex2f(-0.5, -0.5);
		glVertex2f(-0.5, 0.5);
		glVertex2f(0.5, 0.5);
		glVertex2f(0.5, -0.5);
	glEnd();
	//强制刷新缓冲,保证绘图命令被执行
	glFlush();
}

int main(int argc, char ** argv)
{
	//初始化glut
	glutInit(&argc, argv);

	//设置显示模式
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
 
	//设定窗口位置与大小
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(1080, 720);

	//创建窗口
	glutCreateWindow("Renderer");
	//回调渲染函数
	glutDisplayFunc(SceneRendering);
	//循环执行
	glutMainLoop();
}

相关函数的解释(文档里都有)

函数 glutInit(&argc, argv);

这个函数传了主函数的两个参数,它除了初始化GLUT库以外还会与窗口系统沟通。同时可以包含其他有用的选项比如 '-sync' 和 '-gldebug',这样可以自动的检查GL的错误并独立的显示它们,如果操作系统没有合适的OpenGL或者非法命令行选项就会抛出错误,初始化失败。

函数glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

设置一些 GLUT 的参数

Mode参数是一个GLUT库里预定义的可能的布尔组合。你使用mode去指定颜色模式,数量和缓冲区类型。

指定颜色模式的预定义常量有:

  • 1:GLUT_RGBA或者GLUT_RGB。指定一个RGBA窗口,这是一个默认的颜色模式。
  • 2:GLUT_INDEX。指定颜色索引模式。

这个显示模式还允许你选择单缓冲区或双缓冲区窗口。

  • 1:GLUT_SINGLE.单缓冲区窗口。
  • 2:GLUT_DOUBLE.双缓冲区窗口,这是产生流畅动画必须选的。

还可以指定更多,如果你想指定一组特殊的缓冲的话,用下面的变量:

  • 1:GLUT_ACCUM.累积缓冲区。
  • 2:GLUT_STENCIL.模板缓冲区。
  • 3:GLUT_DEPTH.深度缓冲区

函数glutInitWindowPosition(100, 100);

函数设置了窗口的参数(包括窗口大小、窗口位置以及窗口标题)并创建窗口。

  • X: 距离屏幕左边的像素数。-1是默认值,意思就是由窗口管理程序决定窗口出现在哪里。如果不使用默认值,那你就自己设置一个值。
  • Y:距离屏幕上边的像素数。和X一样。

函数glutInitWindowSize(1080, 720);

  • Width:窗口的宽度。
  • Height:窗口的高度。

函数glutCreateWindow("Windowname");

这个函数被用来创建一个显示图像的窗口。它有一个字符指针类型的参数,用来初始化窗口显示的名称,还有一个整数类型的返回值,用来标识该创建的窗口。需要注意的是,所有新建的窗口都是有单独的OpenGL上下文,也就是说有各自的 状态机,因此窗口标识符可以用来区别这些窗口。

函数glutDisplayFunc(SceneRendering);

  • 因为我们工作在一个窗口系统中,可以通过事件回调函数与运行中的项目进行交互。GLUT 可以和基本的窗口系统进行交互,并且提供给我们一些回调函数。
  • 在这里我们仅仅使用了一个主回调函数,这个主回调函数完成了一帧中的所有渲染工作。
  • 这个函数被 GLUT 内部循环不断的调用。

函数glutMainLoop();

这个函数既没有参数,也没有返回值。只是单纯的进入事件处理循环使得GLUT不断的调用渲染图形回调函数。通过这种办法我们就可以在显示器看到图形了。

2,GLUT弹出式菜单

参考文章:

OpenGL---GLUT教程(十) GLUT菜单​blog.csdn.net
9401b4778bae8828056dd8a3e71ed696.png

效果参考:

086fdcec8cd5f57889abe6cb42772649.gif

代码参考:

#include <glui/glut.h>
#include<gl/gl.h>
#include<gl/GLU.h>

#include <string.h>
#include <glui/glui.h>

#define RED 1
#define GREEN 2
#define BLUE 3
#define WHITE 4


float red = 0.0;
float green = 0.0;
float blue = 0.0;

//绘制函数
void myDisplay()
{
	//设置背景色
	glClearColor(.2f, .2f, .2f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	//绘制三角形
	glBegin(GL_TRIANGLES);
	 glColor3f(red, blue, green);
	 glVertex3f(-0.5, -0.5, 0.0);
	 glVertex3f(0.5, 0.0, 0.0);
     glVertex3f(0.0, 0.5, 0.0);
	glEnd();

	//双缓冲
	glutSwapBuffers();
}


void processMenuEvents(int option) {
	//option 就是传递过来的value的值。
	switch (option) {
	case RED:
		red = 1.0;
		green = 0.0;
		blue = 0.0; break;
	case GREEN:
		red = 0.0;
		green = 1.0;
		blue = 0.0; break;
	case BLUE:
		red = 0.0;
		green = 0.0;
		blue = 1.0; break;
	case WHITE:
		red = 1.0;
		green = 1.0;
		blue = 1.0; break;
	}

	glutPostRedisplay();
}


void createGLUTMenus() {

	int menu;

	// 创建菜单并告诉GLUT,processMenuEvents处理菜单事件。
	menu = glutCreateMenu(processMenuEvents);

	//给菜单增加条目
	glutAddMenuEntry("Red", RED);
	glutAddMenuEntry("Blue", BLUE);
	glutAddMenuEntry("Green", GREEN);
	glutAddMenuEntry("White", WHITE);

	// 把菜单和鼠标右键关联起来。
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}


int main(int argc, char *argv[])
{
	//初始化glut
	glutInit(&argc, argv);
	//设置显示模式
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
	//设定窗口位置与大小
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(1080, 720);

	//创建窗口
    glutCreateWindow("OpenGL");
	//回调渲染函数
	glutDisplayFunc(&myDisplay);
	//调用菜单
	createGLUTMenus();
	//循环
	glutMainLoop();

	return 0;
}

3,glui

参考资料:

开源项目之C++界面库 GLUI​blog.csdn.net
d7afc88788146ba314cbef1a95d6f07c.png

修改配置:

添加预处理器定义 GLUI_NO_LIB_PRAGMA,GLUIDLL

1266136c0b0122bfa77ae373fbe646f3.png

添加附加依赖库 glui32dll.lib

67f868697ed251b0a811ad3e773300e8.png

实现效果:

e19859c2e551164e7952de05c909077a.gif

代码参考:

#include <gl/glut.h>
#include<gl/gl.h>
#include<gl/GLU.h>

#include <string.h>
#include <glui/glui.h>

/**************************ID*******************************/
float red = 1.0;
float green = 1.0;
float blue = 1.0;

int   changeRed;
int   changeGreeen;
int   changeBlue;

float redChannelValue;
float greenChannelValue;
float blueChannelValue;

int main_window;

/****************************渲染函数***********************************/
void SceneRendering(void)
{
	//清除颜色缓冲区,并将颜色设置为ClearColor
	glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	//改变颜色值
	if (changeRed)
	{
		red = redChannelValue;
	}

	if (changeGreeen)
	{
		green = greenChannelValue;
	}

	if (changeBlue)
	{
		blue = blueChannelValue;
	}

	//渲染四边形
	glBegin(GL_POLYGON);
	    //顶点颜色/顶点位置
		glColor3f(red, green, blue);
		glVertex2f(-0.5, -0.5);
		glVertex2f(-0.5, 0.5);
		glVertex2f(0.5, 0.5);
		glVertex2f(0.5, -0.5);
	glEnd();
	//强制刷新缓冲,保证绘图命令被执行
	//glFlush();

	//双缓冲
	glutSwapBuffers();
}
/****************************保持窗口比例函数***********************************/
void myGlutReshape(int w, int h)
{
	// 防止除数即高度为0
	// (你可以设置窗口宽度为0).
	if (h == 0)
		h = 1;

	float ratio = 1.0* w / h;

	// 单位化投影矩阵。
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();//导入单位矩阵

	// 设置视口大小为增个窗口大小
	glViewport(0, 0, w, h);

	// 设置正确的投影矩阵
	gluPerspective(45, ratio, 1, 1000);//宽高比例改为当前值,视线区域与屏幕大小一致
	//设置模型视图矩阵
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	gluLookAt(0.0, 0.0, 3.0, 0.0, 0.0, -1.0, 0.0f, 1.0f, 0.0f); //观察者位置
}
/****************************GLUI回调函数***********************************/
void myGlutIdle(void)
{
	//判断是否为当前窗口
	if (glutGetWindow() != main_window)
		glutSetWindow(main_window);

	//glutPostRedisplay 标记当前窗口需要重新绘制
	glutPostRedisplay();
}

//主函数
int main(int argc, char ** argv)
{
	//初始化glut
	glutInit(&argc, argv);

	//设置显示模式
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
	
	//设定窗口位置与大小
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(1080, 720);

	//创建窗口
	main_window = glutCreateWindow("Renderer");
	//回调渲染函数
	glutDisplayFunc(SceneRendering);
	//改变窗口大小时,保留窗口比例
	glutReshapeFunc(myGlutReshape);


	/***************************GLUI CODE*******************************/
	//GLUI版本号
	float version = GLUI_Master.get_version();

	//创建新的UI窗口
	GLUI *glui_window = GLUI_Master.create_glui("GLUI");
	//glui_window->add_statictext("Hello World!");   //输入一行字符串

	//创建Checkbox/Spinner
	new GLUI_Checkbox(glui_window, "ChangeRed", &changeRed);
	(new GLUI_Spinner(glui_window, "RedChannelValue:", &redChannelValue))
		->set_int_limits(0, 1);

	new GLUI_Checkbox(glui_window, "ChangeGreen", &changeGreeen);
	(new GLUI_Spinner(glui_window, "GreenChannelValue:", &greenChannelValue))
		->set_int_limits(0, 1);

	new GLUI_Checkbox(glui_window, "ChangeBlue", &changeBlue);
	(new GLUI_Spinner(glui_window, "BlueChannelValue:", &blueChannelValue))
		->set_int_limits(0, 1);

	//GLUI回调函数
	GLUI_Master.set_glutIdleFunc(myGlutIdle);
												   
	//循环执行
	glutMainLoop();
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值