计算机图形学与OpenGL

电脑截图一片泛白的原因和解决:
    原因:系统显示设置里开启了HDR,
    解决:想办法关闭掉HDR就好, 或者通过Chrome里的设置修改为sRGB也可以
          chrome://flags , color profile修改为sRGB即可

 

计算机图形学的常见算法:
 1.求交算法: 包含:判断是否相交 和 求出交点
    1.1判断两直线段是否有交 : 通过判断以直线段为对角线的2矩形是否相交(如果不相交,就两线段不会有交点)
        (1) 快速排斥试验: 判断两个矩形是否有交的算法=>
              最大值最小值法则: 每个矩形在每个方向上的坐标最大值都要大于另一个矩形在这个坐标方向上的坐标最小值,否则在这个方向上就不能保证一定有位置重叠。使用计算叉积算法
          (2)  跨立试验 ;跨立,指的是一条线段的两端点分别位于另一线段所在直线的两边; 还要用到矢量叉积的几何意义
            //跨立试验只是证明两条线段有交点的必要条件

 2.点和多边形关系的算法实现
    射线法可能遇到的各种交点情况

 3.求多边形外包矩形的算法 : 遍历多边形的所有节点,找出各个坐标方向上的最大最小值

Ray Tracing in One Weekend :GitHub - RayTracing/raytracing.github.io: Main Web Site (Online Books)

(中文翻译):https://raytracing.github.io/books/RayTracingInOneWeekend.html#outputanimage/theppmimageformat

OpenGL是一个图形库,而要画图,就需要先创建一个窗口。不幸的是,OpenGL并没有提供创建窗口的功能,必须自己创建窗口。而创建窗口在每一个操作系统上都不同的,为了方便,我们会使用一个窗口库来简化这一过程。

常用的OpenGL窗口库有 :GLUT、GLFW和SDL;使用得比较多的GLFW。

GLAD是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要初始化GLAD。GLAD也可以使OpenGL基础渲染变得简单。
   简单点说,GLFW用来创建窗口给opengl的上下文(context)绘图,glad用来调用上下文中的函数,GLAD可以简化调用OpenGL函数的操作。
   GLAD在线服务: https://glad.dav1d.de/

OpenGL是由显卡驱动支持的,显卡已经提供了我们需要的OpenGL函数。因此就需要在运行程序时动态地获取函数地址

<1>可能搭配使用的各个库的介绍:

   GLEW : 能自动识别你的平台所支持的全部OpenGL高级扩展函数。也就是说,只要包含一个glew.h头文件,你就能使用 gl,glu,glext,wgl,glx的全部函数.
               // OpenGL Extension Wrangler

  GLFW :一个轻量级的,开源的,跨平台的(C) library; 用来管理窗口、上下文和surface, 读取输入和处理事件等; 
               支持OpenGL及OpenGL ES和Vulkan on desktop.
              // Graphics Library Framework

  GLAD :

  glut :太老了,最后一个版本还是90年代的

  freeglut :完全兼容glut,算是glut的代替品,功能齐全,但是bug太多,稳定性也不好。

  GLM: 是个很有用3D数学库.  //OpenGL Mathematics

  SOIL2 : Simple OpenGL Image Library2

<2>OpenGL的版本:  OpenGL 4.6版本是最后的版本了,而它的新的图形接囗Vulkan(有的人叫OpenGL5)

<3>glClearColor(r,g,b,a) 与 glClear(bitmask):

      glClearColor函数设置好清除颜色,glClear利用glClearColor函数设置好的当前清除颜色设置窗口颜色.

环境配置:
 
 GLFW:可通过源码(cmake)->VS工程->build得到库 或 直接在官网上下载binary  
   GLAD: 通过在线服务选择产生对应的zip后下载使用   
 配置参考: https://blog.csdn.net/Violent_zyy/article/details/115698935
   https://blog.csdn.net/Jormungand_V/article/details/126441491
  

  CMAKE
  glfw : https://www.glfw.org/  //最好下载源码,通过Cmake build出VS工程,再生成库
  GLEW: http://glew.sourceforge.net/  
  GLM : https://github.com/g-truc/glm  
  SOIL 2 :  https://github.com/SpartanJ/SOIL2

制作VS项目模板,方便每创建OpenGL的环境设置
glfw :
   glfw3.lib :
     Release: D:\Softs\Study\OpenGL\glfw-3.3.3\build\src\Release
     Debug :  : D:\Softs\Study\OpenGL\glfw-3.3.3\build\src\Debug
 glfw的include文件目录 : D:\Softs\Study\OpenGL\glfw-3.3.3\include\GLFW

//找不到glew32.dll的解决办法? 把glew32.dll拷贝到build出来的exe同级目录下即可

简要代码逻辑:

int main(void) {
	if (!glfwInit()) { exit(EXIT_FAILURE); }
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	GLFWwindow *window = glfwCreateWindow(600, 600, "First OpenGL", NULL, NULL);
	glfwMakeContextCurrent(window);
	if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
	glfwSwapInterval(1);

	init(window);

	while (!glfwWindowShouldClose(window)) {
		display(window, glfwGetTime());//glfwGetTime()返回的是glfw初始化之后经过的时间
		glfwSwapBuffers(window); //交换缓冲区(GLFW窗囗默认是双缓冲的),以绘制屏幕
		glfwPollEvents(); //处理窗囗相关事件(如按键事件)
	}
	glfwDestroyWindow(window); //销毁窗囗
	glfwTerminate(); //终止运行
	exit(EXIT_SUCCESS);
}

OpenGL4.0版本(2010年),在可编程管线中增加了一个细分阶段。

通过WindowHints()设置了4.3版本,作用是指定了机器必须与OpenGL版本4.3兼容。

GLFW窗囗默认是双缓冲的(即有两个颜色缓冲区,一个显示,一个渲染,渲染整个帧后将交换缓冲区。缓冲用于减少不良的视觉伪影

display(,)函数中传递glfwGetTime(),是方便保证动画在不同计算机上以相同的速度播放。得到的是GLFW初始化之后经过的时间。

图元有: 指点、线、三角形。

顶点着色器按顶点处理,片段着色器按片段(即像素)处理,几何着色器按图元处理

顶点着色器会执行上千甚至百万次,且这些执行通常是并行的。

曲面细分着色器:生成大量三角形,通常是网格形式。
几何着色器应用:可以让图元变形(拉伸、缩小),还可以删除一些图元(从而在渲染的物体上产生"洞"),也提供生成额图元的方法。
              是简单模型转为复杂模型的方法。
      有趣的用法:环面模型(水抱),在物体上增加表面纹理(如凸起、鳞甚至毛发),从而达到需要的效果,
                 而不是增加三角形数这样的高代价做法。

2D屏幕由光栅----矩形像素阵列组成;
3D物体经过光栅化后,图元 -> 片段,对三角形的每对顶点进行插值(一般线性插值就好了)

数据类型使用GL开头的(如GLuint),主要是为了实现跨平台(即平台无关的).

glUseProgram()并没有运行着色器,它只是将着色器加载到硬件GPU中来。

  #version 430
  void main(void){ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
内置变量gl_Position是用来设置顶点在3D空间的坐标位置(只能在顶点着色器中使用);
  #version 430
  out vec4 color;
  void main(void){ color = vec4(0.0, 0.0, 1.0, 1.0); }
片段着色器中,out标签表明color变量是输出变量--在顶点着色器中并不是必须给gl_Position指定out标签,因为gl_Position是预定义的输出变量。

 VAO :Vertex Array Object,顶点数组对象

当准备将数据集发送给管线时,是以缓冲区形式发送的,这些缓冲区最后都会被存入顶点数组对象VAO中。
即使应用程序完全没有使用到任何缓冲区,但OpenGL仍需要在使用着色器的时候至少有一个创建好的VAO,即需要这两行
   glGenVertexArrays(numVAOs, vao);
   glBindVertexArray(vao[0]);

GL_PointSize, 默认1个像素。
在片段着色器中,可使用用gl_FragCoord.x基于位置设置每个像素的颜色在,如:
        if(gl_FragCoord.x < 300)color = vec4(1.0,0.0,0.0,1.0); else color = vec4(0.0,0.0,1.0,1.0);

隐藏面消除:根据深度缓冲区(Z-Buffer),即哪个对象最接近观察者(摄像机)来保留哪个像素的颜色:
   如果距离少于深度缓冲区存储的值,那么用当前像素颜色替换颜色缓冲区中的颜色,
   同时用当前距离替换深度缓冲区中的值,否则抛弃当前像素。

计算机图形学与OpenGL_第1张图片

对于每一个 VAO,只存在一个 EBO

GLSL : 
 layout 变量叫做  attribute 变量, GPU 会进行插值
 相对于上面的变量,另外一种是不进行插值的变量,叫uniform 变量
 uniform float a; //从C++传进 Shader
   glGetUniformLocation()获取变量索引; 再 glUniform1f();
 如果不加 uniform,则变量只能在Shader中使用
 也可以在fragment 中传 uniform 变量
 特殊的 uniform,叫 texture
 创建 texture 与创建 buffer 很像:也要Gen, Bind
  glGenTexture()
  glBindTexture
  //texture有若干个属性选项,常用的4个选项必须要设置:
  宽高要2的n次方才生效
  glTexParameter
 
  glPixelStore(); //必须4字节(4的倍数)对齐,可以先1字节对齐(但性能差一些)
  glTexImage2D(,GL_RGB(GPU端按什么...),...,GL_RGB(CPU内存端))
 纹理单元, 通常 OpenGL 支持32个纹理单元,OpenGLES支持16个纹理单元

一般的图像坐标:原点在左上角,x正方向向右,y轴正方向向下
纹理坐标:0~1,且从左下角到右上角
OpenGL中的坐标:-1~1· 
所以映射出来的图片是上下颠倒的.

你可能感兴趣的:(OpenGL,图形学)