本文为学习OpenGL的学习笔记,如有书写和理解错误还请大佬扶正;
文章为OpenGL配置UI界面,使用的是GLUI;使用GLUI必须先配置GLUT;
一,配置GLUT与GLUI
参考文章:
从零开始OpenGL-- 一、 环境配置www.cnblogs.com参考文章内为VS2017配置GLUT写的很清楚,网上配置基本都是一样,这里不再进行记录;
参考文章内关于GLUI部分配置,会有一些报错(参考文章下有大佬给出解决方案),但依然(太菜)在配置过程中造成一定麻烦,所以在这里记录一下;
1,下载GLUI,并解压
https://github.com/libglui/gluigithub.com2,打开glui.sln文件(路径:glui-2.37msvc),弹出解决方案,无需更改,点击确定
3,重新定位解决方案,点击确定
4,右键点击解决方案,点击批生成,选择前四个,点击生成
生成失败(-..-)(文章使用的GLUI为2.37版本,参考文章为2.36所以会多一种报错)
5,解决错误
打开_gluidll library项目的"属性页"对话框,更改左上角配置为所有配置
单击"链接器"文件夹,单击"高级"属性页,将映像具有安全异常处理程序 改为 /SAFESEH:NO ,然后点击应用。
继续点击批生成->重新生成
同样对于案例项目也进行相应的更改(example1-6)
手动为Release配置和ReleaseGLUDIDL配置L附加依赖库
其中Release配置库为glui32.lib
ReleaseGLUDIDLL配置库为glui32dll.lib
点击批生成,生成剩余的项目
生成成功
剩下的配置与参考文章一致,就不在记录了(可以把相关的库和.h文件放到自己定义的文件夹内,方便移植一些);
生成的6个Demo原文件(glui-2.37msvc)与执行文件(glui-2.37msvcbin)很有参考价值;
二,实践GLUT与GLUI
1,GLUT
官方文档:
GLUT API, version 3www.opengl.org前文记录一直使用GLFW库进行相应窗口创建与管理,GLUT也能实现同样的功能,方法很相似;
实现代码
#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效果参考:
代码参考:
#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++界面库 GLUIblog.csdn.net修改配置:
添加预处理器定义 GLUI_NO_LIB_PRAGMA,GLUIDLL
添加附加依赖库 glui32dll.lib
实现效果:
代码参考:
#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();
}