初识OpenGL,环境搭建

一. 环境搭建

需要准备资源 GLTools 工具类和libGLTools.a文件 如下:

包含了一个可移动正方块的demo:

https://github.com/TeeMoYan/OpenGLTest.git

1.打开XCode,新建一个项目! Xcode -> macOS -> Cocoa Application

2.添加 OpenGl.framework GLUT.framework两个系统库


3.添加准备的资源include和libGLTools.a资源

4.在Bulid Settings 输入Header Search path 中拖入include,生成路径

5.删除不同文件


5.创建main.cpp文件    ( c++



6.复制如下代码到main.cpp

#include "GLTools.h"

#include <glut/glut.h>

//程序入口

int main(int argc,char* argv[]){

}

到此环境搭建完成!此时编译将会通过!(注意将include资源和.a放在同一个目录下)

二 . 一些术语

顶点(vertexs)

OpenGL中的图形是有大量的顶点和顶点之间的连线构成的,可以说,顶点是OpenGL图形的基础单元

着色

沿着顶点之间改变颜色值,能够轻松创建关照照射子啊一个立方体上的效果。

纹理贴图

不过是一个用来贴到三角形或多边形上的图片。在GPU上,纹理是快捷有效的

混合

将不同的颜色混在一起

通常着色器分两种:

1顶点着色器(vertex shader)这个是告诉电脑如何打线稿的——如何处理顶点、法线等的数据的小程序。

2片面着色器(fragment shader)这个是告诉电脑如何上色的——如何处理光、阴影、遮挡、环境等等对物体表面的影响,最终生成一副图像的小程序。

 什么叫管线? 

管线(pipeline),可以理解为渲染流水线。管线,实际上指的是一堆原始图形数据途经一个输送管道,期间经过各种变化处理最终出现在屏幕的过程)管理的。图形渲染管线可以被划分为两个主要部分:第一部分把你的3D坐标转换为2D坐标,第二部分是把2D坐标转变为实际的有颜色的像素。

 什么叫固定管线?

可以简单理解为渲染图像的这个过程,我们只能通过调用GLShaderManager类的固定管线效果实现我们一系列的着色器处理。

 什么可编程管线?  

可以简单理解, 在我们处理图形的过程,我们必须使用顶点着色器和片元着色过程。我们可以才有GLSL自行编写着色器程序,来执行这个过程的事情。

 举例:    假设是一家制造肥皂的工厂,如果是固定管线生产,我们投入肥皂水(顶点数据等)通过管线生产出来的可能是比较固化的肥皂,方的、圆的等等。自由性差了许多。 而如果是可编程管线造肥皂,那我们可以在肥皂水倒入磨具过程中,通过程序修改它的造型。比如修改成桃心等。


客户机、服务

管线分为上下2部分,上部分是客户端, 下半部分则是服务端。

客户端是存储在CPU存储 中的,并且在应 程序中执行 ,或者在主系统内存的驱动程序中执行。驱动程序会将渲染命令和数组组合起来,发送给服务 执 !(在 台典型的个 计算机上,服务 就是实际上就是图形加速卡上的硬件和内存)

服务  和 客户机在功能上也是异步的。 它们是各 独 的软件块或硬件块。我们是希望它们2个端都尽 在 停的 作。客户端 断的把数据块和命令块组合在 起输送到缓冲区,然后缓冲区就会发送到服务 执行。

如果服务器停止工 作等待客户机,或者客户机停止工 作来等待服务器 做好接受更多的命令和准备,我们把这种情况成为管线停滞

图上(primitive Assembly说明的是:3个顶点已经组合在 起, 三 形已经逐个 段的进  光栅化。每个 段通过执 元着  进 填充。 元着  会输出我们将屏幕上看到的最终颜 值

我们必须在这之前为着色器 提供数据,否则什么都无法实现!

有3种向OpenGL着  传递渲染数据的 法可供我们选择:

shader的三种变量类型

uniform变量一般用来表示:变换矩阵,材质,光照参数和颜色等信息;如果在vertex和fragment两者之间声明方式完全一样,则它可以在vertex和fragment共享使用;只读常量数据;

attribute变量是只能在vertex shader中使用的变量;一般用attribute变量来表示一些顶点的数据,如:顶点坐标,法线,纹理坐标,顶点颜色等;

属性总是以四维向 的形式进 内部存储的,即使我们 会使 所有的4个分 。 个顶点位置可能存储(x,y,z),将占有4个分 中的3个。实际上如果是在平 情况下:只要在xy平 上就能绘制,那么Z分 就会 动设置为0;

这 些属性只提供给顶点着  使 ,对于 片元着 木  有太 大意义

纹理 varying变量是vertex和fragment shader之间做数据传递用。一般vertex shader修改varying变量的值,然后fragment shader使用该varying变量的值。因此varying变量在vertex和fragment shader二者之间的声明必须是一致的。application不能使用此变量。

矩阵变换

模型-视图-投影(MVP)矩阵的概念:

模型矩阵--将物体坐标变化成世界坐标

视图矩阵--将世界坐标变换成眼睛坐标

投影矩阵--将眼睛坐标变换成裁剪坐标

在固定管线OpenGL中,模型-视图矩阵可以用glRotatef,glTranslatef,glScalef等函数创建;可编程管线已不可用这些函数,可在应用程序中处理

图元(primitives)

图元可以理解为组成图形的基本单元。比如点、线、三角形。 我们可以通过一系列函数或顶点数据帮助我们实现多种多样的图形。OpenGL中绘制几何图元,必须使用glBegin(GLenum mode)和glEnd()这一对函数!

图元支持类型

阶段1.  顶点 ->图元

几何顶点被组合为图元(点,线段或多边形),然后图元被合成片元,最后片元被转换为帧缓存中的象素数据。

阶段2.  图元  ->片元

图元被分几步转换为片元:图元被适当的裁剪,颜色和纹理数据也相应作出必要的调整,相关的坐标被转换为窗口坐标。最后,光栅化将裁剪好的图元转换为片元。

1) 裁剪

在裁剪时点,线段和多边形处理略微不同。对于点,要么保留原始状态(在裁剪体内部),要么被裁掉(在裁剪体外部)。对于线段和多边形来说,如果部分在裁剪体外部,则需要在裁剪点生成新的几何顶点。对于多边形,还需要在新增的顶点间增加完整的边。不论裁剪了线段还是多边形,都需要给新增几何点赋予边界标志、法线、颜色和纹理坐标信息。

裁剪过程时两步:

a 应用程序指定裁剪(Application-specific clipping),一旦组合图元完成后,如果在程序中用glClipPlane()函数定义了任意的裁剪面,就进行裁剪。

b 视景体裁剪(View volume clipping),随后,图元被投影矩阵投影(进入裁剪坐标系),被相应的视景体裁剪。投影矩阵可以由glFrustum() 或者glOrtho()定义,投影矩阵的操作和上面其他矩阵变换的操作相同。

2) 转换到窗口坐标

裁剪坐标在转换为窗口坐标之前,要除以规格化设备坐标(normalized device coordinates)的w值进行规范化。然后对这些规范化数据进行视口变换(viewport)计算生成窗口坐标。可以用glDepthRange()和glViewport()控制视口大小,决定屏幕上显示图象的区域。

光栅化

光栅化是将一个图元转变为一个二维图象(其实只是布满平面,没有真正的替换帧缓存区)的过程。二维图象上每个点都包含了颜色、深度和纹理数据。将该点和相关信息叫做一个片元(fragment)。(yuyu注:这就是片元和像素之间的关键区别,虽然两者的直观印象都是的像素,但是片元比像素多了许多信息,在光栅化中纹理映射之后图元信息转化为了像素)在这个阶段,对象素绘制和位图进行操作需要用到当前栅格位置(用glRasterPos*()定义)。正如上面讨论的,三种图元的光栅化方法是不同的,另外,象素块和位图也需要光栅化。

官方翻译成栅格化或者像素化。没错,就是把矢量图形转化成像素点儿的过程。我们屏幕上显示的画面都是由像素组成,而三维物体都是点线面构成的。要让点线面,变成能在屏幕上显示的像素,就需要Rasterize这个过程。就是从矢量的点线面的描述,变成像素的描述。

如下图,这是一个放大了1200%的屏幕,前面是告诉计算机我有一个圆形,后面就是计算机把圆形转换成可以显示的像素点。这个过程就是光栅化。

存储着色器的使用

//定义着色器

GLShaderMananger shaderManager;

//初始化着色器

shaderManager.InitalizeStockShaders()

//使用

shaderManager userStockManager(参数列表)

• 单位着色器 UserStockShader(GLT_ATTRIBUTE_VERTEX,GLfloat vColor[4]);

只是简单地使 默认笛卡尔坐标系(坐标范围(-1.0, 1.0))。所有的 段都应 同 种颜 , 何图形为 实 和未渲染 的。 需要设置存储着 个属性: GLT_ATTRIBUTE_VERTEX(顶点分 ) 参数2:vColor[4],你需要的颜 

 • 平面着色器 

UserStockShader(GLT_SHADER_FLAT,GLfloat mvp[16],GLfloat vColor[4]);

 • 上色着色器 

UserStockShader(GLT_SHADER_SHADED,GLfloat mvp[16]);

 • 默认光源着色器 

UserStockShader(GLT_SHADER_DEFAULT_LIGHT,GLfloat mvMatrix[16],GLfloat

• 点光源着色器 

UserStockShader(GLT_SHADER_DEFAULT_LIGHT_DIEF,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vColor[4]);

 • 纹理替换矩阵 

UserStockShader(GLT_SHADER_TEXTURE_REPLACE,GLfloat mvMatrix[16],GLint nTextureUnit);

 • 纹理调整着色器

UserStockShader(GLT_SHADER_TEXTURE_MODULATE,GLfloat mvMatrix[16],GLfloat vColor[4],GLint nTextureUnit);

 • 纹理光源着色器 

UserStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vLightPos[3],GLfloat vBaseColor[4],GLint nTextureUnit); 

常用函数

glutInit() 负责初始化GLUT库。它会处理向程序输入的命令行参数,并且移除其中与控制GLUT如何操作相关的部分。它必须是应用程序第一个GLUT函数,负责设置其他GLUT例程必需的数据结构。

glutInitDisplayMode() 设置了程序所使用的窗口类型。窗口设置更多的OpenGL 特性,例如RAGA颜色空间,使用深度缓存或动画效果。

glutInitWindowsSize() 设置所需的窗口大小,如果不想在这个设置一个固定值,也可以先查询显示设备的尺寸,然后根据计算机的屏幕动态设置窗口的大小。

glutCreateWindow(),它的功能和它的名字一样,如果当前的系统环境可以满足glutInitDisplayMode()的显示模式要求,这里就会创建一个窗口(此时会调用计算机窗口系统的接口)。只有GLUT创建了一个窗口之后(其中包含创建创建OpenGL环境的过程),我们才可以使用OpenGL相关的函数

glewInit()函数,属于另一个辅助库GLEW(OpenGL Extention Wrangler)。GLEW可以简化获取函数地址的过程,并且包含了可以跨平台使用的其他一些OpenGL编程方法。

glutDisplayFunc(),它设置了一个显示回调(diplay callback),即GLUT在每次更新窗口内容的时候回自动调用该例程

glutMainLoop(),这是一个无限执行的循环,它会负责一直处理窗口和操作系统的用户输入等操作。(注意:不会执行在glutMainLoop()之后的所有命令。)

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

推荐阅读更多精彩内容