《Open GL编程指南(原书第8版)》第一章(翻译)

第一章

OpenGL简介

本章目标

描述什么是OpenGL ,在用计算机生成图像时,他能做什么,不能做什么。

了解一个OpenGL程序的基本结构

了解组成OpenGL渲染管线的着色器

 

 

这章主要是简单的介绍了一下OpenGL。我们分成以下几个部分分别去讨论:

  • “啥是OpenGL?”:解释了OpenGL到底是个啥玩意儿,他能干啥不能干啥,以及他是咋工作的。
  • “初窥OpenGL程序”:展示了一个OpenGL程序是长啥样的。
  • “OpenGL语法”:它的语法约定
  • “OpenGL的渲染管线”:讨论OpenGL用于生成图像的渲染管线。
  • “第一个OpenGL程序的相关细节”:剖析这个程序。

啥是OpenGL?


OpenGL其实就是个图形硬件API。

在OpenGL 4.3中包括了超过500条函数,这些函数用来生成物体或图像,创建交互式3D程序。(相比之前貌似精简了一些)

OpenGL 被设计成一种streamlined,独立于不同硬件或操作系统的接口。为实现这一点,OpenGL并不包含某些用于窗口任务或用户输入的函数,因为这些东西在不同平台上往往是大相径庭的。

举个栗子:假如在OpenGL中设计了响应鼠标事件的函数,我们把编写的OpenGL游戏从windows平台移植到Android平台时,玩家就只能呵呵了。不过并不是说我们用OpenGL就不能实现这样的操作,实现这些操作的函数被定义在某些其他的工具库中,这些后面会说到。

OpenGL本身也并不提供创造3D物体或读取图像文件(例如JPEG)的功能,程序员只能利用为数不多的例如点,直线和三角形这样的基本图形去创造复杂的3D物体。

。。。

初窥OpenGL程序


OpenGL能做的事情实在是太多了,一个OpenGL程序往往也会变得庞大和复杂。不过所有的OpenGL程序也无非是做了以下两件事:

  • 初始化那些我们要去渲染的物体的状态
  • 指定要渲染哪些物体

在我们看一些代码之前,我们有必要交待一些图形学术语。渲染——通过模型创造图像的过程。渲染模式也并非独一无二的,常见的有“辐射着色”,“光线追踪”和“栅格化”。而OpenGL是一个基于栅格化(也可以叫做光栅化)的渲染系统。“辐射着色”,“光线追踪”已经超出了本书的范畴,不过这些渲染模式仍然可以用OpenGL去显示图像或在创建图像时计算出这些图像的信息。

我们之后会提到的术语“模型”和“物体”都是由基本的集合图形组成的(点,直线,三角形),这些基本图形则都是由顶点构成的。

还有一个必须提到的基本概念是着色器——由图形硬件去执行的特定函数。我们可以把着色器想象成专为你的GPU编译的小程序。OpenGL内置的编译工具可以把所有的着色器代码编译成GPU可以执行的代码。在OpenGL中有4种着色器,最常见的就是顶点着色器——处理顶点数据,同样重要的还有片段着色器——处理来自光栅化器的数据。不论顶点着色器还是片段着色器都是每个OpenGL程序必不可少的。

最终生成的图像是由画在显示器上的像素点组成的。像素点是能在显示器上显示的最小元素。所有的像素点都存储在缓冲帧中,这些缓冲帧则存储在我们所说的显存中并发送给显示器显示。

 1 ///////////////////////////////////////////////////////////////////////
 2 //
 3 // triangles.cpp
 4 //
 5 ///////////////////////////////////////////////////////////////////////
 6 #include <iostream>
 7 using namespace std;
 8 #include "vgl.h"
 9 #include "LoadShaders.h"
10 enum VAO_IDs { Triangles, NumVAOs };
11 enum Buffer_IDs { ArrayBuffer, NumBuffers };
12 enum Attrib_IDs { vPosition = 0 };
13 GLuint VAOs[NumVAOs];
14 GLuint Buffers[NumBuffers];
15 const GLuint NumVertices = 6;
16 //---------------------------------------------------------------------
17 //
18 // init
19 //
20 void init(void)
21 {
22     glGenVertexArrays(NumVAOs, VAOs);
23     glBindVertexArray(VAOs[Triangles]);
24     GLfloat vertices[NumVertices][2] = {
25     { -0.90, -0.90 }, // Triangle 1
26     { 0.85, -0.90 },
27     { -0.90, 0.85 },
28     { 0.90, -0.85 }, // Triangle 2
29     { 0.90, 0.90 },
30     { -0.85, 0.90 }};
31 
32     glGenBuffers(NumBuffers, Buffers);
33     glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
34     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
35     vertices, GL_STATIC_DRAW);
36 
37     ShaderInfo shaders[] = {
38         { GL_VERTEX_SHADER, "triangles.vert" },
39         { GL_FRAGMENT_SHADER, "triangles.frag" },
40         { GL_NONE, NULL }};
41 
42     GLuint program = LoadShaders(shaders);
43     glUseProgram(program);
44     glVertexAttribPointer(vPosition, 2, GL_FLOAT,
45     GL_FALSE, 0, BUFFER_OFFSET(0));
46     glEnableVertexAttribArray(vPosition);
47 }
48 //---------------------------------------------------------------------
49 //
50 // display
51 //
52 void display(void)
53 {
54     glClear(GL_COLOR_BUFFER_BIT);
55     glBindVertexArray(VAOs[Triangles]);
56     glDrawArrays(GL_TRIANGLES, 0, NumVertices);
57     glFlush();
58 }

代码看起来有点长,不过在以后的开发中你会发现这基本上是每个OpenGL程序所必需的了。我们会用一些非OpenGL官方提供的工具库去创建窗口,接受鼠标键盘输入。当然我们也可以自己写一些函数或类库去实现类似的功能。OpenGL是个C语言编写的类库,不过我们的例子基本上都是用一些比较简单的C++编写的。事实上我们使用C++也不过是为了实现vectors和matrices这样的数据结构。

。。。

OpenGL语法


 

。。。

OpenGL渲染管线


。。。

第一个OpenGL程序的相关细节


  • 本博客文章除注明转载外,均为本人原创或者翻译。
  • 本博客文章欢迎各种形式的转载,但请具有完全民事行为能力的转载者注明文章出处,尊重我的劳动,也尊重你的智商。

 

原文地址:https://www.cnblogs.com/Erainbj/p/3852994.html