近期一年来,VR虚拟现实和AR增强现实技术的宣传甚嚣尘上。事实上VR,AR技术非常早就有了,一直没有流行开来。不可否认价格是影响技术推广的最大壁垒。
谷歌对VR最大的贡献是提供了便宜的谷歌眼镜,依照GOOGLE提供的图纸,使用两个放大镜和一个披萨盒就能轻松DIY出自己的VR眼镜,同一时期谷歌推出来开源的VR SDK,使得开发人员能够轻松构建VR游戏和VR播放器,使得差点儿全部对这一切感兴趣的公司能够轻松的低成本的在技术上布局VR产业链。
非常多VR眼镜已经降到了几十块钱。毫无疑问,谷歌又借着便宜和开源改变了我们的世界。
研究谷歌的SDK,须要具备一定的OPENGL知识,要不理解这一切十分困难。VR的原理十分简单。人能够感受的立体或者3D的世界全依赖人的双眼,人的双眼看到的东西是不一样,存在一个视角差,看一个立体的物体,左右眼能同一时候看到物体中间的部分。只是左眼能看到比右眼很多其它一点的左边部分,右眼能看到比左眼很多其它一点右边部分。大脑对两仅仅眼镜看到的东西分析处理合成来感受这个世界的,一些3D画能够恰当的利于光线和颜色组合达到视觉欺骗也是这个原理。假设对OPENGL熟悉的话,应该非常easy知道3D建模中,Camera的位置不同,能显示出来的对象角度是不一样的,特别是使用透视效果时。人的两眼就相当于3D世界里摄像头。两个摄像头看到的东西和一个是不同的。一般来说,独眼的残疾人假设不动的话。看到的世界是平面的,只是他们能够通过摆头或者移动身体来从不同的角度观察世界,从而在大脑里合成立体的世界。所以VR的原理就是把一张图片或者视频分解两个,分别提供给左右眼看,从而达到欺骗眼睛的效果,终于达到虚拟现实的效果。
谷歌VR SDK使用十分简单,一般来说最好下载最新的google VR sdk,VR SDK包含unity版本号和java版本号。两个版本号功能差点儿相同,一个用于unity平台,一个用于android平台,一个用于游戏开发,一个用于应用开发,当然这不是绝对,有不少应用也是使用unity开发。也有不少游戏使用java开发,选择上感觉能够看自己使用习惯。java版本号包含两个包,一个cardboard.jar提借VR视觉支持,一个audio.jar提供VR声音支持。
CardboardActivity是VRSDK的主类,要使开发的窗体支持VR,窗体须要派生于这个类。能够依据须要调用CardBoardView,支持各种调用,完整代码例如以下,只是完毕后除了看到一个button,其它都是黑冬冬的,由于Renderer我们没有填充内容,是个空的glsurface,熟悉opgengl的。能够完好这个类,后面会加入一个立方体用于測试眼镜
public class TestActivity extends CardboardActivity{ /* @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_main); RajawaliCardboardView cv = (RajawaliCardboardView) findViewById(R.id.view2);//new CardboardView(this); //cv.setRestoreGLStateEnabled(false); //cv.setRenderer(rd); this.setCardboardView(cv); RajawaliCardboardRenderer renderer = new RajawaliCardboardRenderer(this){ @Override protected void initScene() { getCurrentScene().addChild(createSphereWithTexture(new Texture("photo", R.drawable.homepage))); getCurrentCamera().setPosition(Vector3.ZERO); getCurrentCamera().setFieldOfView(75); } @Override public void onNewFrame(HeadTransform headTransform) { super.onNewFrame(headTransform); } @Override protected void onRender(long ellapsedRealtime, double deltaTime) { super.onRender(ellapsedRealtime, deltaTime); } @Override public void onDrawEye(Eye eye) { super.onDrawEye(eye); } @Override public void onFinishFrame(Viewport viewport) { super.onFinishFrame(viewport); } @Override public void onSurfaceChanged(int width, int height) { super.onSurfaceChanged(width, height); } @Override public void onSurfaceCreated(EGLConfig config) { super.onSurfaceCreated(config); } @Override public void onRendererShutdown() { super.onRendererShutdown(); } @Override public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset); } @Override public void onTouchEvent(MotionEvent event) { super.onTouchEvent(event); } }; cv.setRenderer(renderer); cv.setSurfaceRenderer(renderer); } */ /* @Override protected void onCreate(Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); LinearLayout ln = new LinearLayout(this); ln.setBackgroundColor(Color.RED); CardboardView cbView = new CardboardView(this); cbView.setBackgroundColor(Color.BLUE); cbView.setVRModeEnabled(true); //cbView.setAlpha(0); cbView.setAlignmentMarkerEnabled(true); //cbView.setRenderer(new VrRenderer(this)); VrRenderer renderer = new VrRenderer(this); cbView.setRenderer(renderer); cbView.setPreserveEGLContextOnPause(true); setContentView(cbView); cbView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onCardboardTrigger(); } }); //mHideButtonsThread.start(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CardboardView cardboardView = (CardboardView) findViewById(R.id.view2); cardboardView.setRenderer(rd); setCardboardView(cardboardView); vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); imageLeft = (ImageView) findViewById(R.id.image_left); imageRight = (ImageView) findViewById(R.id.image_right); progressLeft = (ProgressBar) findViewById(R.id.progress_left); progressRight = (ProgressBar) findViewById(R.id.progress_right); statusLeft = (TextView) findViewById(R.id.status_text_left); statusRight = (TextView) findViewById(R.id.status_text_right); fadeInAnim = new AlphaAnimation(0.0f, 1.0f); fadeInAnim.setDuration(500); setProgress(true); setStatus(true, getString(R.string.status_finding_files)); // kick off our task to find all MPOs, which will in turn kick off showing the first one. new MpoFindTask().execute((Void) null); } */ private Renderer rd = new Renderer(){ @Override public void onDrawFrame(HeadTransform headTransform, Eye eye, Eye eye1) { } @Override public void onFinishFrame(Viewport viewport) { } @Override public void onSurfaceChanged(int i, int i1) { } @Override public void onSurfaceCreated(EGLConfig eglConfig) { } @Override public void onRendererShutdown() { } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); CardboardView mSurfaceView = new CardboardView(this); addContentView(mSurfaceView, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT)); mSurfaceView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar | View.SYSTEM_UI_FLAG_IMMERSIVE); mSurfaceView.setRenderer(rd); mSurfaceView.setVRModeEnabled(true); //mSurfaceView.addChildrenForAccessibility(); setCardboardView(mSurfaceView); } }
參考:http://www.programcreek.com/java-api-examples/index.php?api=com.google.vrtoolkit.cardboard.CardboardView