该项目地址: 地址

克隆地址为 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角
      1. 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
  1. drawFrameWithHeadTransform(...) 回调:
    [self.stereoRendererDelegate prepareNewFrameWithHeadViewMatrix:headTransform->headView()];
// ...
[self.stereoRendererDelegate drawEyeWithEye:_leftEyeWrapper];
// ...
[self.stereoRendererDelegate drawEyeWithEye:_rightEyeWrapper];
  1. Rebind original framebuffer

  2. _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 <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 源码简单分析的更多相关文章

  1. FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  2. FFmpeg源码简单分析:libswscale的sws_scale()

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  3. Django-session中间件源码简单分析

    Django-session中间件源码简单分析 settings里有关中间件的配置 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddlew ...

  4. FFmpeg源码简单分析:结构体成员管理系统-AVOption

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  5. negroni-gzip源码简单分析解读

    negroni-gzip源码简单分析解读 这是一个为Negroni设计的gzip压缩处理中间件,需要用到已有的compress中的gzip,阅读了不长的源码之后,总结了一些关键要点和注意点. 检查是否 ...

  6. FFmpeg的HEVC解码器源码简单分析:概述

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  7. FFmpeg的HEVC解码器源码简单分析:解码器主干部分

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  8. urllib源码简单分析

    对下面这段代码做分析 import urllib params = urllib.urlencode({'wd': 'python'}) f = urllib.urlopen("http:/ ...

  9. MongoDB 默认写入关注保存数据丢失问题与源码简单分析

    MongoDB 默认写入关注可能保存数据丢失问题分析 问题描述: EDI服务进行优化,将原有MQ发送成功并且DB写入成功,两个条件都达成,响应接收订单数据成功,修改为只有有一个条件成功就响应接收数据成 ...

随机推荐

  1. [转] M2E插件maven-dependency-plugin问题

    转自 : http://blog.csdn.net/cskgnt/article/details/8530526 问题: maven-dependency-plugin (goals "co ...

  2. hibernate--session的CRUD方法, delete, load,get,update,saveorupdate, clear, flush

    删除方法: 新建的对象立马被删除 @Test public void testDelete() { Teacher t = new Teacher(); t.setName("t1" ...

  3. xcode磁盘大清理

     转---Xcode磁盘空间大清理 我的设备是Macbook Air 13’ Mid 2011,128G SSD.最近开始有些存储压力了,用Clean My Mac清理一部分旧文件后,决定对Xcode ...

  4. pom文件说明

    http://www.blogjava.net/hellxoul/archive/2013/05/16/399345.html

  5. Git for Windows 工具下载及配置

    前言,关于git工具的帖子:http://cn.v2ex.com/t/225027 最终选择了git for windows这个工具,路径为:https://git-for-windows.githu ...

  6. Android L(5.0)源码之图形与图像处理之简单图片——Bitmap

    最近在研究android 5.0的gallery模块,学习了相关的知识点,准备写点博客总结一下,有时间了会补充完整

  7. Session监听事件的处理

    设置Session监听  在web.xml文件中: <listener> <listener-class>cjq.login.listener.UpdateLogOutTime ...

  8. Centos 修改时间地区及NTP同步北京时间

    在我们使用CentOS系统的时候,也许时区经常会出现问题,有时候改完之后还是会出错,下面我们就来学习一种方法来改变这个状况.如果没有安装,而你使用的是 CentOS系统 那使用命令 yum insta ...

  9. 普通项目如何转换成Maven项目 --转载自百度知道

    右键普通Java项目,在弹出的菜单中选择[Configure]-[Convert to Maven Project]: 2 在弹出的对话框中输入项目的groupId, artifactId和versi ...

  10. Python - Headless Selenium WebDriver Tests using PyVirtualDisplay

    Here is some Python code showing WebDriver with a virtual display provided by Xvfb: #!/usr/bin/env p ...