Add set_program_uniform function

This commit is contained in:
Grant Sanderson
2023-02-02 21:13:18 -08:00
parent 772ea792d0
commit ac3db9b636
2 changed files with 32 additions and 9 deletions

View File

@ -15,6 +15,7 @@ from manimlib.utils.shaders import image_path_to_texture
from manimlib.utils.shaders import get_texture_id
from manimlib.utils.shaders import get_fill_canvas
from manimlib.utils.shaders import release_texture
from manimlib.utils.shaders import set_program_uniform
from typing import TYPE_CHECKING
@ -224,14 +225,7 @@ class ShaderWrapper(object):
if self.program is None:
return
for name, value in (*self.mobject_uniforms.items(), *camera_uniforms.items()):
if name not in self.program:
continue
if isinstance(value, np.ndarray) and value.ndim > 0:
value = tuple(value)
if name in camera_uniforms and self.program_uniform_mirror.get(name, None) == value:
continue
self.program[name].value = value
self.program_uniform_mirror[name] = value
set_program_uniform(self.program, name, value)
def get_vertex_buffer_object(self, refresh: bool = True):
if refresh:

View File

@ -9,7 +9,6 @@ import numpy as np
from manimlib.config import parse_cli
from manimlib.config import get_configuration
from manimlib.utils.customization import get_customization
from manimlib.utils.directories import get_shader_dir
from manimlib.utils.file_ops import find_file
@ -17,11 +16,13 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Sequence, Optional, Tuple
from manimlib.typing import UniformDict
from moderngl.vertex_array import VertexArray
from moderngl.framebuffer import Framebuffer
ID_TO_TEXTURE: dict[int, moderngl.Texture] = dict()
PROGRAM_UNIFORM_MIRRORS: dict[int, dict[str, float | tuple]] = dict()
@lru_cache()
@ -63,6 +64,34 @@ def get_shader_program(
)
def set_program_uniform(
program: moderngl.Program,
name: str,
value: float | tuple | np.ndarray
) -> bool:
"""
Sets a program uniform, and also keeps track of a dictionary
of previously set uniforms for that program so that it
doesn't needlessly reset it, requiring an exchange with gpu
memory, if it sees the same value again.
Returns True if changed the program, False if it left it as is.
"""
if name not in program:
return False
pid = id(program)
if pid not in PROGRAM_UNIFORM_MIRRORS:
PROGRAM_UNIFORM_MIRRORS[pid] = dict()
uniform_mirror = PROGRAM_UNIFORM_MIRRORS[pid]
if isinstance(value, np.ndarray) and value.ndim > 0:
value = tuple(value)
if uniform_mirror.get(name, None) == value:
return False
uniform_mirror[name] = value
program[name].value = value
return True
@lru_cache()
def get_shader_code_from_file(filename: str) -> str | None:
if not filename: