近期一年來,VR虛擬現實和AR加強現實技術的宣傳甚囂塵上。事實上VR,AR技術很是早就有了,一直沒有流行開來。不能否認價格是影響技術推廣的最大壁壘。php
谷歌對VR最大的貢獻是提供了便宜的谷歌眼鏡,依照GOOGLE提供的圖紙,使用兩個放大鏡和一個披薩盒就能輕鬆DIY出本身的VR眼鏡,同一時期谷歌推出來開源的VR SDK,使得開發人員可以輕鬆構建VR遊戲和VR播放器,使得差點兒所有對這一切感興趣的公司可以輕鬆的低成本的在技術上佈局VR產業鏈。java
很是多VR眼鏡已經降到了幾十塊錢。毫無疑問,谷歌又藉着便宜和開源改變了咱們的世界。android
研究谷歌的SDK,需要具有必定的OPENGL知識,要不理解這一切十分困難。VR的原理十分簡單。人可以感覺的立體或者3D的世界全依賴人的雙眼,人的雙眼看到的東西是不同,存在一個視角差,看一個立體的物體,左右眼能同一時候看到物體中間的部分。只是左眼能看到比右眼不少其它一點的左邊部分,右眼能看到比左眼不少其它一點右邊部分。大腦對兩僅僅眼鏡看到的東西分析處理合成來感覺這個世界的,一些3D畫可以恰當的利於光線和顏色組合達到視覺欺騙也是這個原理。假設對OPENGL熟悉的話,應該很是easy知道3D建模中,Camera的位置不一樣,能顯示出來的對象角度是不同的,特別是使用透視效果時。人的兩眼就至關於3D世界裏攝像頭。兩個攝像頭看到的東西和一個是不一樣的。通常來講,獨眼的殘疾人假設不動的話。看到的世界是平面的,只是他們可以經過擺頭或者移動身體來從不一樣的角度觀察世界,從而在大腦裏合成立體的世界。因此VR的原理就是把一張圖片或者視頻分解兩個,分別提供給左右眼看,從而達到欺騙眼睛的效果,終於達到虛擬現實的效果。api
谷歌VR SDK使用十分簡單,通常來講最好下載最新的google VR sdk,VR SDK包含unity版本號和java版本號。兩個版本號功能差點兒相同,一個用於unity平臺,一個用於android平臺,一個用於遊戲開發,一個用於應用開發,固然這不是絕對,有很多應用也是使用unity開發。也有很多遊戲使用java開發,選擇上感受可以看本身使用習慣。java版本號包含兩個包,一個cardboard.jar提借VR視覺支持,一個audio.jar提供VR聲音支持。ide
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