计算出每一帧耗费的时间
1.在头文件中加入time.h,cpp中实现如下计算时间接口
float GetFrameTime(){static unsigned long long lastTime=0,currentTime=0;timeval current;gettimeofday(¤t, nullptr);//取当前时间currentTime = current.tv_sec * 1000 + current.tv_usec/1000; //s to ms and vs to msunsigned long long frameTime = lastTime==0?0:currentTime - lastTime;lastTime = currentTime;return float (frameTime)/1000.0f; //输出结果为s
}
引入外部的数学库
1.cpp文件中加入GLM的数学库,头文件中加入如下头文件
//引入数学库
#include "Glm/glm.hpp"
#include "Glm/ext.hpp"
齐次坐标与缺省的3D坐标系
1.普通坐标 x,y,z表示[1,2,3],齐次坐标是[1,2,3,1] ,x/w y/w z/w 是真正的3D坐标表示
2.OpenGL坐标系中心为(0, 0, 0)为坐标系原点,其中x,y的坐标方向遵循笛卡尔坐标系,z轴坐标从屏幕原点指向我们,方向为正,想要显示需要推到原点的后面,所以z坐标取负值。
3.CPP中点的初始化定义
struct Vectice{float mPosition[4];//x,y,z,w
};//顶点初始化部分Vectice vertices[3];//CPU -> GPUvertices[0].mPosition[0]=0.5f; //xvertices[0].mPosition[1]=0.5f; //yvertices[0].mPosition[2]=2.0f; //zvertices[0].mPosition[3]=1.0f; //wvertices[1].mPosition[0]=0.5f;vertices[1].mPosition[1]=0.5f;vertices[1].mPosition[2]=2.0f;vertices[1].mPosition[3]=1.0f;vertices[2].mPosition[0]=0.0f;vertices[2].mPosition[1]=0.5f;vertices[2].mPosition[2]=2.0f;vertices[2].mPosition[3]=1.0f;
渲染时的正反面(CCW与CW)的定义
1.CCW逆时针表示图形正面 ; CW顺时针表示图像反面
2.图元都是基于三角形
详解VBO(VertexBufferObject)
1.用来存放vertex 顶点坐标,作为gpu的一段换从空间,可以把cpu上面的数据缓存到次数,gpu执行的时候可以在此读取不需要进行多次cpu->gpu的拷贝操作
GLuint vbo;//vertex buffer object 存放顶点缓冲区的对象glGenBuffers(1,&vbo);//需要1个VBO,把vbo写入到显卡进去,供后续操作glBindBuffer(GL_ARRAY_BUFFER,vbo);//把vbo设置到卡槽上//glBufferData(GL_ARRAY_BUFFER,sizeof(Vectice)*3, nullptr,GL_STATIC_DRAW);//只在GPU上开辟内存不传数据//glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(Vectice)*3,vertices);//加入数组,0指vbo偏移位置glBufferData(GL_ARRAY_BUFFER,sizeof(Vectice)*3,vertices,GL_STATIC_DRAW);//cpu -> gpu,向GL_ARRAY_BUFFER加入数据glBindBuffer(GL_ARRAY_BUFFER,0);//卡槽重新绑定,防止误操作
详解GPU的工作流程
1.shader通常称为着色器,作用是把CPU上的点渲染出来。
2.shader是并行的。
3.流程:数据data (顶点数据) ----->VS(输入:data的顶点数据,输出:gl_Position的 vec4 顶点数据)----->光栅化处理(显卡自动负责,把点连成生成面,其中包括一定像素)------>FS(输入:光栅器的输出的像素,输出画面);注意VS和FS点会同时被并行执行,多个点可以同时处理。
最简单的Shader代码
1.Vertext shader (顶点着色器)
/*vec4是齐次坐标 vector.xyzw 其中xyzw 可以任意组合
vector.rgba 其中rgba 可以任意组合
vector.stpq 其中rgba 可以任意组合
*/
attribute vec4 position; //vec4是齐次坐标
uniform mat4 U_ModelMatrix; //mat4是4x4矩阵 ,模型矩阵需要从C++传递过来
uniform mat4 U_ViewMatrix; //视口矩阵需要从C++传递过来
uniform mat4 U_ProjectionMatrix; //投影矩阵需要从C++传递过来
void main(){//自右向左,模型空间下的点-》世界坐标系-》视口矩阵转到视口空间,摄像机看到的带你-》屏幕空间gl_Position = U_ProjectionMatrix * U_ViewMatrix * U_ModelMatrix * position;
}
2.Fragment shader (片元着色器)
void main(){gl_FragColor = vec4(1.0,1.0,1.0,1.0); //gl_FragColor是输出点的颜色
}
详解Attribute和Uniform关键字
1Uniform,使用的一些变量都是一样的使用Uniform。
2.Attribute,随着属性组变化使用Attribute。
4.varying ,主要负责在vertex 和 fragment 之间传递变量。
3. OPenGLES2.0最多支持8个属性组,3.0支持16个。
更多相关参考
详解3D渲染管线
1.MVP(M,模型矩阵;V,视口矩阵;P,投影矩阵)
自右向左,世界坐标系----------》模型空间下的点-----》视口矩阵转到视口空间,摄像机看到的带你---------》屏幕空间