1#include "ShaderBuilder.h"
3#include "Utilities/Strings.h"
4#include "Utilities/Preprocessor.h"
5#include "ResourceStore.h"
6#include "Renderer/EnginePermutations.h"
8#include "Rendering/IGraphicsDevice.h"
10#include "Foundation/Logging/Logger.h"
11#include "Foundation/StringUtilities.h"
12#include "Foundation/StringView.h"
21 constexpr size_t InitialBufferCapasity = 4096u;
26 } engineTextures[] = {
27 { Strings::add(
"environmentSky"), Strings::add(
"ENVIRONMENT_SKY")},
28 { Strings::add(
"environmentRadiance"), Strings::add(
"ENVIRONMENT_RADIANCE")},
29 { Strings::add(
"environmentIrradiance"), Strings::add(
"ENVIRONMENT_IRRADIANCE")},
30 { Strings::add(
"ambientIrradiance"), Strings::add(
"AMBIENT_IRRADIANCE")},
31 { Strings::add(
"brdfLUT"), Strings::add(
"BRDF_LUT")},
32 { Strings::add(
"cascadedShadowMap"), Strings::add(
"CASCADEDSHADOWMAP")},
33 { Strings::add(
"cubeShadowMap"), Strings::add(
"CUBESHADOWMAP")}
36 struct EngineBufferMember
44 Strings::add(
"projectionMatrix"),
45 Strings::add(
"viewMatrix"),
46 Strings::add(
"inverseViewMatrix"),
47 Strings::add(
"inverseProjectionMatrix"),
48 Strings::add(
"worldToClipMatrix"),
49 Strings::add(
"projectionParameters"),
50 Strings::add(
"clippingPlanes"),
51 Strings::add(
"blueNoiseOffset"),
52 Strings::add(
"viewportOrigin"),
53 Strings::add(
"viewportSize"),
54 Strings::add(
"viewportSizeRcp"),
55 Strings::add(
"shadowDepthClamp"),
56 Strings::add(
"animationTime"),
57 Strings::add(
"exposure"),
58 Strings::add(
"sceneFlags"),
59 Strings::add(
"clientFlags"),
60 Strings::add(
"environmentRadianceMips"),
61 Strings::add(
"environmentIrradianceMips")
65 Strings::add(
"getClipFromViewMatrix"),
66 Strings::add(
"getClipFromWorldMatrix"),
67 Strings::add(
"getViewFromWorldMatrix"),
68 Strings::add(
"getViewFromClipMatrix"),
69 Strings::add(
"getWorldFromViewMatrix")
73 Strings::add(
"worldMatrix"),
74 Strings::add(
"objectId")
78 Strings::add(
"boneTransforms")
82 Strings::add(
"lightPositions"),
83 Strings::add(
"lightDirections"),
84 Strings::add(
"lightColorIntensity"),
85 Strings::add(
"lightParameters"),
86 Strings::add(
"numLights"),
87 Strings::add(
"eyePosition"),
88 Strings::add(
"fogColor"),
89 Strings::add(
"fogDistance"),
90 Strings::add(
"fogAmount"),
91 Strings::add(
"fogEnabled"),
92 Strings::add(
"ambientIntensity"),
93 Strings::add(
"ambientColor"),
94 Strings::add(
"environmentBrightness"),
95 Strings::add(
"skyMultiplier"),
96 Strings::add(
"seaFlags"),
101 Strings::add(
"shadows"),
102 Strings::add(
"cascadeOffsets")
105 struct EngineBuffer {
109 } engineBuffers[] = {
110 { sceneBufferMembers,
sizeof(sceneBufferMembers) /
sizeof(sceneBufferMembers[0]), Strings::add(
"SCENEBUFFER") },
111 { viewGetters,
sizeof(viewGetters) /
sizeof(viewGetters[0]), Strings::add(
"VIEWGETTERS") },
112 { objectBufferMembers,
sizeof(objectBufferMembers) /
sizeof(objectBufferMembers[0]), Strings::add(
"OBJECTBUFFER") },
113 { animationBufferMembers,
sizeof(animationBufferMembers) /
sizeof(animationBufferMembers[0]), Strings::add(
"ANIMATIONBUFFER") },
114 { lightBufferMembers,
sizeof(lightBufferMembers) /
sizeof(lightBufferMembers[0]), Strings::add(
"LIGHTBUFFER") },
115 { shadowBufferMembers,
sizeof(shadowBufferMembers) /
sizeof(shadowBufferMembers[0]), Strings::add(
"SHADOWBUFFER") }
122 content.append(
"#include \"");
124 content.append(path.to_string_view());
125 content.append(
"\"\n");
128 void changeSuffix(std::string& dst,
const std::string_view& from,
const std::string_view& to)
130 auto pos = dst.find(from);
131 if (pos == std::string::npos)
return;
132 dst.replace(pos, to.length(), to);
135 void addEffectDefinesAndStuff(std::string& output,
136 const std::vector<std::pair<std::string, std::string>>& definitions,
137 uint32_t multiViewCount,
bool isVertexShader)
139 output.append(
"#version 300 es\n");
140 if (multiViewCount) {
141 std::string multiViewCountString = std::to_string(multiViewCount);
142 if (isVertexShader) {
143 output.append(
"#extension GL_OVR_multiview : require\nlayout(num_views=");
144 output.append(multiViewCountString);
145 output.append(
") in;\n");
147 output.append(
"#define COGS_MULTIVIEW ");
148 output.append(multiViewCountString);
151 output.append(
"precision highp float;\n"
152 "precision highp int;\n"
153 "precision highp sampler2DArrayShadow;\n"
154 "precision highp samplerCubeShadow;\n"
155 "precision mediump sampler2DArray;\n"
156 "precision highp usampler2D;\n"
157 "layout (std140) uniform;\n");
158 for (
const std::pair<std::string,std::string>& define : definitions) {
159 output.append(
"#define ");
160 output.append(define.first);
162 output.append(define.second);
167 [[nodiscard]] std::string_view attributeVaryingType(
const MaterialDataType type)
170 case MaterialDataType::Float:
return "float ";
break;
171 case MaterialDataType::Float2:
return "vec2 ";
break;
172 case MaterialDataType::Float3:
return "vec3 ";
break;
173 case MaterialDataType::Float4:
return "vec4 ";
break;
174 case MaterialDataType::Float4x4:
return "mat4 ";
break;
175 case MaterialDataType::Int:
return "int ";
break;
176 case MaterialDataType::Int2:
return "ivec4 ";
break;
177 case MaterialDataType::Int3:
return "ivec3 ";
break;
178 case MaterialDataType::Int4:
return "ivec4 ";
break;
179 case MaterialDataType::UInt:
return "uint ";
break;
180 case MaterialDataType::UInt2:
return "uvec4 ";
break;
181 case MaterialDataType::UInt3:
return "uvec3 ";
break;
182 case MaterialDataType::UInt4:
return "uvec4 ";
break;
183 case MaterialDataType::SV_IsFrontFace:
return "bool ";
break;
184 case MaterialDataType::VFACE:
return "float ";
break;
185 case MaterialDataType::Position:
return "vec4 ";
break;
187 LOG_ERROR(logger,
"Unsupported attribute type %d",
int(type));
193 const char* semanticNames[]
203 static_assert(
sizeof(semanticNames) ==
sizeof(semanticNames[0]) * (size_t(ShaderInterfaceMemberDefinition::SemanticName::FirstSystemValueSemantic) - 1));
209 if ((attribute.semantic.name != ShaderInterfaceMemberDefinition::SemanticName::None)
210 && (
size_t(attribute.semantic.name) <
size_t(ShaderInterfaceMemberDefinition::SemanticName::FirstSystemValueSemantic)))
212 shaderSource.append(
"in ");
213 shaderSource.append(attributeVaryingType(attribute.type));
214 shaderSource.append(semanticNames[
size_t(attribute.semantic.name) - 1]);
215 shaderSource.append(std::to_string(attribute.semantic.slot));
216 shaderSource.append(
";\n");
219 switch (attribute.semantic.name) {
220 case ShaderInterfaceMemberDefinition::SemanticName::SV_VertexID: [[fallthrough]];
221 case ShaderInterfaceMemberDefinition::SemanticName::SV_InstanceID:
224 LOG_WARNING(logger,
"Unexpected semantic name '%.*s'",
225 StringViewFormat(ShaderInterfaceMemberDefinition::semanticNameString(attribute.semantic.name)));
229 shaderSource.append(
"\n");
234 shaderSource.append(
"struct ");
235 shaderSource.append(name);
236 shaderSource.append(
" {\n");
237 for (
const auto& attribute : iface.members) {
238 shaderSource.append(
" ");
239 shaderSource.append(attributeVaryingType(attribute.type));
240 shaderSource.append(attribute.name);
241 shaderSource.append(
";\n");
243 shaderSource.append(
"};\n\n");
246 void addAttributeImportFunc(std::string& shaderSource,
const std::string_view& name,
const ShaderInterfaceDefinition& iface)
248 shaderSource.append(name);
249 shaderSource.append(
" importAttributes() {\n");
250 shaderSource.append(
" ");
251 shaderSource.append(name);
252 shaderSource.append(
" t;\n");
253 for (
const auto& attribute : iface.members) {
256 if ((attribute.semantic.name != ShaderInterfaceMemberDefinition::SemanticName::None)
257 && (
size_t(attribute.semantic.name) <
size_t(ShaderInterfaceMemberDefinition::SemanticName::FirstSystemValueSemantic)))
259 shaderSource.append(
" t.");
260 shaderSource.append(attribute.name);
261 shaderSource.append(
" = ");
262 shaderSource.append(semanticNames[
size_t(attribute.semantic.name) - 1]);
263 shaderSource.append(std::to_string(attribute.semantic.slot));
264 shaderSource.append(
";\n");
267 switch (attribute.semantic.name) {
268 case ShaderInterfaceMemberDefinition::SemanticName::SV_VertexID:
269 shaderSource.append(
" t.");
270 shaderSource.append(attribute.name);
271 shaderSource.append(
" = ");
272 shaderSource.append(attributeVaryingType(attribute.type));
273 shaderSource.append(
"(gl_VertexID);\n");
275 case ShaderInterfaceMemberDefinition::SemanticName::SV_InstanceID:
276 shaderSource.append(
" t.");
277 shaderSource.append(attribute.name);
278 shaderSource.append(
" = ");
279 shaderSource.append(attributeVaryingType(attribute.type));
280 shaderSource.append(
"(gl_InstanceID);\n");
287 shaderSource.append(
" return t;\n}\n\n");
290 void addInOutVariables(std::string& shaderSource,
const std::string_view& prefix,
const ShaderInterfaceDefinition& iface,
bool in)
292 if (iface.members.empty())
return;
293 for (
const auto& out : iface.members) {
295 case MaterialDataType::SV_IsFrontFace:
296 case MaterialDataType::VFACE:
300 if (out.modifiers & ShaderInterfaceMemberDefinition::CentroidModifier) {
301 shaderSource.append(
"centroid ");
303 if (out.modifiers & ShaderInterfaceMemberDefinition::NointerpolationModifier) {
304 shaderSource.append(
"flat ");
306 shaderSource.append(in ?
"in " :
"out ");
307 shaderSource.append(attributeVaryingType(out.type));
308 shaderSource.append(prefix);
309 shaderSource.append(out.name);
310 shaderSource.append(
";\n");
314 shaderSource.append(
"\n");
317 void addInterfaceConstructor(std::string& shaderSource,
const std::string_view& name,
const ShaderInterfaceDefinition& iface)
319 shaderSource.append(name);
320 shaderSource.append(
" create");
321 shaderSource.append(name);
322 shaderSource.append(
"() {\n");
323 shaderSource.append(
" ");
324 shaderSource.append(name);
325 shaderSource.append(
" t;\n");
326 for (
const auto& attribute : iface.members) {
327 const char* initializer =
nullptr;
328 switch (attribute.type) {
329 case MaterialDataType::Float: initializer =
"0.0;\n";
break;
330 case MaterialDataType::Float2: initializer =
"vec2(0);\n";
break;
331 case MaterialDataType::Float3: initializer =
"vec3(0);\n";
break;
332 case MaterialDataType::Float4: initializer =
"vec4(0);\n";
break;
333 case MaterialDataType::Float4x4: initializer =
"mat4(0);\n";
break;
338 shaderSource.append(
" t.");
339 shaderSource.append(attribute.name);
340 shaderSource.append(
" = ");
341 shaderSource.append(initializer);
344 shaderSource.append(
" return t;\n}\n\n");
349 shaderSource.append(
"void exportOut(");
350 shaderSource.append(name);
351 shaderSource.append(
" vertexOut) {\n");
352 for (
const auto& attribute : iface.members) {
353 switch (attribute.type) {
354 case MaterialDataType::SV_IsFrontFace:
355 case MaterialDataType::VFACE:
359 shaderSource.append(
" vsfs_");
360 shaderSource.append(attribute.name);
361 shaderSource.append(
" = vertexOut.");
362 shaderSource.append(attribute.name);
363 shaderSource.append(
";\n");
367 shaderSource.append(
"}\n");
372 shaderSource.append(name);
373 shaderSource.append(
" importIn() {\n ");
374 shaderSource.append(name);
375 shaderSource.append(
" t;\n");
376 for (
const auto& attribute : iface.members) {
377 switch (attribute.type) {
378 case MaterialDataType::SV_IsFrontFace:
379 shaderSource.append(
" t.");
380 shaderSource.append(attribute.name);
381 shaderSource.append(
" = gl_FrontFacing;\n");
383 case MaterialDataType::VFACE:
384 shaderSource.append(
" t.");
385 shaderSource.append(attribute.name);
386 shaderSource.append(
" = gl_FrontFacing ? 1.0 : -1.0;\n");
388 case MaterialDataType::Position:
389 shaderSource.append(
" t.");
390 shaderSource.append(attribute.name);
391 shaderSource.append(
" = gl_FragCoord;\n");
394 shaderSource.append(
" t.");
395 shaderSource.append(attribute.name);
396 shaderSource.append(
" = vsfs_");
397 shaderSource.append(attribute.name);
398 shaderSource.append(
";\n");
402 shaderSource.append(
" return t;\n}\n");
407 shaderSource.append(
"void transferAttributes(in VertexIn vertexIn, inout VertexOut vertexOut) {\n");
409 if (member.semantic.name == ShaderInterfaceMemberDefinition::SemanticName::SV_VertexID)
continue;
411 if (dMember.name == member.name) {
412 shaderSource.append(
" vertexOut.");
413 shaderSource.append(member.name);
414 shaderSource.append(
" = ");
415 if (dMember.type == MaterialDataType::Float3 && member.type == MaterialDataType::Float2 && member.semantic.name == ShaderInterfaceMemberDefinition::SemanticName::Normal) {
416 shaderSource.append(
"octDecode(vertexIn.");
417 shaderSource.append(member.name);
418 shaderSource.append(
"); \n");
421 if (dMember.type == MaterialDataType::Float4 && member.type == MaterialDataType::Float3) {
422 shaderSource.append(
"vec4(vertexIn.");
423 shaderSource.append(member.name);
424 shaderSource.append(
", 1.0);\n");
427 if (dMember.type == MaterialDataType::Float4 && member.type == MaterialDataType::Float2) {
428 shaderSource.append(
"vec4(vertexIn.");
429 shaderSource.append(member.name);
430 shaderSource.append(
", 0.0, 1.0);\n");
434 if (dMember.type != member.type) {
435 switch (dMember.type) {
436 case MaterialDataType::Float: shaderSource.append(
"float("); close =
true;
break;
437 case MaterialDataType::Float2: shaderSource.append(
"vec2("); close =
true;
break;
438 case MaterialDataType::Float3: shaderSource.append(
"vec3("); close =
true;
break;
439 case MaterialDataType::Float4: shaderSource.append(
"vec4("); close =
true;
break;
440 case MaterialDataType::Float4x4: shaderSource.append(
"mat4("); close =
true;
break;
441 case MaterialDataType::Int: shaderSource.append(
"int("); close =
true;
break;
442 case MaterialDataType::Int2: shaderSource.append(
"ivec2("); close =
true;
break;
443 case MaterialDataType::Int3: shaderSource.append(
"ivec3("); close =
true;
break;
444 case MaterialDataType::Int4: shaderSource.append(
"ivec4("); close =
true;
break;
445 case MaterialDataType::UInt: shaderSource.append(
"uint("); close =
true;
break;
446 case MaterialDataType::UInt2: shaderSource.append(
"uvec2("); close =
true;
break;
447 case MaterialDataType::UInt3: shaderSource.append(
"uvec3("); close =
true;
break;
448 case MaterialDataType::UInt4: shaderSource.append(
"uvec4("); close =
true;
break;
453 shaderSource.append(
"vertexIn.");
454 shaderSource.append(member.name);
455 if (close) shaderSource.append(1,
')');
456 shaderSource.append(
";\n");
461 shaderSource.append(
"}\n");
465 void addEngineUniformBuffer(std::string& shaderSource,
const std::unordered_set<Cogs::Core::StringRef>& identifiersSeen)
467 for (
const EngineBuffer& engineBuffer : engineBuffers) {
470 bool referenced =
false;
471 for (
size_t i = 0; i < engineBuffer.count; i++) {
472 if (identifiersSeen.contains(engineBuffer.members[i])) {
481 shaderSource.append(
"#define COGS_");
482 shaderSource.append(Strings::get(engineBuffer.name).to_string_view());
483 shaderSource.append(
"_REFERENCED 1\n");
488 void addUniformBuffer(std::string& shaderSource,
489 const std::unordered_set<Cogs::Core::StringRef>& identifiersSeen,
492 if (definition.values.empty())
return;
495 bool isInUse =
false;
497 if (identifiersSeen.contains(Strings::add(member.name))) {
502 if (!isInUse)
return;
505 shaderSource.append(
"uniform ");
506 shaderSource.append(definition.name);
507 shaderSource.append(
" {\n");
509 shaderSource.append(2,
' ');
510 switch (member.type) {
511 case MaterialDataType::Float: shaderSource.append(
"float");
break;
512 case MaterialDataType::Float2: shaderSource.append(
"vec2");
break;
513 case MaterialDataType::Float3: shaderSource.append(
"vec3");
break;
514 case MaterialDataType::Float4: shaderSource.append(
"vec4");
break;
515 case MaterialDataType::Float4x4: shaderSource.append(
"mat4");
break;
516 case MaterialDataType::Float4Array: shaderSource.append(
"vec4");
break;
517 case MaterialDataType::Float4x4Array: shaderSource.append(
"mat4");
break;
518 case MaterialDataType::Int: shaderSource.append(
"int");
break;
519 case MaterialDataType::Int2: shaderSource.append(
"ivec2");
break;
520 case MaterialDataType::Int3: shaderSource.append(
"ivec3");
break;
521 case MaterialDataType::Int4: shaderSource.append(
"ivec4");
break;
522 case MaterialDataType::UInt: shaderSource.append(
"uint");
break;
523 case MaterialDataType::UInt2: shaderSource.append(
"uvec2");
break;
524 case MaterialDataType::UInt3: shaderSource.append(
"uvec3");
break;
525 case MaterialDataType::UInt4: shaderSource.append(
"uvec4");
break;
526 case MaterialDataType::Bool: shaderSource.append(
"bool");
break;
528 shaderSource.append(
"<invalid type>");
531 shaderSource.append(1,
' ');
532 shaderSource.append(member.name);
533 if (member.type == MaterialDataType::Float4Array || member.type == MaterialDataType::Float4x4Array) {
534 assert(member.dimension !=
static_cast<size_t>(-1));
535 shaderSource.append(
"[");
536 shaderSource.append(std::to_string(member.dimension));
537 shaderSource.append(
"]");
539 shaderSource.append(
";\n");
541 shaderSource.append(
"};\n");
545 void addEngineUniforms(std::string& shaderSource,
const std::unordered_set<StringRef>& identifiersSeen)
547 for (
auto& item : engineUniforms) {
548 bool active = identifiersSeen.count(item.name);
549 for (
auto dependee : item.dependees) {
550 active = active || identifiersSeen.count(dependee);
553 shaderSource.append(
"uniform ");
555 case MaterialDataType::Float4:
556 shaderSource.append(
"vec4 ");
558 case MaterialDataType::Float4x4:
559 shaderSource.append(
"mat4 ");
562 assert(
false &&
"Unhandled material data type");
564 auto name = Strings::get(item.name);
565 shaderSource.append(name.to_string_view());
566 shaderSource.append(
";\n");
569 if (identifiersSeen.count(objectId)) shaderSource.append(
"float objectId() { return objectData.x; }\n");
570 if (identifiersSeen.count(animationTime)) shaderSource.append(
"float animationTime() { return objectData.y; }\n");
571 if (identifiersSeen.count(environmentRadianceMips)) shaderSource.append(
"float environmentRadianceMips() { return environmentInfo.x; }\n");
572 if (identifiersSeen.count(environmentIrradianceMips)) shaderSource.append(
"float environmentIrradianceMips() { return environmentInfo.y; }\n");
573 if (identifiersSeen.count(exposure)) shaderSource.append(
"float exposure() { return environmentInfo.z; }\n");
574 if (identifiersSeen.count(environmentBrightness)) shaderSource.append(
"float environmentBrightness() { return environmentInfo.w; }\n");
581 shaderSource.append(
"uniform ");
585 case MaterialDataType::Unknown:
586 case MaterialDataType::Float:
587 case MaterialDataType::Float2:
588 case MaterialDataType::Float3:
589 case MaterialDataType::Float4:
592 case MaterialDataType::Int:
593 case MaterialDataType::Int2:
594 case MaterialDataType::Int3:
595 case MaterialDataType::Int4:
596 shaderSource.append(
"i");
599 case MaterialDataType::UInt:
600 case MaterialDataType::UInt2:
601 case MaterialDataType::UInt3:
602 case MaterialDataType::UInt4:
603 shaderSource.append(
"u");
606 LOG_ERROR(logger,
"Unexpected texture format: %s", DataTypeNames[
static_cast<size_t>(format) < std::size(DataTypeNames) ?
static_cast<size_t>(format) : 0]);
611 case TextureDimensions::Texture2D:
612 shaderSource.append(
"sampler2D ");
614 case TextureDimensions::TexureCube:
615 shaderSource.append(
"samplerCube ");
617 case TextureDimensions::Texture2DArray:
618 shaderSource.append(
"sampler2DArray ");
620 case TextureDimensions::Texture3D:
621 shaderSource.append(
"sampler3D ");
624 LOG_ERROR(logger,
"Unsupported texture type %d",
int(kind));
628 shaderSource.append(
";\n");
631 void addTextures(std::string& shaderSource,
632 const std::unordered_set<Cogs::Core::StringRef>& identifiersSeen,
633 const std::vector<MaterialTextureDefinition>& definition)
635 for (
auto& texture : engineTextures) {
636 if (identifiersSeen.contains(texture.name)) {
637 shaderSource.append(
"#define COGS_");
638 shaderSource.append(Strings::get(texture.defineName).to_string_view());
639 shaderSource.append(
"_REFERENCED 1\n");
642 for (
auto& texture : definition) {
643 if (identifiersSeen.contains(Strings::add(texture.name))) {
644 addTextureDeclaration(shaderSource, texture.name, texture.dimensions, texture.format);
647 shaderSource.append(
"\n");
653bool Cogs::Core::buildEffectES3(
Context* context,
654 std::vector<std::pair<std::string, std::string>>& definitions,
657 uint32_t multiViewCount)
659 if (!materialDefinition.effect.geometryShader.entryPoint.empty()) {
660 LOG_ERROR(logger,
"%s: Geometry shader not allowed in GLES3.", materialDefinition.name.c_str());
663 if (!materialDefinition.effect.hullShader.entryPoint.empty()) {
664 LOG_ERROR(logger,
"%s: Hull shader not allowed in GLES3.", materialDefinition.name.c_str());
667 if (!materialDefinition.effect.domainShader.entryPoint.empty()) {
668 LOG_ERROR(logger,
"%s: Domain shader not allowed in GLES3.", materialDefinition.name.c_str());
671 if (!materialDefinition.effect.computeShader.entryPoint.empty()) {
672 LOG_ERROR(logger,
"%s: Compute shader not allowed in GLES3.", materialDefinition.name.c_str());
676 changeSuffix(materialDefinition.effect.vertexShader.customSourcePath,
".hlsl",
".es30.glsl");
677 changeSuffix(materialDefinition.effect.pixelShader.customSourcePath,
".hlsl",
".es30.glsl");
678 std::string_view prefix = materialDefinition.name;
683 pp.
processed.reserve(::InitialBufferCapasity);
685 std::string vsheader;
686 vsheader.reserve(::InitialBufferCapasity);
687 addEffectDefinesAndStuff(vsheader, definitions, multiViewCount,
true);
688 vsheader.append(
"#define COGS_VERTEX_SHADER 1\n");
689 if (!pp.
process(context, vsheader))
return false;
694 vsbody.reserve(::InitialBufferCapasity);
695 addAttributes(vsbody, materialDefinition.effect.vertexShader.shaderInterface);
696 addInterfaceStruct(vsbody,
"VertexIn", materialDefinition.effect.vertexShader.shaderInterface);
697 addAttributeImportFunc(vsbody,
"VertexIn", materialDefinition.effect.vertexShader.shaderInterface);
698 addInOutVariables(vsbody,
"vsfs_", materialDefinition.effect.pixelShader.shaderInterface,
false);
699 addInterfaceStruct(vsbody,
"VertexOut", materialDefinition.effect.pixelShader.shaderInterface);
700 addInterfaceConstructor(vsbody,
"VertexOut", materialDefinition.effect.pixelShader.shaderInterface);
701 addExportOutFunc(vsbody,
"VertexOut", materialDefinition.effect.pixelShader.shaderInterface);
702 addTransferFunc(vsbody, materialDefinition.effect.vertexShader, materialDefinition.effect.pixelShader);
703 addInclude(vsbody,
Cogs::StringView(), materialDefinition.effect.vertexShader.customSourcePath);
705 vsbody.append(
"#define MATERIAL_VERTEX_FUNCTION ");
706 vsbody.append(materialDefinition.effect.vertexShader.entryPoint.empty() ?
"vertexFunction" : materialDefinition.effect.vertexShader.entryPoint);
710 vsbody.append(
"#define VERTEX_FUNCTION invokeMaterial\n");
711 std::string permutationVS = permutation.getDefinition()->vertexShader;
712 changeSuffix(permutationVS,
".hlsl",
".es30.glsl");
713 addInclude(vsbody,
nullptr, permutationVS);
715 if (!pp.
process(context, vsbody))
return false;
719 std::string vsuniforms;
720 vsuniforms.reserve(::InitialBufferCapasity);
728 addTextures(vsuniforms, pp.
identifiersSeen, materialDefinition.properties.textures);
731 if (!pp.
process(context, vsuniforms))
return false;
735 const std::string shaderName = Cogs::stringConcatenate({ prefix,
"VertexShader", permutation.getDefinition()->name,
".es30.glsl" });
736 const std::string all = Cogs::stringConcatenate({ vsheader, vsuniforms, vsbody });
740 FILE* f = fopen(shaderName.c_str(),
"wb");
741 fwrite(all.c_str(), all.length(), 1, f);
743 LOG_DEBUG(logger,
"Generated %s", shaderName.c_str());
747 std::string vspath =
"Shaders/" + shaderName;
753 pp.
processed.reserve(::InitialBufferCapasity);
755 std::string fsheader;
756 fsheader.reserve(::InitialBufferCapasity);
757 addEffectDefinesAndStuff(fsheader, definitions, multiViewCount,
false);
758 fsheader.append(
"#define COGS_FRAGMENT_SHADER 1\n");
759 if (!pp.
process(context, fsheader))
return false;
764 fsbody.reserve(::InitialBufferCapasity);
765 addInOutVariables(fsbody,
"vsfs_", materialDefinition.effect.pixelShader.shaderInterface,
true);
766 addInterfaceStruct(fsbody,
"VertexIn", materialDefinition.effect.pixelShader.shaderInterface);
767 addImportInFunc(fsbody,
"VertexIn", materialDefinition.effect.pixelShader.shaderInterface);
768 addInclude(fsbody,
nullptr, materialDefinition.effect.pixelShader.customSourcePath);
770 fsbody.append(
"#define MATERIAL_SURFACE_FUNCTION ");
771 fsbody.append(materialDefinition.effect.pixelShader.entryPoint.empty() ?
"surfaceFunction" : materialDefinition.effect.pixelShader.entryPoint);
775 fsbody.append(
"#define SURFACE_FUNCTION invokeMaterial\n");
776 std::string permutationPS = permutation.getDefinition()->pixelShader;
777 changeSuffix(permutationPS,
".hlsl",
".es30.glsl");
778 addInclude(fsbody,
nullptr, permutationPS);
780 if (!pp.
process(context, fsbody))
return false;
784 std::string fsuniforms;
785 fsuniforms.reserve(::InitialBufferCapasity);
793 addTextures(fsuniforms, pp.
identifiersSeen, materialDefinition.properties.textures);
794 addInclude(fsuniforms,
nullptr,
"Engine/Common.es30.glsl");
796 if (!pp.
process(context, fsuniforms))
return false;
800 const std::string shaderName = Cogs::stringConcatenate({ prefix,
"PixelShader", permutation.getDefinition()->name,
".es30.glsl" });
801 const std::string all = Cogs::stringConcatenate({ fsheader, fsuniforms, fsbody });
805 FILE* f = fopen(shaderName.c_str(),
"wb");
806 fwrite(all.c_str(), all.length(), 1, f);
808 LOG_DEBUG(logger,
"Generated %s", shaderName.c_str());
812 std::string fspath =
"Shaders/" + shaderName;
A Context instance contains all the services, systems and runtime components needed to use Cogs.
std::unique_ptr< class ResourceStore > resourceStore
ResourceStore service instance.
Log implementation class.
Provides a weakly referenced view over the contents of a string.
constexpr size_t size() const noexcept
Get the size of the string.
constexpr std::string_view to_string_view() const noexcept
Create a standard library string_view of the same view.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
TextureDimensions
Texture dimensions.
MaterialDataType
Defines available data types for material properties.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
bool process(Context *context, const StringView input)
Run a text block through the preprocessor.
std::unordered_set< StringRef > identifiersSeen
Set of identifiers encountered in active text.
std::string processed
Resulting processed text.