Opened 7 years ago

Closed 7 years ago

#1466 closed defect (fixed)

Can't save offscreen image

Reported by: Greg Couch Owned by: Tom Goddard
Priority: blocker Milestone: 0.8
Component: Graphics Version:
Keywords: Cc:
Blocked By: Blocking: 1427
Notify when closed: Platform: all
Project: ChimeraX

Description

After fixing many offscreen bugs, saving an image now fails with:

Traceback (most recent call last):
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/nogui.py", line 211, in execute
    self._cmd.run(text)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/commands/cli.py", line 2581, in run
    result = ci.function(session, **kw_args)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/commands/save.py", line 61, in save
    fmt.export(session, filename, fmt.nicknames[0], **kw)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/io.py", line 198, in export
    result = self.export_func(session, path, **kw)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/image.py", line 149, in save_image
    transparent_background=transparent_background)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/graphics/view.py", line 378, in image
    if not fb.activate():
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/graphics/opengl.py", line 1817, in activate
    fbo = self.framebuffer_id
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/graphics/opengl.py", line 1813, in framebuffer_id
    self._fbo = fbo = self._create_framebuffer()
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/graphics/opengl.py", line 1694, in _create_framebuffer
    self.depth_texture or self._depth_rb)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/graphics/opengl.py", line 1699, in _create_fbo
    self._opengl_context._framebuffers.add(self)
AttributeError: 'OffScreenRenderingContext' object has no attribute '_framebuffers'

And after naively adding _framebuffers and _bindings to OffScreenRenderingContext (not checked in):

Traceback (most recent call last):
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/nogui.py", line 211, in execute
    self._cmd.run(text)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/commands/cli.py", line 2581, in run
    result = ci.function(session, **kw_args)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/commands/save.py", line 61, in save
    fmt.export(session, filename, fmt.nicknames[0], **kw)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/io.py", line 198, in export
    result = self.export_func(session, path, **kw)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/image.py", line 149, in save_image
    transparent_background=transparent_background)
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/graphics/view.py", line 414, in image
    r.pop_framebuffer()
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/graphics/opengl.py", line 561, in pop_framebuffer
    fb.activate()
  File "..../ChimeraX.app/lib/python3.6/site-packages/chimerax/core/graphics/opengl.py", line 1821, in activate
    GL.glDrawBuffer(self._draw_buffer)
  File "errorchecker.pyx", line 53, in OpenGL_accelerate.errorchecker._ErrorChecker.glCheckError (src/errorchecker.c:1218)
OpenGL.error.GLError: GLError(
        err = 1282,
        description = b'invalid operation',
        baseOperation = glDrawBuffer,
        cArguments = (GL_BACK,)
)

Change History (5)

comment:1 by Greg Couch, 7 years ago

To reproduce, use a ChimeraX Linux daily build from 2018-11-20 or newer. Open some data and then "save image foo.png".

comment:2 by Greg Couch, 7 years ago

Blocking: 1427

comment:3 by Tom Goddard, 7 years ago

The OffScreenRenderingContext will need to have _framebuffers and _bindings attributes (WeakSets) and all the other features of OpenGLContext in order to render. The underscore in these methods is intended to mean they are private within this file (not that the are private within the class) -- Framebuffer and Bindings directly use those attributes and are part of the opengl context management as are several other classes.

comment:4 by Tom Goddard, 7 years ago

The invalid operation error in glDrawBuffer(GL_BACK) is because the Framebuffer constructor assumes that the default framebuffer (id 0) is an on-screen buffer and double buffered so it uses GL_BACK as its draw target. For offscreen rendering the default framebuffer probably needs a draw target like GL_COLOR_ATTACHMENT0. The Render.default_framebuffer() method will need to handle this case.

I'm not going to make changes to this code that I can't test -- I don't have a linux development machine to work on right now. So it will have to wait until I have a machine to test changes on.

comment:5 by Tom Goddard, 7 years ago

Resolution: fixed
Status: assignedclosed

Fixed.

The draw target for OSMesa needed to be GL_FRONT instead of GL_BACK since the default framebuffer is single-buffered.

Note: See TracTickets for help on using tickets.