您当前的位置:首页 > 计算机 > 编程开发 > Other

OpenGL

时间:11-21来源:作者:点击数:

是 API

OpenGL 是一个图形 API,并不是一个独立的平台,它需要一个编程语言来工作。

具体来说:

OpenGL(Open Graphics Library)是一个跨编程语言、跨平台的图形编程程序接口

  • 它将计算机的资源抽象称为一个个 OpenGL 的对象,
  • 对这些资源的操作抽象为一个个的 OpenGL 指令。

工作原理

OpenGL 是一个跨语言、跨平台的编程接口,它主要用于渲染 2D、3D 图像,OpenGL 所做的只是利用 GPU 进行图形相关的运算,你想用 GPU 来加速 2D 或 3D 图像的绘制,那么你用 OpenGL 就可以了。

创建一个 OpenGL 上下文

在应用程序调用任何 OpenGL 的指令之前,需要安排首先创建一个 OpenGL 的上下文。这个上下文是一个非常庞大的状态机,保存了 OpenGL 中的各种状态,这也是 OpenGL 指令执行的基础。

GLUT

官方 OpenGL 的文档里并没有提供一个 API 来进行窗口的创建和操作。为了支持窗口,Windows 提供 WGL 接口,MacOS 则有 CGL。

使用这些接口直接来创建窗口来显示图形通常非常麻烦,所以我们通常使用一个高水平的库来隐藏窗口的创建操作细节。这里使用的窗口库是GLUT。

GLUT 的两个主要目的,一是建立一个跨平台的函式库(事实上 GLUT 就是跨平台的),以及简化学习 OpenGL 的条件。透过 GLUT 编写 OpenGL 通常只需要增加几行额外 GLUT 的代码,而且不需要知道每个不同操作系统处理窗口的 API。

  • OpenGL Utilities 是一组建构于 OpenGL Library 之上的工具组,提供许多很方便的函式,使 OpenGL 更强大且更容易使用。
  • OpenGL Utility Toolkit 是建立在 OpenGL Utilities 上面的工具箱,除了强化 OpenGL Utilities 的不足之外,也增加了 OpenGL 对于视窗介面支援。
  • 所有的 GLUT 函数都以 glut 作为开头,例如 glutPostRedisplay()。

安装库

sudo apt update 
sudo apt install libgl1-mesa-dev
sudo apt install freeglut3 freeglut3-dev
sudo apt install libglfw3 libglfw3-dev
sudo apt install libglew-dev

代码示例一

#include <GL/glut.h>

void init(void)
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glMatrixMode(GL_PROJECTION);
	glOrtho(-5, 5, -5, 5, 5, 15);
	glMatrixMode(GL_MODELVIEW);
	gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);

	return;
}

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0, 0, 0);
	glutWireTeapot(3);	// 画个茶壶
	glFlush();

	return;
}

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(0, 0);
	glutInitWindowSize(300, 300);
	glutCreateWindow("OpenGL 3D View");
	init();
	glutDisplayFunc(display);
	glutMainLoop();

	return 0;
}

编译、运行

$ gcc -o test3.out test3.c -lGL -lGLU -lglut
$ ./test3.out
在这里插入图片描述

代码示例二

#include <GL/glut.h>

#define ColoredVertex(c, v) \
	do {                    \
		glColor3fv(c);      \
		glVertex3fv(v);     \
	} while (0)
static int angle = 0;
static int rotateMode = 0;

void myDisplay(void)
{
	static int list = 0;
	if (list == 0) {
		GLfloat PointA[] = {0.5f, 0.5f, -0.5f}, PointB[] = {0.5f, -0.5f, -0.5f},
				PointC[] = {-0.5f, -0.5f, -0.5f}, PointD[] = {-0.5f, 0.5f, -0.5f},
				PointE[] = {0.5f, 0.5f, 0.5f}, PointF[] = {0.5f, -0.5f, 0.5f},
				PointG[] = {-0.5f, -0.5f, 0.5f}, PointH[] = {-0.5f, 0.5f, 0.5f};
		GLfloat ColorA[] = {1, 0, 0}, ColorB[] = {0, 1, 0}, ColorC[] = {0, 0, 1}, ColorD[] = {1, 1, 0},
				ColorE[] = {1, 0, 1}, ColorF[] = {0, 1, 1}, ColorG[] = {1, 1, 1}, ColorH[] = {0, 0, 0};

		list = glGenLists(1);
		glNewList(list, GL_COMPILE);

		// 面1
		glBegin(GL_POLYGON);
		ColoredVertex(ColorA, PointA);
		ColoredVertex(ColorE, PointE);
		ColoredVertex(ColorH, PointH);
		ColoredVertex(ColorD, PointD);
		glEnd();

		// 面2
		glBegin(GL_POLYGON);
		ColoredVertex(ColorD, PointD);
		ColoredVertex(ColorC, PointC);
		ColoredVertex(ColorB, PointB);
		ColoredVertex(ColorA, PointA);
		glEnd();

		// 面3
		glBegin(GL_POLYGON);
		ColoredVertex(ColorA, PointA);
		ColoredVertex(ColorB, PointB);
		ColoredVertex(ColorF, PointF);
		ColoredVertex(ColorE, PointE);
		glEnd();

		// 面4
		glBegin(GL_POLYGON);
		ColoredVertex(ColorE, PointE);
		ColoredVertex(ColorH, PointH);
		ColoredVertex(ColorG, PointG);
		ColoredVertex(ColorF, PointF);
		glEnd();

		// 面5
		glBegin(GL_POLYGON);
		ColoredVertex(ColorF, PointF);
		ColoredVertex(ColorB, PointB);
		ColoredVertex(ColorC, PointC);
		ColoredVertex(ColorG, PointG);
		glEnd();

		// 面6
		glBegin(GL_POLYGON);
		ColoredVertex(ColorG, PointG);
		ColoredVertex(ColorH, PointH);
		ColoredVertex(ColorD, PointD);
		ColoredVertex(ColorC, PointC);
		glEnd();
		glEndList();

		glEnable(GL_DEPTH_TEST);
	}

	// 已经创建了显示列表,在每次绘制正四面体时将调用它
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glPushMatrix();
	glRotatef(angle / 10, 1, 0.5, 0.0);
	glCallList(list);
	glPopMatrix();
	glutSwapBuffers();
}

void myIdle(void)
{
	++angle;
	if (angle >= 3600.0f) {
		angle = 0.0f;
	}
	myDisplay();
}

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(700, 700);
	glutCreateWindow("First OpenGL Program");

	glutDisplayFunc(&myDisplay);
	glutIdleFunc(&myIdle);	//空闲调用

	glutMainLoop();

	return 0;
}

编译、运行

$ gcc test.c -o test.out -l GL -l glut
$ ./test.out
请添加图片描述

代码示例三

#include <GL/glut.h>

// 初始化参数
void init()
{
	glClearColor(0.1, 0.1, 0.4, 0.0);
	glShadeModel(GL_SMOOTH);
}

void DrawMyObjects(void)
{
	/* draw some points */
	glBegin(GL_POINTS);
	glColor3f(1.0, 0.0, 0.0);
	glVertex2f(-10.0, 11.0);
	glColor3f(1.0, 1.0, 0.0);
	glVertex2f(-9.0, 10.0);
	glColor3f(0.0, 1.0, 1.0);
	glVertex2f(-8.0, 12.0);
	glEnd();

	/* draw some line_segments */
	glBegin(GL_LINES);
	glColor3f(1.0, 1.0, 0.0);
	glVertex2f(-11.0, 8.0);
	glVertex2f(-7.0, 7.0);
	glColor3f(1.0, 0.0, 1.0);
	glVertex2f(-11.0, 9.0);
	glVertex2f(-8.0, 6.0);
	glEnd();

	/* draw one opened_line */
	glBegin(GL_LINE_STRIP);
	glColor3f(0.0, 1.0, 0.0);
	glVertex2f(-3.0, 9.0);
	glVertex2f(2.0, 6.0);
	glVertex2f(3.0, 8.0);
	glVertex2f(-2.5, 6.5);
	glEnd();

	/* draw one closed_line */
	glBegin(GL_LINE_LOOP);
	glColor3f(0.0, 1.0, 1.0);
	glVertex2f(7.0, 7.0);
	glVertex2f(8.0, 8.0);
	glVertex2f(9.0, 6.5);
	glVertex2f(10.3, 7.5);
	glVertex2f(11.5, 6.0);
	glVertex2f(7.5, 6.0);
	glEnd();

	/* draw one filled_polygon */
	glBegin(GL_POLYGON);
	glColor3f(0.5, 0.3, 0.7);
	glVertex2f(-7.0, 2.0);
	glVertex2f(-8.0, 3.0);
	glVertex2f(-10.3, 0.5);
	glVertex2f(-7.5, -2.0);
	glVertex2f(-6.0, -1.0);
	glEnd();

	/* draw some filled_quandrangles */
	glBegin(GL_QUADS);
	glColor3f(0.7, 0.5, 0.2);
	glVertex2f(0.0, 2.0);
	glVertex2f(-1.0, 3.0);
	glVertex2f(-3.3, 0.5);
	glVertex2f(-0.5, -1.0);
	glColor3f(0.5, 0.7, 0.2);
	glVertex2f(3.0, 2.0);
	glVertex2f(2.0, 3.0);
	glVertex2f(0.0, 0.5);
	glVertex2f(2.5, -1.0);
	glEnd();

	/* draw some filled_strip_quandrangles */
	glBegin(GL_QUAD_STRIP);
	glVertex2f(6.0, -2.0);
	glVertex2f(5.5, 1.0);
	glVertex2f(8.0, -1.0);
	glColor3f(0.8, 0.0, 0.0);
	glVertex2f(9.0, 2.0);
	glVertex2f(11.0, -2.0);
	glColor3f(0.0, 0.0, 0.8);
	glVertex2f(11.0, 2.0);
	glVertex2f(13.0, -1.0);
	glColor3f(0.0, 0.8, 0.0);
	glVertex2f(14.0, 1.0);
	glEnd();

	/* draw some filled_triangles */

	glBegin(GL_TRIANGLES);
	glColor3f(0.2, 0.5, 0.7);
	glVertex2f(-10.0, -5.0);
	glVertex2f(-12.3, -7.5);
	glVertex2f(-8.5, -6.0);
	glColor3f(0.2, 0.7, 0.5);
	glVertex2f(-8.0, -7.0);
	glVertex2f(-7.0, -4.5);
	glVertex2f(-5.5, -9.0);
	glEnd();

	/* draw some filled_strip_triangles */
	glBegin(GL_TRIANGLE_STRIP);
	glVertex2f(-1.0, -8.0);
	glVertex2f(-2.5, -5.0);
	glColor3f(0.8, 0.8, 0.0);
	glVertex2f(1.0, -7.0);
	glColor3f(0.0, 0.8, 0.8);
	glVertex2f(2.0, -4.0);
	glColor3f(0.8, 0.0, 0.8);
	glVertex2f(4.0, -6.0);
	glEnd();

	/* draw some filled_fan_triangles */
	glBegin(GL_TRIANGLE_FAN);
	glVertex2f(8.0, -6.0);
	glVertex2f(10.0, -3.0);
	glColor3f(0.8, 0.2, 0.5);
	glVertex2f(12.5, -4.5);
	glColor3f(0.2, 0.5, 0.8);
	glVertex2f(13.0, -7.5);
	glColor3f(0.8, 0.5, 0.2);
	glVertex2f(10.5, -9.0);
	glEnd();
}

// 绘图回调函数
void display()
{
	// 清除之前帧数据
	glClear(GL_COLOR_BUFFER_BIT);
	DrawMyObjects();
	// 执行绘图命令
	glFlush();
}

// 窗口大小变化回调函数
void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 0.1, 100000.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0, 0, 25, 0, 0, -1, 0, 1, 0);
}

int main(int argc, char *argv[])
{
	// 初始化显示模式
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

	// 初始化窗口
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(100, 100);
	glutCreateWindow(argv[0]);

	init();
	glutReshapeFunc(reshape);
	glutDisplayFunc(display);

	// 开始主循环绘制
	glutMainLoop();

	return 0;
}

编译、运行

$ gcc -o test5.out test5.c -lGL -lGLU -lglut
$ ./test5.out
在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐