Oculus VR SDK实现-Oculus针对双眼显示的交换链设计
目录
一、创建交换链
首先我们关注一下ovrFramebuffer这个结构体:
typedef struct {int Width;int Height;int Multisamples;int TextureSwapChainLength;int TextureSwapChainIndex;ovrTextureSwapChain * ColorTextureSwapChain;GLuint * DepthBuffers;GLuint * FrameBuffers;
} ovrFramebuffer;
//创建一个Texture,类型是2D,格式是colorFormatframeBuffer->ColorTextureSwapChain = vrapi_CreateTextureSwapChain(VRAPI_TEXTURE_TYPE_2D, colorFormat, width, height, 1, true);
其中的ovrHmdInfo是VR 头盔(眼镜)相关的一个结构体,包含,分辨率,刷新率,默认分辨率,和水平垂直视野角度。
二、创建DepthBuffer和FrameBuffer
frameBuffer->DepthBuffers = (GLuint *) malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));frameBuffer->FrameBuffers = (GLuint *) malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
//创建渲染缓冲区buffer,12章,P233,glGenRenderbuffers作用是分配n个渲染缓冲区对象名称//这里分配了1个渲染缓冲区名称存储到frameBuffer->DepthBuffers[i]中,名称是不为0的无符号整数// Create multisampled depth buffer.GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i]));//指定渲染缓冲区,第一个值必须指定为GL_RENDERBUFFERGL(glBindRenderbuffer(GL_RENDERBUFFER,frameBuffer->DepthBuffers[i]));GL(glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,multisamples, GL_DEPTH_COMPONENT24, width, height));GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));//创建帧缓冲区buffer// Create the frame buffer.//创建framebufferGL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));GL(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));GL(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture,0, multisamples));GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,frameBuffer->DepthBuffers[i]));GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus( GL_FRAMEBUFFER ));GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) {ALOGE("Incomplete frame buffer object: %s",EglFrameBufferStatusString(renderFramebufferStatus));return false;}
三、基于交换链对Buffer的使用
了解完这一部分,我们现在来看下,程序是如何基于交换链对这些数据结构进行使用的:
ovrFramebuffer_Resolve(frameBuffer);parms.Layers[VRAPI_FRAME_LAYER_TYPE_WORLD].Textures[eye].ColorTextureSwapChain =frameBuffer->ColorTextureSwapChain;parms.Layers[VRAPI_FRAME_LAYER_TYPE_WORLD].Textures[eye].TextureSwapChainIndex =frameBuffer->TextureSwapChainIndex;parms.Layers[VRAPI_FRAME_LAYER_TYPE_WORLD].Textures[eye].TexCoordsFromTanAngles =renderer->TexCoordsTanAnglesMatrix; //纹理坐标parms.Layers[VRAPI_FRAME_LAYER_TYPE_WORLD].Textures[eye].HeadPose =updatedTracking.HeadPose;ovrFramebuffer_Advance(frameBuffer);
因为要画的是左眼和右眼的画面。所以这里有左右眼对应的数据结构所在的对象params的类型ovrFrameParms:
typedef struct
{// Layers composited in the time warp.ovrFrameLayer Layers[VRAPI_FRAME_LAYER_TYPE_MAX];int LayerCount;// Combination of ovrFrameOption flags.int WarpOptions;// Which program to run with these layers.ovrFrameProgram WarpProgram;// Program-specific tuning values.float ProgramParms[4];// Application controlled frame index that uniquely identifies this particular frame.// This must be the same frame index that was passed to vrapi_GetPredictedDisplayTime()// when synthesis of this frame started.long long FrameIndex;// WarpSwap will not return until at least this many V-syncs have// passed since the previous WarpSwap returned.// Setting to 2 will reduce power consumption and may make animation// more regular for applications that can't hold full frame rate.int MinimumVsyncs;// Latency Mode.ovrExtraLatencyMode ExtraLatencyMode;// Rotation from a joypad can be added on generated frames to reduce// judder in FPS style experiences when the application framerate is// lower than the V-sync rate.// This will be applied to the view space distorted// eye vectors before applying the rest of the time warp.// This will only be added when the same ovrFrameParms is used for// more than one V-sync.ovrMatrix4f ExternalVelocity;// jobject that will be updated before each eye for minimal// latency with VRAPI_FRAME_PROGRAM_MASKED_PLANE_EXTERNAL.// IMPORTANT: This should be a JNI weak reference to the object.// The system will try to convert it into a global reference before// calling SurfaceTexture->Update, which allows it to be safely// freed by the application.jobject SurfaceTextureObject;// CPU/GPU performance parameters.ovrPerformanceParms PerformanceParms;// For handling HMD events and power level state changes.ovrJava Java;
} ovrFrameParms;
typedef struct
{// Because OpenGL ES does not support clampToBorder, it is the// application's responsibility to make sure that all mip levels// of the primary eye texture have a black border that will show// up when time warp pushes the texture partially off screen.//CLAMP_TO_BORDER causes OpenGL to only take the border color at the edge of the texture//rather than the average of the border color and texture edge texels.//This allows for a perfect border around the texture.ovrTextureSwapChain * ColorTextureSwapChain;// The depth texture is optional for positional time warp.ovrTextureSwapChain * DepthTextureSwapChain;// Index to the texture from the set that should be displayed.int TextureSwapChainIndex;// Points on the screen are mapped by a distortion correction// function into ( TanX, TanY, -1, 1 ) vectors that are transformed// by this matrix to get ( S, T, Q, _ ) vectors that are looked// up with texture2dproj() to get texels.ovrMatrix4f TexCoordsFromTanAngles;// Only texels within this range should be drawn.// This is a sub-rectangle of the [(0,0)-(1,1)] texture coordinate range.ovrRectf TextureRect;// The tracking state for which ModelViewMatrix is correct.// It is ok to update the orientation for each eye, which// can help minimize black edge pull-in, but the position// must remain the same for both eyes, or the position would// seem to judder "backwards in time" if a frame is dropped.ovrRigidBodyPosef HeadPose;
} ovrFrameLayerTexture;
static void ovrFramebuffer_SetCurrent(ovrFramebuffer * frameBuffer) {GL(glBindFramebuffer(GL_FRAMEBUFFER,frameBuffer->FrameBuffers[frameBuffer->TextureSwapChainIndex]));
}
static void ovrFramebuffer_Resolve(ovrFramebuffer * frameBuffer) {// Discard the depth buffer, so the tiler won't need to write it back out to memory.const GLenum depthAttachment[1] = { GL_DEPTH_ATTACHMENT };glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, depthAttachment);// Flush this frame worth of commands.glFlush();
}
5.更新交换链
parms.Layers[VRAPI_FRAME_LAYER_TYPE_WORLD].Textures[eye].ColorTextureSwapChain =frameBuffer->ColorTextureSwapChain;parms.Layers[VRAPI_FRAME_LAYER_TYPE_WORLD].Textures[eye].TextureSwapChainIndex =frameBuffer->TextureSwapChainIndex;parms.Layers[VRAPI_FRAME_LAYER_TYPE_WORLD].Textures[eye].TexCoordsFromTanAngles =renderer->TexCoordsTanAnglesMatrix; //纹理坐标parms.Layers[VRAPI_FRAME_LAYER_TYPE_WORLD].Textures[eye].HeadPose =updatedTracking.HeadPose;
6.移动到下一帧要使用的交换链索引
static void ovrFramebuffer_Advance(ovrFramebuffer * frameBuffer) {// Advance to the next texture from the set.frameBuffer->TextureSwapChainIndex =(frameBuffer->TextureSwapChainIndex + 1)% frameBuffer->TextureSwapChainLength;
}
每一帧都不停地循环1到6这几个步骤,便实现了,一帧画左眼,一帧画右眼的效果。
Oculus VR SDK实现-Oculus针对双眼显示的交换链设计相关推荐
- Oculus VR SDK实现 -主要结构体及Api接口设计
其中的ovrHmdInfo是VR 头盔(眼镜)相关的一个结构体,包含,分辨率,刷新率,默认分辨率,和水平垂直视野角度. 显示一幅分辨率为2560*2440的图像的时候,每个像素在眼睛中所占用的视 ...
- Oculus VR设计指南
Oculus VR 设计指南 本指南由字节跳动的四位同学共同翻译,西瓜视频的设计师们共同校对. 如果你对 XR 设计工作感兴趣,vivo 正在招聘 XR 方向的人机交互设计师,当然如果你有其他的任何 ...
- oculus vr开发_如何在Oculus Quest上无线玩Steam VR游戏
oculus vr开发 Oculus 眼 The Oculus Quest is a fully stand-alone headset. It's free of the wires of PC-o ...
- 虚拟现实大潮渐近:Oculus VR、EA和Avegant等多家公司...
虚拟现实不是新词,上世纪的许多科幻小说中就描述过未来虚拟现实技术高度发达后的世界,但是这两年,虚拟现实真正在商业市场有了新的突破,代表者就是Oculus VR.近日,一众在虚拟现实领域有所建树的公司结 ...
- Android Studio 2.0+Gradle 2.12编译Oculus Mobile SDK
1. 下载与安装: Android Studio 2.0 https://dl.google.com/dl/android/studio/ide-zips/2.0.0.20/android-stud ...
- oculus vr开发_Oculus IndieCade VR Jam总结
oculus vr开发 Since August 2nd, 220 teams of developers around the world have been working on projects ...
- Oculus VR眼镜调研
VR眼镜 oculus 软件安装 最详细的Oculus Rift VR/3D眼镜安装设置教程(多图) 在线安装Oculus rift驱动[非VPN方法] Rift,Go,Gear VR,Quest: ...
- Android下Opengl ES实现单屏幕双眼显示
http://blog.csdn.net/u011371324/article/details/68946779 默认情况下,Opengl ES使用系统提供的帧缓冲区作为绘图表面,一般情况下,如果只在 ...
- GOOGLE VR SDK开发VR游戏,VR播放器之一
最近一年来,VR虚拟现实和AR增强现实技术的宣传甚嚣尘上.其实VR,AR技术很早就有了,一直没有流行开来,不可否认价格是影响技术推广的最大壁垒.谷歌对VR最大的贡献是提供了廉价的谷歌眼镜,按照GOOG ...
最新文章
- PL/SQL高级编程
- CocoaPods详解之----使用篇
- 每日程序C语言3-三个数大小排序
- poco c++ 开发指南_掌握这个框架,你将会开发通杀全平台的万能爬虫
- php ziparchive(),php的ZipArchive类用法实例
- 坎蒂雷赋权法 matlab,干货 | 利用MATLAB实现FMCW雷达中的常用角度估计方法
- 中国移动:2016年全力推NFC,以公共交通为突破口
- rem在响应式布局中的应用
- C语言---数字迷宫
- 计算机鼠标双击怎么,讲解电脑鼠标左键单击变双击怎么办
- 这个世界上人真的分三六九等,你信吗?
- 一站式跨境电商免费开源ERP平台,简洁的操作,助您高效工作
- Tecplot 输入数学符号
- 腾讯金融云mysql,腾讯云金融级云数据库优势与功能介绍
- CUPS学习五:打印机基础
- C语言中的找特殊数字问题
- mysql 如何存带有特殊符号的微信昵称
- html设置ios状态栏颜色,ios 显示html标签,超链接颜色以及下划线的处理
- 面对困难,你可以等死,也可以马上动手解决问题,解决完一个,就再解决一个,然后就可以回家了。...
- 在线博客系统——最热文章、最新文章
热门文章
- linux安装无法删除分区表,删除LINUX分区
- 电路仿真软件详谈(24),基于proteus电路仿真软件的电压表印刷电路板设计
- 微信Android模块化架构重构实践
- java毕业设计校园招聘论坛设计mybatis+源码+调试部署+系统+数据库+lw
- 2.1_11 Oralce 执行计划之3_直方图(Histograms)
- echarts关系图graph点击折叠
- 图的操作与实现——简易城市交通网
- 朗驰欣创——嵌入式软件面试
- 获取当前日期并转换成day_id:20210810
- 310. Minimum Height Trees 【Medium】 树