Create @foreach shader preprocessor macro in preparation for moving shadow setup out of shadermanager.cpp

pull/541/head
AnyOldName3 7 years ago
parent 548c42b5fd
commit 590531595b

@ -74,13 +74,82 @@ namespace Shader
return true;
}
bool parseFors(std::string& source)
{
const char escapeCharacter = '$';
size_t foundPos = 0;
while ((foundPos = source.find(escapeCharacter)) != std::string::npos)
{
size_t endPos = source.find_first_of(" \n\r()[].;,", foundPos);
if (endPos == std::string::npos)
{
std::cerr << "Unexpected EOF" << std::endl;
return false;
}
std::string command = source.substr(foundPos + 1, endPos - (foundPos + 1));
if (command != "foreach")
{
std::cerr << "Unknown shader directive: $" << command << std::endl;
return false;
}
size_t iterNameStart = endPos + 1;
size_t iterNameEnd = source.find_first_of(" \n\r()[].;,", iterNameStart);
if (iterNameEnd == std::string::npos)
{
std::cerr << "Unexpected EOF" << std::endl;
return false;
}
std::string iteratorName = "$" + source.substr(iterNameStart, iterNameEnd - iterNameStart);
size_t listStart = iterNameEnd + 1;
size_t listEnd = source.find_first_of("\n\r", listStart);
if (listEnd == std::string::npos)
{
std::cerr << "Unexpected EOF" << std::endl;
return false;
}
std::string list = source.substr(listStart, listEnd - listStart);
std::vector<std::string> listElements;
boost::split(listElements, list, boost::is_any_of(","));
size_t contentStart = source.find_first_not_of("\n\r", listEnd);
size_t contentEnd = source.find("$endforeach", contentStart);
if (contentEnd == std::string::npos)
{
std::cerr << "Unexpected EOF" << std::endl;
return false;
}
std::string content = source.substr(contentStart, contentEnd - contentStart);
size_t overallEnd = contentEnd + std::string("$endforeach").length();
// This will be wrong if there are other #line directives, so that needs fixing
int lineNumber = std::count(source.begin(), source.begin() + overallEnd, '\n') + 2;
std::string replacement = "";
for (std::vector<std::string>::const_iterator element = listElements.cbegin(); element != listElements.cend(); element++)
{
std::string contentInstance = content;
size_t foundIterator;
while ((foundIterator = contentInstance.find(iteratorName)) != std::string::npos)
contentInstance.replace(foundIterator, iteratorName.length(), *element);
replacement += contentInstance;
}
replacement += "\n#line " + std::to_string(lineNumber);
source.replace(foundPos, overallEnd - foundPos, replacement);
}
return true;
}
bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines)
{
const char escapeCharacter = '@';
size_t foundPos = 0;
std::vector<std::string> forIterators;
while ((foundPos = source.find(escapeCharacter)) != std::string::npos)
{
size_t endPos = source.find_first_of(" \n\r()[].;", foundPos);
size_t endPos = source.find_first_of(" \n\r()[].;,", foundPos);
if (endPos == std::string::npos)
{
std::cerr << "Unexpected EOF" << std::endl;
@ -88,7 +157,34 @@ namespace Shader
}
std::string define = source.substr(foundPos+1, endPos - (foundPos+1));
ShaderManager::DefineMap::const_iterator defineFound = defines.find(define);
if (defineFound == defines.end())
if (define == "foreach")
{
source.replace(foundPos, 1, "$");
size_t iterNameStart = endPos + 1;
size_t iterNameEnd = source.find_first_of(" \n\r()[].;,", iterNameStart);
if (iterNameEnd == std::string::npos)
{
std::cerr << "Unexpected EOF" << std::endl;
return false;
}
forIterators.push_back(source.substr(iterNameStart, iterNameEnd - iterNameStart));
}
else if (define == "endforeach")
{
source.replace(foundPos, 1, "$");
if (forIterators.empty())
{
std::cerr << "endforeach without foreach" << std::endl;
return false;
}
else
forIterators.pop_back();
}
else if (std::find(forIterators.begin(), forIterators.end(), define) != forIterators.end())
{
source.replace(foundPos, 1, "$");
}
else if (defineFound == defines.end())
{
std::cerr << "Undefined " << define << std::endl;
return false;
@ -113,23 +209,10 @@ namespace Shader
if (shadows)
{
definesWithShadows.insert(std::make_pair(std::string("shadows_enabled"), std::string("1")));
/*definesWithShadows.insert(std::string("shadow_texture_unit_declarations"), std::string(""));
definesWithShadows.insert(std::string("shadow_space_coordinate_declarations"), std::string(""));
definesWithShadows.insert(std::string("shadow_space_coordinate_calculations"), std::string(""));
definesWithShadows.insert(std::string("shadow_texture_sampler_declarations"), std::string(""));
definesWithShadows.insert(std::string("shadow_texture_lookup_calculations"), std::string(""));*/
for (int i = 0; i < numShadowMaps; ++i)
{
definesWithShadows["shadow_texture_unit_declarations"] += "uniform int shadowTextureUnit" + std::to_string(i) + ";\n";
definesWithShadows["shadow_space_coordinate_declarations"] += "varying vec4 shadowSpaceCoords" + std::to_string(i) + ";\n";
definesWithShadows["shadow_space_coordinate_calculations"] += "eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit" + std::to_string(i) + "], gl_EyePlaneT[shadowTextureUnit" + std::to_string(i) + "], gl_EyePlaneR[shadowTextureUnit" + std::to_string(i) + "], gl_EyePlaneQ[shadowTextureUnit" + std::to_string(i) + "]);\n"
+ "shadowSpaceCoords" + std::to_string(i) + " = viewPos * eyePlaneMat;\n";
definesWithShadows["shadow_texture_sampler_declarations"] += "uniform sampler2DShadow shadowTexture" + std::to_string(i) + ";\n";
definesWithShadows["shadow_texture_lookup_calculations"] += "shadowing *= shadow2DProj(shadowTexture" + std::to_string(i) + ", shadowSpaceCoords" + std::to_string(i) + ").r;\n";
}
definesWithShadows["shadow_texture_unit_list"] += std::to_string(i) + ",";
// remove extra comma
definesWithShadows["shadow_texture_unit_list"] = definesWithShadows["shadow_texture_unit_list"].substr(0, definesWithShadows["shadow_texture_unit_list"].length() - 1);
}
definesWithShadows.insert(defines.begin(), defines.end());
@ -161,7 +244,7 @@ namespace Shader
if (shaderIt == mShaders.end())
{
std::string shaderSource = templateIt->second;
if (!parseDefines(shaderSource, definesWithShadows))
if (!parseDefines(shaderSource, definesWithShadows) || !parseFors(shaderSource))
{
// Add to the cache anyway to avoid logging the same error over and over.
mShaders.insert(std::make_pair(std::make_pair(shaderTemplate, defines), nullptr));

@ -58,8 +58,10 @@ varying vec3 passViewPos;
varying vec3 passNormal;
#if SHADOWS
@shadow_texture_sampler_declarations
@shadow_space_coordinate_declarations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
uniform sampler2DShadow shadowTexture@shadow_texture_unit_index;
varying vec4 shadowSpaceCoords@shadow_texture_unit_index;
@endforeach
#endif // SHADOWS
#include "lighting.glsl"
@ -122,7 +124,9 @@ void main()
float shadowing = 1.0;
#if SHADOWS
@shadow_texture_lookup_calculations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
shadowing *= shadow2DProj(shadowTexture@shadow_texture_unit_index, shadowSpaceCoords@shadow_texture_unit_index).r;
@endforeach
#endif // SHADOWS
#if !PER_PIXEL_LIGHTING

@ -49,8 +49,10 @@ varying vec3 passViewPos;
varying vec3 passNormal;
#if SHADOWS
@shadow_texture_unit_declarations
@shadow_space_coordinate_declarations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
uniform int shadowTextureUnit@shadow_texture_unit_index;
varying vec4 shadowSpaceCoords@shadow_texture_unit_index;
@endforeach
#endif // SHADOWS
#include "lighting.glsl"
@ -111,6 +113,9 @@ void main(void)
#if SHADOWS
// This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner.
mat4 eyePlaneMat;
@shadow_space_coordinate_calculations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneT[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneR[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneQ[shadowTextureUnit@shadow_texture_unit_index]);
shadowSpaceCoords@shadow_texture_unit_index = viewPos * eyePlaneMat;
@endforeach
#endif // SHADOWS
}

@ -28,8 +28,10 @@ varying vec3 passViewPos;
varying vec3 passNormal;
#if SHADOWS
@shadow_texture_sampler_declarations
@shadow_space_coordinate_declarations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
uniform sampler2DShadow shadowTexture@shadow_texture_unit_index;
varying vec4 shadowSpaceCoords@shadow_texture_unit_index;
@endforeach
#endif // SHADOWS
#include "lighting.glsl"
@ -74,7 +76,9 @@ void main()
float shadowing = 1.0;
#if SHADOWS
@shadow_texture_lookup_calculations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
shadowing *= shadow2DProj(shadowTexture@shadow_texture_unit_index, shadowSpaceCoords@shadow_texture_unit_index).r;
@endforeach
#endif // SHADOWS
#if !PER_PIXEL_LIGHTING

@ -17,8 +17,10 @@ varying vec3 passViewPos;
varying vec3 passNormal;
#if SHADOWS
@shadow_texture_unit_declarations
@shadow_space_coordinate_declarations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
uniform int shadowTextureUnit@shadow_texture_unit_index;
varying vec4 shadowSpaceCoords@shadow_texture_unit_index;
@endforeach
#endif // SHADOWS
#include "lighting.glsl"
@ -42,9 +44,12 @@ void main(void)
uv = gl_MultiTexCoord0.xy;
#if SHADOWS
// This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner.
mat4 eyePlaneMat;
@shadow_space_coordinate_calculations
#endif // SHADOWS
#if SHADOWS
// This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner.
mat4 eyePlaneMat;
@foreach shadow_texture_unit_index @shadow_texture_unit_list
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneT[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneR[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneQ[shadowTextureUnit@shadow_texture_unit_index]);
shadowSpaceCoords@shadow_texture_unit_index = viewPos * eyePlaneMat;
@endforeach
#endif // SHADOWS
}

@ -1,5 +1,7 @@
#version 120
//DUMPME
#define REFRACTION @refraction_enabled
#define SHADOWS @shadows_enabled
@ -144,9 +146,10 @@ uniform vec3 nodePosition;
uniform float rainIntensity;
#if SHADOWS
@shadow_texture_sampler_declarations
@shadow_space_coordinate_declarations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
uniform sampler2DShadow shadowTexture@shadow_texture_unit_index;
varying vec4 shadowSpaceCoords@shadow_texture_unit_index;
@endforeach
#endif // SHADOWS
float frustumDepth;
@ -165,15 +168,17 @@ void main(void)
vec2 UV = worldPos.xy / (8192.0*5.0) * 3.0;
UV.y *= -1.0;
#if SHADOWS
float shadowing = 1.0;
#if SHADOWS
float shadowing = 1.0;
@shadow_texture_lookup_calculations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
shadowing *= shadow2DProj(shadowTexture@shadow_texture_unit_index, shadowSpaceCoords@shadow_texture_unit_index).r;
@endforeach
float shadow = shadowing;
#else // NOT SHADOWS
float shadow = 1.0;
#endif // SHADOWS
float shadow = shadowing;
#else // NOT SHADOWS
float shadow = 1.0;
#endif // SHADOWS
vec2 screenCoords = screenCoordsPassthrough.xy / screenCoordsPassthrough.z;
screenCoords.y = (1.0-screenCoords.y);

@ -7,9 +7,10 @@ varying float depthPassthrough;
#define SHADOWS @shadows_enabled
#if SHADOWS
@shadow_texture_unit_declarations
@shadow_space_coordinate_declarations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
uniform int shadowTextureUnit@shadow_texture_unit_index;
varying vec4 shadowSpaceCoords@shadow_texture_unit_index;
@endforeach
#endif // SHADOWS
void main(void)
@ -33,6 +34,9 @@ void main(void)
// This matrix has the opposite handedness to the others used here, so multiplication must have the vector to the left. Alternatively it could be transposed after construction, but that's extra work for the GPU just to make the code look a tiny bit cleaner.
mat4 eyePlaneMat;
@shadow_space_coordinate_calculations
@foreach shadow_texture_unit_index @shadow_texture_unit_list
eyePlaneMat = mat4(gl_EyePlaneS[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneT[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneR[shadowTextureUnit@shadow_texture_unit_index], gl_EyePlaneQ[shadowTextureUnit@shadow_texture_unit_index]);
shadowSpaceCoords@shadow_texture_unit_index = viewPos * eyePlaneMat;
@endforeach
#endif // SHADOWS
}

Loading…
Cancel
Save