OpenGL系列之1 - 初识OpenGL

前言:

这是OpenGL的的简单介绍。分为三个部分:

  1. OpenGL的简单认识
  2. 本地搭建OpenGL的环境
  3. OpenGL的部分术语

内容:

一. OpenGL的简单认识

  1. OpenGL的Wikipedia 介绍地址: https://en.wikipedia.org/wiki/OpenGL#Development

Open Graphics Library (OpenGL is a cross-language, cross-platform application programming interface (API) for rendering 2D and 3D vector graphics. The API is typically used to interact with a graphics processing unit (GPU), to achieve hardware-accelerated rendering.

  1. 官方对于OpenGL ES的介绍地址:https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008793-CH1-SW1

OpenGL ES allows an app to harness the power of the underlying graphics processor. The GPU on iOS devices can perform sophisticated 2D and 3D drawing, as well as complex shading calculations on every pixel in the final image.

  1. OpenGL的案例展示:


  2. OpenGL在iOS开发中中的应用范围:

    开放图形库(Open Graphics Library:OpenGL) 被用来展示2D和3D数据,它是一个多用途的开放标准图形库,支持2D、3D数字内容的创建,机械和建筑设计、虚拟原型、飞行模拟、视频游戏等多种应用。您可以使用OpenGL配置3D图形管线并提交数据。顶点被转换和点亮,组成原始图像,进行光栅化后生成2D图像。OpenGL旨在将函数调用转换为可发送到底层图形硬件的图形命令,该底层硬件专门用于处理图形命令,因此OpenGL绘图通常非常快。
    OpenGL for Embedded Systems(OpenGL ES)是OpenGL的简化版本(专门为嵌入式系统设计,在移动端操作系统中应用广泛),该版本消除了冗余功能,提供了更易学习且易于在移动图形硬件中实现的库。

二.OpenGL在Mac上面的环境搭建:
1. 搭建过程:

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

  1. 代码见传送门

三. OpenGL基本的术语了解:

  1. 代码类及函数介绍:
#include "GLShaderManager.h"
/*
  固定管线!
 `#include<GLShaderManager.h>` 移入了GLTool 着色器管理器(shader Mananger)类。
没有着色器,我们就不能在OpenGL(核心框架)进行着色。
着色器管理器不仅允许我们创建并管理着色器,还提供一组“存储着色器”,
他们能够进行一些初步䄦基本的渲染操作。
 */
#include "GLTools.h"
/*
 `#include<GLTools.h>`  GLTool.h头文件包含了大部分GLTool中类似C语言的独立函数
*/
#include <GLUT/GLUT.h>
/*
 在Mac 系统下,`#include<glut/glut.h>`
 在Windows 和 Linux上,我们使用freeglut的静态库版本并且需要添加一个宏
*/
//定义一个,着色管理器
GLShaderManager shaderManager;
//简单的批次容器,是GLTools的一个简单的容器类。
GLBatch triangleBatch;
//blockSize 1/2边长
GLfloat blockSize = 0.1f;
GLfloat vVerts[] = {
    -blockSize,-blockSize,0.0f,
    blockSize,-blockSize,0.0f,
    blockSize,blockSize,0.0f,
    -blockSize,blockSize,0.0f
};
//x轴上移动的距离
GLfloat xPos = 0.0f;
//y轴上移动的距离
GLfloat yPos = 0.0f;
/*
 在窗口大小改变时,接收新的宽度&高度。
 */
void changeSize(int w,int h)
{
    /*
      x,y 参数代表窗口中视图的左下角坐标,而宽度、高度是像素为表示,通常x,y 都是为0
     */
    glViewport(0, 0, w, h);
    
}

void RenderScene(void)
{
    
    //1.清除屏幕颜色
    glClear(GL_COLOR_BUFFER_BIT);
    
    //2.设置画笔颜色 RGBA
    GLfloat vRed[] = {1.0f,0.0f,0.0f,1.0f};
    
    //利用矩阵帮助移动
    //mFinalTransform 结果矩阵
    //mTransformMatrix 平移矩阵
    //mRotationMatrix  旋转矩阵
    M3DMatrix44f mFinalTransform,mTransformMatrix,mRotationMatrix;
    
    //平移 x,y,z,w(缩放因子= 1)
    //3D中平移的原理与矩阵之间关系
    /*
     参数1:矩阵
     参数2、3、4:X,Y,Z上平移距离
     */
    m3dTranslationMatrix44(mTransformMatrix, xPos, yPos, 0.0f);
    
    
    //增加难度! 一边移动,一边旋转
    static float yRot = 0.0f;
    
    /*
     参数1:矩阵
     参数2:弧度
     参数3:X:1,0 1:围绕X轴旋转,0不围绕X轴旋转
     参数4:Y:1,0
     参数5:Z:1,0
     */
    m3dRotationMatrix44(mRotationMatrix, m3dDegToRad(yRot), 0.0f, 0.0f, 1.0f);
    
    //修改旋转度数
    yRot += 5.0f;
    
    //思考:结合2个矩阵的结果 平移矩阵 * 旋转矩阵 = 最终结果矩阵
    m3dMatrixMultiply44(mFinalTransform, mTransformMatrix, mRotationMatrix);
    
    
    //平面着色器
    /*
     1.平移矩阵 mTransformMatrix 与 每个顶点 相乘 -> 新顶点 (顶点着色器)
     2.将片元着色红色 (片元着色器)
     */
    shaderManager.UseStockShader(GLT_SHADER_FLAT,mFinalTransform,vRed);
    
    
    
    //单元着色器(类型,颜色)---第一种方法用到的
    //shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
    
    triangleBatch.Draw();
    
    //从后台缓存区进行渲染
    glutSwapBuffers();
    
    
    
    
}

//移动图形 -- 修改图形坐标!
void SpeacialKeys(int key,int x,int y)
{
    //步长
    GLfloat stepSize = 0.025f;
    
    //计算移动距离
    if (key == GLUT_KEY_UP) {
        yPos += stepSize;
    }
    
    if (key == GLUT_KEY_DOWN) {
        yPos -= stepSize;
    }
    
    if (key == GLUT_KEY_LEFT) {
        xPos -= stepSize;
    }
    
    if (key == GLUT_KEY_RIGHT) {
        xPos += stepSize;
    }
    
    //边界检查
    if (xPos < -1.0f + blockSize) {
        xPos = -1.0f + blockSize;
    }
    
    if (xPos > 1.0f - blockSize) {
        xPos = 1.0f - blockSize;
    }
    
    if (yPos < -1.0f + blockSize) {
        yPos = -1.0f + blockSize;
    }
    
    if (yPos > 1.0f  - blockSize) {
        yPos = 1.0f - blockSize;
    }
    
     glutPostRedisplay();
    
   //第一种方法:通过修改坐标移动物体
   /*
    //步长
    GLfloat stepSize = 0.025f;
    //相对点 D点
    GLfloat blockX = vVerts[0];
    GLfloat blockY = vVerts[10];
    //上
    if (key == GLUT_KEY_UP) {
        blockY += stepSize;
    }
    if (key == GLUT_KEY_DOWN) {
        blockY -= stepSize;
    }
    if (key == GLUT_KEY_LEFT) {
        blockX -= stepSize;
    }
    if (key == GLUT_KEY_RIGHT) {
       
        blockX += stepSize;
    }
    
    //左边
    if (blockX < -1.0f) {
        blockX = -1.0f;
    }
    //右边
    if (blockX > 1.0 - blockSize * 2) {
        blockX = 1.0 - blockSize * 2;
    }
    if (blockY > 1.0f) {
        blockY = 1.0f;
    }
    if (blockY < -1.0f + blockSize * 2) {
        blockY = -1.0f + blockSize * 2;
    }
    
    //计算参考点移动,借助参考D 帮助实现4个顶点的修改。
    //A:
    vVerts[0] = blockX;
    vVerts[1] = blockY - blockSize * 2;
    //B
    vVerts[3] = blockX + blockSize * 2;
    vVerts[4] = blockY - blockSize * 2;
    //C
    vVerts[6] = blockX + blockSize * 2;
    vVerts[7] = blockY;
    //D
    vVerts[9] = blockX;
    vVerts[10] = blockY;
    triangleBatch.CopyVertexData3f(vVerts);
    glutPostRedisplay();
    */
    
}

void setupRC()
{
    //1.设置清屏颜色
    glClearColor(0.33, 0.45, 0.12, 1.0f);
    //初始化固定管线
    shaderManager.InitializeStockShaders();
    /*
    //指定三角形的顶点数据 x,y,z
    GLfloat vVerts[] = {
        -0.5f,0.0f,0.0f,
        0.5f,0.0f,0.0f,
        0.0f,0.5f,0.0f
    };
    */
    triangleBatch.Begin(GL_TRIANGLE_FAN , 4);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
}

int main(int argc,char *argv[])
{
    //设置当前工作目录,针对MAC OS X
    /*
     `GLTools`函数`glSetWorkingDrectory`用来设置当前工作目录。实际上在Windows中是不必要的,因为工作目录默认就是与程序可执行执行程序相同的目录。但是在Mac OS X中,这个程序将当前工作文件夹改为应用程序捆绑包中的`/Resource`文件夹。`GLUT`的优先设定自动进行了这个中设置,但是这样中方法更加安全。
     */
    gltSetWorkingDirectory(argv[0]);
    //初始化GLUT库,这个函数只是传说命令参数并且初始化glut库
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA);
    //GLUT窗口大小、窗口标题
    glutInitWindowSize(800, 600);
    glutCreateWindow("Triangle");
    /*
     GLUT 内部运行一个本地消息循环,拦截适当的消息。然后调用我们不同时间注册的回调函数。我们一共注册2个回调函数:
     1)为窗口改变大小而设置的一个回调函数
     2)包含OpenGL 渲染的回调函数
     */
    //注册重塑函数
    glutReshapeFunc(changeSize);
    //注册显示函数
    glutDisplayFunc(RenderScene);
    glutSpecialFunc(SpeacialKeys);
    /*
     初始化一个GLEW库,确保OpenGL API对程序完全可用。
     在试图做任何渲染之前,要检查确定驱动程序的初始化过程中没有任何问题
     */
    GLenum status = glewInit();
    if (GLEW_OK != status) {
        printf("GLEW Error:%s\n",glewGetErrorString(status));
        return 1;
    }
    //设置我们的渲染环境
    setupRC();
    glutMainLoop();
    return  0;
    
}

  1. 陌生的术语介绍:
  • 着色器

着色器(shader),专为图形处理单元(GPU)编译的一种小型程序。

  • 图元

图元是能够被OpenGL ES 绘制的几何物体,如三角形、线条或者精灵。

  • 光栅化

将输入图元的数学描述转换为与屏幕位置对应的像素片元,称为光栅化。

  • 纹理

最通常的作用是装饰我们的物体模型,它就像是贴纸一样贴在物体表面,使得物体表面拥有图案。但实际上在OpenGL中,纹理的作用不仅限于此,它可以用来存储大量的数据,一个典型的例子就是利用纹理存储地形信息。

  • 渲染

渲染(render),表示计算机从模型创建最终图像的过程。

  • 帧缓存

帧缓存(framebuffer),像素(pixel),是显示器上最小的可见单元。计算机系统将所有的像素保存到帧缓存当中,后者是有图形硬件设备管理的一块独立内存区域,可以直接映射到最终的显示设备上。

参考及拓展:

  1. https://www.jianshu.com/p/62fc87833ed5
    iOS开发-OpenGL ES魔方应用(简友博客)
  2. https://www.jianshu.com/p/c5ad4a3ed1a9
    初识OpenGL,环境搭建 (简友博客)
  3. https://www.jianshu.com/p/736401c03990
    第1章 OpenGL概述(简友博客)

代码传送门:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容