From 9b845d01d71972d125cd9ed6c1fa0d452c1b26d0 Mon Sep 17 00:00:00 2001 From: "Alexander G. Morano" Date: Thu, 1 Aug 2024 19:56:51 -0700 Subject: [PATCH] working for frontend 1.2.7 has regressions for 1.2.8 --- .gitignore | 3 +- core/create_glsl.py | 9 ++-- pyproject.toml | 2 +- sup/shader.py | 110 ++++++++++++++++++++++---------------------- 4 files changed, 61 insertions(+), 63 deletions(-) diff --git a/.gitignore b/.gitignore index ee6423c..3d8272d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ backup node_modules *-lock.json *.config.mjs -package.json \ No newline at end of file +package.json +_TODO*.* \ No newline at end of file diff --git a/core/create_glsl.py b/core/create_glsl.py index 363cc6c..49c9dde 100644 --- a/core/create_glsl.py +++ b/core/create_glsl.py @@ -114,11 +114,9 @@ def run(self, ident, **kw) -> tuple[torch.Tensor]: # everybody wang comp tonight mode = parse_param(kw, Lexicon.MODE, EnumConvertType.STRING, EnumScaleMode.NONE.name)[0] mode = EnumScaleMode[mode] - wihi = parse_param(kw, Lexicon.WH, EnumConvertType.VEC2INT, [(512, 512)], MIN_IMAGE_SIZE)[0] sample = parse_param(kw, Lexicon.SAMPLE, EnumConvertType.STRING, EnumInterpolation.LANCZOS4.name)[0] sample = EnumInterpolation[sample] - matte = parse_param(kw, Lexicon.MATTE, EnumConvertType.VEC4INT, [(0, 0, 0, 255)], 0, 255)[0] variables = kw.copy() @@ -134,9 +132,7 @@ def run(self, ident, **kw) -> tuple[torch.Tensor]: logger.error(e) return - self.__glsl.size = wihi self.__glsl.fps = parse_param(kw, Lexicon.FPS, EnumConvertType.INT, 24, 1, 120)[0] - if batch > 0: self.__delta = delta step = 1. / self.__glsl.fps @@ -161,9 +157,9 @@ def run(self, ident, **kw) -> tuple[torch.Tensor]: h, w = firstImage.shape[:2] self.__glsl.size = (w, h) + img = self.__glsl.render(self.__delta, **vars) if mode != EnumScaleMode.NONE: - img = image_scalefit(img, w, h, mode, sample) img = cv2tensor_full(img, matte) images.append(img) @@ -283,6 +279,9 @@ def import_dynamic() -> Tuple[str,...]: "PARAM": meta.get('_', []), "SORT": sort_order, }) + print(f'GLSL {name} (JOV) {emoji}'.upper()) + print(meta.get('_', [])) + print() sort += 10 ret.append((class_name, class_def,)) diff --git a/pyproject.toml b/pyproject.toml index e37631f..8555dcf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "jovimetrix" description = "Integrates Webcam, MIDI, Spout and GLSL shader support. Animation via tick. Parameter manipulation with wave generator. Math operations with Unary and Binary support. Value conversion for all major types (int, string, list, dict, Image, Mask). Shape mask generation, image stacking and channel ops, batch splitting, merging and randomizing, load images and video from anywhere, dynamic bus routing with a single node, export support for GIPHY, save output anywhere! flatten, crop, transform; check colorblindness, make stereogram or stereoscopic images, or liner interpolate values and more." -version = "1.2.8" +version = "1.2.9" license = { file = "LICENSE" } dependencies = [ "aenum>=3.1.15, <4", diff --git a/sup/shader.py b/sup/shader.py index dd286d2..177426a 100644 --- a/sup/shader.py +++ b/sup/shader.py @@ -151,7 +151,6 @@ def __init_window(self, vertex:str=None, fragment:str=None, force:bool=False) -> self.__init_framebuffer() self.__init_program(vertex, fragment, force) - self.__init_vars() logger.debug("init window") def __compile_shader(self, source:str, shader_type:str) -> None: @@ -175,66 +174,42 @@ def __init_program(self, vertex:str=None, fragment:str=None, force:bool=False) - logger.debug("Fragment program is empty. Using Default.") fragment = self.PROG_FRAGMENT - if force or vertex != self.__source_vertex_raw or fragment != self.__source_fragment_raw: - glfw.make_context_current(self.__window) - try: - gl.glDeleteProgram(self.__program) - except Exception as e: - pass - - self.__source_vertex = self.__compile_shader(vertex, gl.GL_VERTEX_SHADER) - fragment_full = self.PROG_HEADER + fragment + self.PROG_FOOTER - self.__source_fragment = self.__compile_shader(fragment_full, gl.GL_FRAGMENT_SHADER) - - self.__program = gl.glCreateProgram() - gl.glAttachShader(self.__program, self.__source_vertex) - gl.glAttachShader(self.__program, self.__source_fragment) - gl.glLinkProgram(self.__program) - if gl.glGetProgramiv(self.__program, gl.GL_LINK_STATUS) != gl.GL_TRUE: - log = gl.glGetProgramInfoLog(self.__program).decode() - logger.error(f"Program linking error: {log}") - raise RuntimeError(log) - - self.__source_fragment_raw = fragment - self.__source_vertex_raw = vertex - logger.debug("init program") + if not force and vertex == self.__source_vertex_raw and fragment == self.__source_fragment_raw: + return - def __init_framebuffer(self) -> None: glfw.make_context_current(self.__window) + try: + gl.glDeleteProgram(self.__program) + except Exception as e: + pass - self.__fbo = gl.glGenFramebuffers(1) - gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.__fbo) - - self.__fbo_texture = gl.glGenTextures(1) - gl.glBindTexture(gl.GL_TEXTURE_2D, self.__fbo_texture) - glfw.set_window_size(self.__window, self.__size[0], self.__size[1]) + self.__source_vertex = self.__compile_shader(vertex, gl.GL_VERTEX_SHADER) + fragment_full = self.PROG_HEADER + fragment + self.PROG_FOOTER + self.__source_fragment = self.__compile_shader(fragment_full, gl.GL_FRAGMENT_SHADER) - gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.__size[0], self.__size[1], 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, None) - gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) - gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) - gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.__fbo_texture, 0) + self.__program = gl.glCreateProgram() + gl.glAttachShader(self.__program, self.__source_vertex) + gl.glAttachShader(self.__program, self.__source_fragment) + gl.glLinkProgram(self.__program) + if gl.glGetProgramiv(self.__program, gl.GL_LINK_STATUS) != gl.GL_TRUE: + log = gl.glGetProgramInfoLog(self.__program).decode() + logger.error(f"Program linking error: {log}") + raise RuntimeError(log) - gl.glViewport(0, 0, self.__size[0], self.__size[1]) - logger.debug("init framebuffer") + self.__source_fragment_raw = fragment + self.__source_vertex_raw = vertex - def __init_vars(self) -> None: - glfw.make_context_current(self.__window) gl.glUseProgram(self.__program) - self.__shaderVar = { - 'iResolution': gl.glGetUniformLocation(self.__program, "iResolution"), - 'iTime': gl.glGetUniformLocation(self.__program, "iTime"), - 'iFrameRate': gl.glGetUniformLocation(self.__program, "iFrameRate"), - 'iFrame': gl.glGetUniformLocation(self.__program, "iFrame"), - 'iMouse': gl.glGetUniformLocation(self.__program, "iMouse") - } + self.__shaderVar = {} + statics = ['iResolution', 'iTime', 'iFrameRate', 'iFrame', 'iMouse'] + for s in statics: + if (val := gl.glGetUniformLocation(self.__program, s)) > -1: + self.__shaderVar[s] = val - if (resolution := self.__shaderVar['iResolution']) > -1: + if (resolution := self.__shaderVar.get('iResolution', -1)) > -1: gl.glUniform3f(resolution, self.__size[0], self.__size[1], 0) - if (framerate := self.__shaderVar['iFrameRate']) > -1: - gl.glUniform1i(framerate, self.__fps) - self.__userVar = {} # read the fragment and setup the vars.... for match in RE_VARIABLE.finditer(self.__source_fragment_raw): @@ -255,6 +230,25 @@ def __init_vars(self) -> None: ] logger.debug("init vars") + logger.debug("init program") + + def __init_framebuffer(self) -> None: + glfw.make_context_current(self.__window) + + self.__fbo = gl.glGenFramebuffers(1) + gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.__fbo) + + self.__fbo_texture = gl.glGenTextures(1) + gl.glBindTexture(gl.GL_TEXTURE_2D, self.__fbo_texture) + glfw.set_window_size(self.__window, self.__size[0], self.__size[1]) + + gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.__size[0], self.__size[1], 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, None) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) + gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) + gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.__fbo_texture, 0) + + gl.glViewport(0, 0, self.__size[0], self.__size[1]) + logger.debug("init framebuffer") def __del__(self) -> None: self.__cleanup() @@ -310,9 +304,10 @@ def fps(self) -> int: def fps(self, fps:int) -> None: fps = max(1, min(120, int(fps))) self.__fps = fps - glfw.make_context_current(self.__window) - gl.glUseProgram(self.__program) - gl.glUniform1f(self.__shaderVar['iFrameRate'], self.__fps) + if (iFrameRate := self.__shaderVar.get('iFrameRate', -1)) > -1: + glfw.make_context_current(self.__window) + gl.glUseProgram(self.__program) + gl.glUniform1f(self.__shaderVar['iFrameRate'], iFrameRate) @property def mouse(self) -> Tuple[int, int]: @@ -344,13 +339,16 @@ def render(self, time_delta:float=0., **kw) -> np.ndarray: self.runtime = time_delta - if (val := self.__shaderVar['iTime']) > -1: + if (val := self.__shaderVar.get('iTime', -1)) > -1: gl.glUniform1f(val, self.__runtime) - if (val := self.__shaderVar['iFrame']) > -1: + if (val := self.__shaderVar.get('iFrameRate', -1)) > -1: + gl.glUniform1i(val, self.__fps) + + if (val := self.__shaderVar.get('iFrame', -1)) > -1: gl.glUniform1i(val, self.frame) - if (val := self.__shaderVar['iMouse']) > -1: + if (val := self.__shaderVar.get('iMouse', -1)) > -1: gl.glUniform4f(val, self.__mouse[0], self.__mouse[1], 0, 0) texture_index = 0