opengl系列文章–001
一: 运行结果

二:代码未注释之前的状态
//# 常用opengl函数
// 作者 广都--编程每日问 2022-7-20 w: wo15985300747
// 有什么问题可以相互讨论。
#include <windows.h>
#include <GL/glut.h>
void myglClearColor(double r, double g, double b) { // 自定义函数,可以使用rgb 模式
glClearColor(r / 255, g / 255, b / 255, 1.0); //蓝色
}
void myglColor3f(double r, double g, double b) {
glColor3f(r / 255, g / 255, b / 255);
}
void myDisplay(void) {
myglClearColor(0, 199, 140); // 土耳其蓝
glClear(GL_COLOR_BUFFER_BIT); //唯一参数表示需要被清除的缓冲区。
glRectf(-0.5f, -0.5f, 0.5f, 0.5f); // 左上和右下 对角线(左下到右上)
myglColor3f(107, 142, 35);
glRectf(-0.1, -0.2, 0.5f, 0.9f);
glFlush();
}
int main(int argc, char *argv[]) {
HWND winhwnd;
winhwnd = FindWindow("ConsoleWindowClass", NULL); //获取窗口句柄
if (winhwnd) { //如果找到了
ShowWindow(winhwnd, SW_HIDE); //隐藏之
}
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(500, 200);
glutInitWindowSize(400, 400);
int ax = glutCreateWindow("OpenGL程序 基本函数解析");
HWND hWnd =::FindWindow(0, "OpenGL程序 基本函数解析");
glutDisplayFunc(&myDisplay); // 刷新
glutMainLoop();
return 0;
}
三: 代码注释版本
// 注释者 广都 1975767630 有兴趣可以一起交流注释代码 2022-7-20- 1:00
// 由于 windows.h 预定义了一些宏,这些可能会和gl发生冲突,所以推荐的做法是先 导入windows ,再导入其他库,
// 本代码的内容 opengl 基本函数解释,常规rgb模式和 opengl颜色模式的解释
//GLUT的头文件
//本来OpenGL程序一般还要包含<GL/gl.h>和<GL/glu.h>,但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含
#include <windows.h>
#include <GL/glut.h>
void myglClearColor(double r, double g, double b) { // 自定义函数,可以使用rgb 模式
glClearColor(r / 255, g / 255, b / 255, 1.0); //蓝色
}
void myglColor3f(double r, double g, double b) {
glColor3f(r / 255, g / 255, b / 255);
}
void myDisplay(void)
{
// 当前坐标系采取的 是 以屏幕中心为原点的方式, 边长 只有1
// 1
// -1 (0,0) 1
// -1
// 很多程序都是在 vs 环境下写的,由于vs 本身会引用很多的头文件,所以其他编译器拿到手,缺少这些文件,会报错。
//将“清空颜色”设为黑色
//在RGB模式下,使用glClearColor来指定“空”的颜色,它需要四个参数,其参数的意义跟
//glColor4f相似。通常有RGB模式和RGBA模式,其中RGB模式有R、G、B三个分量,取值范围
//为0.0~1.0;而RGBA模式有R、G、B、A四个分量,其中A即Alpha值,与透明度有关。
// RGBA模式中,每一个像素会保存以下数据:R值(红色分量)、G值(绿色分量)、B值(蓝色分量)和A值(alpha分量)
// glClearColor(0.0,0.0,0.0,0.0);
// glClearColor 是使用了百分比,实际上使用的是 255为极限的数字,这里我们要做的事情是写一个自定义函数。
// opengl 和rgb的对比
// 0.0,0.0,0.0,0.0 纯黑
// 0.0, 0.0, 1.0, 1.0 蓝色
// glClearColor(0.2, 0.5, 1.0, 1.0);//蓝色
// myglClearColor(153, 51, 250); // 胡紫色
myglClearColor(0, 199, 140); // 土耳其蓝
//执行实际的缓冲
glClear(GL_COLOR_BUFFER_BIT); //唯一参数表示需要被清除的缓冲区。
/*
GLbitfield:可以使用 | 运算符组合不同的缓冲标志位,表明需要清除的缓冲,
例如glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)表示要清除颜色缓冲以及深度缓冲,可以使用以下标志位
GL_COLOR_BUFFER_BIT: 当前可写的颜色缓冲
GL_DEPTH_BUFFER_BIT: 深度缓冲
GL_ACCUM_BUFFER_BIT: 累积缓冲
GL_STENCIL_BUFFER_BIT: 模板缓冲
*/
// 固有的多边形,无需使用glbengin 和glend 函数,因为他们本身就是独立的。
//画一个矩形。四个参数分别表示了位于对角线上的两个点的横、纵坐标
glRectf(-0.5f, -0.5f, 0.5f, 0.5f); // 左上和右下 对角线(左下到右上)
// 指定当前使用的颜色 四边形函数
// glColor3f(1, 0, 0); // 设置接下来一段时间的 颜色,确保自己得到输入的结果
myglColor3f(107, 142, 35);
glRectf(-0.1, -0.2, 0.5f, 0.9f);
//保证前面的OpenGL命令立即执行(而不是让它们在缓冲区中等待)
glFlush();
/*glFlush()是OpenGL [1] 中的函数,用于强制刷新缓冲,保证绘图命令将被执行,而不是存储在缓冲区 [2] 中等待其他的OpenGL命令。
简单地说glFlush()就是强制刷新,OpenGL是使用一条 渲染管线 [3] 线性处理命令的,一般情况下,我们提交给OpenGL的指令并不是马上送到驱动程序
[4] 里执行的,而是放到一个缓冲区里面,等这个缓冲区满了再一次过发到驱动程序里执行;很多时候只有几条指令是填充不满那个缓冲区的,
就是说这些指令根本没有被发送到驱动里,所以我们要调用glFlush来强制把这些指令送到驱动里进行处理。
8?S
glFinish()[调试bug] 将缓冲区的指令立即送往硬件执行,但是要一直等到硬件执行完这些指令之后才返回。
如果直接绘制到前缓冲,那么在你想保存屏幕截图之前,就需要调用这个函数,确保绘制完毕。
如果使用双缓冲,则这个函数不会有太大作用。
如果我传输到硬件的某条命令造成了GPU的崩溃,找出使得GPU崩溃的那条指令的简单方法是在每个绘制操作之后调用这个函数。这样就可以准确找出造成崩溃的命令。
另外,Direct3D不支持Finish概念。
*/
}
//带命令行参数的main函数
int main(int argc, char *argv[]) {
// 申明一个句柄,用来操作窗口大小
// 关闭控制台界面,但是会造成闪烁,需要编译的时候直接去掉,这个是选项的问题
HWND winhwnd;
winhwnd = FindWindow("ConsoleWindowClass", NULL); //获取窗口句柄
if (winhwnd) { //如果找到了
ShowWindow(winhwnd, SW_HIDE); //隐藏之
}
//以glut开头的函数都是GLUT工具包所提供的函数
//对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了
glutInit(&argc, argv);
// 作用主要是在创建窗口的时候,指定其显示模式的类型。
/* GLUT_DOUBLE/ GLUT_SINGLE
GLUT_RGBA表示颜色模式,另外还有GLUT_RGB 和 GLUT_INDEX模式
缓冲区类型:GLUT_DOUBLE表示使用双缓冲窗口,与之对应的是GLUT_SINGLE模式,二者的区别是:
单缓冲,实际上就是将所有的绘图指令在窗口上执行,就是直接在窗口上绘图,这样的绘图效率是比较慢的,如果使用单缓冲,而电脑比较慢,屏幕会发生闪烁。一般只用于显示单独的一副非动态的图像。
双缓冲,实际上的绘图指令是在一个缓冲区完成,这里的绘图非常的快,在绘图指令完成之后,再通过交换指令把完成的图形立即显示在屏幕上,这就避免了出现绘图的不完整,同时效率很高。一般用于生成动画效果。
*/
//设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜 色)。
//GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
//设置初始窗口的位置(窗口左上角相对于桌面坐标(x,y))
//坐标(0,0)是指屏幕左上角的位置. x, y单位均为像素.
// 重新设置窗口的位置,窗口函数的大小
/*
设置函数的扩展关系,那么相关的函数是:
1. 获得当前的窗口位置,
设置窗口位置
2. 获得窗口大小,
3. 设置窗口大小
4. 销毁窗体
5. 显示窗体,
隐藏窗体
6.设置为当前窗口
*/
//设置窗口在屏幕中的位置
glutInitWindowPosition(500, 200);
//设置窗口的大小
glutInitWindowSize(400, 400);
//根据前面设置的信息创建窗口。参数将被作为窗口的标题
//注意:窗口被创建后,并不立即显示到屏幕上。需要调用glutMainLoop才能看到窗口
// int glutCreateWindow(char *name); 返回一个窗口函数,从1开始 ansii的字符串
// 得想个办法获得它的句柄
// 问题, 通过 返回的opengl句柄 获得 win的句柄
int ax = glutCreateWindow("OpenGL程序 基本函数解析");
HWND hWnd =::FindWindow(0, "OpenGL程序 基本函数解析");
// SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);// 设置win图标,该函数目前不可用
// 还需要设置窗体图标
//每当GLUT确定一个窗口的内容需要重新显示时,通过glutDisplayFunc() 所注册的那个回调函数就会被执行
//应该把重绘场景所需要的所有代码都放在这个显示回调函数里。
// glutReshapeFunc(reshape); // 串口大小变化回调函数
glutDisplayFunc(&myDisplay); // 刷新
//所有已经创建的窗口将会在这时显示,对这些窗口的渲染也开始生效
//事件处理循环开始启动,已注册的显示回调函数被触发。一旦进入循环,它就永远不会退出。
glutMainLoop();
return 0;
}
四: 用到的rgb模式 图片

1070

被折叠的 条评论
为什么被折叠?



