# The contents of this file are subject to the Common Public Attribution License # Version 1.0 (the “License”); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # https://myou.dev/licenses/LICENSE-CPAL. The License is based on the Mozilla # Public License Version 1.1 but Sections 14 and 15 have been added to cover use # of software over a computer network and provide for limited attribution for # the Original Developer. In addition, Exhibit A has been modified to be # consistent with Exhibit B. # # Software distributed under the License is distributed on an “AS IS” basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for # the specific language governing rights and limitations under the License. # # The Original Code is Myou Engine. # # the Original Developer is the Initial Developer. # # The Initial Developer of the Original Code is the Myou Engine developers. # All portions of the code written by the Myou Engine developers are Copyright # (c) 2024. All Rights Reserved. # # Alternatively, the contents of this file may be used under the terms of the # GNU Affero General Public License version 3 (the [AGPL-3] License), in which # case the provisions of [AGPL-3] License are applicable instead of those above. # # If you wish to allow use of your version of this file only under the terms of # the [AGPL-3] License and not to allow others to use your version of this file # under the CPAL, indicate your decision by deleting the provisions above and # replace them with the notice and other provisions required by the [AGPL-3] # License. If you do not delete the provisions above, a recipient may use your # version of this file under either the CPAL or the [AGPL-3] License. import ../types import std/tables # Forward declarations proc newEffectShader*(engine: MyouEngine, texture_names: seq[string], texture_types: seq[TextureType] = @[], library = "", code = "", output_names = @["outColor"], mat_name = "effect_shader", defines = initTable[string, string](), add_input_size_ubo = true): Material # End forward declarations import std/strformat import std/strutils import ../graphics/material import ../graphics/render import ../graphics/ubo proc newEffectShader*(engine: MyouEngine, texture_names: seq[string], texture_types: seq[TextureType] = @[], library = "", code = "", output_names = @["outColor"], mat_name = "effect_shader", defines = initTable[string, string](), add_input_size_ubo = true): Material = var textures: OrderedTable[string, Texture] var samplers_code: seq[string] var extensions = "" for i,name in texture_names: textures[name] = nil let t = if i < texture_types.len: texture_types[i] else: Tex2D let gltype = case t: of Tex2D: "sampler2D" of Tex2DArray: "sampler2DArray" of Tex3D: "sampler3D" of TexCube: "samplerCube" of TexExternal: extensions = "#extension GL_OES_EGL_image_external_essl3 : require" "samplerExternalOES" samplers_code.add &"uniform {gltype} {name};" if add_input_size_ubo: samplers_code.add &"#define {name}_size inputs[{i}].size" samplers_code.add &"#define {name}_px_size inputs[{i}].px_size" samplers_code.add &"#define {name}_px_lod inputs[{i}].px_lod" var outputs_code: seq[string] for o in output_names: outputs_code.add &"out vec4 {o};" var ubos: seq[UBO] if add_input_size_ubo: ubos.add engine.newUBO("EffectShaderInputs", EffectShaderInput, texture_names.len) samplers_code.insert(dedent """ struct EffectShaderInput { vec3 size; float px_lod; vec3 px_size; float lod; }; layout(std140) uniform EffectShaderInputs { EffectShaderInput inputs[""" & $textures.len & """]; };""", 0) result = engine.newMaterial(mat_name, nil, vertex = extensions & "\n" & get_render_uniform_blocks() & "\n" & dedent &""" in vec3 vertex; out vec2 coord; out vec3 coord3D, coord3D_x, coord3D_y; void main(){{ coord = vertex.xy; // TODO: coord3D = (view_matrix_inverse * vec4(vec3(vertex.xy*2.0-1.0, -1.0), 0.0)).xyz; coord3D_x = coord3D.zxy; coord3D_y = coord3D.yzx; gl_Position = vec4(vertex.xy*2.0-1.0, 0.0, 1.0); }}""", fragment = @[ library, samplers_code.join("\n"), "in vec2 coord;", "in vec3 coord3D, coord3D_x, coord3D_y;", outputs_code.join("\n"), "void main(){", code, "}"].join("\n"), ubos = ubos, textures = textures, defines = defines, )