通过OpenGL ES在iOS平台实践增强现实(一)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了通过OpenGL ES在iOS平台实践增强现实(一),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5891字,纯文字阅读大概需要9分钟。
内容图文
http://ios.9tech.cn/news/2013/1108/38495.html
- 1.本文采用OpenGL ES 1固定渲染管线实现,目标为在设备拍摄到的现实世界中,绘制世界坐标轴,并根据设备所在位置和朝向,绘制周围一定范围内的指定目标(比如餐厅,咖啡馆等)。首先说明几个OpenGL的容易混淆的基础知识
- OpenGL采用右手坐标系(伸出你的右手,拇指和食指垂直,中指分别和拇指,食指垂直,此时拇指代表x坐标轴,食指代表y坐标轴,中指代表z坐标轴,这就是右手坐标系)
- OpenGL采用列向量,所以矩阵与向量运算为矩阵左乘
- OpenGL的glMutMatrixf等操作为右乘
- OpenGL采用列主序存储矩阵
- 2.下面为在iOS平台初始化绘制环境的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
self.context = context;
[EAGLContext setCurrentContext:context];
glGenFramebuffersOES(1, &_framebuffer);
// 创建帧缓冲区
glGenRenderbuffersOES(1, &_renderbuffer);
// 创建绘制缓冲区
glBindFramebufferOES(GL_FRAMEBUFFER_OES, _framebuffer);
// 绑定帧缓冲区到渲染管线
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _renderbuffer);
// 绑定绘制缓冲区到渲染管线
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, _renderbuffer);
// 绑定绘制缓冲区到帧缓冲区
GLint width;
GLint height;
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];
// 为绘制缓冲区分配存储区,此处将CAEAGLLayer的绘制存储区作为绘制缓冲区的存储区
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &width);
// 获取绘制缓冲区的像素宽度
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &height);
// 获取绘制缓冲区的像素高度
glGenRenderbuffersOES(1, &_depthbuffer);
// 创建深度缓冲区
glBindRenderbufferOES(GL_RENDERBUFFER_OES, _depthbuffer);
// 绑定深度缓冲区到渲染管线
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
// 为深度缓冲区分配存储区
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, _depthbuffer);
// 绑定深度缓冲区到帧缓冲区
glMatrixMode(GL_PROJECTION);
// 改变矩阵变换模式到投影矩阵,以后的矩阵操作都会是对投影矩阵操作
GLfloat w = 0.5 * tanf(M_PI / 8);
glFrustumf(-w, w, -w*height/width, w*height/width, 0.5, 3000);
// 视锥定义
glViewport(0, 0, width, height);
// 视口定义
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | - (void)getViewMatrix:(GLfloat *)matrix { GLfloat x = _orientation.x; GLfloat y = _orientation.y; GLfloat z = _orientation.z; GLfloat w = _orientation.w; GLfloat *rot = malloc(sizeof(GLfloat) * 16); rot[0] = 1-2*y*y-2*z*z; rot[1] = 2*x*y-2*w*z; rot[2] = 2*x*z+2*w*y; rot[3] = 0.0; rot[4] = 2*x*y+2*w*z; rot[5] = 1-2*x*2-2*z*z; rot[6] = 2*y*z-2*w*x; rot[7] = 0.0; rot[8] = 2*x*z-2*w*y; rot[9] = 2*y*z+2*w*z; rot[10] = 1-2*x*x-2*y*y; rot[11] = 0.0; rot[12] = 0; rot[13] = 0; rot[14] = 0; rot[15] = 1.0; GLfloat transX = -rot[0]*_position.x - rot[4]*_position.y - rot[8]*_position.z; GLfloat transY = -rot[1]*_position.x - rot[5]*_position.y - rot[9]*_position.z; GLfloat transZ = -rot[2]*_position.x - rot[6]*_position.y - rot[10]*_position.z; rot[12] = transX; rot[13] = transY; rot[14] = transZ; memcpy(matrix, rot, sizeof(GLfloat)*16); free(rot); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | - (void)getViewMatrix:(GLfloat *)matrix { GLfloat x = _orientation.x; GLfloat y = _orientation.y; GLfloat z = _orientation.z; GLfloat w = _orientation.w; GLfloat *rot = malloc(sizeof(GLfloat) * 16); rot[0] = 1-2*y*y-2*z*z; rot[1] = 2*x*y-2*w*z; rot[2] = 2*x*z+2*w*y; rot[3] = 0.0; rot[4] = 2*x*y+2*w*z; rot[5] = 1-2*x*2-2*z*z; rot[6] = 2*y*z-2*w*x; rot[7] = 0.0; rot[8] = 2*x*z-2*w*y; rot[9] = 2*y*z+2*w*z; rot[10] = 1-2*x*x-2*y*y; rot[11] = 0.0; rot[12] = 0; rot[13] = 0; rot[14] = 0; rot[15] = 1.0; GLfloat transX = -rot[0]*_position.x - rot[4]*_position.y - rot[8]*_position.z; GLfloat transY = -rot[1]*_position.x - rot[5]*_position.y - rot[9]*_position.z; GLfloat transZ = -rot[2]*_position.x - rot[6]*_position.y - rot[10]*_position.z; rot[12] = transX; rot[13] = transY; rot[14] = transZ; memcpy(matrix, rot, sizeof(GLfloat)*16); free(rot); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | - (void)render { glBindRenderbufferOES(GL_RENDERBUFFER_OES, _renderbuffer); // 绑定绘制缓冲区到渲染管线 //glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清空绘制缓冲区和深度缓冲区 glEnableClientState(GL_VERTEX_ARRAY); MZGLCamera *camera = self.camera; GLfloat *matrix = malloc(sizeof(GLfloat) * 16); [camera getViewMatrix:matrix]; glMatrixMode(GL_MODELVIEW_MATRIX); // 改变矩阵变换模式到模型矩阵 glLoadIdentity(); // 将模型矩阵更新为单位矩阵 glEnable(GL_DEPTH_TEST); // 开始深度测试 glDepthFunc(GL_LESS); // 切换深度测试模式为待绘制像素距离屏幕距离小于深度缓冲区当前值则绘制,否则不绘制 glLoadMatrixf(matrix); // 根据摄像机位置设置模型矩阵,此处的矩阵为摄像机世界矩阵的逆矩阵 glVertexPointer(3, GL_FLOAT, 0, _lineVertexBuffer); glColor4f(1.0, 1.0, 0.0, 1.0); glDrawElements(GL_LINES, _lineVertexCount, GL_UNSIGNED_BYTE, _lineIndexBuffer); // 绘制世界坐标系的坐标轴 glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); // 开启纹理绘制 glEnable(GL_ALPHA_TEST); // 开启Alpha测试 glAlphaFunc(GL_GREATER, 0.5f); // 切换Alpha测试模式为不透明度大于0.5则绘制,否则不绘制 glColor4f(1.0, 1.0, 1.0, 1.0); // 填充绘制缓冲区 NSArray *values = [self.entityDictionary allValues]; for (NSObject *entity in values) { if ([entity conformsToProtocol:@protocol(MZGLRenderable)]) { if ([entity isKindOfClass:[MZGLBillboard class]]) { MZGLBillboard *billboard = (MZGLBillboard *)entity; glVertexPointer(3, GL_FLOAT, 0, billboard.vertexBuffer); // 设置顶点缓冲指针 glTexCoordPointer(2, GL_FLOAT, 0, billboard.coordinates); // 设置纹理坐标指针 [billboard preRender:self]; glLoadIdentity(); GLfloat *transform = [billboard worldTrasform]; // 设置模型世界矩阵 glLoadMatrixf(matrix); // 将模型矩阵设置为摄像机世界矩阵的逆矩阵 glMultMatrixf(transform); // 右乘模型的世界矩阵 [billboard.texure bind]; // 绑定纹理 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 绘制顶点 } } } [_context presentRenderbuffer:GL_RENDERBUFFER]; // 绘制到绘制缓冲区 } |
下面是在测试数据在模拟器上的效果,后续会说明如何结合陀螺仪去将虚拟世界中的摄像头和设备绑定到一起
来自:cnblogs
分享到微信
0人喜欢
原文:http://www.cnblogs.com/xuejinhui/p/4337529.html
内容总结
以上是互联网集市为您收集整理的通过OpenGL ES在iOS平台实践增强现实(一)全部内容,希望文章能够帮你解决通过OpenGL ES在iOS平台实践增强现实(一)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。
来源:【匿名】