OpenGL是一种用于创建实时3D图像的编程接口。
走向3D
三维(3D)表示一个正在描述或显示的物体具有三个维度:宽度,高度,深度。几个世纪以来,艺术家们已经知道如何让一幅画有立体感并具有真实感的深度,通过颜料在二维画布上创作的作品,它其实本质上画的是一个二维物体。类似,计算机3D图像实质上也是平面的,它只是在计算机屏幕上所显示的二维图像,但它可以提供深度的错觉。实际上如果我们需要一个物体的二维画面从不同角度上感知三维空间,我们可以通过透视、隐藏直线消除、颜色、着色和其他技巧来创建深度幻觉。
2D + 透视 = 3D
3D图形术语
- 变化&投影
- 光栅化:实际绘制或填充每个顶点之间的像素形成过程
- 着色:沿着顶点之间改变颜色值。着色器则是图形硬件上执行的单独程序,用来处理顶点和光栅化任务。
- 纹理贴图:初学可以简单理解为贴到图形上的图片(但纹理并不是图片, 二者不等价)。在GPU上,纹理是快捷有效的。
- 混合:混合是将不同的颜色混合在一起。
3D图形的常见用途
实时3D图形的应用范围包括交互式游戏和模拟数据的可视化显示(供科学、医学或商业应用);
在计算机领域,3D图形的应用几乎没有止境。目前最常见的用途,游戏、AR、VR,都是基于openGL的。3D图形在科学视觉和工程应用中非常流行,物美价廉的3D硬件大量涌现使得这些应用技术空前的流行火爆。
Mac OS X以及iOS都是使用openGL对所有窗口和控件进行渲染,从而创建了功能强大,引人入胜的可视化界面。
例如设计使用的3D Max, 游戏制作的Unity 3D, Cocos2D底层都是使用了openGL。医学上的影像渲染也是依托于openGL。
着色器
在实时计算机图形中,最前沿的技术是可编程着色器(Programmable Shading)。图形卡不再是低能的渲染芯片。而是功能强大的高度可编程的渲染计算机。类似CPU的术语GPU应运而生。它代表图形处理单元,特指当今图形卡上的可编程芯片。它们是高度并行,并且具有非常快的速度。同样重要的是, 程序员可以进行重新配置图形卡的工作方式,几乎可以实现任何想要得到的特殊效果。
3D编程的基本原则
- 并发工具包
openGL基于一种底层渲染API,我们不能告诉它“在什么地方绘制”, 而是我们需要自己动手,通过载入三角形,应用必要的变化和正确的纹理、着色器并在必要应用混合模式来组合一个模型。这使得我们能够进行大量的底层控制,与使用高层工具包相比,使用openGL这样的底层API动人之处在于,我们不能仅仅是重现许多标准3D渲染,我们可以创造自己的算法,甚至可以取发现一些新的捷径、性能技巧和艺术视觉技术。 - 坐标系统
在openGL或几乎所有的3D API中创建一个用于绘图窗口时, 必须制定希望使用的坐标系统以及指定的坐标如何映射到实际的屏幕像素。
OpenGL在Mac上的环境搭建
准备资源
- CLTools
- glew
- libGLTools.a
这些资源都可以从网上下载到
配置Xcode的openGL环境
-
打开Xcode -> macOS -> Cocoa Application
image.png -
添加OpenGL.framework 和 GLUT.framework 两个系统库
image.png -
libGLTools.a直接拖到工程的Frameworks文件里面,另外删除文件:AppDelegate.h、AppDelegate.m、main.m、ViewController.h、ViewController.m;创建main.cpp文件
image.png
image.png
image.png
image.png -
在main.cpp中复制以下代码, 来测试环境是否配置成功:
#include <stdio.h>
#include "GLTools.h"
#include <GLUT/GLUT.h>
GLBatch triangleBatch;
GLShaderManager shaderManager;
//窗口大小改变时接受新的宽度和高度,其中0,0代表窗口中视口的左下角坐标,w,h代表像素
void ChangeSize(int w,int h)
{
glViewport(0,0, w, h);
}
//为程序作一次性的设置
void SetupRC()
{
//设置背影颜色
glClearColor(0.0f,0.0f,1.0f,1.0f);
//初始化着色管理器
shaderManager.InitializeStockShaders();
//设置三角形,其中数组vVert包含所有3个顶点的x,y,笛卡尔坐标对。
GLfloat vVerts[] = {
-0.5f,0.0f,0.0f,
0.5f,0.0f,0.0f,
0.0f,0.5f,0.0f,
};
//批次处理
triangleBatch.Begin(GL_TRIANGLES,3);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
}
//开始渲染
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_IDENTITY着色器,这个着色器只是使用指定颜色以默认笛卡尔坐标第在屏幕上渲染几何图形
shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
//提交着色器
triangleBatch.Draw();
//将在后台缓冲区进行渲染,然后在结束时交换到前台
glutSwapBuffers();
}
int main(int argc,char* argv[])
{
//设置当前工作目录,针对MAC OS X
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);
//GLUT窗口大小,标题窗口
glutInitWindowSize(800,600);
glutCreateWindow("Triangle");
//注册回调函数
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
//驱动程序的初始化中没有出现任何问题。
GLenum err = glewInit();
if(GLEW_OK != err) {
fprintf(stderr,"glew error:%s\n",glewGetErrorString(err));
return 1;
}
//调用SetupRC
SetupRC();
glutMainLoop();
return 0;
}
- 编译, 将报错的地方文件
<>
系统引入, 改为“”
普通引入
效果图
image.png那么环境搭建到此就成功了。
网友评论