OpenGL笔记(二)

笔记(答案见后)

1. 如何配置OpenGL库?

2. C++中,从磁盘加载数据到CPU有哪些步骤?

3. 在写shader的时候,用于检查错误的时候除了要用到glGetShaderiv(),还会用到什么函数用来报错?

4. char log[512] 如何cout整个字符数组?

5. 两个正交的向量叉乘会产生什么?

6. 在GLSL中,用vec4*vec4可以吗?

7. 新渲染管线中,怎么用OpenGL画四边形?

8. Unity里贴图一般是用正方形贴图,如果要做游戏最好是用正方形,因为现在即使很多设备已经开始支持长方形,但是仍有低端设备只支持正方形贴图。
如下图:
在这里插入图片描述
none是原图的尺寸,to larger或toSmaller是换成正方形贴图

9. OpenGL的贴图uv坐标数值具体怎么从着色器中传递呢?片元着色器通过哪个函数取得纹理贴图的uv坐标?

10. 在用到纹理贴图的时候, 根据教程用到了stb_image库的头文件,对于一张特定的rgb或者rgba的图,可以用以下函数存储贴图数据:

GLint height, width, nrChannel;
unsigned char* data1 = stbi_load("container.jpg", &width, &height, &nrChannel, 0);

所以data存储的是什么信息?

扫描二维码关注公众号,回复: 6498380 查看本文章

11. 注意,texture和buffer类型不同,所以生成texture的时候,用的函数是glGenTextures而不是glGenBuffers.

12. glm三个常用函数的格式:
glm::translate,glm::rotate和glm::scale函数

13. 注意,glm::mat4 matrix1,在glm0.98(包括0.98)版本之前,默认矩阵为单位矩阵,但是在0.99之后,默认矩阵为零矩阵
所以要想创建单位矩阵应该这么写:

glm::mat4 matrix1=glm::mat4(1.0f);

14. 学习了一个新的函数,用于将矩阵的数据传入uniform中。

15. 在坐标变换中,旋转、平移和缩放的顺序是?

16. 注意,

glm::rotate(glm::mat4 matrix1),glm::vec3(1.0f,0,0));

这个函数的旋转矩阵是对matrix1左乘还是右乘?

17. 在实际操作中,从模型坐标系转换到世界坐标系好说,但是怎么从世界坐标系转换到观察坐标系?

18. 记录下来 关于怎么计算MVP矩阵更高效,什么时候在GPU上,什么时候在CPU上?

19. 关于Z-buffer,即depth-buffer,深度缓冲?

20. LookAt矩阵是怎么来的?

21. MVP矩阵分别用到哪几个函数?

22. Warning2: glm函数中:
glm::cross(cameraFront, cameraUp )glm::cross(cameraUp,cameraFront )所得到的向量是相反的。
而且 glm::vec3才是真正的向量,不能直接写成(1.0f,0.5f,0.6f)的形式.

23. 什么是drawcall?

24.学到了一些很实用的电脑快捷键操作,比如:
a.怎么按键删除该行?
b.怎么搜索?
c.怎么替换?
d.怎么选择一个方框里的所有内容?
e.重命名?

25.在C#中,看到了这些东西:///、#region,是什么意思?

笔记答案

1.其实就是配置glew和glfw的库,需要在VS的项目属性中增加三个操作:
一.添加头文件的配置路径
在这里插入图片描述
将两个头文件所在的路径加入目录中。

二.添加lib文件的配置路径
在这里插入图片描述
即将lib文件库的所在路径加入附加库目录

三.输入具体库的名称
在这里插入图片描述
因为设置了库的路径,但是没有指明要具体加载哪些库文件

2.C++通过文件流的方式传输文件:
一. 通过streambuffer的形式,C++创建文件流filestream 打开磁盘上的数据,读入内存。

二. 文件流的格式有很多种,所以streambuffer的形式不适合C++读取,所以要把它转化为stringstreambuffer的字符串的形式

三.但是CPU只吃char *(字符数组)类型,并没有string这个概念,所以要把stringBuffer再转换成string ,再最后换成char *类型

如下图所示:
在这里插入图片描述

3. 会用到这个函数
void glGetShaderInfoLog(GLuint shader,GLsizei maxLength,GLsizei *length,GLchar *infoLog);
函数作用:获取着色器的信息日志,说白了就是搞清除到底哪里错了。

glGetShaderInfoLog尽可能多地在infoLog中返回信息日志,最多可返回maxLength个字符。实际返回的字符数(不包括空终止字符)由length指定。 如果不需要返回字符串的长度,则可以在length参数中传递NULL值。 可以通过调用值为GL_INFO_LOG_LENGTH的glGetShaderiv来获取存储返回的信息日志所需的缓冲区大小。

着色器对象的信息日志是一个字符串,其中可能包含诊断信息,警告信息以及有关上次编译操作的其他信息。 创建着色器对象时,其信息日志将为长度为0的字符串。

4. cout<<log<<endl;

5. 会产生一个与两个向量都垂直的第三个向量,一起可以组成直角坐标系。
在这里插入图片描述

6. 可以,比如:
在这里插入图片描述

2019.1.16
我们现在看到的glBegin()、glRectf()以及glEnd()这些函数都是以前固定管线模式中所使用的API函数。 所以说以前的GL_POLOGON已经不适用了
注意:GL_QUADS, glEdgeFlag and glPolygonMode are not supported in OpenGL ES.
现在的OpenGL只支持三种图元:点,线和三角形,所以如果要画四边形,需要把基本图元换成线

9. 首先传入顶点着色器,顶点着色器内部会完成三角形遍历的操作,然后再把UV坐标原封不动的传给片元着色器。
特别注意的是,GLSL为了方便向片元着色器传入纹理,设置了一个内置的数据类型:sampler(采样器),
比如:uniform sampler2D ourTexture;//2D贴图
通过texture()函数可以从给定的贴图中取得顶点着色器的uv坐标对应的颜色。
在这里插入图片描述
texture函数,第一个参数是传入的贴图,第二个是指定的Uv坐标,然后会返回一个vec4的颜色值。

10. data是按照rgb或rgba的顺序,将所有的点按颜色顺序存储起来,比如

for(int i=0;i<size;i++)
cout<<(int)data[i];

就可以输出所有的像素点 的rgb值

2019.1.21
14. 在shader中写了uniform之后,要把具体的参数值传入uniform之中.
所以需要两步操作:
第一,获取名叫xx的uniform的地址。
第二,将要导入的信息导入uniform之中。

unsigned int uniformLocation1=glGetUniformLocation(programId,name);
glUniformMatrix4fv(uniformLocation1,1,GL_FALSE,glm::value_ptr(dataOfMatrix));

第二个参数是矩阵的个数,第三个参数是是否需要将矩阵转置,最后一个将矩阵资料转换成uniform特定格式的指针。

15. 先缩放,再旋转,再平移 ,至于为什么不是先旋转再缩放,这个暂时还不清楚

16. 是右乘,因为没有必要左乘,所以是建立一个单位矩阵trans,最终的变换矩阵:
trans=TranslateMat*RotateMat*ScaleMat 这个顺序,而实际顺序是反的,心里明白就行

17. remain 明天看

18. 在这里插入图片描述在这里插入图片描述
也就是说,GPU确实更擅长计算矩阵运算,但是送到GPU上面的运算每帧都会计算,所以如果MVP矩阵不变,可以先从CPU计算后传进去GPU,但如果M矩阵一直在变,(比如物体在旋转),就可以在CPU中计算不变的VP矩阵穿进去,再在GPU中和变化的M矩阵相乘

19. GLFW库自动会提供一个Buffer,每个片元都存储了其深度,也就是深度缓冲,别忘了OpenGL还有一个自动的颜色缓冲区,当深度更大的时候,其颜色会被抛弃,也叫深度测试,关于开启深度测试,很简单:

glEnable(GL_DEPTH_TEST);  //开启属性
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   //在每一帧清除颜色缓冲的时候,同时也清除深度缓冲

注意是GL_DEPTH_TEST不是GL_DEPTH

2019.1.23
20. 根据摄像机在世界坐标系的位置,和在摄像机坐标系中的原点相减,可以得到相机朝向的一个轴1,再任取一个向量,用叉乘取得轴2,再对轴1和轴2取叉乘可以得到轴3。
轴1、2、3即可形成相机坐标系的三条正交轴,可以组成LookAt matrix:
在这里插入图片描述
在这里插入图片描述
GLM库自动化简了这个过程,第一个坐标是摄像机在世界坐标系的坐标,
第二个是摄像机在观察空间的坐标
第三个是(任意给的,目前是我猜的,也有可能统一规定是这个)给定的轴2,参数1减去参数2 再和轴2 正交可以得出轴3.

21.
ModelMat: glm::translate、glm::rotate、glm::scale; //目的:对模型进行变换
ViewMat: glm::lookAt(); //给三个向量,目的就俩:确定摄像机位置和确定看的方向
ProjectionMat: glm::perspective(); //给投影平截头体的参数 ,角度,near,far和aspect 目的:确定投影在哪

23. 调用一次glDrawElements或者glDrawArrays就是调用一次draw call
不论是Unity或其它引擎,减少Draw Call无非就是尽可能少用材质
在这里插入图片描述
http://www.manew.com/4702.html

2019.1.25
24.学到了一些很实用的电脑快捷键操作,比如:
a.怎么按键删除该行?
ctrl+L
b.怎么搜索?
ctrl+I
c.怎么替换?
ctrl+H
d.怎么选择一个方框里的所有内容?
ctrl+alt+键盘(或鼠标)
e.重命名?
F2

///注意是反斜线,跟C++注释的方向正好相反,///是XML注释,不是一般的注释。
XML注释: extensible Markup Language (可拓展标志语言)
具体作用如下,总之是一种注释语言:
1.能够生成一个XML文件。这样呢看起来会对程序的内容一目了然。
2.以这种方式对你的类,属性,方法等等加上注释之后,当你在其他地方使用以这种方式加上的类,属性,方法等等地时候,黄色的提示框里面会把你写的注释显示出来,是你更加明白你要使用的功能的作用。

至于#region,是一种方便文档布局的文字
比如#region .....#endregion 就可以收起所写的代码

猜你喜欢

转载自blog.csdn.net/alexhu2010q/article/details/86658429