Skip to content

Commit fcf730b

Browse files
support cardboard VR rendering
1 parent f88b834 commit fcf730b

File tree

13 files changed

+1024
-2
lines changed

13 files changed

+1024
-2
lines changed

cocos/2d/CCCamera.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ void Camera::applyViewport()
447447

448448
if(nullptr == _fbo)
449449
{
450-
glViewport(getDefaultViewport()._left, getDefaultViewport()._bottom, getDefaultViewport()._width, getDefaultViewport()._height);
450+
//glViewport(getDefaultViewport()._left, getDefaultViewport()._bottom, getDefaultViewport()._width, getDefaultViewport()._height);
451451
}
452452
else
453453
{

cocos/Android.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ navmesh/CCNavMeshAgent.cpp \
214214
navmesh/CCNavMeshDebugDraw.cpp \
215215
navmesh/CCNavMeshObstacle.cpp \
216216
navmesh/CCNavMeshUtils.cpp \
217+
vr/CCVRGeneric.cpp \
218+
vr/CCVRCardboard.cpp \
219+
vr/cardboard/CbApi.cpp \
217220
../external/ConvertUTF/ConvertUTFWrapper.cpp \
218221
../external/ConvertUTF/ConvertUTF.c \
219222
../external/tinyxml2/tinyxml2.cpp \

cocos/platform/CCGLView.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ THE SOFTWARE.
3333
#include "renderer/CCRenderer.h"
3434
#include "vr/CCVRProtocol.h"
3535
#include "vr/CCVRGeneric.h"
36+
#include "vr/CCVRCardboard.h"
3637

3738
NS_CC_BEGIN
3839

@@ -492,7 +493,7 @@ void GLView::setVREnabled(bool enabled)
492493
_vrEnabled = enabled;
493494
if (_vrEnabled && !_vrImpl)
494495
{
495-
_vrImpl = new VRGeneric;
496+
_vrImpl = new VRCardboard;
496497
_vrImpl->setup(this);
497498
}
498499
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package org.cocos2dx.lib;
2+
3+
import android.content.Context;
4+
5+
import com.google.vrtoolkit.cardboard.CardboardDeviceParams;
6+
import com.google.vrtoolkit.cardboard.Distortion;
7+
import com.google.vrtoolkit.cardboard.Eye;
8+
import com.google.vrtoolkit.cardboard.FieldOfView;
9+
import com.google.vrtoolkit.cardboard.HeadMountedDisplayManager;
10+
import com.google.vrtoolkit.cardboard.ScreenParams;
11+
import com.google.vrtoolkit.cardboard.sensors.HeadTracker;
12+
import com.google.vrtoolkit.cardboard.DistortionRenderer;
13+
14+
public class CbAPIWrapper {
15+
private static HeadMountedDisplayManager mHmdManager;
16+
private static HeadTracker mHeadTracker;
17+
private static DistortionRenderer mDistortionRenderer;
18+
private static final Eye[] mEyes = new Eye[2];
19+
private static boolean mIsEnterVRMode = false;
20+
21+
public static void initialize(Context context, float[] params){
22+
mHeadTracker = HeadTracker.createFromContext(context);
23+
mHmdManager = new HeadMountedDisplayManager(context);
24+
mDistortionRenderer = new DistortionRenderer();
25+
mEyes[0] = new Eye(Eye.Type.LEFT);
26+
mEyes[1] = new Eye(Eye.Type.RIGHT);
27+
28+
CardboardDeviceParams cdp = mHmdManager.getHeadMountedDisplay().getCardboardDeviceParams();
29+
ScreenParams sp = mHmdManager.getHeadMountedDisplay().getScreenParams();
30+
params[0] = sp.getWidth();
31+
params[1] = sp.getHeight();
32+
params[2] = sp.getWidthMeters();
33+
params[3] = sp.getHeightMeters();
34+
params[4] = sp.getBorderSizeMeters();
35+
36+
params[5] = cdp.getInterLensDistance();
37+
if (cdp.getVerticalAlignment() == CardboardDeviceParams.VerticalAlignmentType.BOTTOM){
38+
params[6] = 0;
39+
}else if (cdp.getVerticalAlignment() == CardboardDeviceParams.VerticalAlignmentType.CENTER){
40+
params[6] = 1;
41+
}else{
42+
params[6] = 2;
43+
}
44+
45+
params[7] = cdp.getVerticalDistanceToLensCenter();
46+
params[8] = cdp.getScreenToLensDistance();
47+
48+
params[9] = cdp.getLeftEyeMaxFov().getLeft();
49+
params[10] = cdp.getLeftEyeMaxFov().getRight();
50+
params[11] = cdp.getLeftEyeMaxFov().getBottom();
51+
params[12] = cdp.getLeftEyeMaxFov().getTop();
52+
}
53+
54+
public static void getEyes(float[] eyesParams){
55+
CardboardDeviceParams cdp = mHmdManager.getHeadMountedDisplay().getCardboardDeviceParams();
56+
float eyeToScreenDis = updateFieldOfView(mEyes[0].getFov(), mEyes[1].getFov());
57+
mDistortionRenderer.onFovChanged(mHmdManager.getHeadMountedDisplay(), mEyes[0].getFov(), mEyes[1].getFov(), eyeToScreenDis);
58+
mDistortionRenderer.updateViewports(mEyes[0].getViewport(), mEyes[1].getViewport());
59+
60+
//viewport
61+
eyesParams[0] = mEyes[0].getViewport().x;
62+
eyesParams[1] = mEyes[0].getViewport().y;
63+
eyesParams[2] = mEyes[0].getViewport().width;
64+
eyesParams[3] = mEyes[0].getViewport().height;
65+
//fov
66+
eyesParams[4] = mEyes[0].getFov().getLeft();
67+
eyesParams[5] = mEyes[0].getFov().getRight();
68+
eyesParams[6] = mEyes[0].getFov().getBottom();
69+
eyesParams[7] = mEyes[0].getFov().getTop();
70+
71+
//viewport
72+
eyesParams[8] = mEyes[1].getViewport().x;
73+
eyesParams[9] = mEyes[1].getViewport().y;
74+
eyesParams[10] = mEyes[1].getViewport().width;
75+
eyesParams[11] = mEyes[1].getViewport().height;
76+
//fov
77+
eyesParams[12] = mEyes[1].getFov().getLeft();
78+
eyesParams[13] = mEyes[1].getFov().getRight();
79+
eyesParams[14] = mEyes[1].getFov().getBottom();
80+
eyesParams[15] = mEyes[1].getFov().getTop();
81+
}
82+
83+
public static void enterVrMode(){
84+
mHeadTracker.startTracking();
85+
mIsEnterVRMode = true;
86+
}
87+
88+
public static void leaveVrMode(){
89+
mHeadTracker.stopTracking();
90+
mIsEnterVRMode = false;
91+
}
92+
93+
public static void getLastHeadView(float[] viewMat){
94+
mHeadTracker.getLastHeadView(viewMat, 0);
95+
}
96+
97+
public static void beforeDrawFrame(){
98+
if (!mIsEnterVRMode) return;
99+
mDistortionRenderer.beforeDrawFrame();
100+
}
101+
102+
public static void afterDrawFrame(){
103+
if (!mIsEnterVRMode) return;
104+
mDistortionRenderer.afterDrawFrame();
105+
}
106+
107+
private static float updateFieldOfView(FieldOfView leftEyeFov, FieldOfView rightEyeFov) {
108+
CardboardDeviceParams cdp = mHmdManager.getHeadMountedDisplay().getCardboardDeviceParams();
109+
ScreenParams screen = mHmdManager.getHeadMountedDisplay().getScreenParams();
110+
Distortion distortion = cdp.getDistortion();
111+
112+
//float idealFovAngle = (float)Math.toDegrees(Math.atan2(cdp.getLensDiameter() / 2.0F, cdp.getEyeToLensDistance()));
113+
114+
float eyeToScreenDist = 0.011F + cdp.getScreenToLensDistance();
115+
116+
float outerDist = (screen.getWidthMeters() - cdp.getInterLensDistance()) / 2.0F;
117+
118+
float innerDist = cdp.getInterLensDistance() / 2.0F;
119+
float bottomDist = cdp.getVerticalDistanceToLensCenter() - screen.getBorderSizeMeters();
120+
121+
float topDist = screen.getHeightMeters() + screen.getBorderSizeMeters() - cdp.getVerticalDistanceToLensCenter();
122+
123+
float outerAngle = (float)Math.toDegrees(Math.atan2(distortion.distort(outerDist), eyeToScreenDist));
124+
125+
float innerAngle = (float)Math.toDegrees(Math.atan2(distortion.distort(innerDist), eyeToScreenDist));
126+
127+
float bottomAngle = (float)Math.toDegrees(Math.atan2(distortion.distort(bottomDist), eyeToScreenDist));
128+
129+
float topAngle = (float)Math.toDegrees(Math.atan2(distortion.distort(topDist), eyeToScreenDist));
130+
131+
leftEyeFov.setLeft(Math.min(outerAngle, leftEyeFov.getLeft()));
132+
leftEyeFov.setRight(Math.min(innerAngle, leftEyeFov.getRight()));
133+
leftEyeFov.setBottom(Math.min(bottomAngle, leftEyeFov.getBottom()));
134+
leftEyeFov.setTop(Math.min(topAngle, leftEyeFov.getTop()));
135+
136+
rightEyeFov.setLeft(Math.min(innerAngle, rightEyeFov.getLeft()));
137+
rightEyeFov.setRight(Math.min(outerAngle, rightEyeFov.getRight()));
138+
rightEyeFov.setBottom(Math.min(bottomAngle, rightEyeFov.getBottom()));
139+
rightEyeFov.setTop(Math.min(topAngle, rightEyeFov.getTop()));
140+
141+
return eyeToScreenDist;
142+
}
143+
}

cocos/platform/android/jni/JniHelper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace cocos2d {
6767
JavaVM* JniHelper::_psJavaVM = nullptr;
6868
jmethodID JniHelper::loadclassMethod_methodID = nullptr;
6969
jobject JniHelper::classloader = nullptr;
70+
jobject JniHelper::_activity = nullptr;
7071
std::unordered_map<JNIEnv*, std::vector<jobject>> JniHelper::localRefs;
7172

7273
JavaVM* JniHelper::getJavaVM() {
@@ -122,6 +123,10 @@ namespace cocos2d {
122123
_env = JniHelper::cacheEnv(_psJavaVM);
123124
return _env;
124125
}
126+
127+
jobject JniHelper::getActivity() {
128+
return _activity;
129+
}
125130

126131
bool JniHelper::setClassLoaderFrom(jobject activityinstance) {
127132
JniMethodInfo _getclassloaderMethod;
@@ -149,6 +154,7 @@ namespace cocos2d {
149154

150155
JniHelper::classloader = cocos2d::JniHelper::getEnv()->NewGlobalRef(_c);
151156
JniHelper::loadclassMethod_methodID = _m.methodID;
157+
JniHelper::_activity = cocos2d::JniHelper::getEnv()->NewGlobalRef(activityinstance);;
152158

153159
return true;
154160
}

cocos/platform/android/jni/JniHelper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class CC_DLL JniHelper
4646
static void setJavaVM(JavaVM *javaVM);
4747
static JavaVM* getJavaVM();
4848
static JNIEnv* getEnv();
49+
static jobject getActivity();
4950

5051
static bool setClassLoaderFrom(jobject activityInstance);
5152
static bool getStaticMethodInfo(JniMethodInfo &methodinfo,
@@ -174,6 +175,8 @@ class CC_DLL JniHelper
174175
const char *paramCode);
175176

176177
static JavaVM* _psJavaVM;
178+
179+
static jobject _activity;
177180

178181
static jstring convert(cocos2d::JniMethodInfo& t, const char* x);
179182

cocos/vr/CCVRCardboard.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/****************************************************************************
2+
Copyright (c) 2016 Chukong Technologies Inc.
3+
4+
http://www.cocos2d-x.org
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.
23+
****************************************************************************/
24+
25+
#include "platform/CCPlatformMacros.h"
26+
#include "vr/CCVRCardboard.h"
27+
#include "renderer/CCRenderer.h"
28+
#include "renderer/CCGLProgramState.h"
29+
#include "renderer/ccGLStateCache.h"
30+
#include "base/CCDirector.h"
31+
#include "2d/CCScene.h"
32+
#include "2d/CCCamera.h"
33+
#include "2d/CCSprite.h"
34+
#include "platform/CCGLView.h"
35+
#include "platform/android/jni/JniHelper.h"
36+
37+
38+
NS_CC_BEGIN
39+
40+
VRCardboard::VRCardboard()
41+
{
42+
}
43+
44+
VRCardboard::~VRCardboard()
45+
{
46+
}
47+
48+
void VRCardboard::setup(GLView* glview)
49+
{
50+
CCLOG("JNIENV: 0x%x, ACTIVITY: 0x%x, JAVAVM: 0x%x", (int)JniHelper::getEnv(), (int)JniHelper::getActivity(), (int)JniHelper::getJavaVM());
51+
cbJava java;
52+
java.ActivityObject = JniHelper::getEnv()->NewGlobalRef(JniHelper::getActivity());
53+
java.Env = JniHelper::getEnv();
54+
JniHelper::getEnv()->GetJavaVM(&java.Vm);
55+
if (cbapi_Initialize(&java, &_hmd)){
56+
_eyes = cbapi_GetEyes();
57+
}
58+
cbapi_EnterVrMode();
59+
}
60+
61+
void VRCardboard::cleanup()
62+
{
63+
cbapi_LeaveVrMode();
64+
}
65+
66+
void VRCardboard::render(Scene* scene, Renderer* renderer)
67+
{
68+
GLint viewport[4];
69+
glGetIntegerv(GL_VIEWPORT, viewport);
70+
71+
cbapi_beforeDrawFrame();
72+
glEnable(GL_SCISSOR_TEST);
73+
glDepthMask(true);
74+
for (unsigned short i = 0; i < CB_EYE_NUM; ++i){
75+
auto vp = _eyes.eyeParams[i].viewport;
76+
glScissor(vp.x, vp.y, vp.width, vp.height);
77+
glViewport(vp.x, vp.y, vp.width, vp.height);
78+
glClearColor(0.125f, 0.125f, 0.125f, 1.0f);
79+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
80+
const float eyeOffset = ( i ? -0.5f : 0.5f ) * _hmd.device.interLensDistance;
81+
scene->render(renderer, Vec3(eyeOffset,0,0));
82+
}
83+
glDepthMask(false);
84+
glDisable(GL_SCISSOR_TEST);
85+
cbapi_afterDrawFrame();
86+
87+
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
88+
}
89+
90+
NS_CC_END

cocos/vr/CCVRCardboard.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/****************************************************************************
2+
Copyright (c) 2016 Chukong Technologies Inc.
3+
4+
http://www.cocos2d-x.org
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.
23+
****************************************************************************/
24+
25+
#include "vr/CCVRProtocol.h"
26+
#include "renderer/CCCustomCommand.h"
27+
#include "renderer/CCFrameBuffer.h"
28+
#include "vr/cardboard/CbApi.h"
29+
30+
NS_CC_BEGIN
31+
32+
class Camera;
33+
class Sprite;
34+
35+
class CC_DLL VRCardboard : public VRProtocol
36+
{
37+
public:
38+
VRCardboard();
39+
virtual ~VRCardboard();
40+
41+
virtual void setup(GLView* glview);
42+
virtual void cleanup();
43+
virtual void render(Scene* scene, Renderer* renderer);
44+
45+
protected:
46+
47+
cbHeadMountedDisplay _hmd;
48+
cbEyes _eyes;
49+
};
50+
51+
NS_CC_END

0 commit comments

Comments
 (0)