Skip to content

Commit 4e5d080

Browse files
author
Collin Meyer
committed
Add support for vr goggle phone holders (Split display rendering of video)
1 parent 518a92b commit 4e5d080

12 files changed

+1741
-77
lines changed

app/src/main/java/com/fpvout/digiview/MainActivity.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,10 @@ public void onClick(View v) {
113113
mUsbMaskConnection = new UsbMaskConnection();
114114
Handler videoReaderEventListener = new Handler(this.getMainLooper(), msg -> onVideoReaderEvent((VideoReaderExoplayer.VideoReaderEventMessageCode) msg.obj));
115115

116-
mVideoReader = new VideoReaderExoplayer(fpvView, this, videoReaderEventListener);
116+
SurfaceView surfaceVideoLeft = findViewById(R.id.surfaceViewLeft);
117+
SurfaceView surfaceVideoRight = findViewById(R.id.surfaceViewRight);
118+
119+
mVideoReader = new VideoReaderExoplayer(fpvView, surfaceVideoLeft, surfaceVideoRight, this, videoReaderEventListener);
117120

118121
if (!usbConnected) {
119122
if (searchDevice()) {

app/src/main/java/com/fpvout/digiview/VideoReaderExoplayer.java

+220-75
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/*
2+
* Copyright 2014 Google Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.fpvout.digiview.gles;
18+
19+
import java.nio.FloatBuffer;
20+
21+
/**
22+
* Base class for stuff we like to draw.
23+
*/
24+
public class Drawable2d {
25+
private static final int SIZEOF_FLOAT = 4;
26+
27+
/**
28+
* Simple equilateral triangle (1.0 per side). Centered on (0,0).
29+
*/
30+
private static final float TRIANGLE_COORDS[] = {
31+
0.0f, 0.577350269f, // 0 top
32+
-0.5f, -0.288675135f, // 1 bottom left
33+
0.5f, -0.288675135f // 2 bottom right
34+
};
35+
private static final float TRIANGLE_TEX_COORDS[] = {
36+
0.5f, 0.0f, // 0 top center
37+
0.0f, 1.0f, // 1 bottom left
38+
1.0f, 1.0f, // 2 bottom right
39+
};
40+
private static final FloatBuffer TRIANGLE_BUF =
41+
GlUtil.createFloatBuffer(TRIANGLE_COORDS);
42+
private static final FloatBuffer TRIANGLE_TEX_BUF =
43+
GlUtil.createFloatBuffer(TRIANGLE_TEX_COORDS);
44+
45+
/**
46+
* Simple square, specified as a triangle strip. The square is centered on (0,0) and has
47+
* a size of 1x1.
48+
* <p>
49+
* Triangles are 0-1-2 and 2-1-3 (counter-clockwise winding).
50+
*/
51+
private static final float RECTANGLE_COORDS[] = {
52+
-0.5f, -0.5f, // 0 bottom left
53+
0.5f, -0.5f, // 1 bottom right
54+
-0.5f, 0.5f, // 2 top left
55+
0.5f, 0.5f, // 3 top right
56+
};
57+
private static final float RECTANGLE_TEX_COORDS[] = {
58+
0.0f, 1.0f, // 0 bottom left
59+
1.0f, 1.0f, // 1 bottom right
60+
0.0f, 0.0f, // 2 top left
61+
1.0f, 0.0f // 3 top right
62+
};
63+
private static final FloatBuffer RECTANGLE_BUF =
64+
GlUtil.createFloatBuffer(RECTANGLE_COORDS);
65+
private static final FloatBuffer RECTANGLE_TEX_BUF =
66+
GlUtil.createFloatBuffer(RECTANGLE_TEX_COORDS);
67+
68+
/**
69+
* A "full" square, extending from -1 to +1 in both dimensions. When the model/view/projection
70+
* matrix is identity, this will exactly cover the viewport.
71+
* <p>
72+
* The texture coordinates are Y-inverted relative to RECTANGLE. (This seems to work out
73+
* right with external textures from SurfaceTexture.)
74+
*/
75+
private static final float FULL_RECTANGLE_COORDS[] = {
76+
-1.0f, -1.0f, // 0 bottom left
77+
1.0f, -1.0f, // 1 bottom right
78+
-1.0f, 1.0f, // 2 top left
79+
1.0f, 1.0f, // 3 top right
80+
};
81+
private static final float FULL_RECTANGLE_TEX_COORDS[] = {
82+
0.0f, 0.0f, // 0 bottom left
83+
1.0f, 0.0f, // 1 bottom right
84+
0.0f, 1.0f, // 2 top left
85+
1.0f, 1.0f // 3 top right
86+
};
87+
private static final FloatBuffer FULL_RECTANGLE_BUF =
88+
GlUtil.createFloatBuffer(FULL_RECTANGLE_COORDS);
89+
private static final FloatBuffer FULL_RECTANGLE_TEX_BUF =
90+
GlUtil.createFloatBuffer(FULL_RECTANGLE_TEX_COORDS);
91+
92+
93+
private FloatBuffer mVertexArray;
94+
private FloatBuffer mTexCoordArray;
95+
private int mVertexCount;
96+
private int mCoordsPerVertex;
97+
private int mVertexStride;
98+
private int mTexCoordStride;
99+
private Prefab mPrefab;
100+
101+
/**
102+
* Enum values for constructor.
103+
*/
104+
public enum Prefab {
105+
TRIANGLE, RECTANGLE, FULL_RECTANGLE
106+
}
107+
108+
/**
109+
* Prepares a drawable from a "pre-fabricated" shape definition.
110+
* <p>
111+
* Does no EGL/GL operations, so this can be done at any time.
112+
*/
113+
public Drawable2d(Prefab shape) {
114+
switch (shape) {
115+
case TRIANGLE:
116+
mVertexArray = TRIANGLE_BUF;
117+
mTexCoordArray = TRIANGLE_TEX_BUF;
118+
mCoordsPerVertex = 2;
119+
mVertexStride = mCoordsPerVertex * SIZEOF_FLOAT;
120+
mVertexCount = TRIANGLE_COORDS.length / mCoordsPerVertex;
121+
break;
122+
case RECTANGLE:
123+
mVertexArray = RECTANGLE_BUF;
124+
mTexCoordArray = RECTANGLE_TEX_BUF;
125+
mCoordsPerVertex = 2;
126+
mVertexStride = mCoordsPerVertex * SIZEOF_FLOAT;
127+
mVertexCount = RECTANGLE_COORDS.length / mCoordsPerVertex;
128+
break;
129+
case FULL_RECTANGLE:
130+
mVertexArray = FULL_RECTANGLE_BUF;
131+
mTexCoordArray = FULL_RECTANGLE_TEX_BUF;
132+
mCoordsPerVertex = 2;
133+
mVertexStride = mCoordsPerVertex * SIZEOF_FLOAT;
134+
mVertexCount = FULL_RECTANGLE_COORDS.length / mCoordsPerVertex;
135+
break;
136+
default:
137+
throw new RuntimeException("Unknown shape " + shape);
138+
}
139+
mTexCoordStride = 2 * SIZEOF_FLOAT;
140+
mPrefab = shape;
141+
}
142+
143+
/**
144+
* Returns the array of vertices.
145+
* <p>
146+
* To avoid allocations, this returns internal state. The caller must not modify it.
147+
*/
148+
public FloatBuffer getVertexArray() {
149+
return mVertexArray;
150+
}
151+
152+
/**
153+
* Returns the array of texture coordinates.
154+
* <p>
155+
* To avoid allocations, this returns internal state. The caller must not modify it.
156+
*/
157+
public FloatBuffer getTexCoordArray() {
158+
return mTexCoordArray;
159+
}
160+
161+
/**
162+
* Returns the number of vertices stored in the vertex array.
163+
*/
164+
public int getVertexCount() {
165+
return mVertexCount;
166+
}
167+
168+
/**
169+
* Returns the width, in bytes, of the data for each vertex.
170+
*/
171+
public int getVertexStride() {
172+
return mVertexStride;
173+
}
174+
175+
/**
176+
* Returns the width, in bytes, of the data for each texture coordinate.
177+
*/
178+
public int getTexCoordStride() {
179+
return mTexCoordStride;
180+
}
181+
182+
/**
183+
* Returns the number of position coordinates per vertex. This will be 2 or 3.
184+
*/
185+
public int getCoordsPerVertex() {
186+
return mCoordsPerVertex;
187+
}
188+
189+
@Override
190+
public String toString() {
191+
if (mPrefab != null) {
192+
return "[Drawable2d: " + mPrefab + "]";
193+
} else {
194+
return "[Drawable2d: ...]";
195+
}
196+
}
197+
}

0 commit comments

Comments
 (0)