mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-15 16:39:41 +00:00
mono-only version of the shader linking system introduced in the stereo MR
This commit is contained in:
parent
dd4f1e3044
commit
dc3045c970
19 changed files with 412 additions and 99 deletions
|
@ -55,6 +55,7 @@ if (GTEST_FOUND AND GMOCK_FOUND)
|
||||||
|
|
||||||
shader/parsedefines.cpp
|
shader/parsedefines.cpp
|
||||||
shader/parsefors.cpp
|
shader/parsefors.cpp
|
||||||
|
shader/parselinks.cpp
|
||||||
shader/shadermanager.cpp
|
shader/shadermanager.cpp
|
||||||
|
|
||||||
../openmw/options.cpp
|
../openmw/options.cpp
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <gmock/gmock.h>
|
#include <gmock/gmock.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -16,6 +17,12 @@ namespace
|
||||||
const std::string mName = "shader";
|
const std::string mName = "shader";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool parseFors(std::string& source, const std::string& templateName)
|
||||||
|
{
|
||||||
|
std::vector<std::string> dummy;
|
||||||
|
return parseDirectives(source, dummy, {}, {}, templateName);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ShaderParseForsTest, empty_should_succeed)
|
TEST_F(ShaderParseForsTest, empty_should_succeed)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(parseFors(mSource, mName));
|
ASSERT_TRUE(parseFors(mSource, mName));
|
||||||
|
|
100
apps/openmw_test_suite/shader/parselinks.cpp
Normal file
100
apps/openmw_test_suite/shader/parselinks.cpp
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
#include <components/shader/shadermanager.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace testing;
|
||||||
|
using namespace Shader;
|
||||||
|
|
||||||
|
using DefineMap = ShaderManager::DefineMap;
|
||||||
|
|
||||||
|
struct ShaderParseLinksTest : Test
|
||||||
|
{
|
||||||
|
std::string mSource;
|
||||||
|
std::vector<std::string> mLinkTargets;
|
||||||
|
ShaderManager::DefineMap mDefines;
|
||||||
|
const std::string mName = "my_shader.glsl";
|
||||||
|
|
||||||
|
bool parseLinks()
|
||||||
|
{
|
||||||
|
return parseDirectives(mSource, mLinkTargets, mDefines, {}, mName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(ShaderParseLinksTest, empty_should_succeed)
|
||||||
|
{
|
||||||
|
ASSERT_TRUE(parseLinks());
|
||||||
|
EXPECT_EQ(mSource, "");
|
||||||
|
EXPECT_TRUE(mLinkTargets.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ShaderParseLinksTest, should_fail_for_single_escape_symbol)
|
||||||
|
{
|
||||||
|
mSource = "$";
|
||||||
|
ASSERT_FALSE(parseLinks());
|
||||||
|
EXPECT_EQ(mSource, "$");
|
||||||
|
EXPECT_TRUE(mLinkTargets.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ShaderParseLinksTest, should_fail_on_first_found_escaped_not_valid_directive)
|
||||||
|
{
|
||||||
|
mSource = "$foo ";
|
||||||
|
ASSERT_FALSE(parseLinks());
|
||||||
|
EXPECT_EQ(mSource, "$foo ");
|
||||||
|
EXPECT_TRUE(mLinkTargets.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ShaderParseLinksTest, should_fail_on_absent_link_target)
|
||||||
|
{
|
||||||
|
mSource = "$link ";
|
||||||
|
ASSERT_FALSE(parseLinks());
|
||||||
|
EXPECT_EQ(mSource, "$link ");
|
||||||
|
EXPECT_TRUE(mLinkTargets.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ShaderParseLinksTest, should_not_require_newline)
|
||||||
|
{
|
||||||
|
mSource = "$link \"foo.glsl\"";
|
||||||
|
ASSERT_TRUE(parseLinks());
|
||||||
|
EXPECT_EQ(mSource, "");
|
||||||
|
ASSERT_EQ(mLinkTargets.size(), 1);
|
||||||
|
EXPECT_EQ(mLinkTargets[0], "foo.glsl");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ShaderParseLinksTest, should_require_quotes)
|
||||||
|
{
|
||||||
|
mSource = "$link foo.glsl";
|
||||||
|
ASSERT_FALSE(parseLinks());
|
||||||
|
EXPECT_EQ(mSource, "$link foo.glsl");
|
||||||
|
EXPECT_EQ(mLinkTargets.size(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ShaderParseLinksTest, should_be_replaced_with_empty_line)
|
||||||
|
{
|
||||||
|
mSource = "$link \"foo.glsl\"\nbar";
|
||||||
|
ASSERT_TRUE(parseLinks());
|
||||||
|
EXPECT_EQ(mSource, "\nbar");
|
||||||
|
ASSERT_EQ(mLinkTargets.size(), 1);
|
||||||
|
EXPECT_EQ(mLinkTargets[0], "foo.glsl");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ShaderParseLinksTest, should_only_accept_on_true_condition)
|
||||||
|
{
|
||||||
|
mSource =
|
||||||
|
R"glsl(
|
||||||
|
$link "foo.glsl" if 1
|
||||||
|
$link "bar.glsl" if 0
|
||||||
|
)glsl";
|
||||||
|
ASSERT_TRUE(parseLinks());
|
||||||
|
EXPECT_EQ(mSource,
|
||||||
|
R"glsl(
|
||||||
|
|
||||||
|
|
||||||
|
)glsl");
|
||||||
|
ASSERT_EQ(mLinkTargets.size(), 1);
|
||||||
|
EXPECT_EQ(mLinkTargets[0], "foo.glsl");
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
#include <osg/Program>
|
#include <osg/Program>
|
||||||
|
|
||||||
|
@ -142,11 +143,123 @@ namespace Shader
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseFors(std::string& source, const std::string& templateName)
|
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos)
|
||||||
|
{
|
||||||
|
size_t iterNameStart = foundPos + strlen("$foreach") + 1;
|
||||||
|
size_t iterNameEnd = source.find_first_of(" \n\r()[].;,", iterNameStart);
|
||||||
|
if (iterNameEnd == std::string::npos)
|
||||||
|
{
|
||||||
|
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string list = source.substr(listStart, listEnd - listStart);
|
||||||
|
std::vector<std::string> listElements;
|
||||||
|
if (list != "")
|
||||||
|
Misc::StringUtils::split(list, listElements, ",");
|
||||||
|
|
||||||
|
size_t contentStart = source.find_first_not_of("\n\r", listEnd);
|
||||||
|
size_t contentEnd = source.find("$endforeach", contentStart);
|
||||||
|
if (contentEnd == std::string::npos)
|
||||||
|
{
|
||||||
|
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string content = source.substr(contentStart, contentEnd - contentStart);
|
||||||
|
|
||||||
|
size_t overallEnd = contentEnd + std::string("$endforeach").length();
|
||||||
|
|
||||||
|
size_t lineDirectivePosition = source.rfind("#line", overallEnd);
|
||||||
|
int lineNumber;
|
||||||
|
if (lineDirectivePosition != std::string::npos)
|
||||||
|
{
|
||||||
|
size_t lineNumberStart = lineDirectivePosition + std::string("#line ").length();
|
||||||
|
size_t lineNumberEnd = source.find_first_not_of("0123456789", lineNumberStart);
|
||||||
|
std::string lineNumberString = source.substr(lineNumberStart, lineNumberEnd - lineNumberStart);
|
||||||
|
lineNumber = std::stoi(lineNumberString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lineDirectivePosition = 0;
|
||||||
|
lineNumber = 2;
|
||||||
|
}
|
||||||
|
lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + overallEnd, '\n');
|
||||||
|
|
||||||
|
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 parseLinkDirective(std::string& source, std::string& linkTarget, const std::string& templateName, size_t foundPos)
|
||||||
|
{
|
||||||
|
size_t endPos = foundPos + 5;
|
||||||
|
size_t lineEnd = source.find_first_of('\n', endPos);
|
||||||
|
// If lineEnd = npos, this is the last line, so no need to check
|
||||||
|
std::string linkStatement = source.substr(endPos, lineEnd - endPos);
|
||||||
|
std::regex linkRegex(
|
||||||
|
R"r(\s*"([^"]+)"\s*)r" // Find any quoted string as the link name -> match[1]
|
||||||
|
R"r((if\s+)r" // Begin optional condition -> match[2]
|
||||||
|
R"r((!)?\s*)r" // Optional ! -> match[3]
|
||||||
|
R"r(([_a-zA-Z0-9]+)?)r" // The condition -> match[4]
|
||||||
|
R"r()?\s*)r" // End optional condition -> match[2]
|
||||||
|
);
|
||||||
|
std::smatch linkMatch;
|
||||||
|
bool hasCondition = false;
|
||||||
|
std::string linkConditionExpression;
|
||||||
|
if (std::regex_match(linkStatement, linkMatch, linkRegex))
|
||||||
|
{
|
||||||
|
linkTarget = linkMatch[1].str();
|
||||||
|
hasCondition = !linkMatch[2].str().empty();
|
||||||
|
linkConditionExpression = linkMatch[4].str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(Debug::Error) << "Shader " << templateName << " error: Expected a shader filename to link";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (linkTarget.empty())
|
||||||
|
{
|
||||||
|
Log(Debug::Error) << "Shader " << templateName << " error: Empty link name";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasCondition)
|
||||||
|
{
|
||||||
|
bool condition = !(linkConditionExpression.empty() || linkConditionExpression == "0");
|
||||||
|
if (linkMatch[3].str() == "!")
|
||||||
|
condition = !condition;
|
||||||
|
|
||||||
|
if (!condition)
|
||||||
|
linkTarget = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
source.replace(foundPos, lineEnd - foundPos, "");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parseDirectives(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const ShaderManager::DefineMap& defines, const ShaderManager::DefineMap& globalDefines, const std::string& templateName)
|
||||||
{
|
{
|
||||||
const char escapeCharacter = '$';
|
const char escapeCharacter = '$';
|
||||||
size_t foundPos = 0;
|
size_t foundPos = 0;
|
||||||
while ((foundPos = source.find(escapeCharacter)) != std::string::npos)
|
|
||||||
|
while ((foundPos = source.find(escapeCharacter, foundPos)) != 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)
|
if (endPos == std::string::npos)
|
||||||
|
@ -154,72 +267,25 @@ namespace Shader
|
||||||
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string command = source.substr(foundPos + 1, endPos - (foundPos + 1));
|
std::string directive = source.substr(foundPos + 1, endPos - (foundPos + 1));
|
||||||
if (command != "foreach")
|
if (directive == "foreach")
|
||||||
{
|
{
|
||||||
Log(Debug::Error) << "Shader " << templateName << " error: Unknown shader directive: $" << command;
|
if (!parseForeachDirective(source, templateName, foundPos))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else if (directive == "link")
|
||||||
size_t iterNameStart = endPos + 1;
|
|
||||||
size_t iterNameEnd = source.find_first_of(" \n\r()[].;,", iterNameStart);
|
|
||||||
if (iterNameEnd == std::string::npos)
|
|
||||||
{
|
{
|
||||||
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
std::string linkTarget;
|
||||||
return false;
|
if (!parseLinkDirective(source, linkTarget, templateName, foundPos))
|
||||||
}
|
return false;
|
||||||
std::string iteratorName = "$" + source.substr(iterNameStart, iterNameEnd - iterNameStart);
|
if (!linkTarget.empty() && linkTarget != templateName)
|
||||||
|
linkedShaderTemplateNames.push_back(linkTarget);
|
||||||
size_t listStart = iterNameEnd + 1;
|
|
||||||
size_t listEnd = source.find_first_of("\n\r", listStart);
|
|
||||||
if (listEnd == std::string::npos)
|
|
||||||
{
|
|
||||||
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string list = source.substr(listStart, listEnd - listStart);
|
|
||||||
std::vector<std::string> listElements;
|
|
||||||
if (list != "")
|
|
||||||
Misc::StringUtils::split (list, listElements, ",");
|
|
||||||
|
|
||||||
size_t contentStart = source.find_first_not_of("\n\r", listEnd);
|
|
||||||
size_t contentEnd = source.find("$endforeach", contentStart);
|
|
||||||
if (contentEnd == std::string::npos)
|
|
||||||
{
|
|
||||||
Log(Debug::Error) << "Shader " << templateName << " error: Unexpected EOF";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string content = source.substr(contentStart, contentEnd - contentStart);
|
|
||||||
|
|
||||||
size_t overallEnd = contentEnd + std::string("$endforeach").length();
|
|
||||||
|
|
||||||
size_t lineDirectivePosition = source.rfind("#line", overallEnd);
|
|
||||||
int lineNumber;
|
|
||||||
if (lineDirectivePosition != std::string::npos)
|
|
||||||
{
|
|
||||||
size_t lineNumberStart = lineDirectivePosition + std::string("#line ").length();
|
|
||||||
size_t lineNumberEnd = source.find_first_not_of("0123456789", lineNumberStart);
|
|
||||||
std::string lineNumberString = source.substr(lineNumberStart, lineNumberEnd - lineNumberStart);
|
|
||||||
lineNumber = std::stoi(lineNumberString);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lineDirectivePosition = 0;
|
Log(Debug::Error) << "Shader " << templateName << " error: Unknown shader directive: $" << directive;
|
||||||
lineNumber = 2;
|
return false;
|
||||||
}
|
}
|
||||||
lineNumber += std::count(source.begin() + lineDirectivePosition, source.begin() + overallEnd, '\n');
|
|
||||||
|
|
||||||
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;
|
return true;
|
||||||
|
@ -265,6 +331,10 @@ namespace Shader
|
||||||
else
|
else
|
||||||
forIterators.pop_back();
|
forIterators.pop_back();
|
||||||
}
|
}
|
||||||
|
else if (define == "link")
|
||||||
|
{
|
||||||
|
source.replace(foundPos, 1, "$");
|
||||||
|
}
|
||||||
else if (std::find(forIterators.begin(), forIterators.end(), define) != forIterators.end())
|
else if (std::find(forIterators.begin(), forIterators.end(), define) != forIterators.end())
|
||||||
{
|
{
|
||||||
source.replace(foundPos, 1, "$");
|
source.replace(foundPos, 1, "$");
|
||||||
|
@ -288,7 +358,7 @@ namespace Shader
|
||||||
|
|
||||||
osg::ref_ptr<osg::Shader> ShaderManager::getShader(const std::string &templateName, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType)
|
osg::ref_ptr<osg::Shader> ShaderManager::getShader(const std::string &templateName, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mMutex);
|
std::unique_lock<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
// read the template if we haven't already
|
// read the template if we haven't already
|
||||||
TemplateMap::iterator templateIt = mShaderTemplates.find(templateName);
|
TemplateMap::iterator templateIt = mShaderTemplates.find(templateName);
|
||||||
|
@ -319,7 +389,8 @@ namespace Shader
|
||||||
if (shaderIt == mShaders.end())
|
if (shaderIt == mShaders.end())
|
||||||
{
|
{
|
||||||
std::string shaderSource = templateIt->second;
|
std::string shaderSource = templateIt->second;
|
||||||
if (!parseDefines(shaderSource, defines, mGlobalDefines, templateName) || !parseFors(shaderSource, templateName))
|
std::vector<std::string> linkedShaderNames;
|
||||||
|
if (!createSourceFromTemplate(shaderSource, linkedShaderNames, templateName, defines))
|
||||||
{
|
{
|
||||||
// Add to the cache anyway to avoid logging the same error over and over.
|
// Add to the cache anyway to avoid logging the same error over and over.
|
||||||
mShaders.insert(std::make_pair(std::make_pair(templateName, defines), nullptr));
|
mShaders.insert(std::make_pair(std::make_pair(templateName, defines), nullptr));
|
||||||
|
@ -333,6 +404,10 @@ namespace Shader
|
||||||
static unsigned int counter = 0;
|
static unsigned int counter = 0;
|
||||||
shader->setName(Misc::StringUtils::format("%u %s", counter++, templateName));
|
shader->setName(Misc::StringUtils::format("%u %s", counter++, templateName));
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
getLinkedShaders(shader, linkedShaderNames, defines);
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
shaderIt = mShaders.insert(std::make_pair(std::make_pair(templateName, defines), shader)).first;
|
shaderIt = mShaders.insert(std::make_pair(std::make_pair(templateName, defines), shader)).first;
|
||||||
}
|
}
|
||||||
return shaderIt->second;
|
return shaderIt->second;
|
||||||
|
@ -348,6 +423,9 @@ namespace Shader
|
||||||
osg::ref_ptr<osg::Program> program = programTemplate ? cloneProgram(programTemplate) : osg::ref_ptr<osg::Program>(new osg::Program);
|
osg::ref_ptr<osg::Program> program = programTemplate ? cloneProgram(programTemplate) : osg::ref_ptr<osg::Program>(new osg::Program);
|
||||||
program->addShader(vertexShader);
|
program->addShader(vertexShader);
|
||||||
program->addShader(fragmentShader);
|
program->addShader(fragmentShader);
|
||||||
|
addLinkedShaders(vertexShader, program);
|
||||||
|
addLinkedShaders(fragmentShader, program);
|
||||||
|
|
||||||
found = mPrograms.insert(std::make_pair(std::make_pair(vertexShader, fragmentShader), program)).first;
|
found = mPrograms.insert(std::make_pair(std::make_pair(vertexShader, fragmentShader), program)).first;
|
||||||
}
|
}
|
||||||
return found->second;
|
return found->second;
|
||||||
|
@ -377,11 +455,14 @@ namespace Shader
|
||||||
// I'm not sure how to handle a shader that was already broken as there's no way to get a potential replacement to the nodes that need it.
|
// I'm not sure how to handle a shader that was already broken as there's no way to get a potential replacement to the nodes that need it.
|
||||||
continue;
|
continue;
|
||||||
std::string shaderSource = mShaderTemplates[templateId];
|
std::string shaderSource = mShaderTemplates[templateId];
|
||||||
if (!parseDefines(shaderSource, defines, mGlobalDefines, templateId) || !parseFors(shaderSource, templateId))
|
std::vector<std::string> linkedShaderNames;
|
||||||
|
if (!createSourceFromTemplate(shaderSource, linkedShaderNames, templateId, defines))
|
||||||
// We just broke the shader and there's no way to force existing objects back to fixed-function mode as we would when creating the shader.
|
// We just broke the shader and there's no way to force existing objects back to fixed-function mode as we would when creating the shader.
|
||||||
// If we put a nullptr in the shader map, we just lose the ability to put a working one in later.
|
// If we put a nullptr in the shader map, we just lose the ability to put a working one in later.
|
||||||
continue;
|
continue;
|
||||||
shader->setShaderSource(shaderSource);
|
shader->setShaderSource(shaderSource);
|
||||||
|
|
||||||
|
getLinkedShaders(shader, linkedShaderNames, defines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,4 +478,35 @@ namespace Shader
|
||||||
program->releaseGLObjects(state);
|
program->releaseGLObjects(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ShaderManager::createSourceFromTemplate(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const std::string& templateName, const ShaderManager::DefineMap& defines)
|
||||||
|
{
|
||||||
|
if (!parseDefines(source, defines, mGlobalDefines, templateName))
|
||||||
|
return false;
|
||||||
|
if (!parseDirectives(source, linkedShaderTemplateNames, defines, mGlobalDefines, templateName))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderManager::getLinkedShaders(osg::ref_ptr<osg::Shader> shader, const std::vector<std::string>& linkedShaderNames, const DefineMap& defines)
|
||||||
|
{
|
||||||
|
mLinkedShaders.erase(shader);
|
||||||
|
if (linkedShaderNames.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto& linkedShaderName : linkedShaderNames)
|
||||||
|
{
|
||||||
|
auto linkedShader = getShader(linkedShaderName, defines, shader->getType());
|
||||||
|
if (linkedShader)
|
||||||
|
mLinkedShaders[shader].emplace_back(linkedShader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderManager::addLinkedShaders(osg::ref_ptr<osg::Shader> shader, osg::ref_ptr<osg::Program> program)
|
||||||
|
{
|
||||||
|
auto linkedIt = mLinkedShaders.find(shader);
|
||||||
|
if (linkedIt != mLinkedShaders.end())
|
||||||
|
for (const auto& linkedShader : linkedIt->second)
|
||||||
|
program->addShader(linkedShader);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
|
@ -51,7 +52,12 @@ namespace Shader
|
||||||
|
|
||||||
void releaseGLObjects(osg::State* state);
|
void releaseGLObjects(osg::State* state);
|
||||||
|
|
||||||
|
bool createSourceFromTemplate(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const std::string& templateName, const ShaderManager::DefineMap& defines);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void getLinkedShaders(osg::ref_ptr<osg::Shader> shader, const std::vector<std::string>& linkedShaderNames, const DefineMap& defines);
|
||||||
|
void addLinkedShaders(osg::ref_ptr<osg::Shader> shader, osg::ref_ptr<osg::Program> program);
|
||||||
|
|
||||||
std::string mPath;
|
std::string mPath;
|
||||||
|
|
||||||
DefineMap mGlobalDefines;
|
DefineMap mGlobalDefines;
|
||||||
|
@ -67,15 +73,23 @@ namespace Shader
|
||||||
typedef std::map<std::pair<osg::ref_ptr<osg::Shader>, osg::ref_ptr<osg::Shader> >, osg::ref_ptr<osg::Program> > ProgramMap;
|
typedef std::map<std::pair<osg::ref_ptr<osg::Shader>, osg::ref_ptr<osg::Shader> >, osg::ref_ptr<osg::Program> > ProgramMap;
|
||||||
ProgramMap mPrograms;
|
ProgramMap mPrograms;
|
||||||
|
|
||||||
|
typedef std::vector<osg::ref_ptr<osg::Shader> > ShaderList;
|
||||||
|
typedef std::map<osg::ref_ptr<osg::Shader>, ShaderList> LinkedShadersMap;
|
||||||
|
LinkedShadersMap mLinkedShaders;
|
||||||
|
|
||||||
std::mutex mMutex;
|
std::mutex mMutex;
|
||||||
|
|
||||||
osg::ref_ptr<const osg::Program> mProgramTemplate;
|
osg::ref_ptr<const osg::Program> mProgramTemplate;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool parseFors(std::string& source, const std::string& templateName);
|
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos);
|
||||||
|
bool parseLinkDirective(std::string& source, std::string& linkTarget, const std::string& templateName, size_t foundPos);
|
||||||
|
|
||||||
bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines,
|
bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines,
|
||||||
const ShaderManager::DefineMap& globalDefines, const std::string& templateName);
|
const ShaderManager::DefineMap& globalDefines, const std::string& templateName);
|
||||||
|
|
||||||
|
bool parseDirectives(std::string& source, std::vector<std::string>& linkedShaderTemplateNames, const ShaderManager::DefineMap& defines,
|
||||||
|
const ShaderManager::DefineMap& globalDefines, const std::string& templateName);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,10 @@ set(SHADER_FILES
|
||||||
depth.glsl
|
depth.glsl
|
||||||
objects_vertex.glsl
|
objects_vertex.glsl
|
||||||
objects_fragment.glsl
|
objects_fragment.glsl
|
||||||
|
openmw_fragment.glsl
|
||||||
|
openmw_fragment.h.glsl
|
||||||
|
openmw_vertex.glsl
|
||||||
|
openmw_vertex.h.glsl
|
||||||
terrain_vertex.glsl
|
terrain_vertex.glsl
|
||||||
terrain_fragment.glsl
|
terrain_fragment.glsl
|
||||||
lighting.glsl
|
lighting.glsl
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
uniform mat4 projectionMatrix;
|
#include "openmw_vertex.glsl"
|
||||||
|
|
||||||
centroid varying vec4 passColor;
|
centroid varying vec4 passColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
|
gl_Position = mw_modelToClip(gl_Vertex);
|
||||||
|
|
||||||
passColor = gl_Color;
|
passColor = gl_Color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
|
#include "openmw_vertex.h.glsl"
|
||||||
|
|
||||||
#if @useUBO
|
#if @useUBO
|
||||||
#extension GL_ARB_uniform_buffer_object : require
|
#extension GL_ARB_uniform_buffer_object : require
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,7 +48,6 @@ uniform mat4 osg_ViewMatrixInverse;
|
||||||
uniform mat4 osg_ViewMatrix;
|
uniform mat4 osg_ViewMatrix;
|
||||||
uniform float windSpeed;
|
uniform float windSpeed;
|
||||||
uniform vec3 playerPos;
|
uniform vec3 playerPos;
|
||||||
uniform mat4 projectionMatrix;
|
|
||||||
|
|
||||||
#if @groundcoverStompMode == 0
|
#if @groundcoverStompMode == 0
|
||||||
#else
|
#else
|
||||||
|
@ -143,7 +144,7 @@ void main(void)
|
||||||
if (length(gl_ModelViewMatrix * vec4(position, 1.0)) > @groundcoverFadeEnd)
|
if (length(gl_ModelViewMatrix * vec4(position, 1.0)) > @groundcoverFadeEnd)
|
||||||
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
|
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
else
|
else
|
||||||
gl_Position = projectionMatrix * viewPos;
|
gl_Position = mw_viewToClip(mw_viewStereoAdjust(viewPos));
|
||||||
|
|
||||||
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
|
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
|
#include "openmw_vertex.h.glsl"
|
||||||
|
|
||||||
#if @useUBO
|
#if @useUBO
|
||||||
#extension GL_ARB_uniform_buffer_object : require
|
#extension GL_ARB_uniform_buffer_object : require
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,8 +10,6 @@
|
||||||
#extension GL_EXT_gpu_shader4: require
|
#extension GL_EXT_gpu_shader4: require
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform mat4 projectionMatrix;
|
|
||||||
|
|
||||||
#if @diffuseMap
|
#if @diffuseMap
|
||||||
varying vec2 diffuseMapUV;
|
varying vec2 diffuseMapUV;
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,9 +38,9 @@ varying vec3 passNormal;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
|
gl_Position = mw_modelToClip(gl_Vertex);
|
||||||
|
|
||||||
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
vec4 viewPos = mw_modelToView(gl_Vertex);
|
||||||
gl_ClipVertex = viewPos;
|
gl_ClipVertex = viewPos;
|
||||||
euclideanDepth = length(viewPos.xyz);
|
euclideanDepth = length(viewPos.xyz);
|
||||||
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
|
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
uniform mat4 projectionMatrix;
|
#include "openmw_vertex.h.glsl"
|
||||||
|
|
||||||
#if @diffuseMap
|
#if @diffuseMap
|
||||||
varying vec2 diffuseMapUV;
|
varying vec2 diffuseMapUV;
|
||||||
|
@ -23,9 +23,9 @@ varying float passFalloff;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
|
gl_Position = mw_modelToClip(gl_Vertex);
|
||||||
|
|
||||||
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
vec4 viewPos = mw_modelToView(gl_Vertex);
|
||||||
gl_ClipVertex = viewPos;
|
gl_ClipVertex = viewPos;
|
||||||
#if @radialFog
|
#if @radialFog
|
||||||
euclideanDepth = length(viewPos.xyz);
|
euclideanDepth = length(viewPos.xyz);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
|
#include "openmw_vertex.h.glsl"
|
||||||
|
|
||||||
#if @useUBO
|
#if @useUBO
|
||||||
#extension GL_ARB_uniform_buffer_object : require
|
#extension GL_ARB_uniform_buffer_object : require
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,8 +10,6 @@
|
||||||
#extension GL_EXT_gpu_shader4: require
|
#extension GL_EXT_gpu_shader4: require
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform mat4 projectionMatrix;
|
|
||||||
|
|
||||||
#if @diffuseMap
|
#if @diffuseMap
|
||||||
varying vec2 diffuseMapUV;
|
varying vec2 diffuseMapUV;
|
||||||
#endif
|
#endif
|
||||||
|
@ -72,9 +72,9 @@ varying vec3 passNormal;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
|
gl_Position = mw_modelToClip(gl_Vertex);
|
||||||
|
|
||||||
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
vec4 viewPos = mw_modelToView(gl_Vertex);
|
||||||
|
|
||||||
gl_ClipVertex = viewPos;
|
gl_ClipVertex = viewPos;
|
||||||
euclideanDepth = length(viewPos.xyz);
|
euclideanDepth = length(viewPos.xyz);
|
||||||
|
|
26
files/shaders/openmw_fragment.glsl
Normal file
26
files/shaders/openmw_fragment.glsl
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
#include "openmw_fragment.h.glsl"
|
||||||
|
|
||||||
|
uniform sampler2D reflectionMap;
|
||||||
|
|
||||||
|
vec4 mw_sampleReflectionMap(vec2 uv)
|
||||||
|
{
|
||||||
|
return texture2D(reflectionMap, uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if @refraction_enabled
|
||||||
|
uniform sampler2D refractionMap;
|
||||||
|
uniform sampler2D refractionDepthMap;
|
||||||
|
|
||||||
|
vec4 mw_sampleRefractionMap(vec2 uv)
|
||||||
|
{
|
||||||
|
return texture2D(refractionMap, uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
float mw_sampleRefractionDepthMap(vec2 uv)
|
||||||
|
{
|
||||||
|
return texture2D(refractionDepthMap, uv).x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
8
files/shaders/openmw_fragment.h.glsl
Normal file
8
files/shaders/openmw_fragment.h.glsl
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
@link "openmw_fragment.glsl"
|
||||||
|
|
||||||
|
vec4 mw_sampleReflectionMap(vec2 uv);
|
||||||
|
|
||||||
|
#if @refraction_enabled
|
||||||
|
vec4 mw_sampleRefractionMap(vec2 uv);
|
||||||
|
float mw_sampleRefractionDepthMap(vec2 uv);
|
||||||
|
#endif
|
35
files/shaders/openmw_vertex.glsl
Normal file
35
files/shaders/openmw_vertex.glsl
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
#include "openmw_vertex.h.glsl"
|
||||||
|
|
||||||
|
uniform mat4 projectionMatrix;
|
||||||
|
|
||||||
|
vec4 mw_modelToClip(vec4 pos)
|
||||||
|
{
|
||||||
|
return projectionMatrix * mw_modelToView(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 mw_modelToView(vec4 pos)
|
||||||
|
{
|
||||||
|
return gl_ModelViewMatrix * pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 mw_viewToClip(vec4 pos)
|
||||||
|
{
|
||||||
|
return projectionMatrix * pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 mw_viewStereoAdjust(vec4 pos)
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mw_viewMatrix()
|
||||||
|
{
|
||||||
|
return gl_ModelViewMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat4 mw_projectionMatrix()
|
||||||
|
{
|
||||||
|
return projectionMatrix;
|
||||||
|
}
|
8
files/shaders/openmw_vertex.h.glsl
Normal file
8
files/shaders/openmw_vertex.h.glsl
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
@link "openmw_vertex.glsl"
|
||||||
|
|
||||||
|
vec4 mw_modelToClip(vec4 pos);
|
||||||
|
vec4 mw_modelToView(vec4 pos);
|
||||||
|
vec4 mw_viewToClip(vec4 pos);
|
||||||
|
vec4 mw_viewStereoAdjust(vec4 pos);
|
||||||
|
mat4 mw_viewMatrix();
|
||||||
|
mat4 mw_projectionMatrix();
|
|
@ -1,8 +1,9 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
|
#include "openmw_vertex.h.glsl"
|
||||||
|
|
||||||
#include "skypasses.glsl"
|
#include "skypasses.glsl"
|
||||||
|
|
||||||
uniform mat4 projectionMatrix;
|
|
||||||
uniform int pass;
|
uniform int pass;
|
||||||
|
|
||||||
varying vec4 passColor;
|
varying vec4 passColor;
|
||||||
|
@ -10,7 +11,7 @@ varying vec2 diffuseMapUV;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
|
gl_Position = mw_modelToClip(gl_Vertex);
|
||||||
passColor = gl_Color;
|
passColor = gl_Color;
|
||||||
|
|
||||||
if (pass == PASS_CLOUDS)
|
if (pass == PASS_CLOUDS)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
|
#include "openmw_vertex.h.glsl"
|
||||||
|
|
||||||
#if @useUBO
|
#if @useUBO
|
||||||
#extension GL_ARB_uniform_buffer_object : require
|
#extension GL_ARB_uniform_buffer_object : require
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,8 +10,6 @@
|
||||||
#extension GL_EXT_gpu_shader4: require
|
#extension GL_EXT_gpu_shader4: require
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uniform mat4 projectionMatrix;
|
|
||||||
|
|
||||||
varying vec2 uv;
|
varying vec2 uv;
|
||||||
varying float euclideanDepth;
|
varying float euclideanDepth;
|
||||||
varying float linearDepth;
|
varying float linearDepth;
|
||||||
|
@ -31,9 +31,9 @@ varying vec3 passNormal;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
|
gl_Position = mw_modelToClip(gl_Vertex);
|
||||||
|
|
||||||
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
|
vec4 viewPos = mw_modelToView(gl_Vertex);
|
||||||
gl_ClipVertex = viewPos;
|
gl_ClipVertex = viewPos;
|
||||||
euclideanDepth = length(viewPos.xyz);
|
euclideanDepth = length(viewPos.xyz);
|
||||||
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
|
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
|
#include "openmw_fragment.h.glsl"
|
||||||
|
|
||||||
#if @useUBO
|
#if @useUBO
|
||||||
#extension GL_ARB_uniform_buffer_object : require
|
#extension GL_ARB_uniform_buffer_object : require
|
||||||
#endif
|
#endif
|
||||||
|
@ -207,12 +209,6 @@ varying float linearDepth;
|
||||||
|
|
||||||
uniform sampler2D normalMap;
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
uniform sampler2D reflectionMap;
|
|
||||||
#if REFRACTION
|
|
||||||
uniform sampler2D refractionMap;
|
|
||||||
uniform sampler2D refractionDepthMap;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform float osg_SimulationTime;
|
uniform float osg_SimulationTime;
|
||||||
|
|
||||||
uniform float near;
|
uniform float near;
|
||||||
|
@ -299,14 +295,14 @@ void main(void)
|
||||||
|
|
||||||
vec2 screenCoordsOffset = normal.xy * REFL_BUMP;
|
vec2 screenCoordsOffset = normal.xy * REFL_BUMP;
|
||||||
#if REFRACTION
|
#if REFRACTION
|
||||||
float depthSample = linearizeDepth(texture2D(refractionDepthMap,screenCoords).x) * radialise;
|
float depthSample = linearizeDepth(mw_sampleRefractionDepthMap(screenCoords)) * radialise;
|
||||||
float depthSampleDistorted = linearizeDepth(texture2D(refractionDepthMap,screenCoords-screenCoordsOffset).x) * radialise;
|
float depthSampleDistorted = linearizeDepth(mw_sampleRefractionDepthMap(screenCoords-screenCoordsOffset)) * radialise;
|
||||||
float surfaceDepth = linearizeDepth(gl_FragCoord.z) * radialise;
|
float surfaceDepth = linearizeDepth(gl_FragCoord.z) * radialise;
|
||||||
float realWaterDepth = depthSample - surfaceDepth; // undistorted water depth in view direction, independent of frustum
|
float realWaterDepth = depthSample - surfaceDepth; // undistorted water depth in view direction, independent of frustum
|
||||||
screenCoordsOffset *= clamp(realWaterDepth / BUMP_SUPPRESS_DEPTH,0,1);
|
screenCoordsOffset *= clamp(realWaterDepth / BUMP_SUPPRESS_DEPTH,0,1);
|
||||||
#endif
|
#endif
|
||||||
// reflection
|
// reflection
|
||||||
vec3 reflection = texture2D(reflectionMap, screenCoords + screenCoordsOffset).rgb;
|
vec3 reflection = mw_sampleReflectionMap(screenCoords + screenCoordsOffset).rgb;
|
||||||
|
|
||||||
// specular
|
// specular
|
||||||
float specular = pow(max(dot(reflect(vVec, normal), lVec), 0.0),SPEC_HARDNESS) * shadow;
|
float specular = pow(max(dot(reflect(vVec, normal), lVec), 0.0),SPEC_HARDNESS) * shadow;
|
||||||
|
@ -324,7 +320,7 @@ void main(void)
|
||||||
rainSpecular *= clamp(fresnel*6.0 + specular * sunSpec.w, 0.0, 1.0);
|
rainSpecular *= clamp(fresnel*6.0 + specular * sunSpec.w, 0.0, 1.0);
|
||||||
|
|
||||||
// refraction
|
// refraction
|
||||||
vec3 refraction = texture2D(refractionMap, screenCoords - screenCoordsOffset).rgb;
|
vec3 refraction = mw_sampleRefractionMap(screenCoords - screenCoordsOffset).rgb;
|
||||||
vec3 rawRefraction = refraction;
|
vec3 rawRefraction = refraction;
|
||||||
|
|
||||||
// brighten up the refraction underwater
|
// brighten up the refraction underwater
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
uniform mat4 projectionMatrix;
|
#include "openmw_vertex.h.glsl"
|
||||||
|
|
||||||
varying vec4 position;
|
varying vec4 position;
|
||||||
varying float linearDepth;
|
varying float linearDepth;
|
||||||
|
@ -10,11 +10,11 @@ varying float linearDepth;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
|
gl_Position = mw_modelToClip(gl_Vertex);
|
||||||
|
|
||||||
position = gl_Vertex;
|
position = gl_Vertex;
|
||||||
|
|
||||||
vec4 viewPos = gl_ModelViewMatrix * gl_Vertex;
|
vec4 viewPos = mw_modelToView(gl_Vertex);
|
||||||
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
|
linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
|
||||||
|
|
||||||
setupShadowCoords(viewPos, normalize((gl_NormalMatrix * gl_Normal).xyz));
|
setupShadowCoords(viewPos, normalize((gl_NormalMatrix * gl_Normal).xyz));
|
||||||
|
|
Loading…
Reference in a new issue