博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CardboardSDK-iOS 源码简单分析
阅读量:4475 次
发布时间:2019-06-08

本文共 3356 字,大约阅读时间需要 11 分钟。

该项目地址:

克隆地址为 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... 函数,该函数主要功能:

  1. (VR模式下) 根据当前传感器数据计算出各变换矩阵,存入leftEyerightEye对象中去。
  2. (非VR模式下)monocularEye 更新viewport
  3. (若需要时)更新左右眼的fov:updateFovsWithLeftEyeFov:leftEye->fov() rightEyeFov:rightEye->fov() 然后调用 _distortionRenderer->fovDidChange(...) 计算结果存储在传入的 leftEye rightEye 参数中。具体内容为:
    • 1) updateFovsWithLeftEyeFov...:计算出上下左右四个方向的fov角
    • 2) fovDidChange(...): 根据fov值计算出两个眼的viewport具体数值。
  4. _distortionRenderer->updateViewports(leftEye->viewport(), rightEye->viewport())更新左右眼的viewport

4. glkView:(GLKView *)view drawInRect:(CGRect)rect

绘制的回调函数。

1) _distortionRenderer->beforeDrawFrame()

  • (需要时) updateTextureAndDistortionMesh() (See [1])
  • glBindFramebuffer

2) drawFrameWithHeadTransform(...) 回调:

[self.stereoRendererDelegate prepareNewFrameWithHeadViewMatrix:headTransform->headView()];// ...[self.stereoRendererDelegate drawEyeWithEye:_leftEyeWrapper];// ...[self.stereoRendererDelegate drawEyeWithEye:_rightEyeWrapper];

3) Rebind original framebuffer

4) _distortionRenderer->afterDrawFrame()---> undistortTexture(_textureID) (See [2])

5)finishFrameWithViewPort: callback: stereoRendererDelegate finishFrameWithViewportRect:

需要分析说明的如下

[1] DistortionRenderer::updateTextureAndDistortionMesh() :

  1. create mesh
  2. 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 
- (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樂这个工程,做了一点点自己的修改,欢迎围观:

转载于:https://www.cnblogs.com/psklf/p/6369771.html

你可能感兴趣的文章
html自适应meta标签,自适应布局meta标签中viewport、content、width、initial-scale、minimum-scale、maximum-scale总结...
查看>>
html怎么加入编辑器,HTML 编辑器
查看>>
python发挥程度_你为什么用 Python?
查看>>
file 选择的文件胖多有多大_「HTML5 进阶」FileAPI 文件操作实战,内附详细案例,建议收藏...
查看>>
玄惭 mysql_阿里云数据库专家玄惭的“武功”全记录之最佳实践、双十一特别篇...
查看>>
c mysql 时间段查询_mySql 时间段查询
查看>>
mysql sql乱码怎么解决_MYSQL数据库导入SQL文件出现乱码如何解决
查看>>
mysql的存储过程与事务_mysql的存储过程与事务入门
查看>>
java程序员闯关题网站_Java程序员每周必逛的十大学习网站
查看>>
python面试装饰器_Python测开面试题之装饰器
查看>>
flashcache mysql_flashcache的实现与分析
查看>>
linux shell 里面执行python 程序_Linux下编写脚本Shell和Python的区别?
查看>>
python中if elif语句优化_python – 最有效的方式做一个if-elif-elif-else语句当else做的最多?...
查看>>
win10 配置 maven_home 一会儿成功一会儿失败_在macbook上运行移动硬盘里的win10和macos...
查看>>
python怎么画多重饼状图_Python通过matplotlib画双层饼图及环形图简单示例
查看>>
棋盘最短路径 python_Dijkstra 最短路径算法 Python 实现
查看>>
eclipse配置mysql教程_在Eclipse连接mysql-----配置jbdc_MySQL
查看>>
java map合并_java 实现合并map示例Demo1
查看>>
java 8 string_String.join() --Java8中String类新增方法
查看>>
java 布局教程_java布局学习(新)
查看>>