mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
107 lines
2.8 KiB
Python
107 lines
2.8 KiB
Python
import os
|
|
import warnings
|
|
import re
|
|
import moderngl
|
|
import json
|
|
|
|
from manimlib.constants import SHADER_DIR
|
|
|
|
# Mobjects that should be rendered with
|
|
# the same shader will be organized and
|
|
# clumped together based on keeping track
|
|
# of a dict holding all the relevant information
|
|
# to that shader
|
|
|
|
|
|
SHADER_INFO_KEYS = [
|
|
# A structred array caring all of the points/color/lighting/etc. information
|
|
# needed for the shader.
|
|
"data",
|
|
# Filename of vetex shader
|
|
"vert",
|
|
# Filename of geometry shader, if there is one
|
|
"geom",
|
|
# Filename of fragment shader
|
|
"frag",
|
|
# A dictionary mapping names (as they show up in)
|
|
# the shader to filepaths for textures.
|
|
"texture_paths",
|
|
# E.g. moderngl.TRIANGLE_STRIP
|
|
"render_primative",
|
|
]
|
|
|
|
|
|
def get_shader_info(data=None,
|
|
vert_file=None,
|
|
geom_file=None,
|
|
frag_file=None,
|
|
render_primative=moderngl.TRIANGLE_STRIP,
|
|
texture_paths=None,
|
|
):
|
|
return {
|
|
key: value
|
|
for key, value in zip(
|
|
SHADER_INFO_KEYS,
|
|
[
|
|
data,
|
|
vert_file, geom_file, frag_file,
|
|
texture_paths or {},
|
|
str(render_primative)
|
|
]
|
|
)
|
|
}
|
|
|
|
|
|
def is_valid_shader_info(shader_info):
|
|
data = shader_info["data"]
|
|
return all([
|
|
data is not None and len(data) > 0,
|
|
shader_info["vert"],
|
|
shader_info["frag"],
|
|
])
|
|
|
|
|
|
def shader_info_to_id(shader_info):
|
|
# A unique id for a shader based on the
|
|
# files holding its code and texture
|
|
tuples = [
|
|
(key, shader_info[key])
|
|
for key in SHADER_INFO_KEYS[1:] # Skip data
|
|
]
|
|
return json.dumps(tuples)
|
|
|
|
|
|
def shader_id_to_info(sid):
|
|
result = dict(json.loads(sid))
|
|
result["data"] = None
|
|
return result
|
|
|
|
|
|
def same_shader_type(info1, info2):
|
|
return all([
|
|
info1[key] == info2[key]
|
|
for key in SHADER_INFO_KEYS[1:] # Skip data
|
|
])
|
|
|
|
|
|
def get_shader_code_from_file(filename):
|
|
if not filename:
|
|
return None
|
|
|
|
filepath = os.path.join(SHADER_DIR, filename)
|
|
if not os.path.exists(filepath):
|
|
warnings.warn(f"No file at {filepath}")
|
|
return
|
|
|
|
with open(filepath, "r") as f:
|
|
result = f.read()
|
|
|
|
# To share functionality between shaders, some functions are read in
|
|
# from other files an inserted into the relevant strings before
|
|
# passing to ctx.program for compiling
|
|
# Replace "#INSERT " lines with relevant code
|
|
insertions = re.findall(r"^#INSERT .*\.glsl$", result, flags=re.MULTILINE)
|
|
for line in insertions:
|
|
inserted_code = get_shader_code_from_file(line.replace("#INSERT ", ""))
|
|
result = result.replace(line, inserted_code)
|
|
return result
|