| 
									
										
										
										
											2024-03-11 13:05:37 -05:00
										 |  |  | """Functions used to generate source files during build time""" | 
					
						
							| 
									
										
										
										
											2024-02-28 14:25:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | import os.path | 
					
						
							| 
									
										
										
										
											2024-07-31 14:15:56 -05:00
										 |  |  | from typing import Optional | 
					
						
							| 
									
										
										
										
											2024-05-21 15:14:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-31 14:15:56 -05:00
										 |  |  | from methods import print_error, to_raw_cstring | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | class RDHeaderStruct: | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.vertex_lines = [] | 
					
						
							|  |  |  |         self.fragment_lines = [] | 
					
						
							|  |  |  |         self.compute_lines = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.vertex_included_files = [] | 
					
						
							|  |  |  |         self.fragment_included_files = [] | 
					
						
							| 
									
										
										
										
											2020-08-12 22:21:01 -03:00
										 |  |  |         self.compute_included_files = [] | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.reading = "" | 
					
						
							|  |  |  |         self.line_offset = 0 | 
					
						
							|  |  |  |         self.vertex_offset = 0 | 
					
						
							|  |  |  |         self.fragment_offset = 0 | 
					
						
							|  |  |  |         self.compute_offset = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 22:21:46 +09:00
										 |  |  | def include_file_in_rd_header(filename: str, header_data: RDHeaderStruct, depth: int) -> RDHeaderStruct: | 
					
						
							| 
									
										
										
										
											2024-03-24 18:02:56 +01:00
										 |  |  |     with open(filename, "r", encoding="utf-8") as fs: | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |         line = fs.readline() | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |         while line: | 
					
						
							|  |  |  |             index = line.find("//") | 
					
						
							|  |  |  |             if index != -1: | 
					
						
							|  |  |  |                 line = line[:index] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if line.find("#[vertex]") != -1: | 
					
						
							|  |  |  |                 header_data.reading = "vertex" | 
					
						
							|  |  |  |                 line = fs.readline() | 
					
						
							|  |  |  |                 header_data.line_offset += 1 | 
					
						
							|  |  |  |                 header_data.vertex_offset = header_data.line_offset | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if line.find("#[fragment]") != -1: | 
					
						
							|  |  |  |                 header_data.reading = "fragment" | 
					
						
							|  |  |  |                 line = fs.readline() | 
					
						
							|  |  |  |                 header_data.line_offset += 1 | 
					
						
							|  |  |  |                 header_data.fragment_offset = header_data.line_offset | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if line.find("#[compute]") != -1: | 
					
						
							|  |  |  |                 header_data.reading = "compute" | 
					
						
							|  |  |  |                 line = fs.readline() | 
					
						
							|  |  |  |                 header_data.line_offset += 1 | 
					
						
							|  |  |  |                 header_data.compute_offset = header_data.line_offset | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             while line.find("#include ") != -1: | 
					
						
							|  |  |  |                 includeline = line.replace("#include ", "").strip()[1:-1] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if includeline.startswith("thirdparty/"): | 
					
						
							|  |  |  |                     included_file = os.path.relpath(includeline) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-21 15:14:59 +02:00
										 |  |  |                 if included_file not in header_data.vertex_included_files and header_data.reading == "vertex": | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                     header_data.vertex_included_files += [included_file] | 
					
						
							|  |  |  |                     if include_file_in_rd_header(included_file, header_data, depth + 1) is None: | 
					
						
							| 
									
										
										
										
											2024-04-26 12:35:07 -05:00
										 |  |  |                         print_error(f'In file "{filename}": #include "{includeline}" could not be found!"') | 
					
						
							| 
									
										
										
										
											2024-05-21 15:14:59 +02:00
										 |  |  |                 elif included_file not in header_data.fragment_included_files and header_data.reading == "fragment": | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                     header_data.fragment_included_files += [included_file] | 
					
						
							|  |  |  |                     if include_file_in_rd_header(included_file, header_data, depth + 1) is None: | 
					
						
							| 
									
										
										
										
											2024-04-26 12:35:07 -05:00
										 |  |  |                         print_error(f'In file "{filename}": #include "{includeline}" could not be found!"') | 
					
						
							| 
									
										
										
										
											2024-05-21 15:14:59 +02:00
										 |  |  |                 elif included_file not in header_data.compute_included_files and header_data.reading == "compute": | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                     header_data.compute_included_files += [included_file] | 
					
						
							|  |  |  |                     if include_file_in_rd_header(included_file, header_data, depth + 1) is None: | 
					
						
							| 
									
										
										
										
											2024-04-26 12:35:07 -05:00
										 |  |  |                         print_error(f'In file "{filename}": #include "{includeline}" could not be found!"') | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 line = fs.readline() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             line = line.replace("\r", "").replace("\n", "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if header_data.reading == "vertex": | 
					
						
							|  |  |  |                 header_data.vertex_lines += [line] | 
					
						
							|  |  |  |             if header_data.reading == "fragment": | 
					
						
							|  |  |  |                 header_data.fragment_lines += [line] | 
					
						
							|  |  |  |             if header_data.reading == "compute": | 
					
						
							|  |  |  |                 header_data.compute_lines += [line] | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             line = fs.readline() | 
					
						
							|  |  |  |             header_data.line_offset += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return header_data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-19 21:01:58 -07:00
										 |  |  | def build_rd_header( | 
					
						
							| 
									
										
										
										
											2023-11-21 15:33:14 -06:00
										 |  |  |     filename: str, optional_output_filename: Optional[str] = None, header_data: Optional[RDHeaderStruct] = None | 
					
						
							| 
									
										
										
										
											2023-03-19 21:01:58 -07:00
										 |  |  | ) -> None: | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |     header_data = header_data or RDHeaderStruct() | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  |     include_file_in_rd_header(filename, header_data, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-19 21:01:58 -07:00
										 |  |  |     if optional_output_filename is None: | 
					
						
							|  |  |  |         out_file = filename + ".gen.h" | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         out_file = optional_output_filename | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  |     out_file_base = out_file | 
					
						
							|  |  |  |     out_file_base = out_file_base[out_file_base.rfind("/") + 1 :] | 
					
						
							|  |  |  |     out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :] | 
					
						
							|  |  |  |     out_file_ifdef = out_file_base.replace(".", "_").upper() | 
					
						
							|  |  |  |     out_file_class = out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "ShaderRD" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |     if header_data.compute_lines: | 
					
						
							|  |  |  |         body_parts = [ | 
					
						
							| 
									
										
										
										
											2024-07-31 14:15:56 -05:00
										 |  |  |             "static const char _compute_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.compute_lines), | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |             f'setup(nullptr, nullptr, _compute_code, "{out_file_class}");', | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         body_parts = [ | 
					
						
							| 
									
										
										
										
											2024-07-31 14:15:56 -05:00
										 |  |  |             "static const char _vertex_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.vertex_lines), | 
					
						
							|  |  |  |             "static const char _fragment_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.fragment_lines), | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |             f'setup(_vertex_code, _fragment_code, nullptr, "{out_file_class}");', | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |     body_content = "\n\t\t".join(body_parts) | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |     # Intended curly brackets are doubled so f-string doesn't eat them up. | 
					
						
							|  |  |  |     shader_template = f"""/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */
 | 
					
						
							|  |  |  | #ifndef {out_file_ifdef}_RD | 
					
						
							|  |  |  | #define {out_file_ifdef}_RD | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | #include "servers/rendering/renderer_rd/shader_rd.h" | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | class {out_file_class} : public ShaderRD {{ | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | 	{out_file_class}() {{ | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | 		{body_content} | 
					
						
							|  |  |  | 	}} | 
					
						
							|  |  |  | }}; | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | #endif | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-09 14:29:24 -06:00
										 |  |  |     with open(out_file, "w", encoding="utf-8", newline="\n") as fd: | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |         fd.write(shader_template) | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def build_rd_headers(target, source, env): | 
					
						
							| 
									
										
										
										
											2025-01-01 15:40:46 -06:00
										 |  |  |     env.NoCache(target) | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  |     for x in source: | 
					
						
							| 
									
										
										
										
											2023-03-19 21:01:58 -07:00
										 |  |  |         build_rd_header(filename=str(x)) | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class RAWHeaderStruct: | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self.code = "" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 22:21:46 +09:00
										 |  |  | def include_file_in_raw_header(filename: str, header_data: RAWHeaderStruct, depth: int) -> None: | 
					
						
							| 
									
										
										
										
											2024-03-24 18:02:56 +01:00
										 |  |  |     with open(filename, "r", encoding="utf-8") as fs: | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |         line = fs.readline() | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |         while line: | 
					
						
							|  |  |  |             while line.find("#include ") != -1: | 
					
						
							|  |  |  |                 includeline = line.replace("#include ", "").strip()[1:-1] | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                 included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline) | 
					
						
							|  |  |  |                 include_file_in_raw_header(included_file, header_data, depth + 1) | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |                 line = fs.readline() | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 12:09:48 -05:00
										 |  |  |             header_data.code += line | 
					
						
							|  |  |  |             line = fs.readline() | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-19 21:01:58 -07:00
										 |  |  | def build_raw_header( | 
					
						
							| 
									
										
										
										
											2023-11-21 15:33:14 -06:00
										 |  |  |     filename: str, optional_output_filename: Optional[str] = None, header_data: Optional[RAWHeaderStruct] = None | 
					
						
							| 
									
										
										
										
											2023-03-19 21:01:58 -07:00
										 |  |  | ): | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |     header_data = header_data or RAWHeaderStruct() | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  |     include_file_in_raw_header(filename, header_data, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-19 21:01:58 -07:00
										 |  |  |     if optional_output_filename is None: | 
					
						
							|  |  |  |         out_file = filename + ".gen.h" | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         out_file = optional_output_filename | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  |     out_file_base = out_file.replace(".glsl.gen.h", "_shader_glsl") | 
					
						
							|  |  |  |     out_file_base = out_file_base[out_file_base.rfind("/") + 1 :] | 
					
						
							|  |  |  |     out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :] | 
					
						
							|  |  |  |     out_file_ifdef = out_file_base.replace(".", "_").upper() | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     shader_template = f"""/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */
 | 
					
						
							|  |  |  | #ifndef {out_file_ifdef}_RAW_H | 
					
						
							|  |  |  | #define {out_file_ifdef}_RAW_H | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char {out_file_base}[] = {{ | 
					
						
							| 
									
										
										
										
											2024-07-31 14:15:56 -05:00
										 |  |  | {to_raw_cstring(header_data.code)} | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  | }}; | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-09 14:29:24 -06:00
										 |  |  |     with open(out_file, "w", encoding="utf-8", newline="\n") as f: | 
					
						
							| 
									
										
										
										
											2022-06-30 11:14:07 +09:00
										 |  |  |         f.write(shader_template) | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def build_raw_headers(target, source, env): | 
					
						
							| 
									
										
										
										
											2025-01-01 15:40:46 -06:00
										 |  |  |     env.NoCache(target) | 
					
						
							| 
									
										
										
										
											2020-08-13 09:35:41 +02:00
										 |  |  |     for x in source: | 
					
						
							| 
									
										
										
										
											2023-03-19 21:01:58 -07:00
										 |  |  |         build_raw_header(filename=str(x)) |