-
Notifications
You must be signed in to change notification settings - Fork 0
/
stereocamera.py
134 lines (122 loc) · 4.6 KB
/
stereocamera.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import ctypes
from pi3d.constants import *
from pi3d.Shader import Shader
from pi3d.Camera import Camera
from pi3d.shape.Sprite import Sprite
from pi3d.util.OffScreenTexture import OffScreenTexture
from pi3d.Display import Display
#new branch
#----sterocamera changed to double quadra camera
#----in case, your compared with other single camera, study argorithm
class StereoCam(object):
"""For creating an apparatus with two sprites to hold left and right
eye views.
This Class is used to hold the 3D Camera which should be used to draw
the 3D objects. It also holds a 2D Camera for drawing the Sprites"""
def __init__(self, shader="uv_flat", mipmap=False, separation=0.4, interlace=0):
""" calls Texture.__init__ but doesn't need to set file name as
texture generated from the framebuffer. Keyword Arguments:
*shader*
to use when drawing sprite, defaults to post_base, a simple
3x3 convolution that does basic edge detection. Can be copied to
project directory and modified as required.
*mipmap*
can be set to True with slight cost to speed, or use fxaa shader
*separation*
distance between the two camera positions - how wide apart the
eye views are.
*interlace*
if interlace > 0 then the images are not taken with glScissor and
must be drawn with a special interlacing shader.
"""
# load shader
if interlace <= 0:
self.shader = Shader(shader)
else:
self.shader = Shader(vshader_source = """
precision mediump float;
attribute vec3 vertex;
attribute vec2 texcoord;
uniform mat4 modelviewmatrix[2];
varying vec2 texcoordout;
void main(void) {
texcoordout = texcoord;
gl_Position = modelviewmatrix[1] * vec4(vertex,1.0);
}
""", fshader_source = """
precision mediump float;
uniform sampler2D tex0;
uniform sampler2D tex1;
varying vec2 texcoordout;
void main(void) {{
vec4 texc0 = texture2D(tex0, texcoordout);
vec4 texc1 = texture2D(tex1, texcoordout);
vec2 coord = vec2(gl_FragCoord);
gl_FragColor = mix(texc0, texc1, step(0.5, fract(coord.x / {:f})));
}}
""".format(interlace * 2.0))
#self.shader = Shader("2d_flat")
self.camera_3d = Camera()
self.camera_2d = Camera(is_3d=False)
self.offs = separation / 2.0
self.interlace = interlace
self.textures = []
self.sprites = []
self.tex_list = []
for i in range(2):
self.textures.append(OffScreenTexture(name="stereo"))
ix, iy = self.textures[i].ix, self.textures[i].iy
#two sprites full width but moved so that they are centred on the
#left and right edges. The offset values then move the uv mapping
#so the image is on the right of the left sprite and left of the
#right sprite
self.sprites.append(Sprite(z=20.0, w=ix, h=iy, flip=True))
if interlace <= 0:
self.sprites[i].positionX(-ix/2.0 + i*ix)
self.sprites[i].set_offset((i * 0.5 - 0.25, 0.0))
else:
self.sprites[i].set_2d_size(w=ix, h=iy)
self.textures[i].blend = True
self.textures[i].mipmap = mipmap
self.tex_list.append(self.textures[i])
def move_camera(self, position, rot, tilt):
self.camera_3d.reset()
self.camera_3d.rotate(tilt, rot, 0)
self.camera_3d.position(position)
def start_capture(self, side):
""" after calling this method all object.draw()s will rendered
to this texture and not appear on the display.
*side*
Either 0 or 1 to determine stereoscopic view
"""
offs = -self.offs if side == 0 else self.offs
self.camera_3d.position((self.camera_3d.mtrx[2,3] * offs, 0,
-self.camera_3d.mtrx[0,3] * offs))
tex = self.textures[side]
tex._start()
if self.interlace <= 0:
xx = tex.ix / 4.0 # draw the middle only - half width
yy = 0
ww = tex.ix / 2.0
hh = tex.iy
opengles.glEnable(GL_SCISSOR_TEST)
opengles.glScissor(ctypes.c_int(int(xx)), ctypes.c_int(int(yy)),
ctypes.c_int(int(ww)), ctypes.c_int(int(hh)))
def end_capture(self, side):
""" stop capturing to texture and resume normal rendering to default
"""
self.textures[side]._end()
if self.interlace <= 0:
opengles.glDisable(GL_SCISSOR_TEST)
def draw(self):
""" draw the shape using the saved texture
"""
if self.interlace <= 0:
for i in range(2):
self.sprites[i].draw(self.shader, [self.tex_list[i]], 0.0, 0.0, self.camera_2d)
else:
self.sprites[0].draw(self.shader, self.tex_list, 0.0, 0.0, self.camera_2d)
##master commit
##success commit
Status API Training Shop Blog About
© 2016 GitHub, Inc. Terms Privacy Security Contact Help