OpenGL ES 学习日志。
本文将学习OpenGL ES (超级宝典)记录下的日志,将同步到上,欢迎大家批评,顺便说一句,这本书 是第五版,俗称,蓝宝书
总结的几个名词,仅供个人参考。
- 渲染 : 将数学和图形数据转换成3D空间图像的操作叫做渲染。
- Transformation(变换) -- 通过变换,或者说旋转 这些点,并在他们之间绘制线段,我们就能在一个2D屏幕上创造出一个3D的世界错觉。
- 光栅化(Rasterization)实际绘制或填充每个点之间的像素,形成的线段就叫光删化。
- 纹理贴图(个人理解就是图片 贴合在绘制的2D图形上)
- 混合(个人理解就是将两个不同颜色的图片叠在一起,然后重叠的那个颜色 (当然了透明度肯定不是100%))
- 3D几何图形无非是将顶点间的点连接起来,然后对三角形进行光删化。而使得对对象变得有实体。变换,着色,纹理与混合。
- 还有一个很重要的概念就是(三维笛卡尔坐标系)--- 因为读书的时候并没有好好学习,所以,在理解笛卡尔三维坐标系上有很大的难度,但是网上有篇文章写的非常的清楚 网址在 "http://www.360doc.com/content/14/0302/15/13998280_357087559.shtml" 利用 太极,两仪,四象,八卦 来分析笛卡尔三维坐标系。其实把二维笛卡尔坐标系作为一个面,然后再加上一个坐标系,Z 使其成为一个立体的图形。
支持阵容
GLUT :框架,OpenGL 的主要的编程框架。
GLEW :开源库
GLTools:包含了一个用语言操作矩阵向向量的3D 数学库。
变量类型 和 字节长度。
OepnGL数据类型 | 最小位宽 | 描述 |
---|---|---|
GLBoolean | 1 | 真 or 假 |
GLbyte | 8 | 有符号的八位整数 |
GLubyte | 8 | 无符号的八位整数 |
GLChar | 8 | 字符串 |
GLShort | 16 | 有符号16位整数 |
GLuShort | 16 | 无符号16位整数 |
GLhalf | 16 | 半精度浮点数 |
GLint | 32 | 有符号的32位整数 |
GLuint | 32 | 无符号的32位整数 |
GLSizei | 32 | 无符号的32位整数 |
GLunem | 32 | 无符号的32位整数 |
GLFloat | 32 | 32位浮点数 |
GLclampf | 32 | 【0 - 1】范围内的32位浮点数 |
GLbitfield | 32 | 32位 |
GLdouble | 64 | 64位双精度 |
GLclampd | 64 | 【0 - 1】64位双精度 |
GLint64 | 64 | 有符号64位整数 |
GLuint64 | 64 | 无符号64位整数 |
GLSizeiptr | 本地操作系统指针大小 | 无符号整数 |
GLinptr | 本地操作系统指针大小 | 有符号整数 |
GLSync | 本地操作系统指针大小 | 同步对象句柄 |
openGL 并没有对指针和数组做特殊的考虑。我们可参考C语言声明一个100个GLshort变量的数组
GLShort shorts[100];
声明一个长度为100的指向 GLDouble 类型变量的指针数组
GLdouble *doubles[10];
OpenGL 错误
openGL 在内部保留了一组错误标志(共4个)其中每个标志代表着一种不同的数据类型的错误,当一个错误发生时,与这个错误相对应的标志就会被设置,可以调用 glGetError 这个函数
GLunem glGetError(void);
通常情况下,我们需要在循环中调用 上面的函数,直到返回 GL_NO_ERROR
为止
错误代码 | 描述 |
---|---|
GL_INVALID_ENUM | 枚举参数超出范围 |
GL_INVALID_VALUE | 数值参数超出范围 |
GL_INVALID_OPERATION | 在当前状态中操作非法 |
GL_OUT_OF_MEMORY | 没有足够的内存来执行这条命令 |
GL_NO_ERROR | 没有错误出现 |
OpenGL查询版本号 和 生产商有关的特定的信息
const GLubyte *glGetString(GLEnum name)
上面的的函数返回一个静态的字符串,描述GL 函数库中所请求的信息。
OpenGL 实用glHint获取线索
glHint函数允许我们制定片中于视觉质量还是速度,以适应各种不同类型的操作,简而言之 就是(速度 和 质量的 选择)
void glHint (GLenum target.GLEnum mode)
绘制第一个三角形
// Created by 张孝江 on 2020/10/8.
//
#define GL_SILENCE_DEPRECATION //为了解除警告的宏。
#include
#include
#include
//批处理
GLBatch batch;
//渲染
GLShaderManager shaderManager;
#pragma mark - 定义视口的大小 /窗口里面包含视口/。改变视口并不会改变坐标系,
void changeWindowsSize(GLint width , GLint height){
glViewport(0, 0, width, height);
printf("改变后的宽是%d\n,改变后的高是%d",width,height);
}
#pragma mark - 设置程序的一些属性
void setupRC(){
///设置程序窗口的颜色,
glClearColor(0, 0, 1, 1);
///初始化着色器
shaderManager.InitializeStockShaders();
///设置三角形的顶点数据 //从左到右。 因为 我们渲染的是一个三角形,所以 Y 轴的 点都为0.
//坐标是以屏幕的中心为原点的。左边- 右边+ 上+ 下- ,这样子就会有八个象限 立体来说。中国古人对于空间的理解是 混沌(点) -> 太极(线)->四象 -(平面 (笛卡尔 2D坐标系))-> 八卦(笛卡尔3D 坐标系。)
//此外,还有 左手坐标系,和 右手坐标系。
GLfloat vVters[] = {
//三角形第一个点在三维笛卡尔坐标系的位置
-0.5,-0.0f,-0.0f,
//三角形第二个点在三维笛卡尔坐标系的位置
0.0f,0.5f,0.0f,
//三角形第三个点在三维笛卡尔坐标系的位置
0.5f,0.0f,0.0f,
};
//处理数据
batch.Begin(GL_TRIANGLES, 3);
batch.CopyVertexData3f(vVters);
batch.End();
}
#pragma mark //画屏幕
void RenderScene (void){
//清除缓冲区的内容
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//设置三角形的填充颜色。
GLfloat vred[] = {1.0f,0.0f,0.0f,1.0f};
//传递到存储着色器,即GLT_SHADER_IDENITY 着色器
shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vred);
//提交着色器
batch.Draw();
//将在后台缓冲区进行渲染 然后交换到前台
glutSwapBuffers();
}
//按键使视图进行变化
void specilalkeys(int key,int x,int y){
GLfloat c = 0.25f;
GLfloat vVters[] = {
-0.5,0.0f,0.0f,
0.0f,0.5f,0.0f,
0.5f,0.0f,0.0f,
};
if (key == GLUT_KEY_UP) {
vVters[4] +=c;
}
if (key == GLUT_KEY_DOWN) {
vVters[4] -=c;
}
if (key == GLUT_KEY_LEFT) {
vVters[0]-=c;
}
if (key == GLUT_KEY_RIGHT) {
vVters[0]+=c;
}
batch.CopyVertexData3f(vVters);
glutPostRedisplay();
}
///main 函数
int main(int argc,char * argv[])
{
/*设置当前的工作目录 (针对macOS)*/
gltSetWorkingDirectory(argv[0]);
/*初始化GLUT*/
glutInit(&argc, argv);
/*初始化双缓冲窗口,其中标志GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL分别指
双缓冲窗口、RGBA颜色模式、深度测试、模板缓冲区*/
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
/*设置初始值窗口大小*/
glutInitWindowSize(313,218);
/*设置窗口的标题*/
glutCreateWindow("我的第一个三角形");
/*注册回调函数 此函数可监听窗口大小的改变 切 glView*/
glutReshapeFunc(changeWindowsSize);
/*注册函数回调 绘制屏幕 上面函数一旦发生改变,下面的函数就立刻执行绘制。*/
glutDisplayFunc(RenderScene);
/*为了让其移动注册回调函数*/
glutSpecialFunc(specilalkeys);
/*驱动程序初始化过程中可能遇到的问题。说上有说名*/
GLenum err = glewInit();
if(GLEW_OK != err) {
fprintf(stderr,"glew error:%s\n",glewGetErrorString(err));
return 1;
}
/*绘制三角形*/
setupRC();
glutMainLoop();
return 0;
}