Skip to content

Commit 6dbfbcc

Browse files
committed
WIP, works for scene shader
1 parent 6fd949a commit 6dbfbcc

File tree

3 files changed

+279
-2
lines changed

3 files changed

+279
-2
lines changed

servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,37 @@
3131
#pragma once
3232

3333
#include "../storage_rd/material_storage.h"
34+
#include "core/string/ustring.h"
3435
#include "servers/rendering/renderer_rd/pipeline_hash_map_rd.h"
35-
#include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
36+
#include "servers/rendering/renderer_rd/shader_loader_rd.h"
37+
// #include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
3638

37-
namespace RendererSceneRenderImplementation {
39+
class SceneForwardClusteredShaderRD : public ShaderRD {
40+
public:
41+
SceneForwardClusteredShaderRD() {
42+
// static const char _vertex_code[];
43+
// static const char _fragment_code[];
44+
// static const char *_compute_code = nullptr;
45+
ShaderLoaderRD::ShaderLoadResult res = ShaderLoaderRD::get_singleton()->load_shader_file("./shaders/forward_clustered/scene_forward_clustered.glsl");
46+
const char *vertex_code = nullptr;
47+
const char *fragment_code = nullptr;
48+
const char *compute_code = nullptr;
49+
50+
if (!res.vertex_code.is_empty()) {
51+
vertex_code = res.vertex_code.utf8().get_data();
52+
}
53+
if (!res.fragment_code.is_empty()) {
54+
fragment_code = res.fragment_code.utf8().get_data();
55+
}
56+
if (!res.compute_code.is_empty()) {
57+
compute_code = res.compute_code.utf8().get_data();
58+
}
3859

60+
setup(vertex_code, fragment_code, compute_code, "SceneForwardClusteredShaderRD");
61+
}
62+
};
63+
64+
namespace RendererSceneRenderImplementation {
3965
class SceneShaderForwardClustered {
4066
private:
4167
static SceneShaderForwardClustered *singleton;
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/**************************************************************************/
2+
/* shader_loader_rd.cpp */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#include "shader_loader_rd.h"
32+
33+
#include "core/io/dir_access.h"
34+
#include "core/io/file_access.h"
35+
#include "core/io/json.h"
36+
#include "core/templates/hash_set.h"
37+
#include "core/templates/vector.h"
38+
39+
ShaderLoaderRD *ShaderLoaderRD::singleton = nullptr;
40+
41+
ShaderLoaderRD::ShaderLoaderRD() {
42+
ERR_FAIL_COND(singleton != nullptr);
43+
singleton = this;
44+
}
45+
46+
ShaderLoaderRD::~ShaderLoaderRD() {
47+
singleton = nullptr;
48+
}
49+
50+
static void _process_shader_file(const String &p_path, Vector<String> &r_vertex_lines, Vector<String> &r_fragment_lines, Vector<String> &r_compute_lines, HashSet<String> &r_vertex_included, HashSet<String> &r_fragment_included, HashSet<String> &r_compute_included, int p_depth);
51+
52+
static void _include_shader_file(const String &p_path, Vector<String> &r_lines, HashSet<String> &r_included_files, int p_depth) {
53+
if (r_included_files.has(p_path)) {
54+
return;
55+
}
56+
57+
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ);
58+
ERR_FAIL_COND_MSG(file.is_null(), vformat("Shader include file does not exist: %s", p_path));
59+
60+
r_included_files.insert(p_path);
61+
62+
while (!file->eof_reached()) {
63+
String line = file->get_line();
64+
65+
// Note: Keep comments as they might be useful for the LLM.
66+
// int comment_pos = line.find("//");
67+
// if (comment_pos != -1) {
68+
// line = line.substr(0, comment_pos);
69+
// }
70+
71+
// Check for #include directive.
72+
int include_pos = line.find("#include ");
73+
if (include_pos != -1) {
74+
// Extract the include filename
75+
String include_directive = line.substr(include_pos + 9).strip_edges();
76+
if (include_directive.length() >= 2 && include_directive[0] == '"' && include_directive[include_directive.length() - 1] == '"') {
77+
String include_file = include_directive.substr(1, include_directive.length() - 2);
78+
79+
// Resolve the include path.
80+
String resolved_path;
81+
if (include_file.begins_with("thirdparty/")) {
82+
resolved_path = include_file;
83+
} else {
84+
String base_dir = p_path.get_base_dir();
85+
resolved_path = base_dir.path_join(include_file).simplify_path();
86+
}
87+
88+
_include_shader_file(resolved_path, r_lines, r_included_files, p_depth + 1);
89+
}
90+
} else {
91+
r_lines.push_back(line);
92+
}
93+
}
94+
}
95+
96+
static void _process_shader_file(const String &p_path, Vector<String> &r_vertex_lines, Vector<String> &r_fragment_lines, Vector<String> &r_compute_lines, HashSet<String> &r_vertex_included, HashSet<String> &r_fragment_included, HashSet<String> &r_compute_included, int p_depth) {
97+
Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ);
98+
ERR_FAIL_COND_MSG(file.is_null(), vformat("Shader file does not exist: %s", p_path));
99+
100+
enum Section {
101+
SECTION_NONE,
102+
SECTION_VERTEX,
103+
SECTION_FRAGMENT,
104+
SECTION_COMPUTE
105+
};
106+
107+
Section current_section = SECTION_NONE;
108+
Vector<String> *current_lines = nullptr;
109+
HashSet<String> *current_included = nullptr;
110+
111+
while (!file->eof_reached()) {
112+
String line = file->get_line();
113+
114+
// Note: Keep comments as they might be useful for the LLM.
115+
// int comment_pos = line.find("//");
116+
// if (comment_pos != -1) {
117+
// line = line.substr(0, comment_pos);
118+
// }
119+
120+
// Check for section markers
121+
if (line.find("#[vertex]") != -1) {
122+
current_section = SECTION_VERTEX;
123+
current_lines = &r_vertex_lines;
124+
current_included = &r_vertex_included;
125+
continue;
126+
} else if (line.find("#[fragment]") != -1) {
127+
current_section = SECTION_FRAGMENT;
128+
current_lines = &r_fragment_lines;
129+
current_included = &r_fragment_included;
130+
continue;
131+
} else if (line.find("#[compute]") != -1) {
132+
current_section = SECTION_COMPUTE;
133+
current_lines = &r_compute_lines;
134+
current_included = &r_compute_included;
135+
continue;
136+
}
137+
138+
if (current_section != SECTION_NONE && current_lines != nullptr && current_included != nullptr) {
139+
int include_pos = line.find("#include ");
140+
if (include_pos != -1) {
141+
// Extract the include filename
142+
String include_directive = line.substr(include_pos + 9).strip_edges();
143+
if (include_directive.length() >= 2 && include_directive[0] == '"' && include_directive[include_directive.length() - 1] == '"') {
144+
String include_file = include_directive.substr(1, include_directive.length() - 2);
145+
146+
// Resolve the include path
147+
// TODO: Handle this correctly
148+
String resolved_path;
149+
if (include_file.begins_with("thirdparty/")) {
150+
resolved_path = include_file;
151+
} else {
152+
String base_dir = p_path.get_base_dir();
153+
resolved_path = base_dir.path_join(include_file).simplify_path();
154+
}
155+
156+
// Only include if not already included in this section
157+
if (!current_included->has(resolved_path)) {
158+
_include_shader_file(resolved_path, *current_lines, *current_included, p_depth + 1);
159+
}
160+
}
161+
} else {
162+
current_lines->push_back(line);
163+
}
164+
}
165+
}
166+
}
167+
168+
ShaderLoaderRD::ShaderLoadResult ShaderLoaderRD::load_shader_file(const String &p_path) {
169+
ShaderLoadResult result;
170+
171+
Vector<String> vertex_lines;
172+
Vector<String> fragment_lines;
173+
Vector<String> compute_lines;
174+
175+
HashSet<String> vertex_included;
176+
HashSet<String> fragment_included;
177+
HashSet<String> compute_included;
178+
179+
Ref<DirAccess> dir = DirAccess::open(p_path.get_base_dir());
180+
String s = dir->get_full_path(p_path, DirAccess::ACCESS_FILESYSTEM);
181+
182+
_process_shader_file(p_path, vertex_lines, fragment_lines, compute_lines, vertex_included, fragment_included, compute_included, 0);
183+
184+
result.vertex_code = String("\n").join(vertex_lines);
185+
result.fragment_code = String("\n").join(fragment_lines);
186+
result.compute_code = String("\n").join(compute_lines);
187+
188+
// Add final newline if there's content.
189+
if (!result.vertex_code.is_empty()) {
190+
result.vertex_code += "\n";
191+
}
192+
if (!result.fragment_code.is_empty()) {
193+
result.fragment_code += "\n";
194+
}
195+
if (!result.compute_code.is_empty()) {
196+
result.compute_code += "\n";
197+
}
198+
199+
return result;
200+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**************************************************************************/
2+
/* shader_loader_rd.h */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#pragma once
32+
33+
#include "core/string/ustring.h"
34+
35+
class ShaderLoaderRD {
36+
static ShaderLoaderRD *singleton;
37+
38+
public:
39+
ShaderLoaderRD();
40+
~ShaderLoaderRD();
41+
42+
struct ShaderLoadResult {
43+
String fragment_code;
44+
String vertex_code;
45+
String compute_code;
46+
};
47+
48+
ShaderLoadResult load_shader_file(const String &p_path);
49+
50+
static ShaderLoaderRD *get_singleton() { return singleton; }
51+
};

0 commit comments

Comments
 (0)