
OpenGL
超級码力
Keep Reading , Keep Writing , Keep Coding.
展开
-
Xcode上创建openGL项目
创建opengl项目步骤1,创建一个Cocoa的项目。 2,将项目中的AppDelegate.h,AppDelegate.m,MainMenu.xib文件删除。然后将main.m文件删除,改为main.cpp文件。 3,将include文件(OpenGL超级宝典5版源码里有这个文件)和libGLTools.a(mac上的动态库)导入到项目里。 4,在项目设置,Build Phases下的Lin原创 2015-03-16 17:33:46 · 4395 阅读 · 4 评论 -
OpenGL--阴影
理论基础 阴影:就是我们所说的影子,其实现原理其实就是把场景渲染了两次,第一次是把相机放到光源位置渲染场景 ,然后存储渲染的深度信息到一张纹理上,即阴影图(只关心深度信息,所以此时可以关闭光照和纹理贴图提高效率)。第二次再从观察者的角度来渲染场景,在这次渲染时才渲染阴影,这次的渲染过程本质就是纹理贴图,只不过这个纹理是阴影图,贴图的方式根据我们设置的深度纹理过滤方式处理。生成阴影的过程是这样的:对原创 2015-04-24 15:47:18 · 7238 阅读 · 3 评论 -
OpenGL--骨骼动画
理论基础骨骼蒙皮动画其实现类似人体模型,由节点(关节)树构成,节点间通过骨骼连接,每块骨骼至多一个父节点,父节点带动子骨骼运动。具体是关节带动其对应子骨骼运动从而牵动绑定到其上的皮肤变化。骨骼是刚体不会变形,只能绕父节点旋转(构造前面章节有提–3D世界实现中的机器人手臂例子,早期的骨骼动画就是这样,不过在关节处会有明显裂缝,所以才引出现在的蒙皮概念)。而绑定到其上的皮肤顶点则是实时变换拉伸的,变换原创 2015-05-30 16:56:56 · 8682 阅读 · 4 评论 -
OpenGL--抗锯齿
理论基础 1,锯齿:在图元边缘处我们能相当清楚地看到两种颜色的分界,我们把这种称之为锯齿。为什么会产生?这是因为我们的图像是由一个个像素组成的,而每个像素近似一个很小的正方形,这样由正方形组成的图像边缘肯定会产生锯齿。示意图如下: 2,抗锯齿:常见的抗锯齿方法有两种:混合和多重采样。使用混合消除锯齿的原理是,在边缘处降低alpha值再做混合操作从而达到欺骗眼睛的目的。然而混合操作受绘制顺序的原创 2015-04-11 15:15:29 · 4917 阅读 · 0 评论 -
OpenGL--光照
理论基础 1,人眼所看到的五颜六色的世界是由于物体表面反射到眼睛的颜色形成的,而这个反射颜色是由物体本身和光源共同决定的。某种颜色的物体反射对应颜色的光,吸收其它颜色的光,如红色物体吸收全部的G,B颜色,反射全部的R颜色。opengl把光单独分成4种类型:环境光(均匀充满场景),散射光(手电筒),镜面光(朝特定一方向反射),发射光(夜明珠)。他们单独计算,最后叠加在一起,构成整个光照系统。原创 2015-04-10 09:41:23 · 2181 阅读 · 0 评论 -
opengl入门
基本概念1,OpenGL:是图形硬件的一种软件接口。通俗点讲就是一套API,调用接口而已,用于图像的渲染。与微软的Direct类似,不过它是跨平台的。 2,OpenGL渲染管线:是指从调用OpenGL图形程序到图形最终渲染到屏幕的实现过程。其实就是OpenGL底层代码执行的一个流程。具体流程是这样的:它首先是一个CS的架构模式,它的程序允许通过网络运行,运行图形程序并发出绘图命令的计算机称为客户机原创 2015-03-17 11:36:09 · 3109 阅读 · 0 评论 -
OpenGL--粒子系统
理论基础 1,粒子系统的基本思想是用许多形状简单且赋予生命的微小粒子作为基本元素来表示物体(一般由点或很小的多边形通过纹理贴图表示),侧重于物体的总体形态和特征的动态变化。把物体定义为许多不规则,随机分布的粒子,且每个粒子均有一定的生命周期。随着时间的推移,旧的粒子不断消失(死亡),新的粒子不断加入(生长)。粒子的这种出生,成长,衰老和死亡的过程,能够较好地反映模糊物体的动态特性。因此它比起传统的原创 2015-05-21 10:32:06 · 16089 阅读 · 11 评论 -
OpenGL--3D世界(视图变换,模型变换,投影变换,视口变换)
理论基础 1,OpenGL渲染3D物体到屏幕上的过程其实类似我们平时用照相机拍照的过程,这个步骤大致如下:一,把照相机固定在三脚架并让它对准场景(视图变换)二,把场景中的物体调整摆放好(模型变换)三,选择照相机的镜头,并调整放大倍数(投影变换)四,确定最终照片的大小(视口变换)。其中视图变换必须要在模型变换之前,其它可以在任何时候。 2,视图变换:设置摄像机的位置,gluLookAt(摄像机位置原创 2015-03-25 13:59:55 · 12412 阅读 · 1 评论 -
OpenGL--shader入门
理论基础实例代码//源程序#include "GLTools.h"#include "GLShaderManager.h"#ifdef __APPLE__#include #else#define FREEGLUT_STATIC#include #endifGLuint v, f, f2,p;GLint loc;//文件读取(将本地shader文原创 2015-03-31 17:05:12 · 4618 阅读 · 0 评论 -
OpenGL--多重纹理
理论基础 多重纹理是指在同一个模型表面指定两个或两个以上的纹理,这些纹理通过一定的融合方式进行混合形成的效果。其每一层各自执行自己的纹理操作,并把结果传递给下一层,直到全部完全。主要应用在如:光照效果,贴花,合成,细节纹理等。 代码示例#include <GLTools.h>#ifdef __APPLE__#include <glut/glut.h>#else#define FREEGL原创 2015-04-22 19:49:46 · 5477 阅读 · 0 评论 -
OpenGL--雾
理论基础 雾效果:计算机图像有时候由于过于清晰和锐利,反而显得不太逼真。我们可以通过添加雾效果,使整幅图像变得更加逼真。所谓雾效果,就是使远处的物体看上去逐渐变得模糊。雾效果可以提高性能,因为它可以不绘制那些因为雾的影响而不可见的物体。其实现原理其实就是根据雾距离观察点的距离计算出一个混合因子,然后用它把雾颜色与目标颜色进行混合得到的效果。实例代码 1,RGBA模式下的5个雾化球体#inclu原创 2015-04-13 10:45:38 · 3284 阅读 · 0 评论 -
OpenGL--环境映射
理论基础 三维场景中得物体不仅受光照影响,而且受周围环境的影响,如金属,水面等材质都可以映射出周围环境的图像。模拟物体光滑表面能够映射出周围环境的技术叫做环境映射(也称反射映射)。 其原理是通过立方体纹理(cube)实现的,具体是:把摄像机放在反射物体旁边,分别朝6个方向照得6张纹理,组成立方体纹理。然后就是利用这个立方体纹理通过一些复制的计算,把反射纹理映射到我们的光亮物体表面,从而形成物体反原创 2015-04-22 12:00:21 · 4036 阅读 · 2 评论 -
OpenGL--多级纹理
理论基础 多级纹理(Mipmap):就是分辨率递减的同一纹理,根据距离观察点的距离选着最适合的分辨率纹理。 它主要解决两方面问题:一,闪烁,当屏幕上被渲染物体的表面与它所应用的纹理图像相比显得非常小时,就会出现闪烁。尤其当相机和物体在移动的时候,这种负面效果更容易被看到。二,性能问题,加载了大量的纹理数据之后,还要对其进行过滤处理(缩小),在屏幕上显示的只是一小部分。纹理越大,所造成的性能影响就原创 2015-04-21 10:50:32 · 3269 阅读 · 0 评论 -
OpenGL--混合
理论基础 混合:主要就是用来做一些如透明的特效,其实就是源颜色与目标颜色(先写入帧缓冲的是目标颜色,后将要写入的是源颜色)进行混合计算得到一个新颜色的过程。混合发生在图元光栅化之后,片段写入帧缓冲之前,片段与对应位置的帧缓冲区像素进行互操作形成新的像素颜色的过程及时混合。需要通过glEnable(GL_BLEND)来激活混合功能,否则的话片段直接覆盖对应像素。颜色的alpha分量值此时就会发挥作用原创 2015-04-10 16:47:34 · 2105 阅读 · 0 评论 -
OpenGL--天空盒
理论基础1,目前虚拟场景中天空建模常用的方法有天空顶(SkyDome:半球形)和天空盒(SkyBox:长方体)两种方法。其本质都是摄像机处在一个盒子中间,这个盒子通过纹理贴图形成的虚拟世界场景。其中天空盒绘制技术非常简单,因此被广泛应用。然而,有时也会存在一些问题,例如使用雾效时,如果雾被设置在观察者的旁边,天空盒将减淡甚至消失。另一个更坑爹的问题是雾会聚积在天空盒的顶点处,从而使天空盒的多边形暴露原创 2016-12-08 16:13:28 · 19293 阅读 · 10 评论 -
OpenGL--摄像机漫游
理论基础在3D游戏中,我们通常可以通过鼠标或键盘操纵角色英雄在场景中移动,从不同的角度观察物体,这其实就是本章要介绍的摄像机漫游。 关于摄像机漫游其实就是围绕一个函数实现的(通过改变视点以及观察方向来实现),具体的函数为OpenGL中辅助函数库中的gluLookat(),通过设置相应的参数实现场景的漫游效果。函数如下: void gluLookAt(GLdouble eyex,GLdouble原创 2016-11-28 17:07:28 · 11814 阅读 · 3 评论 -
OpenGL--GLSL基础
Shader简介首先简单介绍一下Shader是什么,Shader意为着色器,只是整个图形渲染管线流程中的某几个单元,也可以理解为图形渲染管线中的几处会被执行的代码,Shader主要包括:顶点Shader,片段Shader以及几何Shader这3种。那么顶点,片段和几何分别是什么呢?顶点很好理解,如要绘制一张图片,一般是一个由四个顶点组成的图形。就是我们读书那会几何学里的顶点一个意思。片...原创 2018-05-27 22:47:10 · 935 阅读 · 0 评论 -
OpenGL--模板测试
理论基础 模板测试:通俗点讲就是为屏幕每个像素设置了一个模板值,然后拿一个参考值与之比较,满足条件就通过,则对应像素就会绘制,否则不绘制。类似深度测试一样,只是服务情形不同,深度测试主要用来消除背面的,而模板测试主要可以实现裁剪,指明哪里可以绘制,哪里不绘制。(比较规则:glStencilFunc,修改模板缓冲区的值:glStencilOp)代码示例1,模板实现裁剪实例#include "GLT原创 2015-04-25 17:17:37 · 2503 阅读 · 0 评论 -
OpenGL--帧缓冲区
理论基础 1,帧缓冲区(显存):是由像素组成的二维数组,每一个存储单元对应屏幕上的一个像素,整个帧缓冲对应一帧图像即当前屏幕画面。帧缓冲通常包括:颜色缓冲,深度缓冲,模板缓冲和累积缓冲。这些缓冲区可能是在一块内存区域,也可能单独分开,看硬件。而像素数据在进入帧缓冲之前(称为片段)必须通过一系列测试才能写入帧缓冲,如果片段在其中某个测试没有通过,后面的测试或操作都将不再进行。这些测试或操作流程是:开原创 2015-04-27 11:05:21 · 6852 阅读 · 0 评论 -
OpenGL--图元
基础概念 1,图元:组成3D物体最小的单位,包括:点,直线,多边形。就和化学里所有物体都是由原子组成的一样。 2,点:数学上的点,只有位置,没有大小。但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点。另一方面,无论图形输出设备(例如,显示器)如何精确,始终不能输出一个无穷小的点。默认情况下,OpenGL中的点将被画成单个的像素,虽然它可能足够小,但并不会是无穷小。同一像素上,Ope原创 2015-03-18 17:20:42 · 2985 阅读 · 0 评论 -
OpenGL--顶点数组与缓冲区中使用顶点数组
理论基础法线向量:简称法线,是一条垂直于某个表面的方向向量。opengl中除了顶点之外,不能为多边形的其他地方分配法线。法线的作用是定义了物体的表面在空间中的方向,具体地说就是,定义了它相对于光源的方向。opengl就是使用法线向量来确定这个物体的各个顶点所接收的光照。(glNormal*()设置顶点法线)顶点数组:就是把一些顶点数据保存到数组中储存,这些数据包括:顶点坐标,表面法线,RG原创 2015-03-21 17:43:55 · 3935 阅读 · 0 评论 -
OpenGL--双缓冲
双缓冲 就是先将图片绘制到后台缓冲区,然后再交换到前台缓冲区显示。为什么要这么做?一种解释是我们的渲染一般是多线程处理,如果直接绘制到屏幕显示,有可能会出现一张图片还只绘制一部分而下一张又来了的情况,使屏幕看上去在抖动的感觉。所以增加一个后台缓冲区,先绘制到后台,然后直接整张完整的图交换到前台,这样就可以流畅的显示了。实例代码#include "GLTools.h"#include "GLS原创 2015-03-17 16:16:30 · 3655 阅读 · 0 评论 -
OpenGL--纹理组合器函数
理论基础 纹理组合器函数(glTexEnvf):简单点讲就是指定纹理贴图和材质混合的方式。固定管线时代,它只是告诉你,纹理的像素读取出来之后,其实还可以经过一些复杂变换,然后才拿去使用,这样可以搞出一些绚丽效果。不过现在shader可以进行更多更自由的变换,所以这东西现在就没什么用了。实例代码#include "GLTools.h"#ifdef __APPLE__#include <glut/原创 2015-04-23 17:45:45 · 2311 阅读 · 0 评论 -
OpenGL--点参数
理论基础 点参数:在有些情况下,我们对如圆或球体的渲染时,不想用效率较低的多边形近似模拟。这时我们可以用点参数,它根据点和观察点的距离,对点的大小和亮度进行衰减。如:雨滴,飞溅的血滴等。代码示例#include "GLTools.h"#include "GLShaderManager.h"#ifdef __APPLE__#include <glut/glut.h>#else#define原创 2015-04-13 15:42:42 · 3273 阅读 · 0 评论 -
OpenGL--多边形偏移
理论基础 多边形偏移:有时候我们需要着重显示多边形的边缘,一般做法是先绘制实心的再在同一位置绘制空心的,这样就可以突出边缘。但是,由于直线与多边形的光栅化并不完全相同,即使在同一位置绘制它们的深度值也不一定相同,这样绘制的直线可能忽浓忽淡。这时我们就可以激活多边形偏移来解决这个问题,其原理就是给实体或线框的深度加上一个偏移值。即把实体推向远处或把线框拉近,具体偏移值多少是通过设置glPolygon原创 2015-04-13 17:48:23 · 4031 阅读 · 0 评论 -
OpenGL--位图
理论基础 位图:就是对应一些二进制位来操作像素,0则表对应像素不绘制,1表绘制,这样来模拟绘制图像。一般可以用来绘制字符,但位图无法做缩放或旋转等特效。位图示例图如下: 注:在opengl 3.0以后基本废弃了。实例代码#include "GLTools.h"#include "GLShaderManager.h"#ifdef __APPLE__#include <glut/glut.h>原创 2015-04-14 19:35:06 · 2871 阅读 · 0 评论 -
OpenGL--显示列表
理论基础 显示列表:是一组存储在一起的OpenGL函数,可以在以后执行。调用一个显示列表时,它所存储的函数就会按照顺序执行。类似存储在服务端(GPU)的缓冲区对象,能够提高效率。在创建显示列表时,只有表达式的值存储在显示列表中,并且这个值也不会再修改。还有像有返回值的函数与依赖客户端状态的函数都不能放在显示列表中。这主要是因为这样的函数需要依赖客服端数据与状态,但显示列表是存储在服务端的。注:在O原创 2015-04-14 10:24:31 · 2643 阅读 · 0 评论 -
OpenGL--替换纹理图像的全部或一部分
理论基础 和修改原有纹理相比,创建新纹理的开销更大。我们主要使用glTexSubImage*和glCopyTexSubImage*()来修改纹理,前者用于替换的纹理来源外部读取,后者替换的纹理来源自身帧缓冲区。实例代码#include "GLTools.h"#ifdef __APPLE__#include <glut/glut.h>#else#define FREEGLUT_STATIC原创 2015-04-20 15:30:10 · 5065 阅读 · 0 评论 -
OpenGL--纹理贴图基础
理论基础 纹理贴图:通俗地讲就是可以把我们读取的纹理加载到图元表面的一种技术,这样大大的提高了图像的表现质量。实例代码 //读取tga格式图片/*tga图片头信息结构*/#pragma pack(1)//结构体字节对齐typedef struct{ GLbyte identsize; // Size of ID field that follows he原创 2015-04-18 17:07:17 · 3390 阅读 · 1 评论 -
OpenGL--图像
理论基础 图像:它与位图相似,都是二进制位来表示屏幕对应像素,只是图像的每个像素并不是由1个位来表示的,它的每个像素包含更多地信息。即位图1个位对应1个像素,图像多个位对应1个像素。OpenGL图像操作归根结底就是对像素进行操作。示例图如下: 注释:这些东西现在也基本是废弃机制了.代码示例(图像的缩放与复制操作)#include "GLTools.h"#include "GLShaderMa原创 2015-04-15 14:34:19 · 2017 阅读 · 0 评论 -
OpenGL--自动生成纹理坐标
理论基础 纹理坐标自动生成:有两种形式,一种整形形式(glTexGeni),一种向量形式(glTexGenfv),使用它比手动设置纹理坐标方便(glTexCoord)。实例代码#include <GLTools.h>#ifdef __APPLE__#include <glut/glut.h>#else#define FREEGLUT_STATIC#include <GL/glut.h>原创 2015-04-21 14:49:42 · 5072 阅读 · 0 评论 -
OpenGL--贝塞尔曲线或曲面
理论基础 贝塞尔曲线和曲面:OpenGL只能直接绘制基本图元,对于曲线和曲面我们一般采用一系列线段或多边形来模拟的,这样当线段或多边形增多时必定很耗性能。其实对于这种曲线和曲面,我们可以使用一些控制点,通过求值器程序先计算出坐标等信息,然后直接用这些数据绘制,这样不仅节省内存,还提高了模拟曲线或曲面的精度(本质还是通过线段或多边形绘制的,只是求值器提前算出了曲线或曲面的顶点信息)。 求值器使用一原创 2015-04-29 10:32:37 · 12702 阅读 · 2 评论 -
OpenGL--选择和反馈
理论基础 选择和反馈:整的来说就是鼠标点击,然后算出到底点击的是哪个物体。在选择和反馈模式下,绘制信息返回给应用程序而不是像在渲染模式中那样送往帧缓冲,在这种模式下,屏幕将被冻结,没有图形出现。实现的一般步骤是:1,创建选择缓存,用于记录返回的点中物体信息 2,调用glRenderMode(GL_SELECT)进入选择模式 3,用glInitName(),glPushName()等来初始化名字栈原创 2015-04-29 17:09:32 · 3728 阅读 · 5 评论 -
OpenGL--分格化
理论基础 分格化:OpenGL渲染的都是一些简单的凸多边形,对于那些复杂的多边形,如凹多边形,含孔多边形以及自交叉的多边形,OpenGL函数库不能对他们进行渲染。不过OpenGL实用库(GLU)提供了一系列分格化函数,它们可以将一个复杂的多边形划分为一系列简单凸多边形,我们就把这个过程叫做分格化(又称网格化)。分格化一般步骤:1,创建分格化对象 2,注册对应阶段分格处理的回调函数(复杂点的是相交原创 2015-04-28 16:53:07 · 2559 阅读 · 1 评论 -
OpenGL--二次几何体
理论基础 二次几何体:就是指一些常用的三维物体,如球体,圆柱体,圆盘和圆锥体等,OpenGL核心库也不能直接模拟和渲染,但我们可以使用GLU库来创建这些二次几何体。创建和渲染二次几何体的过程:1,创建一个二次对象 2,注册一个错误回调 3,指定二次对象的渲染属性(绘制模式,法线类型,是否生成纹理坐标,法线方向) 4,调用二次几何体渲染函数 5,删除二次对象。注释:二次几何体opengl 3.1以原创 2015-04-28 19:14:22 · 2430 阅读 · 0 评论 -
OpenGL--使用Shader
创建Shader关于在OpenGL中怎么创建Shader这个在很早我博客中就有过详细介绍了。这里全当复习,温故而知新~ 在OpenGL中,存在Program和Shader两个概念,Program相当于当前渲染管线所使用的程序,是Shader的容器,可以挂载多个Shader。而每个Shader相当于一个C模块,首先需要对Shader脚本进行编译,然后讲编译好的Shader挂载到Program上...原创 2018-06-10 17:33:05 · 22877 阅读 · 3 评论