opengl基本例子解析

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模式 图片

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值