Commit 26edbdf0 authored by Dalai Felinto's avatar Dalai Felinto
Browse files

Debug, and left-eye rendering

parent d52fc549
...@@ -41,13 +41,13 @@ def HMD(display_backend): ...@@ -41,13 +41,13 @@ def HMD(display_backend):
class HMD_Data: class HMD_Data:
status = None status = None
projection_matrix = Matrix() projection_matrix = Matrix.Identity(4)
modelview_matrix = Matrix() modelview_matrix = Matrix.Identity(4)
interpupillary_distance = Vector((0.0, 0.0)) interpupillary_distance = Vector((0.0, 0.0))
width = 0 width = 0
height = 0 height = 0
fbo_id = 0 framebuffer_object = 0
texture_id = 0 color_object = 0
# ############################################################ # ############################################################
...@@ -56,56 +56,60 @@ class HMD_Data: ...@@ -56,56 +56,60 @@ class HMD_Data:
class HMD_Base: class HMD_Base:
__slots__ = { __slots__ = {
"_fbo", "_color_object",
"_current_eye",
"_framebuffer_object",
"_height", "_height",
"_interpupillary_distance", "_interpupillary_distance",
"_modelview_matrix", "_modelview_matrix",
"_name", "_name",
"_offscreen_object", "_offscreen_object",
"_projection_matrix", "_projection_matrix",
"_texture",
"_width", "_width",
} }
def __init__(self, name): def __init__(self, name):
self._name = name self._name = name
self._projection_matrix = Matrix.Identity(4) self._current_eye = 0
self._modelview_matrix = Matrix.Identity(4)
self._interpupillary_distance = Vector((0.0, 0.0))
self._width = 0 self._width = 0
self._height = 0 self._height = 0
self._fbo_id = 0 self._projection_matrix = [Matrix.Identity(4), Matrix.Identity(4)]
self._texture_id = 0 self._modelview_matrix = [Matrix.Identity(4), Matrix.Identity(4)]
self._offscreen_object = None self._interpupillary_distance = Vector((0.0, 0.0))
self._framebuffer_object = [0, 0]
self._color_object = [0, 0]
self._offscreen_object = [None, None]
@property @property
def offscreen_object(self): def width(self):
return self._offscreen_object return self._width
@property @property
def fbo(self): def height(self):
return self._fbo_id return self._height
@property @property
def texture(self): def offscreen_object(self):
return self._texture_id return self._offscreen_object[self._current_eye]
@property @property
def width(self): def framebuffer_object(self):
return self._width return self._framebuffer_object[self._current_eye]
@property @property
def height(self): def color_object(self):
return self._height return self._color_object[self._current_eye]
@property @property
def projection_matrix(self): def projection_matrix(self):
return self._projection_matrix return self._projection_matrix[self._current_eye]
@property @property
def modelview_matrix(self): def modelview_matrix(self):
TODO # calculate return self._modelview_matrix[self._current_eye]
return self._modelview_matrix
def setEye(self, eye):
self._current_eye = int(bool(eye))
def isConnected(self): def isConnected(self):
""" """
...@@ -124,9 +128,10 @@ class HMD_Base: ...@@ -124,9 +128,10 @@ class HMD_Base:
:rtype: bool :rtype: bool
""" """
try: try:
self._offscreen_object = gpu.offscreen_object_create(self._width, self._height) for i in range(2):
self._fbo_id = self._offscreen_object.framebuffer_object self._offscreen_object[i] = gpu.offscreen_object_create(self._width, self._height)
self._texture_id = self._offscreen_object.color_object self._framebuffer_object[i] = self._offscreen_object[i].framebuffer_object
self._color_object[i] = self._offscreen_object[i].color_object
except Exception as E: except Exception as E:
print(E) print(E)
...@@ -135,15 +140,15 @@ class HMD_Base: ...@@ -135,15 +140,15 @@ class HMD_Base:
else: else:
return True return True
def loop(self): def loop(self, context):
""" """
Get fresh tracking data Get fresh tracking data
""" """
assert False, "loop() not implemented for the \"{0}\" device".format(self._name) self.updateMatrices(context)
def frameReady(self): def frameReady(self):
""" """
The frame is ready to be send to the device The frame is ready to be sent to the device
""" """
assert False, "frameReady() not implemented for the \"{0}\" device".format(self._name) assert False, "frameReady() not implemented for the \"{0}\" device".format(self._name)
...@@ -152,8 +157,16 @@ class HMD_Base: ...@@ -152,8 +157,16 @@ class HMD_Base:
Garbage collection Garbage collection
""" """
try: try:
gpu.offscreen_object_free(self._offscreen_object) for i in range(2):
gpu.offscreen_object_free(self._offscreen_object[i])
except Exception as E: except Exception as E:
print(E) print(E)
def updateMatrices(self, context):
"""
Update OpenGL drawing matrices
"""
TODO
...@@ -37,17 +37,17 @@ class Debug(HMD_Base): ...@@ -37,17 +37,17 @@ class Debug(HMD_Base):
""" """
print_debug('init()') print_debug('init()')
self._width = 1024 self._width = 512
self._height = 512 self._height = 512
return super(Debug, self).init() return super(Debug, self).init()
def loop(self): def loop(self, context):
""" """
Get fresh tracking data Get fresh tracking data
""" """
print_debug('loop()') print_debug('loop()')
#debug_draw(self._offscreen_object, self._width, self._height) super(Debug, self).loop(context)
def frameReady(self): def frameReady(self):
""" """
...@@ -62,136 +62,17 @@ class Debug(HMD_Base): ...@@ -62,136 +62,17 @@ class Debug(HMD_Base):
print_debug('quit()') print_debug('quit()')
return super(Debug, self).quit() return super(Debug, self).quit()
def updateMatrices(self, context):
"""
Update OpenGL drawing matrices
"""
camera = context.scene.camera
# ################## modelview_matrix = camera.matrix_world.inverted()
# Debug Debug Debug projection_matrix = camera.calc_matrix_camera()
# ##################
from bgl import *
global _time
_time = 0
# ##################
# OpenGL generic routines
# ##################
def view_setup():
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glMatrixMode(GL_TEXTURE)
glPushMatrix()
glLoadIdentity()
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
glOrtho(-1, 1, -1, 1, -20, 20)
gluLookAt(0.0, 0.0, 1.0, 0.0,0.0,0.0, 0.0,1.0,0.0)
def view_reset():
# Get texture info
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_TEXTURE)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
# ##################
# Draw an animated cube on the offscreen object
# ##################
def debug_draw(offscreen_object, width, height):
"""
draw in the FBO
"""
import time
import math
import gpu
global _time
# setup
viewport = Buffer(GL_INT, 4)
glGetIntegerv(GL_VIEWPORT, viewport)
glViewport(0, 0, width, height)
gpu.offscreen_object_bind(offscreen_object, True)
glClearColor(1.0, 1.0, 1.0, 1.0)
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glDisable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
view_setup()
# actual drawing
speed = 0.01
one = 1.0
zer = 0.0
_time, _int = math.modf(_time + speed)
factor = _time * 2.0
if factor > 1.0:
factor = 2.0 - factor;
one = one - factor;
zer = factor - zer;
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, 20.0)
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
current_color = Buffer(GL_FLOAT, 4)
glGetFloatv(GL_CURRENT_COLOR, current_color);
glEnable(GL_COLOR_MATERIAL)
glBegin(GL_QUADS)
glColor3f(one, zer, zer)
glVertex3f(-0.75, -0.75, 0.0)
glColor3f(zer, one, zer)
glVertex3f( 0.75, -0.75, 0.0)
glColor3f(zer, zer, one)
glVertex3f( 0.75, 0.75, 0.0)
glColor3f(one, one, zer)
glVertex3f(-0.75, 0.75, 0.0)
glEnd()
glColor4fv(current_color)
glDisable(GL_COLOR_MATERIAL)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
glDisable(GL_DEPTH_TEST)
view_reset() for i in range(2):
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]) self._modelview_matrix[i] = modelview_matrix
self._projection_matrix[i] = projection_matrix
# unbinding
gpu.offscreen_object_unbind(offscreen_object, True)
...@@ -51,9 +51,11 @@ class Oculus(HMD_Base): ...@@ -51,9 +51,11 @@ class Oculus(HMD_Base):
return: status, projection matrix, eye separation, width, height return: status, projection matrix, eye separation, width, height
""" """
self._width = 512 #TODO
self._height = 512 #TODO
return super(Oculus, self).init() return super(Oculus, self).init()
def loop(self): def loop(self, context):
""" """
Get fresh tracking data Get fresh tracking data
""" """
...@@ -63,6 +65,7 @@ class Oculus(HMD_Base): ...@@ -63,6 +65,7 @@ class Oculus(HMD_Base):
return:head position, head orientation return:head position, head orientation
""" """
super(Oculus, self).loop(context)
def frameReady(self): def frameReady(self):
""" """
......
...@@ -59,7 +59,7 @@ class VirtualRealityDisplayOperator(bpy.types.Operator): ...@@ -59,7 +59,7 @@ class VirtualRealityDisplayOperator(bpy.types.Operator):
return {'FINISHED'} return {'FINISHED'}
if event.type == 'TIMER': if event.type == 'TIMER':
self.loop(vr.color_object) self.loop(context, vr.color_object_left, vr.color_object_right)
if vr.preview_scale and context.area: if vr.preview_scale and context.area:
area.tag_redraw() area.tag_redraw()
...@@ -140,9 +140,13 @@ class VirtualRealityDisplayOperator(bpy.types.Operator): ...@@ -140,9 +140,13 @@ class VirtualRealityDisplayOperator(bpy.types.Operator):
# get the data from device # get the data from device
width = self._hmd.width width = self._hmd.width
height = self._hmd.height height = self._hmd.height
texture = self._hmd.texture
self._preview.init(texture) color_object = [0, 0]
for i in range(2):
self._hmd.setEye(i)
color_object[i] = self._hmd.color_object
self._preview.init(color_object[0], color_object[1])
self._area_hash = hash(context.area) self._area_hash = hash(context.area)
# setup modal # setup modal
...@@ -152,25 +156,26 @@ class VirtualRealityDisplayOperator(bpy.types.Operator): ...@@ -152,25 +156,26 @@ class VirtualRealityDisplayOperator(bpy.types.Operator):
return True return True
def loop(self, color_object): def loop(self, context, color_object_left, color_object_right):
""" """
Get fresh tracking data and render into the FBO Get fresh tracking data and render into the FBO
""" """
self._hmd.loop() self._hmd.loop(context)
offscreen_object = self._hmd.offscreen_object
modelview_matrix = self._hmd.modelview_matrix
projection_matrix = self._hmd.projection_matrix
TODO # need to run this twice, once for each eye for i in range(2):
self._hmd.setEye(i)
# drawing offscreen_object = self._hmd.offscreen_object
# bpy.ops.view3d.offscreen(offscreen_object=offscreen_object, projection_matrix=projection_matrix, modelview_matrix=modelview_matrix) modelview_matrix = self._hmd.modelview_matrix
bpy.ops.view3d.offscreen(projection_matrix=projection_matrix, modelview_matrix=modelview_matrix) projection_matrix = self._hmd.projection_matrix
self._preview.update(color_object) # drawing
# bpy.ops.view3d.offscreen(offscreen_object=offscreen_object, projection_matrix=projection_matrix, modelview_matrix=modelview_matrix)
bpy.ops.view3d.offscreen(projection_matrix=projection_matrix, modelview_matrix=modelview_matrix) #DEBUG
self._hmd.frameReady() self._hmd.frameReady()
self._preview.update(color_object_left, color_object_right) #DEBUG
def _draw_callback_px(self, context): def _draw_callback_px(self, context):
"""callback function, run every time the viewport is refreshed""" """callback function, run every time the viewport is refreshed"""
...@@ -199,8 +204,14 @@ class VirtualRealityInfo(bpy.types.PropertyGroup): ...@@ -199,8 +204,14 @@ class VirtualRealityInfo(bpy.types.PropertyGroup):
subtype='PERCENTAGE', subtype='PERCENTAGE',
) )
color_object = bpy.props.IntProperty( color_object_left = bpy.props.IntProperty(
name="Color Object", name="Color Object Left",
default=0,
subtype='UNSIGNED',
)
color_object_right = bpy.props.IntProperty(
name="Color Object Right",
default=0, default=0,
subtype='UNSIGNED', subtype='UNSIGNED',
) )
......
...@@ -7,7 +7,6 @@ that is projected in the HMD ...@@ -7,7 +7,6 @@ that is projected in the HMD
""" """
from .opengl_helper import ( from .opengl_helper import (
draw_rectangle,
view_reset, view_reset,
view_setup, view_setup,
) )
...@@ -19,17 +18,20 @@ TODO = True ...@@ -19,17 +18,20 @@ TODO = True
class Preview: class Preview:
__slots__ = { __slots__ = {
"_texture", "_color_object_left",
"_color_object_right",
} }
def init(self, texture): def init(self, color_object_left, color_object_right):
""" """
Initialize preview window Initialize preview window
:param texture: 2D Texture binding ID (bind to the Framebuffer Object) :param color_object_left: 2D Texture binding ID (bind to the Framebuffer Object) for left eye
:type texture: bgl.GLint :type color_object_left: bgl.GLuint
:param color_object_right: 2D Texture binding ID (bind to the Framebuffer Object) for right eye
:type color_object_right: bgl.GLuint
""" """
self.update(texture) self.update(color_object_left, color_object_right)
def quit(self): def quit(self):
""" """
...@@ -37,14 +39,33 @@ class Preview: ...@@ -37,14 +39,33 @@ class Preview:
""" """
pass pass
def update(self, texture): def update(self, color_object_left, color_object_right):
""" """
Resize preview window Update OpenGL binding textures
:param texture: 2D Texture binding ID (bind to the Framebuffer Object) :param color_object_left: 2D Texture binding ID (bind to the Framebuffer Object) for left eye
:type texture: bgl.GLint :type color_object_left: bgl.GLuint
:param color_object_right: 2D Texture binding ID (bind to the Framebuffer Object) for right eye
:type color_object_right: bgl.GLuint
""" """
self._texture = texture self._color_object_left = color_object_left
self._color_object_right = color_object_right
def _drawRectangle(self, eye):
texco = [(1, 1), (0, 1), (0, 0), (1,0)]
verco = [[(0.0, 1.0), (-1.0, 1.0), (-1.0, -1.0), ( 0.0, -1.0)],
[(1.0, 1.0), ( 0.0, 1.0), ( 0.0, -1.0), ( 1.0, -1.0)]]
glPolygonMode(GL_FRONT_AND_BACK , GL_FILL)
glColor4f(1.0, 1.0, 1.0, 0.0)
glBegin(GL_QUADS)
for i in range(4):
glTexCoord3f(texco[i][0], texco[i][1], 0.0)
glVertex2f(verco[eye][i][0], verco[eye][i][1])
glEnd()
def loop(self, scale): def loop(self, scale):
""" """
...@@ -53,8 +74,6 @@ class Preview: ...@@ -53,8 +74,6 @@ class Preview: