Make EMotionFX shaders load from the Shaders directory, instead of prepending "Shaders" to all filenames (#56)
Because the `shaderPath` variable is used as a base directory, it needs to end with the directory separator. Otherwise the parts before the data dir become a file prefix used when loading all shaders. Attempts to load "Line_VS.glsl" from "Shaders/" end up instead trying to load "ShadersLine_VS.glsl".
This commit is contained in:
@@ -131,8 +131,14 @@ namespace RenderGL
|
||||
|
||||
void GLRenderUtil::Validate()
|
||||
{
|
||||
mLineShader->Validate();
|
||||
mMeshShader->Validate();
|
||||
if (mLineShader)
|
||||
{
|
||||
mLineShader->Validate();
|
||||
}
|
||||
if (mMeshShader)
|
||||
{
|
||||
mMeshShader->Validate();
|
||||
}
|
||||
}
|
||||
|
||||
// destroy the allocated memory
|
||||
|
||||
@@ -116,12 +116,12 @@ namespace RenderGL
|
||||
}
|
||||
|
||||
|
||||
bool GLSLShader::CompileShader(const GLenum type, unsigned int* outShader, const char* filename)
|
||||
bool GLSLShader::CompileShader(const GLenum type, unsigned int* outShader, AZ::IO::PathView filename)
|
||||
{
|
||||
QFile file(filename);
|
||||
QFile file(QString::fromUtf8(filename.Native().data(), aznumeric_caster(filename.Native().size())));
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
AZ_Error("EMotionFX", false, "[GLSL] Failed to open shader file '%s'.", filename);
|
||||
AZ_Error("EMotionFX", false, "[GLSL] Failed to open shader file '%.*s'.", AZ_STRING_ARG(filename.Native()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace RenderGL
|
||||
|
||||
if (success == false)
|
||||
{
|
||||
MCore::LogError("[GLSL] Failed to compile shader '%s'.", filename);
|
||||
MCore::LogError("[GLSL] Failed to compile shader '%.*s'.", AZ_STRING_ARG(filename.Native()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// Init
|
||||
bool GLSLShader::Init(const char* vFile, const char* pFile, MCore::Array<AZStd::string>& defines)
|
||||
bool GLSLShader::Init(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName, MCore::Array<AZStd::string>& defines)
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
/*const char* args[] = { "unroll all",
|
||||
@@ -225,24 +225,24 @@ namespace RenderGL
|
||||
glUseProgram(0);
|
||||
|
||||
// compile shaders
|
||||
if (vFile && CompileShader(GL_VERTEX_SHADER, &mVertexShader, vFile) == false)
|
||||
if (!vertexFileName.empty() && CompileShader(GL_VERTEX_SHADER, &mVertexShader, vertexFileName) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pFile && CompileShader(GL_FRAGMENT_SHADER, &mPixelShader, pFile) == false)
|
||||
if (!pixelFileName.empty() && CompileShader(GL_FRAGMENT_SHADER, &mPixelShader, pixelFileName) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// create program
|
||||
mProgram = glCreateProgram();
|
||||
if (vFile)
|
||||
if (!vertexFileName.empty())
|
||||
{
|
||||
glAttachShader(mProgram, mVertexShader);
|
||||
}
|
||||
|
||||
if (pFile)
|
||||
if (!pixelFileName.empty())
|
||||
{
|
||||
glAttachShader(mProgram, mPixelShader);
|
||||
}
|
||||
@@ -256,7 +256,7 @@ namespace RenderGL
|
||||
|
||||
if (!success)
|
||||
{
|
||||
MCore::LogInfo("[OpenGL] Failed to link shaders '%s' and '%s' ", vFile, pFile);
|
||||
MCore::LogInfo("[OpenGL] Failed to link shaders '%.*s' and '%.*s' ", AZ_STRING_ARG(vertexFileName.Native()), AZ_STRING_ARG(pixelFileName.Native()));
|
||||
InfoLog(mProgram, &QOpenGLExtraFunctions::glGetProgramInfoLog);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define __RENDERGL_GLSLSHADER_H
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include "Shader.h"
|
||||
|
||||
// include OpenGL
|
||||
@@ -45,7 +46,7 @@ namespace RenderGL
|
||||
MCORE_INLINE unsigned int GetProgram() const { return mProgram; }
|
||||
bool CheckIfIsDefined(const char* attributeName);
|
||||
|
||||
bool Init(const char* vertexFileName, const char* pixelFileName, MCore::Array<AZStd::string>& defines);
|
||||
bool Init(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName, MCore::Array<AZStd::string>& defines);
|
||||
void SetAttribute(const char* name, uint32 dim, uint32 type, uint32 stride, size_t offset) override;
|
||||
|
||||
void SetUniform(const char* name, float value) override;
|
||||
@@ -81,11 +82,11 @@ namespace RenderGL
|
||||
ShaderParameter* FindAttribute(const char* name);
|
||||
ShaderParameter* FindUniform(const char* name);
|
||||
|
||||
bool CompileShader(const GLenum type, unsigned int* outShader, const char* filename);
|
||||
bool CompileShader(const GLenum type, unsigned int* outShader, AZ::IO::PathView filename);
|
||||
template<class T>
|
||||
void InfoLog(GLuint object, T func);
|
||||
|
||||
AZStd::string mFileName;
|
||||
AZ::IO::Path mFileName;
|
||||
|
||||
MCore::Array<uint32> mActivatedAttribs;
|
||||
MCore::Array<uint32> mActivatedTextures;
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// try to initialize the graphics system
|
||||
bool GraphicsManager::Init(const char* shaderPath)
|
||||
bool GraphicsManager::Init(AZ::IO::PathView shaderPath)
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
@@ -364,7 +364,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// try to load a texture
|
||||
Texture* GraphicsManager::LoadTexture([[maybe_unused]] const char* filename, [[maybe_unused]] bool createMipMaps)
|
||||
Texture* GraphicsManager::LoadTexture([[maybe_unused]] AZ::IO::PathView filename, [[maybe_unused]] bool createMipMaps)
|
||||
{
|
||||
//Texture Library is no longer used
|
||||
//temporarily blank
|
||||
@@ -373,19 +373,19 @@ namespace RenderGL
|
||||
|
||||
|
||||
// try to load a texture
|
||||
Texture* GraphicsManager::LoadTexture(const char* filename)
|
||||
Texture* GraphicsManager::LoadTexture(AZ::IO::PathView filename)
|
||||
{
|
||||
return LoadTexture(filename, mCreateMipMaps);
|
||||
}
|
||||
|
||||
|
||||
// LoadPostProcessShader
|
||||
PostProcessShader* GraphicsManager::LoadPostProcessShader(const char* cFileName)
|
||||
PostProcessShader* GraphicsManager::LoadPostProcessShader(AZ::IO::PathView cFileName)
|
||||
{
|
||||
AZStd::string filename = mShaderPath + AZStd::string(cFileName);
|
||||
AZ::IO::PathView filename = mShaderPath / cFileName;
|
||||
|
||||
// check if the shader is already in the cache
|
||||
Shader* s = mShaderCache.FindShader(filename.c_str());
|
||||
Shader* s = mShaderCache.FindShader(filename.Native());
|
||||
if (s)
|
||||
{
|
||||
return (PostProcessShader*)s;
|
||||
@@ -393,19 +393,19 @@ namespace RenderGL
|
||||
|
||||
// load the shader from disk
|
||||
PostProcessShader* shader = new PostProcessShader();
|
||||
if (!shader->Init(filename.c_str()))
|
||||
if (!shader->Init(filename))
|
||||
{
|
||||
delete shader;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mShaderCache.AddShader(filename.c_str(), shader);
|
||||
mShaderCache.AddShader(filename.Native(), shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
// LoadShader
|
||||
GLSLShader* GraphicsManager::LoadShader(const char* vertexFileName, const char* pixelFileName)
|
||||
GLSLShader* GraphicsManager::LoadShader(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName)
|
||||
{
|
||||
MCore::Array<AZStd::string> defines;
|
||||
return LoadShader(vertexFileName, pixelFileName, defines);
|
||||
@@ -413,34 +413,21 @@ namespace RenderGL
|
||||
|
||||
|
||||
// LoadShader
|
||||
GLSLShader* GraphicsManager::LoadShader(const char* vFile, const char* pFile, MCore::Array<AZStd::string>& defines)
|
||||
GLSLShader* GraphicsManager::LoadShader(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName, MCore::Array<AZStd::string>& defines)
|
||||
{
|
||||
AZStd::string vStr;
|
||||
AZStd::string pStr;
|
||||
|
||||
if (vFile)
|
||||
{
|
||||
vStr = AZStd::string::format("%s%s", mShaderPath.c_str(), vFile);
|
||||
}
|
||||
|
||||
if (pFile)
|
||||
{
|
||||
pStr = AZStd::string::format("%s%s", mShaderPath.c_str(), pFile);
|
||||
}
|
||||
const AZ::IO::Path vertexPath {vertexFileName.empty() ? AZ::IO::Path{} : mShaderPath / vertexFileName};
|
||||
const AZ::IO::Path pixelPath {pixelFileName.empty() ? AZ::IO::Path{} : mShaderPath / pixelFileName};
|
||||
|
||||
// construct the lookup string for the shader cache
|
||||
AZStd::string dStr;
|
||||
AZStd::string cacheLookupStr = vertexPath.Native() + pixelPath.Native();
|
||||
const uint32 numDefines = defines.GetLength();
|
||||
for (uint32 n = 0; n < numDefines; n++)
|
||||
{
|
||||
dStr += AZStd::string::format("#%s", defines[n].c_str());
|
||||
cacheLookupStr += AZStd::string::format("#%s", defines[n].c_str());
|
||||
}
|
||||
|
||||
AZStd::string cStr;
|
||||
cStr = AZStd::string::format("%s%s%s", vStr.c_str(), pStr.c_str(), dStr.c_str());
|
||||
|
||||
// check if the shader is already in the cache
|
||||
Shader* cShader = mShaderCache.FindShader(cStr.c_str());
|
||||
Shader* cShader = mShaderCache.FindShader(cacheLookupStr);
|
||||
if (cShader)
|
||||
{
|
||||
return (GLSLShader*)cShader;
|
||||
@@ -448,13 +435,13 @@ namespace RenderGL
|
||||
|
||||
// load the shader from disk
|
||||
GLSLShader* shader = new GLSLShader();
|
||||
if (!shader->Init(vFile ? vStr.c_str() : nullptr, pFile ? pStr.c_str() : nullptr, defines))
|
||||
if (!shader->Init(vertexPath, pixelPath, defines))
|
||||
{
|
||||
delete shader;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mShaderCache.AddShader(cStr.c_str(), shader);
|
||||
mShaderCache.AddShader(cacheLookupStr, shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef __RENDERGL_GRAPHICSMANAGER__H
|
||||
#define __RENDERGL_GRAPHICSMANAGER__H
|
||||
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <MCore/Source/StandardHeaders.h>
|
||||
#include <MCore/Source/Vector.h>
|
||||
#include <MCore/Source/Color.h>
|
||||
@@ -57,21 +58,21 @@ namespace RenderGL
|
||||
const char* GetDeviceName();
|
||||
const char* GetDeviceVendor();
|
||||
MCORE_INLINE RenderTexture* GetRenderTexture() { return mRenderTexture; }
|
||||
MCORE_INLINE const char* GetShaderPath() const { return mShaderPath.c_str(); }
|
||||
MCORE_INLINE AZ::IO::PathView GetShaderPath() const { return mShaderPath; }
|
||||
MCORE_INLINE TextureCache* GetTextureCache() { return &mTextureCache; }
|
||||
|
||||
bool Init(const char* shaderPath = "Shaders/");
|
||||
bool Init(AZ::IO::PathView shaderPath = "Shaders");
|
||||
|
||||
bool GetIsPostProcessingEnabled() const { return mPostProcessing; }
|
||||
PostProcessShader* LoadPostProcessShader(const char* filename);
|
||||
GLSLShader* LoadShader(const char* vertexFileName, const char* pixelFileName);
|
||||
GLSLShader* LoadShader(const char* vertexFileName, const char* pixelFileName, MCore::Array<AZStd::string>& defines);
|
||||
PostProcessShader* LoadPostProcessShader(AZ::IO::PathView filename);
|
||||
GLSLShader* LoadShader(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName);
|
||||
GLSLShader* LoadShader(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName, MCore::Array<AZStd::string>& defines);
|
||||
|
||||
MCORE_INLINE void SetGBuffer(GBuffer* gBuffer) { mGBuffer = gBuffer; }
|
||||
MCORE_INLINE GBuffer* GetGBuffer() { return mGBuffer; }
|
||||
|
||||
Texture* LoadTexture(const char* filename, bool createMipMaps);
|
||||
Texture* LoadTexture(const char* filename);
|
||||
Texture* LoadTexture(AZ::IO::PathView filename, bool createMipMaps);
|
||||
Texture* LoadTexture(AZ::IO::PathView filename);
|
||||
|
||||
void SetCreateMipMaps(bool createMipMaps) { mCreateMipMaps = createMipMaps; }
|
||||
MCORE_INLINE bool GetCreateMipMaps() const { return mCreateMipMaps; }
|
||||
@@ -96,7 +97,7 @@ namespace RenderGL
|
||||
|
||||
void SetShader(Shader* shader);
|
||||
MCORE_INLINE void SetRenderTexture(RenderTexture* texture) { mRenderTexture = texture; }
|
||||
MCORE_INLINE void SetShaderPath(const char* shaderPath) { mShaderPath = shaderPath; }
|
||||
MCORE_INLINE void SetShaderPath(AZ::IO::PathView shaderPath) { mShaderPath = shaderPath; }
|
||||
|
||||
MCORE_INLINE void SetBloomEnabled(bool enabled) { mBloomEnabled = enabled; }
|
||||
MCORE_INLINE void SetBloomThreshold(float threshold) { mBloomThreshold = threshold; }
|
||||
@@ -154,7 +155,7 @@ namespace RenderGL
|
||||
MCommon::Camera* mCamera; /**< The camera used for rendering. */
|
||||
|
||||
ShaderCache mShaderCache; /**< The shader manager used to load and manage vertex and pixel shaders. */
|
||||
AZStd::string mShaderPath; /**< The absolute path to the directory where the shaders are located. This string will be added as prefix to each shader file the user tries to load. */
|
||||
AZ::IO::Path mShaderPath; /**< The absolute path to the directory where the shaders are located. This string will be added as prefix to each shader file the user tries to load. */
|
||||
MCore::RGBAColor mClearColor; /**< The scene background color. */
|
||||
MCore::RGBAColor mGradientSourceColor; /**< The background gradient source color. */
|
||||
MCore::RGBAColor mGradientTargetColor; /**< The background gradient target color. */
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include "PostProcessShader.h"
|
||||
#include "GraphicsManager.h"
|
||||
|
||||
@@ -82,7 +83,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// Init
|
||||
bool PostProcessShader::Init(const char* filename)
|
||||
bool PostProcessShader::Init(AZ::IO::PathView filename)
|
||||
{
|
||||
MCore::Array<AZStd::string> defines;
|
||||
return GLSLShader::Init(nullptr, filename, defines);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef __RENDERGL_POSTPROCESS_SHADER_H
|
||||
#define __RENDERGL_POSTPROCESS_SHADER_H
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include "GLSLShader.h"
|
||||
#include "RenderTexture.h"
|
||||
|
||||
@@ -34,7 +35,7 @@ namespace RenderGL
|
||||
|
||||
void Deactivate() override;
|
||||
|
||||
bool Init(const char* filename);
|
||||
bool Init(AZ::IO::PathView filename);
|
||||
void Render();
|
||||
|
||||
private:
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// add the shader to the cache (assume there are no duplicate names)
|
||||
void ShaderCache::AddShader(const char* filename, Shader* shader)
|
||||
void ShaderCache::AddShader(AZStd::string_view filename, Shader* shader)
|
||||
{
|
||||
mEntries.AddEmpty();
|
||||
mEntries.GetLast().mName = filename;
|
||||
@@ -57,12 +57,12 @@ namespace RenderGL
|
||||
|
||||
|
||||
// try to locate a shader based on its name
|
||||
Shader* ShaderCache::FindShader(const char* filename) const
|
||||
Shader* ShaderCache::FindShader(AZStd::string_view filename) const
|
||||
{
|
||||
const uint32 numEntries = mEntries.GetLength();
|
||||
for (uint32 i = 0; i < numEntries; ++i)
|
||||
{
|
||||
if (AzFramework::StringFunc::Equal(mEntries[i].mName.c_str(), filename, false /* no case */)) // non-case-sensitive name compare
|
||||
if (AzFramework::StringFunc::Equal(mEntries[i].mName, filename, false /* no case */)) // non-case-sensitive name compare
|
||||
{
|
||||
return mEntries[i].mShader;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace RenderGL
|
||||
~ShaderCache(); // automatically calls Release
|
||||
|
||||
void Release();
|
||||
void AddShader(const char* filename, Shader* shader);
|
||||
Shader* FindShader(const char* filename) const;
|
||||
void AddShader(AZStd::string_view filename, Shader* shader);
|
||||
Shader* FindShader(AZStd::string_view filename) const;
|
||||
bool CheckIfHasShader(Shader* shader) const;
|
||||
|
||||
private:
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ namespace EMStudio
|
||||
|
||||
// create graphics manager and initialize it
|
||||
mGraphicsManager = new RenderGL::GraphicsManager();
|
||||
if (mGraphicsManager->Init(shaderPath.c_str()) == false)
|
||||
if (mGraphicsManager->Init(shaderPath) == false)
|
||||
{
|
||||
MCore::LogError("Could not initialize OpenGL graphics manager.");
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user