OpenGL学习——基本概念

203 阅读5分钟

阅读说明

添加Books书签

  • 黄色 - 性能优化(建议)
  • 绿色 - 流程图
  • 紫色- 概念定义
  • 红色- 重点注意
  • 蓝色- 知识点

图书框架

第一章 基本概念

变换、投影、光栅化、着色、纹理、混合

复习展开

第二章 项目实践

  • 配置MacOS项目

  • 了解OpenGL必备库

    • GLUT
  • 示例代码

《OpenGL超级宝典第五版》——基本概念

第三章 基本渲染

分类如下:

  • 渲染流程:客户端-服务器模式

  • 坐标系

    • 正投影
    • 透视投影
  • 存储着色器

    • 属性Attributes
    • 变量Uniform
  • 3D坐标空间=>2D屏幕投影(图形绘制)

“我们关心的不是物理屏幕坐标和像素,而是视景体中的位置坐标。将这些点、线和三角形从创建的3D空间投影到计算机屏幕上的2D图形则是着色器程序和光栅化硬件所要完成的工作”

  • 点、线、多边形绘制
  • 裁剪测试
  • 混合

    • 颜色混合
    • 混合方程式
    • 抗锯齿
    • 多重采样

第四章 基本变换

  • 数学概念

    • 向量、矩阵
    • 点乘、叉乘
  • 变换

    • 视觉坐标
    • 视图变换
    • 模型变换
    • 投影变换
    • 视口变换
    • 模型视图二元性(A/B对象相对变换)
  • 模型视图:移动变换矩阵的构造

  • 投影矩阵

    • 正投影矩阵
    • 透视投影
    • 模型视图投影矩阵(模型相对视图)
  • 变换管线(顶点变换管线👇)

  • 角色移动(3D环境中渲染流程)

  • 角色移动的实现

    • 角色帧——存储移动的数据结构
    • 照相机管理——移动过程,变换的管理

第五章 基础纹理

  • 纹理贴图、位图、像素图、

  • 纹理载入、像素包装、颜色缓冲区读取、纹理参数

  • 纹理单元、纹理坐标、环绕模式

  • 纹理过滤

    • 最邻近过滤
    • 线性过滤
  • Mip贴图

    • Mip贴图过滤
  • 各向异性过滤

  • 纹理压缩、图片压缩

句柄(Handle):是计算机中用于间接访问资源的整数标识符。

句柄是由管理该对象的模块负责生成和释放,使用者不需要关心其内部实现。

第六章 基本着色器

  • 着色器内建函数
  • 模拟光线、表面法线、顶点照明、漫反射、环境反射、镜面反射
  • ADS着手、Phone着色算法
  • 侵蚀着色器、卡通着色器

第七章 高级纹理

  • 图像纹理、矩形纹理、立方体贴图
  • 多重纹理
  • Point Sprite (点精灵)、旋转点精灵顶点
  • 纹理代理

学习过程

  1. 建立Mac OS 项目

MacOS配置Xcode上的OpenGL环境,给出详细步骤和示例代码,以供调试?

  1. 绘制三角形示例程序

对于MacOS配置Xcode上的OpenGL环境,可以按以下步骤进行:

  1. 安装Xcode 在Mac App Store中搜索Xcode并安装最新版的Xcode。Xcode中已经包含了OpenGL和其他开发框架。
  2. 创建OpenGL项目 打开Xcode,选择"Create a new Xcode project",选择"MacOS"和"Command Line Tool"项目模板。
  3. 配置OpenGL框架 在TARGETS的General设置里,在Linked Frameworks and Libraries中点击"+",搜索并添加OpenGL和GLUT框架。
  4. 添加OpenGL代码 在main.cpp中添加OpenGL初始化和绘制代码
  5. 编译并运行 点击Xcode中的"Run"按钮,如果成功会出现一个黑色窗口并绘制一个白色三角形。
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>

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

  // 初始化GLUT库
  glutInit(&argc, argv); 
  // 设置显示模式
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  // 创建窗口
  glutCreateWindow("OpenGL Demo");

  // 调用绘制函数
  glutDisplayFunc(DrawScene);

  // 启动消息循环
  glutMainLoop();

  return 0;
}

// 绘制函数
void DrawScene(){
  // 清空颜色缓冲
  glClear(GL_COLOR_BUFFER_BIT);
  // 绘制一个三角形
  glBegin(GL_TRIANGLES);
    glVertex2f(-0.5, -0.5);
    glVertex2f(0.5, -0.5); 
    glVertex2f(0, 0.5);
  glEnd();

  // 交换缓冲区
  glFlush();
}

如何配置Define GL_SILENCE_DEPRECATION to silence these warnings?

  • OpenGL代码所在的cpp文件中,在包含OpenGL头文件之前定义:
cpp
Copy code
#define GL_SILENCE_DEPRECATION
#include <OpenGL/OpenGL.h>
  • 或者在编译设置的Other C++ Flags中加上: -DGL_SILENCE_DEPRECATION

这将定义GL_SILENCE_DEPRECATION宏,告诉OpenGL头文件屏蔽deprecated的函数调用警告。

  1. 解决版本兼容问题

《深入理解OpenGL,WebGL和OpenGL ES》

性能优化

画面流畅的建议

“随着机器、驱动程序版本等因素的改变,帧速率也将随之改变,这将在不同的机器上产生不可预料的动画速率。但是,时间则是以恒定速度流动的,不管帧速率如何。更高的帧速率应该会产生更平滑的动画,而不是更快的动画。”

// 基于时间的动画
static CstopWatch rotTimer;
float yRot = rotTimer.GetElapsedSeconds() * 60.0f;

// 而不是,基于帧
yRot += 1.0f;
m3dRotationMatrix44(mRotate, m3dDegToRad(yRot), 0.0f, 1.0f, 0.0f);

矩阵定义

GLfloat matrix[16];       // Nice OpenGL friendly matrix
GLfloat matrix[4][4];     // Popular, but not as efficient for OpenGL

着色器优化

一个着色器性能优化的常规原则是,将尽可能多的处理过程移出片段着色器而放入顶点着色器

  • 开销很大的正弦和余弦函数,从片段着色计算转移到顶点着色器中
uniform matrix mvp;
in vec4 position;
in float angle;

out mat2 rotation_matrix;

void main(void)
{
  const float sin_theta = sin(angle);
  const float cos_theta = cos(angle);
  rotation_matrix = mat2(cos_theta, sin_theta,
          -sin_theta, cos_theta);
  gl_Position = mvp * position;
}
uniform sampler2D sprite_texture;

in mat2 rotation_matrix;

out vec4 color;

void main(void)
{
  const vec2 pt = gl_PointCoord – vec2(0.5);
  color = texture(sprite_texture, rotation_matrix * pt + vec2(0.5));
}

参考

OpenGL学习:learnopengl.com/

OpenGL学习(中文版):learnopengl-cn.github.io/

《计算机图形学》

《OpenGL超级宝典 第五版》