Skip to content

Commit

Permalink
Improved setting of OpenGL colors (#2111)
Browse files Browse the repository at this point in the history
* Improve setting of opengl colors

* Use keyword arguments and move tests to opengl folder
  • Loading branch information
k4pran authored Oct 2, 2021
1 parent dd16347 commit a93d112
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 7 deletions.
4 changes: 4 additions & 0 deletions manim/mobject/opengl_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,10 @@ def set_color(self, color, opacity=None, recurse=True):
self.set_rgba_array(color, opacity, recurse=False)
# Recurse to submobjects differently from how set_rgba_array
# in case they implement set_color differently
if color is not None:
self.color = Color(color)
if opacity is not None:
self.opacity = opacity
if recurse:
for submob in self.submobjects:
submob.set_color(color, recurse=True)
Expand Down
32 changes: 29 additions & 3 deletions manim/mobject/types/opengl_vectorized_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import moderngl
import numpy as np
from colour import Color

from ... import config
from ...constants import *
Expand Down Expand Up @@ -152,6 +153,14 @@ def init_colors(self):
return self

def set_fill(self, color=None, opacity=None, recurse=True):
if color is not None:
self.fill_color = Color(color)
if opacity is not None:
self.fill_opacity = opacity
if recurse:
for submobject in self.submobjects:
submobject.set_fill(color, opacity, recurse)

self.set_rgba_array(color, opacity, "fill_rgba", recurse)
return self

Expand All @@ -163,6 +172,20 @@ def set_stroke(
background=None,
recurse=True,
):
if color is not None:
self.stroke_color = Color(color)
if opacity is not None:
self.stroke_opacity = opacity
if recurse:
for submobject in self.submobjects:
submobject.set_stroke(
color=color,
width=width,
opacity=opacity,
background=background,
recurse=recurse,
)

self.set_rgba_array(color, opacity, "stroke_rgba", recurse)

if width is not None:
Expand Down Expand Up @@ -235,9 +258,12 @@ def match_style(self, vmobject, recurse=True):
sm1.match_style(sm2)
return self

def set_color(self, color, recurse=True):
self.set_fill(color, recurse=recurse)
self.set_stroke(color, recurse=recurse)
def set_color(self, color, opacity=None, recurse=True):
self.color = Color(color)
if opacity is not None:
self.opacity = opacity
self.set_fill(color, opacity=opacity, recurse=recurse)
self.set_stroke(color, opacity=opacity, recurse=recurse)
return self

def set_opacity(self, opacity, recurse=True):
Expand Down
16 changes: 12 additions & 4 deletions manim/renderer/opengl_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ def __init__(self, file_writer_class=SceneFileWriter, skip_animations=False):
# Initialize texture map.
self.path_to_texture_id = {}

self._background_color = color_to_rgba(config["background_color"], 1.0)

def init_scene(self, scene):
self.partial_movie_files = []
self.file_writer = self._file_writer_class(
Expand Down Expand Up @@ -405,8 +407,7 @@ def play(self, scene, *args, **kwargs):
scene.play_internal()

def clear_screen(self):
window_background_color = color_to_rgba(config["background_color"])
self.frame_buffer_object.clear(*window_background_color)
self.frame_buffer_object.clear(*self.background_color)
self.window.swap_buffers()

def render(self, scene, frame_offset, moving_mobjects):
Expand All @@ -424,8 +425,7 @@ def render(self, scene, frame_offset, moving_mobjects):
self.window.swap_buffers()

def update_frame(self, scene):
window_background_color = color_to_rgba(config["background_color"])
self.frame_buffer_object.clear(*window_background_color)
self.frame_buffer_object.clear(*self.background_color)
self.refresh_perspective_uniforms(scene.camera)

for mobject in scene.mobjects:
Expand Down Expand Up @@ -531,3 +531,11 @@ def pixel_coords_to_space_coords(self, px, py, relative=False):
# Only scale wrt one axis
scale = fh / ph
return fc + scale * np.array([(px - pw / 2), (py - ph / 2), 0])

@property
def background_color(self):
return self._background_color

@background_color.setter
def background_color(self, value):
self._background_color = color_to_rgba(value, 1.0)
95 changes: 95 additions & 0 deletions tests/opengl/test_color_opengl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import numpy as np

from manim import BLACK, PURE_GREEN, Scene
from manim.mobject.opengl_mobject import OpenGLMobject
from manim.mobject.types.opengl_vectorized_mobject import OpenGLVMobject


def test_import_color(using_opengl_renderer):
import manim.utils.color as C

C.WHITE


def test_background_color(using_opengl_renderer):
S = Scene()
S.renderer.background_color = "#ff0000"
S.renderer.update_frame(S)
assert np.all(S.renderer.get_frame()[0, 0] == np.array([255, 0, 0, 255]))

S.renderer.background_color = "#436f80"
S.renderer.update_frame(S)
assert np.all(S.renderer.get_frame()[0, 0] == np.array([67, 111, 128, 255]))

S.renderer.background_color = "#fff"
S.renderer.update_frame(S)
assert np.all(S.renderer.get_frame()[0, 0] == np.array([255, 255, 255, 255]))


def test_set_color(using_opengl_renderer):
m = OpenGLMobject()
assert m.color.hex == "#fff"
np.alltrue(m.rgbas == np.array((0.0, 0.0, 0.0, 1.0)))

m.set_color(BLACK)
assert m.color.hex == "#000"
np.alltrue(m.rgbas == np.array((1.0, 1.0, 1.0, 1.0)))

m.set_color(PURE_GREEN, opacity=0.5)
assert m.color.hex == "#0f0"
np.alltrue(m.rgbas == np.array((0.0, 1.0, 0.0, 0.5)))

m = OpenGLVMobject()
assert m.color.hex == "#fff"
np.alltrue(m.fill_rgba == np.array((0.0, 0.0, 0.0, 1.0)))
np.alltrue(m.stroke_rgba == np.array((0.0, 0.0, 0.0, 1.0)))

m.set_color(BLACK)
assert m.color.hex == "#000"
np.alltrue(m.fill_rgba == np.array((1.0, 1.0, 1.0, 1.0)))
np.alltrue(m.stroke_rgba == np.array((1.0, 1.0, 1.0, 1.0)))

m.set_color(PURE_GREEN, opacity=0.5)
assert m.color.hex == "#0f0"
np.alltrue(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5)))
np.alltrue(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5)))


def test_set_fill_color(using_opengl_renderer):
m = OpenGLVMobject()
assert m.fill_color.hex == "#fff"
np.alltrue(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5)))

m.set_fill(BLACK)
assert m.fill_color.hex == "#000"
np.alltrue(m.fill_rgba == np.array((1.0, 1.0, 1.0, 1.0)))

m.set_fill(PURE_GREEN, opacity=0.5)
assert m.fill_color.hex == "#0f0"
np.alltrue(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5)))


def test_set_stroke_color(using_opengl_renderer):
m = OpenGLVMobject()
assert m.stroke_color.hex == "#fff"
np.alltrue(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5)))

m.set_stroke(BLACK)
assert m.stroke_color.hex == "#000"
np.alltrue(m.stroke_rgba == np.array((1.0, 1.0, 1.0, 1.0)))

m.set_stroke(PURE_GREEN, opacity=0.5)
assert m.stroke_color.hex == "#0f0"
np.alltrue(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5)))


def test_set_fill(using_opengl_renderer):
m = OpenGLMobject()
assert m.color.hex == "#fff"
m.set_color(BLACK)
assert m.color.hex == "#000"

m = OpenGLVMobject()
assert m.color.hex == "#fff"
m.set_color(BLACK)
assert m.color.hex == "#000"

0 comments on commit a93d112

Please sign in to comment.