Skip to content

Commit 860a19f

Browse files
committed
Add headless rendering
1 parent 9d2c0a7 commit 860a19f

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

manim/renderer/opengl_renderer.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -186,20 +186,25 @@ def __init__(self):
186186
self.num_plays = 0
187187
self.skip_animations = False
188188

189-
self.window = Window()
190-
191189
self.camera = OpenGLCamera()
192190

193-
# Initialize context.
194-
self.context = self.window.ctx
191+
if config["preview"]:
192+
self.window = Window()
193+
self.context = self.window.ctx
194+
self.frame_buffer_object = self.context.detect_framebuffer()
195+
else:
196+
self.window = None
197+
self.context = moderngl.create_standalone_context()
198+
self.frame_buffer_object = self.get_frame_buffer_object(self.context, 0)
199+
self.frame_buffer_object.use()
200+
195201
self.context.enable(moderngl.BLEND)
196202
self.context.blend_func = (
197203
moderngl.SRC_ALPHA,
198204
moderngl.ONE_MINUS_SRC_ALPHA,
199205
moderngl.ONE,
200206
moderngl.ONE,
201207
)
202-
self.frame_buffer_object = self.context.detect_framebuffer()
203208

204209
# Initialize shader map.
205210
self.id_to_shader_program = {}
@@ -242,7 +247,10 @@ def render_mobjects(self, mobs):
242247
for mob in mobs:
243248
shader_wrapper_list = mob.get_shader_wrapper_list()
244249
render_group_list = map(
245-
lambda x: self.get_render_group(self.context, x), shader_wrapper_list
250+
lambda shader_wrapper: self.get_render_group(
251+
self.context, shader_wrapper
252+
),
253+
shader_wrapper_list,
246254
)
247255
for render_group in render_group_list:
248256
self.render_render_group(render_group)
@@ -370,23 +378,40 @@ def update_frame():
370378
self.frame_buffer_object.clear(*window_background_color)
371379
self.refresh_perspective_uniforms(scene.camera)
372380
self.render_mobjects(scene.mobjects)
373-
self.window.swap_buffers()
374381
self.animation_elapsed_time = time.time() - self.animation_start_time
375382

376383
window_background_color = (0.2, 0.2, 0.2, 1)
377384
update_frame()
378-
379385
self.file_writer.write_frame(self)
380386

381-
while self.animation_elapsed_time < frame_offset:
382-
update_frame()
387+
if self.window is not None:
388+
self.window.swap_buffers()
389+
while self.animation_elapsed_time < frame_offset:
390+
# TODO: Just sleep?
391+
update_frame()
392+
self.window.swap_buffers()
383393

384394
def scene_finished(self, scene):
385395
self.file_writer.finish(self.partial_movie_files)
386396

387397
def save_static_frame_data(self, scene, static_mobjects):
388398
pass
389399

400+
def get_frame_buffer_object(self, context, samples=0):
401+
pixel_width = config["pixel_width"]
402+
pixel_height = config["pixel_height"]
403+
num_channels = 4
404+
return context.framebuffer(
405+
color_attachments=context.texture(
406+
(pixel_width, pixel_height),
407+
components=num_channels,
408+
samples=samples,
409+
),
410+
depth_attachment=context.depth_renderbuffer(
411+
(pixel_width, pixel_height), samples=samples
412+
),
413+
)
414+
390415
def get_raw_frame_buffer_object_data(self, dtype="f1"):
391416
# Copy blocks from the fbo_msaa to the drawn fbo using Blit
392417
# pw, ph = self.get_pixel_shape()

0 commit comments

Comments
 (0)