Commit 7a101aa0 authored by Dalai Felinto's avatar Dalai Felinto
Browse files

Use the new gpu.offscreen_object_*() functions

parent 2a4568ff
...@@ -6,6 +6,8 @@ from mathutils import ( ...@@ -6,6 +6,8 @@ from mathutils import (
Vector, Vector,
) )
import gpu
# ############################################################ # ############################################################
# Data structs # Data structs
...@@ -44,8 +46,8 @@ class HMD_Data: ...@@ -44,8 +46,8 @@ class HMD_Data:
interpupillary_distance = Vector((0.0, 0.0)) interpupillary_distance = Vector((0.0, 0.0))
width = 0 width = 0
height = 0 height = 0
fbo = 0 fbo_id = 0
texture = 0 texture_id = 0
# ############################################################ # ############################################################
...@@ -59,6 +61,7 @@ class HMD_Base: ...@@ -59,6 +61,7 @@ class HMD_Base:
"_interpupillary_distance", "_interpupillary_distance",
"_modelview_matrix", "_modelview_matrix",
"_name", "_name",
"_offscreen_object",
"_projection_matrix", "_projection_matrix",
"_texture", "_texture",
"_width", "_width",
...@@ -71,16 +74,21 @@ class HMD_Base: ...@@ -71,16 +74,21 @@ class HMD_Base:
self._interpupillary_distance = Vector((0.0, 0.0)) self._interpupillary_distance = Vector((0.0, 0.0))
self._width = 0 self._width = 0
self._height = 0 self._height = 0
self._fbo = 0 self._fbo_id = 0
self._texture = 0 self._texture_id = 0
self._offscreen_object = None
@property
def offscreen_object(self):
return self._offscreen_object
@property @property
def fbo(self): def fbo(self):
return self._fbo return self._fbo_id
@property @property
def texture(self): def texture(self):
return self._texture return self._texture_id
@property @property
def width(self): def width(self):
...@@ -115,7 +123,17 @@ class HMD_Base: ...@@ -115,7 +123,17 @@ class HMD_Base:
:return: return True if the device was properly initialized :return: return True if the device was properly initialized
:rtype: bool :rtype: bool
""" """
assert False, "init() not implemented for the \"{0}\" device".format(self._name) try:
self._offscreen_object = gpu.offscreen_object_create(self._width, self._height)
self._fbo_id = self._offscreen_object.framebuffer_object
self._texture_id = self._offscreen_object.color_object
except Exception as E:
print(E)
return False
else:
return True
def loop(self): def loop(self):
""" """
...@@ -133,5 +151,9 @@ class HMD_Base: ...@@ -133,5 +151,9 @@ class HMD_Base:
""" """
Garbage collection Garbage collection
""" """
assert False, "quit() not implemented for the \"{0}\" device".format(self._name) try:
gpu.offscreen_object_free(self._offscreen_object)
except Exception as E:
print(E)
...@@ -18,10 +18,6 @@ class Debug(HMD_Base): ...@@ -18,10 +18,6 @@ class Debug(HMD_Base):
def __init__(self): def __init__(self):
super(Debug, self).__init__('Debug') super(Debug, self).__init__('Debug')
@property
def texture(self):
return self._fbo._gl_data.color_tex
def isConnected(self): def isConnected(self):
""" """
Check if device is connected Check if device is connected
...@@ -44,30 +40,32 @@ class Debug(HMD_Base): ...@@ -44,30 +40,32 @@ class Debug(HMD_Base):
self._width = 1024 self._width = 1024
self._height = 512 self._height = 512
self._fbo = FBO(self._width, self._height) return super(Debug, self).init()
return True
def loop(self): def loop(self):
""" """
Get fresh tracking data Get fresh tracking data
""" """
print_debug('loop()') print_debug('loop()')
debug_draw(self._offscreen_object, self._width, self._height)
def frameReady(self): def frameReady(self):
""" """
The frame is ready to be send to the device The frame is ready to be send to the device
""" """
self._fbo.run()
print_debug('frameReady()') print_debug('frameReady()')
def quit(self): def quit(self):
""" """
Garbage collection Garbage collection
""" """
self._fbo.delete()
print_debug('quit()') print_debug('quit()')
return super(Debug, self).quit()
# ##################
# Debug Debug Debug
# ##################
from bgl import * from bgl import *
...@@ -75,18 +73,6 @@ from bgl import * ...@@ -75,18 +73,6 @@ from bgl import *
global _time global _time
_time = 0 _time = 0
# ##################
# Data struct
# ##################
class GLdata:
def __init__(self):
self.color_tex = -1
self.fb = -1
self.rb = -1
self.width = 0
self.height = 0
# ################## # ##################
# OpenGL generic routines # OpenGL generic routines
...@@ -122,217 +108,90 @@ def view_reset(): ...@@ -122,217 +108,90 @@ def view_reset():
# ################## # ##################
# FBO related routines # Draw an animated cube on the offscreen object
# ################## # ##################
class FBO: def debug_draw(offscreen_object, width, height):
__slots__ = { """
"_gl_data", draw in the FBO
} """
import time
def __init__(self, width, height): import math
import gpu
# initialize opengl data
self._gl_data = GLdata()
# initialize fbo
self.setup(width, height)
def setup(self, width, height):
gl_data = self._gl_data
gl_data.width = width
gl_data.height = height
id_buf = Buffer(GL_INT, 1) global _time
act_fbo = Buffer(GL_INT, 1) # setup
glGetIntegerv(GL_FRAMEBUFFER, act_fbo) viewport = Buffer(GL_INT, 4)
glGetIntegerv(GL_VIEWPORT, viewport)
act_tex = Buffer(GL_INT, 1) glViewport(0, 0, width, height)
glGetIntegerv(GL_ACTIVE_TEXTURE, act_tex)
#RGBA8 2D texture, 24 bit depth texture, width x height
glGenTextures(1, id_buf)
gl_data.color_tex = id_buf.to_list()[0]
glBindTexture(GL_TEXTURE_2D, gl_data.color_tex)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
# NULL means reserve texture memory, but texels are undefined
null_buffer = Buffer(GL_BYTE, [(gl_data.width + 1) * (gl_data.height + 1) * 4])
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, gl_data.width, gl_data.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, null_buffer)
glBindTexture(GL_TEXTURE_2D, act_tex[0])
glGenFramebuffers(1, id_buf)
gl_data.fb = id_buf.to_list()[0]
glBindFramebuffer(GL_FRAMEBUFFER, gl_data.fb)
# Attach 2D texture to this FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl_data.color_tex, 0)
glGenRenderbuffers(1, id_buf)
gl_data.depth_rb = id_buf.to_list()[0]
glBindRenderbuffer(GL_RENDERBUFFER, gl_data.depth_rb)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, gl_data.width, gl_data.height)
# Attach depth buffer to FBO
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gl_data.depth_rb)
# Does the GPU support current FBO configuration?
status = glCheckFramebufferStatus(GL_FRAMEBUFFER)
glBindFramebuffer(GL_FRAMEBUFFER, act_fbo[0])
if status == GL_FRAMEBUFFER_COMPLETE:
print("FBO: good: {0} : {1} : {2}".format(gl_data.color_tex, gl_data.depth_rb, gl_data.fb))
else:
print("FBO: error", status)
def run(self):
"""
draw in the FBO
"""
gl_data = self._gl_data
act_fbo = Buffer(GL_INT, 1) gpu.offscreen_object_bind(offscreen_object, True)
glGetIntegerv(GL_FRAMEBUFFER, act_fbo)
# setup glClearColor(1.0, 1.0, 1.0, 1.0)
viewport = Buffer(GL_INT, 4) glClearDepth(1.0)
glGetIntegerv(GL_VIEWPORT, viewport) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glViewport(0, 0, gl_data.width, gl_data.height)
glBindFramebuffer(GL_FRAMEBUFFER, gl_data.fb) glDisable(GL_DEPTH_TEST)
glActiveTexture(GL_TEXTURE0) glDepthFunc(GL_LESS)
glClearColor(1.0, 1.0, 1.0, 1.0) view_setup()
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
act_tex = Buffer(GL_INT, 1) # actual drawing
glGetIntegerv(GL_ACTIVE_TEXTURE, act_tex) speed = 0.01
glDisable(GL_DEPTH_TEST) one = 1.0
glDepthFunc(GL_LESS) zer = 0.0
# actual drawing _time, _int = math.modf(_time + speed)
view_setup() factor = _time * 2.0
glEnable(GL_TEXTURE_2D) if factor > 1.0:
glActiveTexture(GL_TEXTURE0) factor = 2.0 - factor;
glBindTexture(GL_TEXTURE_2D, gl_data.color_tex)
# actual drawing one = one - factor;
self._draw_a_quad() zer = factor - zer;
glBindTexture(GL_TEXTURE_2D, act_tex[0]) glMatrixMode(GL_PROJECTION)
glPushMatrix()
glDisable(GL_TEXTURE_2D) glLoadIdentity()
glDisable(GL_DEPTH_TEST) glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, 20.0)
view_reset()
glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
# unbinding
glBindFramebuffer(GL_FRAMEBUFFER, act_fbo[0])
glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
def _draw_a_quad(self):
"""
draw an animated quad on the screen
"""
import time
import math
global _time
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;
glClearColor(1.0, 1.0, 1.0, 1.0)
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
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) glMatrixMode(GL_MODELVIEW)
glPopMatrix() glPushMatrix()
glLoadIdentity()
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
glMatrixMode(GL_MODELVIEW) current_color = Buffer(GL_FLOAT, 4)
glPopMatrix() glGetFloatv(GL_CURRENT_COLOR, current_color);
def _debug_quad(self): glEnable(GL_COLOR_MATERIAL)
viewport = Buffer(GL_INT, 4)
glGetIntegerv(GL_VIEWPORT, viewport)
glViewport(300, 200, 256, 256)
glScissor(300, 200, 256, 256)
# actual drawing glBegin(GL_QUADS)
self._draw_a_quad() 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()
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]) glColor4fv(current_color)
glScissor(viewport[0], viewport[1], viewport[2], viewport[3]) glDisable(GL_COLOR_MATERIAL)
def delete(self): glMatrixMode(GL_PROJECTION)
""" glPopMatrix()
cleanup FBO data
"""
gl_data = self._gl_data
id_buf = Buffer(GL_INT, 1)
id_buf.to_list()[0] = gl_data.color_tex glMatrixMode(GL_MODELVIEW)
glDeleteTextures(1, id_buf) glPopMatrix()
id_buf.to_list()[0] = gl_data.depth_rb glDisable(GL_DEPTH_TEST)
glDeleteRenderbuffers(1, id_buf)
id_buf.to_list()[0] = gl_data.fb view_reset()
glDeleteFramebuffers(1, id_buf) glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
def __del__(self): # unbinding
self.delete() gpu.offscreen_object_unbind(offscreen_object, True)
...@@ -49,8 +49,9 @@ class Oculus(HMD_Base): ...@@ -49,8 +49,9 @@ class Oculus(HMD_Base):
""" """
Oculus SDK bridge Oculus SDK bridge
return: status, fbo, texture, projection matrix, eye separation, width, height return: status, projection matrix, eye separation, width, height
""" """
return super(Oculus, self).init()
def loop(self): def loop(self):
""" """
...@@ -82,4 +83,5 @@ class Oculus(HMD_Base): ...@@ -82,4 +83,5 @@ class Oculus(HMD_Base):
delete fbo, rbo, tex_id delete fbo, rbo, tex_id
""" """
return super(Oculus, self).quit()
...@@ -158,16 +158,14 @@ class VirtualRealityDisplayOperator(bpy.types.Operator): ...@@ -158,16 +158,14 @@ class VirtualRealityDisplayOperator(bpy.types.Operator):
""" """
self._hmd.loop() self._hmd.loop()
fbo = self._hmd.fbo offscreen_object = self._hmd.offscreen_object
width = self._hmd.width
height = self._hmd.height
projection_matrix = self._hmd.projection_matrix
modelview_matrix = self._hmd.modelview_matrix modelview_matrix = self._hmd.modelview_matrix
projection_matrix = self._hmd.projection_matrix
TODO TODO # need to run this twice, once for each eye
"""
bpy.ops.view3d.offscreen(fbo, width, height, projection_matrix, modelview_matrix) # drawing
""" # bpy.ops.view3d.offscreen(offscreen_object=offscreen_object, projection_matrix=projection_matrix, modelview_matrix=modelview_matrix)
self._hmd.frameReady() self._hmd.frameReady()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment