CardboardSDK-iOS 源码简单分析
该项目地址: 地址
克隆地址为 https://github.com/rsanchezsaez/CardboardSDK-iOS.git
目前如果想在iOS设备上实现双目VR的功能,Google 已经提供了官方的sdk,上手简单,但是由于在实际使用中有其他需求,GVR的源码无法修改,所以还是使用这个野生的SDK来开发。这篇文章主要就是简单分析一下这个sdk的ViewController 的代码,至于内部的复杂数学计算,暂时无法涉及。
CBDViewController
主要要分析的就是 CBDViewController
这个类,其继承了 GLKViewController
并实现樂 GLKViewControllerDelegate
这个接口。成员:stereoRendererDelegate
负责实现若干个回调函数,比如在Cardboard各个设置完成后进行所需的绘制工作。
1. Init
初始化各个成员变量,设置GLKViewController的delegate为self,启动设备的传感器,开始监听。
2. ViewDidLoad
创建OpenGL的Context 并回调 [self.stereoRendererDelegate setupRendererWithView:self.view]
此时设置Context为 glview.context
,可以进行绘制的准备工作,比如创建program 上传attribute,uniform的数据。
3. glkViewControllerUpdate:(GLKViewController *)controller
Called before each frame is displayed, 所以此处所做的事情主要是根据传感器数据计算出绘制所需的参数,主要是变换矩阵,fov和viewport仅需要在更新视窗的时候更新。
调用 calculateFrameParametersWithHeadTransform...
函数,该函数主要功能:
- (VR模式下) 根据当前传感器数据计算出各变换矩阵,存入
leftEye
和rightEye
对象中去。 - (非VR模式下)
monocularEye
更新viewport - (若需要时)更新左右眼的fov:
updateFovsWithLeftEyeFov:leftEye->fov() rightEyeFov:rightEye->fov()
然后调用_distortionRenderer->fovDidChange(...)
计算结果存储在传入的leftEye
rightEye
参数中。具体内容为:updateFovsWithLeftEyeFov...
:计算出上下左右四个方向的fov角
fovDidChange(...)
: 根据fov值计算出两个眼的viewport具体数值。
_distortionRenderer->updateViewports(leftEye->viewport(), rightEye->viewport())
更新左右眼的viewport
4. glkView:(GLKView *)view drawInRect:(CGRect)rect
绘制的回调函数。
_distortionRenderer->beforeDrawFrame()
- (需要时)
updateTextureAndDistortionMesh()
(See [1]) glBindFramebuffer
drawFrameWithHeadTransform(...)
回调:
[self.stereoRendererDelegate prepareNewFrameWithHeadViewMatrix:headTransform->headView()];
// ...
[self.stereoRendererDelegate drawEyeWithEye:_leftEyeWrapper];
// ...
[self.stereoRendererDelegate drawEyeWithEye:_rightEyeWrapper];
Rebind original framebuffer
_distortionRenderer->afterDrawFrame()
--->undistortTexture(_textureID)
(See [2])
5)finishFrameWithViewPort
: callback: stereoRendererDelegate finishFrameWithViewportRect:
需要分析说明的如下
[1] DistortionRenderer::updateTextureAndDistortionMesh()
:
- create mesh
- setup rendertexture and renderbuffer
首先创建两个program用于绘制畸变校正。这两个program的区别在于纹理,无矫正只有一个纹理sampler,带矫正的分别有RGB三个纹理sampler. 然后计算畸变矫正所需参数然后创建 DistortionMesh 对象: 创建对象时生成所需的vertexData和indexData 并绑定到相应的array buffer上面去。 再之后创建纹理、renderbuffer和framebuffer.这里创建的就是用于off-screen render的framebuffer,所以这里创建的纹理,其内容是空的,glTexImage2D(GL_TEXTURE_2D, 0, textureFormat, width, height, 0, textureFormat, textureType, nil);
因为这个SDK的功能就是留出这么一块framebuffer来给调用者绘制,绘制完了以后他自己将其当作纹理经过矫正后分别绘制到两个眼睛上面去。
[2] undistortTexture(_textureID)
:
做一OpenGL状态的备份:将所有的OpenGL状态相关信息统统保存下来。若需要时,仍然是调用一遍 updateTextureAndDistortionMesh
. 调用 renderDistortionMesh(_leftEyeDistortionMesh, textureID)
内部实现:目前已知vertexData indexData以及TextureId 将这些数据统统上传至畸变矫正用的program上,并绘制。完成后将保存的gl信息统统设置回去。
简单使用
分析提供的例子可知,简单使用时只需要继承这个CBDViewController类,并实现几个GLKViewController的方法,设置好stereoRendererDelegate 即可。主要的工作就是stereoRendererDelegate完成的,回调函数一览:
@protocol CBDStereoRendererDelegate <NSObject>
- (void)setupRendererWithView:(GLKView *)glView;
- (void)shutdownRendererWithView:(GLKView *)glView;
- (void)renderViewDidChangeSize:(CGSize)size;
- (void)prepareNewFrameWithHeadViewMatrix:(GLKMatrix4)headViewMatrix;
- (void)drawEyeWithEye:(CBDEye *)eye;
- (void)finishFrameWithViewportRect:(CGRect)viewPort;
@optional
- (void)triggerPressed;
@end
最后
我fork樂这个工程,做了一点点自己的修改,欢迎围观:
地址
CardboardSDK-iOS 源码简单分析的更多相关文章
- FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- FFmpeg源码简单分析:libswscale的sws_scale()
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
- Django-session中间件源码简单分析
Django-session中间件源码简单分析 settings里有关中间件的配置 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddlew ...
- FFmpeg源码简单分析:结构体成员管理系统-AVOption
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
- negroni-gzip源码简单分析解读
negroni-gzip源码简单分析解读 这是一个为Negroni设计的gzip压缩处理中间件,需要用到已有的compress中的gzip,阅读了不长的源码之后,总结了一些关键要点和注意点. 检查是否 ...
- FFmpeg的HEVC解码器源码简单分析:概述
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- FFmpeg的HEVC解码器源码简单分析:解码器主干部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- urllib源码简单分析
对下面这段代码做分析 import urllib params = urllib.urlencode({'wd': 'python'}) f = urllib.urlopen("http:/ ...
- MongoDB 默认写入关注保存数据丢失问题与源码简单分析
MongoDB 默认写入关注可能保存数据丢失问题分析 问题描述: EDI服务进行优化,将原有MQ发送成功并且DB写入成功,两个条件都达成,响应接收订单数据成功,修改为只有有一个条件成功就响应接收数据成 ...
随机推荐
- SQL SERVER 2008 Hierarchyid数据类型
以往我们在关系数据库中建立树状结构的时候,通常使用ID+ParentID来实现两条纪录间的父子关系.但这种方式只能标示其相对位置.解决这类问题在SqlServer2005出现之前通常是采用游标来操作, ...
- MapReduce 简单的全文搜索2
上一个全文搜索实现了模糊查找,这个主要实现了精确查找,就是比如你查找mapreduce is simple那么他就只查找有这个句子的文章,而不是查找有这三个单词的文章. 这个版本需要重写反向索引,因为 ...
- .htaccess 使用大全
重新和重定向 注意:首先需要服务器安装和启用mod_rewrite模块. 强制 www RewriteEngine on RewriteCond %{HTTP_HOST} ^example\.com ...
- Undefined symbols for architecture i386: "_crc32", referenced from:——crc链接错误
有时候用别人的框架,你会碰到下面的错误,很是吓人,什么玩意,我怎么看不懂!!! Undefined symbols for architecture i386: "_RELEASE&quo ...
- STM32驱动TEA5767收音机模块
Tea5767是飞利浦公司出的一款集成化的收音机芯片,大四的时候机缘巧合遇到了这个芯片,用了一下,写点资料 主要特性 TEA5767HN是一款低功耗立体声收音IC,广泛应用于手机MP3 .MP 4 播 ...
- Memcached源码分析
作者:Calix,转载请注明出处:http://calixwu.com 最近研究了一下memcached的源码,在这里系统总结了一下笔记和理解,写了几 篇源码分析和大家分享,整个系列分为“结构篇”和“ ...
- js 捕获浏览器关闭或者刷新页面给出提示
window.onbeforeunload = function() { return " "; }document.onkeydown = function() {if ((wi ...
- td文字过长部分显示,鼠标移动显示全部内容
只要在该td中加上title属性,鼠标移到这里就会看到全部内容, 在td中加上div,属性设置如下,就能显示宽度为200px的内容,大于则隐藏.代码如下: <td title="我是代 ...
- 快速搭建LNMP
[centos 6.4 server]系统安装请参考:http://blog.zhuyin.org/748.html1.防火墙设置: iptables -F service iptables save ...
- SpringBoot JPA实现增删改查、分页、排序、事务操作等功能
今天给大家介绍一下SpringBoot中JPA的一些常用操作,例如:增删改查.分页.排序.事务操作等功能.下面先来介绍一下JPA中一些常用的查询操作: //And --- 等价于 SQL 中的 and ...