;; create and return a frame buffer struct (E_fbo)
;; if _texid is greater than 0 then use existing _texid
(bind-func create_fbo
  (lambda (width:i32 height:i32 _texid:i32 _depthid:i32)
    (let ((texid:i32 0)
    (depthid:i32 0)
    (fboid:i32* (salloc))
    (fbo:E_fbo* (halloc))) ;; heap alloc
      (glGenFramebuffers 1 fboid)
      ;; bind the fbo
      (glBindFramebuffer GL_FRAMEBUFFER (pref fboid 0))
      (if (> _texid 0) (set! texid _texid))
      (if (> _depthid 0) (set! texid _depthid))
      (set! texid (fbo_create_texture width height))
      (set! depthid (fbo_create_depth_buffer width height))
      ;; Attach the texture texid to the color buffer of our fbo
      (glFramebufferTexture2D GL_FRAMEBUFFER GL_COLOR_ATTACHMENT0 GL_TEXTURE_2D texid 0)
      ;; Attach the texture depthid to the depth buffer of our fbo
      (glFramebufferTexture2D GL_FRAMEBUFFER GL_DEPTH_ATTACHMENT GL_TEXTURE_2D depthid 0)
      (tfill! fbo (pref fboid 0) texid depthid width height)
      (let ((status:i32 (glCheckFramebufferStatus GL_FRAMEBUFFER))
            (err:i32 (glGetError)))
  (if (<> status GL_FRAMEBUFFER_COMPLETE)
            (if (<> err GL_NO_ERROR)
                (begin (printf "GL ERR: FRAMEBUFFER err: %d\n" err)
                       (set! fbo (cast null E_fbo*))
                       1)
                (begin
                  (printf "Possible framebuf error?: %d\n" err)
                  1))))
      (glClearColor 0.0 1.0 0.0 1.0)
      (glClear (+ GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
      ;; unbind the frame buffer
      (glBindFramebuffer GL_FRAMEBUFFER 0)
      ;; return the extfbo struct
      fbo)))