OpenGL使用及面试题汇总

OpenGL概念及问题

OpenGL中怎么传递变量

GLSL语言中的变量有:uniform变量,attribute变量,varying变量

  • uniform变量
    uniform变量是外部application程序传递给(vertex和fragment)shader的变量。Qt中它是application通过函数program->setUniformValue("uniform_name", value_name);赋值的。
    在(vertex和fragment)shader程序内部,uniform变量就像是C语言里面的常量(const ),它不能被shader程序修改。

  • attribute变量
    attribute变量是只能在vertex shader中使用的变量。(不能在fragment shader中声明和使用)。
    attribute变量用来表示一些顶点的数据,如:顶点坐标,法线,纹理坐标,顶点颜色等。
    在application中(Qt中),一般用函数void QOpenGLShaderProgram::bindAttributeLocation(const char *name, int location)来绑定每个attribute变量的位置,然后用函数glVertexAttribPointer()为每个attribute变量赋值。

  • varying变量
    varying变量是vertex和fragment shader之间做数据传递用的。一般vertex shader修改varying变量的值,然后fragment shader使用该varying变量的值。因此varying变量在vertex和fragment shader二者之间的声明必须是一致的。application不能使用此变量。

着色器是什么

着色器是一种存在于GPU中的程序。它们是可编程的,并允许操作几何和像素颜色。
不同的着色器(顶点(Vertex)着色器,面片(Fragment)着色器)整体构成了一个管线。

着色器是怎么工作的(管线的处理流程)

渲染管线通过几个阶段处理数据,分别为:
1)基于顶点的操作
顶点着色器处理顶点,每个顶点由空间矩阵变换,有效地将其3D坐标系统改变为新的坐标系统。就像摄影相机将3D风景转换成2D照片一样。

2)图元装配
以指定的顺序连接顶点构建基本体状态

3)图元处理
屏幕外面的任何图元都被剪辑并在下一阶段忽略

4)栅格化
测试像素是否在图元的边内。如果他们不是,他们被丢弃。如果他们在图元内,他们被带到下一个阶段。通过测试的像素集被称为片段。

5)片面处理
将颜色或纹理应用到片段内的像素

6)基于片段的操作
片段被提交到几个测试,如:透明度(Alpha)测试,模板(Stencil)测试,深度(Depth)测试等

结果:像素被保存在帧缓存(Framebuffer)中,更具体地,保存在Default-Framebuffer中。这些是你在移动设备屏幕上看到的像素。

三维数据如何在二维屏幕上显示

主要是通过图形渲染管线(管线:实际上是指一堆原始图像数据途径一个输送管道,期间经过经过各种变换处理,最终输出在屏幕上的过程)管理的,其被划分为两个过程:

1.把3D坐标转换为2D坐标。
2.把2D坐标转换为实际有颜色的像素。

CPU和GPU之间如何调度的
  • 1.GLSL运行在GPU,其通过接口实现和CPU之间的数据转换。
  • 2.OpenGL主程序由CPU调度运行,图像处理部分通过GLSL交由GPU执行。数据传递分3个步骤:
    1)利用内置的OpenGL函数生成一个ID号码
    2)对该ID号码进行内存类型的绑定,接收系统内存中数据的“标识符”就准备好了。
    3)对这部分内存进行初始化,初始化的内容来自于系统内存中,这一部分功能利用glBufferData函数完成。
OpenGL中缓冲区的概念

[1] 帧缓冲(frame buffer):帧缓冲是下面几种缓冲的合集。通过帧缓冲可以将你的场景渲染到一个不同的帧缓冲中,可以使我们能够在场景中创建镜子这样的效果,或者做出一些炫酷的特效,存放显示用的数据的。
[2] 颜色缓冲(color buffer):存储所有片段的颜色:即视觉输出的效果。
[3] 深度缓冲(depth buffer):根据缓冲的z值,确定哪些面片被遮挡。由GLFW自动生成。
[4] 模板缓冲(stencil buffer):与深度测试类似,通过比较模板值和预设值,决定是否丢弃片段。

mipmap是什么

MIP来源于拉丁文中的multum in parvo,意为在一个小空间里的多数。MIP map(有时候拼写成mipmap)是多级渐远纹理,也是目前应用最为广泛的纹理映射(map)技术之一。简单来说,就是实现 “实物(图片)看起来近大远小,近处清晰远处模糊”的效果。

多级渐远纹理背后的理念很简单:距观察者的距离超过一定的阈值,OpenGL会使用不同的多级渐远纹理,即最适合物体的距离的那个。由于距离远,解析度不高也不会被用户注意到。

OpenGL的常用坐标系

将坐标转换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分步,也就是类似于流水线那样子,实现的,在流水线里面我们在将对象转换到屏幕空间之前会先将其转换到多个坐标系统(Coordinate System)。将对象的坐标转换到几个过渡坐标系(Intermediate Coordinate System)的优点在于,在这些特定的坐标系统中进行一些操作或运算更加方便和容易,这一点很快将会变得很明显。对我们来说比较重要的总共有5个不同的坐标系统:

  • 局部空间(Local Space,或者称为物体空间(Object Space))
  • 世界空间(World Space)
  • 观察空间(View Space,或者称为视觉空间(Eye Space))
  • 裁剪空间(Clip Space)
  • 屏幕空间(Screen Space)

OpenGL使用及面试题汇总_第1张图片

1.局部坐标是对象相对于局部原点的坐标;也是对象开始的坐标。
2.将局部坐标转换为世界坐标,世界坐标是作为一个更大空间范围的坐标系统。这些坐标是相对于世界的原点的。
3.接下来我们将世界坐标转换为观察坐标,观察坐标是指以摄像机或观察者的角度观察的坐标。
4.在将坐标处理到观察空间之后,我们需要将其投影到裁剪坐标。裁剪坐标是处理-1.0到1.0范围内并判断哪些顶点将会出现在屏幕上。
5.最后,我们需要将裁剪坐标转换为屏幕坐标,我们将这一过程成为视口变换(Viewport Transform)。视口变换将位于-1.0到1.0范围的坐标转换到由glViewport函数所定义的坐标范围内。最后转换的坐标将会送到光栅器,由光栅器将其转化为片段。

OpenGL中的常用矩阵,各有什么作用

参考上面OpenGL的常用坐标系中的图片。

  • model:主要针对模型的平移、旋转、缩放、错切等功能,将模型由局部空间转换到世界空间
  • view:视图矩阵。摄像机/观察者的位置等信息(设置鼠标移动、滚轮等效果),将所有世界坐标转换为观察坐标。
  • projection:投影矩阵。裁剪坐标 转换到屏幕上。
OpenGL的使用方式及步骤

1、顶点着色程序的源代码和片段作色程序的源代码要分别保存到一个字符数组里面;
2、使用glCreateshader()分别创建一个顶点着色器对象和一个片段着色器对象;
3、使用glShaderSource()分别将顶点着色程序的源代码字符数组绑定到顶点着色器对象,将片段着色程序的源代码字符数组绑定到片段着色器对象;
4、使用glCompileShader()分别编译顶点着色器对象和片段着色器对象;
5、使用glCreaterProgram()创建一个(着色)程序对象;
6、使用glAttachShader()分别将顶点着色器对象和片段着色器对象附加到(着色)程序对象上;
7、使用glLinkProgram()对(着色)程序对象执行链接操作
8、使用glValidateProgram()对(着色)程序对象进行正确性验证(图中没有)
9、最后使用glUseProgram()将OpenGL渲染管道切换到着色器模式,并使用刚才做好的(着色)程序对象。
然后,才可以提交顶点。

步骤如下图所示:
OpenGL使用及面试题汇总_第2张图片

参考

1. LearnOpenGL-CN
2. 林小竹@CSDN
3. 代笔墨客@CSDN
4. 概述:渲染引擎如何工作?

你可能感兴趣的:(GSCOPE,计算机图形学)