Commit 0f2c2509 authored by Dalai Felinto's avatar Dalai Felinto
Browse files

opengl routines to handle framebuffer

parent 94f82b65
Loading
Loading
Loading
Loading
+4 −0
Changes for space_view3d_virtual_reality/__init__.py: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ from . import oculus

from . import ui

from . import sandbox

def get_context_3dview (context):
    """returns area and space"""
    screen = context.screen
@@ -238,12 +240,14 @@ class VirtualRealityViewportOperator(bpy.types.Operator):

def register():
    bpy.utils.register_class(VirtualRealityViewportOperator)
    sandbox.register()
    ui.register()


def unregister():
    bpy.utils.unregister_class(VirtualRealityViewportOperator)
    ui.unregister()
    sandbox.unregister()


if __name__ == '__main__':
+74 −0
Changes for space_view3d_virtual_reality/opengl_helper.py: 74 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -145,6 +145,80 @@ def delete_image(tex_id):
    if glIsTexture(tex_id):
        glDeleteTextures(1, id_buf)

# ##################
# Framebuffer Routines
# ##################

def check_framebuffer_status(target):
    status = glCheckFramebufferStatus(target)

    if status ==  GL_FRAMEBUFFER_COMPLETE:
        return True
    elif status == GL_FRAMEBUFFER_UNDEFINED:
        print("framebuffer not complete: GL_FRAMEBUFFER_UNDEFINED - returned if the specified framebuffer is the default read or draw framebuffer, but the default framebuffer does not exist.")
    elif status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
        print("framebuffer not complete: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT - returned if any of the framebuffer attachment points are framebuffer incomplete.")
    elif status == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
        print("framebuffer not complete: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT - returned if the framebuffer does not have at least one image attached to it.")
    elif status == GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
        print("framebuffer not complete: GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER - returned if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for any color attachment point named by GL_DRAW_BUFFERi.")
    elif status ==  GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
        print("framebuffer not complete: GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER - returned if GL_READ_BUFFER is not GL_NONE and the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color attachment point named by GL_READ_BUFFER.")
    elif status ==  GL_FRAMEBUFFER_UNSUPPORTED:
        print("framebuffer not complete: GL_FRAMEBUFFER_UNSUPPORTED - returned if the combination of internal formats of the attached images violates an implementation-dependent set of restrictions.")
    elif status ==  GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
        print("framebuffer not complete: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE - returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; or, if the attached images are a mix of renderbuffers and      textures, the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES. also returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS i     s not the same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached textures.")
    elif status ==  GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
        print("framebuffer not complete: GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS - returned if any framebuffer attachment is layered, and any populated attachment is not layered, or if all populated color attachments are not from textures of the same target.")
    else:
        print("framebuffer not complete: status 0x%x (unknown)" % (status,))

    return False


def create_framebuffer(width, height, target=GL_RGBA):
    """create an empty framebuffer"""
    id_buf = Buffer(GL_INT, 1)

    glGenFramebuffers(1, id_buf)
    fbo_id = id_buf.to_list()[0]

    if fbo_id == 0:
        print("Framebuffer error on creation")
        return -1

    tex_id = create_image(width, height)

    glBindFramebuffer(GL_FRAMEBUFFER, fbo_id)
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0)

    glGenRenderbuffers(1, id_buf)
    depth_id = id_buf.to_list()[0]

    glBindRenderbuffer(GL_RENDERBUFFER, depth_id)
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height)

    # attach the depth buffer
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_id)

    #glDrawBuffers(fbo_id, GL_COLOR_ATTACHMENT0)

    if not check_framebuffer_status(GL_DRAW_FRAMEBUFFER):
        delete_framebuffer(fbo_id)
        glBindFramebuffer(GL_FRAMEBUFFER, 0)
        return -1

    glBindFramebuffer(GL_FRAMEBUFFER, 0)
    return fbo_id


def delete_framebuffer(fbo_id):
    """clear created framebuffer"""
    id_buf = Buffer(GL_INT, 1)
    id_buf.to_list()[0] = fbo_id

    if glIsFramebuffer(fbo_id):
        glDeleteFramebuffers(1, id_buf)

# ##################
# GLSL Screen Shader
+65 −0
Changes for space_view3d_virtual_reality/sandbox.py: 65 added lines, 0 removed lines.
Original line number Diff line number Diff line
import bpy

TODO = True

from .opengl_helper import (
        create_framebuffer,
        delete_framebuffer,
        )


class VirtualRealitySandboxOperator(bpy.types.Operator):
    """"""
    bl_idname = "view3d.virtual_reality_sandbox"
    bl_label = "Toggle Virtual Reality Sandbox"
    bl_description = ""

    _fbo = -1
    _timer = None
    _width = 1920
    _height = 1080

    @classmethod
    def poll(cls, context):
        return True

    def modal(self, context, event):
        if event.type == 'TIMER':
            TODO # update FBO

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        TODO # check if oculus is connected

        if context.area.type == 'VIEW_3D':
            self._timer = context.window_manager.event_timer_add(1.0 / 75.0, context.window) # 75 Hz
            self._init(self._width, self._height)
            return {'MODAL'}

        return {'CANCELLED'}

    def _quit(self):
        """garbage collect"""
        if self._timer:
            context.window_manager.event_timer_remove(self._timer)
            del self._timer

        if self._fbo != -1:
            delete_framebuffer(self._fbo_id)

    def _init(self, width, height):
        self._fbo = create_framebuffer(width, height


# ############################################################
# Un/Registration
# ############################################################

def register():
    bpy.utils.register_class(VirtualRealitySandboxOperator)


def unregister():
    bpy.utils.unregister_class(VirtualRealitySandboxOperator)
+3 −0
Changes for space_view3d_virtual_reality/ui.py: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@ class VirtualRealityPanel(bpy.types.Panel):
        col = layout.column()
        col.operator("view3d.virtual_reality_toggle", text="Virtual Reality Preview", icon="PLAY")

        col.separator()
        col.operator("view3d.virtual_reality_sandbox", text="Sandbox", icon="PLAY")


# ############################################################
# Un/Registration