学习OpenGL-番外-glut入门(vs2022)(一)

glut的版本自1998年后就没有更新了,但是其窗口实现相比glfw简便许多。本文主要为文档GLUT » Lighthouse3d.com的学习笔记。

1、环境配置

选择项目-管理NuGet程序包-浏览-搜索freeglut下载即可。FreeGLUT 是 GLUT 的一个开源替代品,旨在提供更多功能和更好的兼容性,它们之间的函数调用和用法基本相同。

头文件为:#include <GL/freeglut.h>,如果为Mac系统,头文件为#include <GLUT/freeglut.h>

2、窗口初始化

glut的窗口初始化相当简单快捷:

#include <GL/freeglut.h>
#include <iostream>
using namespace std;


int main(int argc, char** argv) {

	//初始化 GLUT 库
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);    //设置显示模式

	glutInitWindowPosition(100, 100);   //初始化窗口位置(左上角)
	glutInitWindowSize(320, 320);       //初始化窗口大小
	glutCreateWindow("Lighthouse3D- GLUT Tutorial");  //创建窗口

	return 1;

}

 其中,值得主要的glutInitDisplayMode函数,用于设置窗口显示模式。

用于指定颜色模型的预定义常量包括:

  • GLUT_RGBA 或 GLUT_RGB – 选择 RGBA 窗口。这是默认颜色模式。
  • GLUT_INDEX – 选择颜色索引模式。

显示模式还允许您选择单缓冲区或双缓冲区窗口。预定义的常量为:

  • GLUT_SINGLE – 单个缓冲区窗口
  • GLUT_DOUBLE – 双缓冲区窗口,需要有流畅的动画。

还有更多,您可以指定是否需要具有一组特定缓冲区的窗口。最常见的是:

  • GLUT_ACCUM – 累积缓冲区
  • GLUT_STENCIL – 模具缓冲区
  • GLUT_DEPTH – 深度缓冲区

与glfw相同的,这一步创建的窗口没有任何循环,会在创建完成后立刻关闭。

3、窗口循环与三角形绘制示例

void glutDisplayFunc(void (*funcName)(void))注册显示回调函数。告诉 GLUT 在需要重新绘制窗口内容时应该调用哪个函数。

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

void renderScene(void) {

	// 设置清除颜色(背景颜色)
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // 黑色

	// 清除颜色缓冲区和深度缓冲区
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

	//glBegin() 与 glEnd() 之间的代码块被称为一个图元的定义块。
	//	在这个代码块中,可以通过一系列的顶点坐标来定义一个或多个图元(如点、线、三角形等)。
	//	当调用 glEnd() 函数时,表示当前图元的定义结束,OpenGL 将根据之前定义的顶点坐标绘制相应的图元。

	glutSwapBuffers();     // 交换前后缓冲区
}

int main(int argc, char** argv) {

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(320, 320);
	glutCreateWindow("Lighthouse3D - GLUT Tutorial");

	glutDisplayFunc(renderScene);    //用于注册显示回调函数。告诉 GLUT 在需要重新绘制窗口内容时应该调用哪个函数

	glutMainLoop();      //glut窗口循环函数

	return 1;
}

 绘制结果如下:

4、窗口回调函数

上面形成的三角形会随着窗口的变化而变形。发生这种情况是因为我们没有正确设置透视。默认情况下,透视假定宽度/高度之比为 1,并相应地绘制。因此,当比例改变时,视角就会失真。因此,每次比率变化时,都需要重新计算透视。

窗口回调函数非常通用,这里主要介绍组成其的三个函数:

(1)GLUT 提供了一种方法来定义在调整窗口大小时应调用哪个函数,即注册用于重新计算透视的回调。即glutReshapeFunc 函数。

glutReshapeFunc(void (*func)(int width, int height)

(2)gluPerspective用于设置透视投影矩阵。这个矩阵定义了视锥体的属性,可以确定在三维场景中如何将对象投影到二维视图平面上。

void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);

示例:gluPerspective(45.0, ratio, 1.0, 100.0);

  • 45.0:表示视野角度为 45 度。这个角度决定了视锥体的开口大小,通常 45 度是一个合理的默认值。
  • ratio:表示窗口的宽高比。例如,如果窗口的宽度是 800 像素,高度是 600 像素,那么 ratio 应该是 800/600 即 1.333。
  • 1.0:表示近裁剪面距离为 1.0 个单位。这意味着任何离摄像机(观察者)距离小于 1.0 的物体都不会被绘制。
  • 100.0:表示远裁剪面距离为 100.0 个单位。这意味着任何离摄像机距离大于 100.0 的物体都不会被绘制。

(3)glMatrixMode(GLenum mode) 是一个 OpenGL 函数,用于设置当前的矩阵模式。OpenGL 中有几种不同的矩阵模式,每种模式用于不同的目的,主要有以下三种:

  • GL_MODELVIEW:模型视图矩阵模式,这是用于定义对象的变换(如平移、旋转、缩放)和相机的视角变换。
  • GL_PROJECTION:投影矩阵模式,这是用于定义投影变换,包括正投影和透视投影。
  • GL_TEXTURE:纹理矩阵模式,这是用于对纹理坐标进行变换。
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

void changeSize(int w, int h) {         //回调函数,窗口大小改变时调用

	// 检查窗口的高度是否为0,以免出现除零错误
	if (h == 0)
		h = 1;

	float ratio = w * 1.0 / h;

	// 切换到投影矩阵模式
	glMatrixMode(GL_PROJECTION);

	// 将当前矩阵重置为单位矩阵
	glLoadIdentity();

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

	// 设置正确的透视投影
	gluPerspective(45, ratio, 1, 100);

	//切换回模型视图矩阵模式
	glMatrixMode(GL_MODELVIEW);
}

void renderScene(void) {

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glBegin(GL_TRIANGLES);
	glVertex3f(-2, -2, -5.0);
	glVertex3f(2, 0.0, -5.0);
	glVertex3f(0.0, 2, -5.0);
	glEnd();

	glutSwapBuffers();
}

int main(int argc, char** argv) {

	// init GLUT and create window
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(320, 320);
	glutCreateWindow("Lighthouse3D - GLUT Tutorial");

	// register callbacks
	glutDisplayFunc(renderScene);
	glutReshapeFunc(changeSize);

	// enter GLUT event processing loop
	glutMainLoop();

	return 1;
}

​​​​​​​

  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值