Allow all shader files to be loaded only once
Todo: preload
This commit is contained in:
parent
7894e5c864
commit
2a9656bfdc
@ -919,7 +919,6 @@ void IrrDriver::applyResolutionSettings()
|
||||
// FIXME: this load sequence is (mostly) duplicated from main.cpp!!
|
||||
// That's just error prone
|
||||
// (we're sure to update main.cpp at some point and forget this one...)
|
||||
ShaderBase::updateShaders();
|
||||
VAOManager::getInstance()->kill();
|
||||
resetTextureTable();
|
||||
cleanUnicolorTextures();
|
||||
@ -930,6 +929,7 @@ void IrrDriver::applyResolutionSettings()
|
||||
}
|
||||
delete m_renderer;
|
||||
initDevice();
|
||||
ShaderBase::updateShaders();
|
||||
|
||||
font_manager = new FontManager();
|
||||
font_manager->loadFonts();
|
||||
|
@ -19,198 +19,16 @@
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include "graphics/shader.hpp"
|
||||
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/shared_gpu_objects.hpp"
|
||||
#include "graphics/spherical_harmonics.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
std::string ShaderBase::m_shader_header = "";
|
||||
std::vector<void(*)()> ShaderBase::m_all_kill_functions;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a string with the content of header.txt (which contains basic
|
||||
* shader defines).
|
||||
*/
|
||||
const std::string& ShaderBase::getHeader()
|
||||
{
|
||||
// Only read file first time
|
||||
if (m_shader_header.empty())
|
||||
{
|
||||
std::ifstream stream(file_manager->getShader("header.txt"), std::ios::in);
|
||||
if (stream.is_open())
|
||||
{
|
||||
std::string line = "";
|
||||
while (getline(stream, line))
|
||||
m_shader_header += "\n" + line;
|
||||
stream.close();
|
||||
}
|
||||
} // if m_shader_header.empty()
|
||||
|
||||
return m_shader_header;
|
||||
} // getHeader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a single shader.
|
||||
* \param file Filename of the shader to load.
|
||||
* \param type Type of the shader.
|
||||
*/
|
||||
GLuint ShaderBase::loadShader(const std::string &file, unsigned type)
|
||||
{
|
||||
GLuint id = glCreateShader(type);
|
||||
|
||||
std::ostringstream code;
|
||||
#if !defined(USE_GLES2)
|
||||
code << "#version " << CVS->getGLSLVersion()<<"\n";
|
||||
#else
|
||||
if (CVS->isGLSL())
|
||||
code << "#version 300 es\n";
|
||||
#endif
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
// Some drivers report that the compute shaders extension is available,
|
||||
// but they report only OpenGL 3.x version, and thus these extensions
|
||||
// must be enabled manually. Otherwise the shaders compilation will fail
|
||||
// because STK tries to use extensions which are available, but disabled
|
||||
// by default.
|
||||
if (type == GL_COMPUTE_SHADER)
|
||||
{
|
||||
if (CVS->isARBComputeShaderUsable())
|
||||
code << "#extension GL_ARB_compute_shader : enable\n";
|
||||
if (CVS->isARBImageLoadStoreUsable())
|
||||
code << "#extension GL_ARB_shader_image_load_store : enable\n";
|
||||
if (CVS->isARBArraysOfArraysUsable())
|
||||
code << "#extension GL_ARB_arrays_of_arrays : enable\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CVS->isAMDVertexShaderLayerUsable())
|
||||
code << "#extension GL_AMD_vertex_shader_layer : enable\n";
|
||||
|
||||
if (CVS->isARBExplicitAttribLocationUsable())
|
||||
code << "#extension GL_ARB_explicit_attrib_location : enable\n";
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
code << "#extension GL_ARB_bindless_texture : enable\n";
|
||||
code << "#define Use_Bindless_Texture\n";
|
||||
}
|
||||
code << "//" << file << "\n";
|
||||
if (!CVS->isARBUniformBufferObjectUsable())
|
||||
code << "#define UBO_DISABLED\n";
|
||||
if (CVS->isAMDVertexShaderLayerUsable())
|
||||
code << "#define VSLayer\n";
|
||||
if (CVS->needsRGBBindlessWorkaround())
|
||||
code << "#define SRGBBindlessFix\n";
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
//shader compilation fails with some drivers if there is no precision qualifier
|
||||
if (type == GL_FRAGMENT_SHADER)
|
||||
code << "precision mediump float;\n";
|
||||
#else
|
||||
int range[2], precision;
|
||||
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range, &precision);
|
||||
|
||||
if (precision > 0)
|
||||
code << "precision highp float;\n";
|
||||
else
|
||||
code << "precision mediump float;\n";
|
||||
#endif
|
||||
code << "#define MAX_BONES " << SharedGPUObjects::getMaxMat4Size() << "\n";
|
||||
|
||||
code << getHeader();
|
||||
|
||||
std::ifstream stream(file_manager->getShader(file), std::ios::in);
|
||||
if (stream.is_open())
|
||||
{
|
||||
std::string Line = "";
|
||||
while (getline(stream, Line))
|
||||
{
|
||||
const std::string stk_include = "#stk_include";
|
||||
std::size_t pos = Line.find(stk_include);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::size_t pos = Line.find("\"");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
Log::error("shader", "Invalid #stk_include line: '%s'.", Line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string filename = Line.substr(pos+1);
|
||||
|
||||
pos = filename.find("\"");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
Log::error("shader", "Invalid #stk_include line: '%s'.", Line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
filename = filename.substr(0, pos);
|
||||
|
||||
std::ifstream include_stream(file_manager->getShader(filename), std::ios::in);
|
||||
if (!include_stream.is_open())
|
||||
{
|
||||
Log::error("shader", "Couldn't open included shader: '%s'.", filename.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string include_line = "";
|
||||
while (getline(include_stream, include_line))
|
||||
{
|
||||
code << "\n" << include_line;
|
||||
}
|
||||
|
||||
include_stream.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
code << "\n" << Line;
|
||||
}
|
||||
}
|
||||
|
||||
stream.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("shader", "Can not open '%s'.", file.c_str());
|
||||
}
|
||||
|
||||
Log::info("shader", "Compiling shader : %s", file.c_str());
|
||||
const std::string &source = code.str();
|
||||
char const *source_pointer = source.c_str();
|
||||
int len = source.size();
|
||||
glShaderSource(id, 1, &source_pointer, &len);
|
||||
glCompileShader(id);
|
||||
|
||||
GLint result = GL_FALSE;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
int info_length;
|
||||
Log::error("GLWrap", "Error in shader %s", file.c_str());
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_length);
|
||||
if (info_length<0)
|
||||
info_length = 1024;
|
||||
char *error_message = new char[info_length];
|
||||
error_message[0] = 0;
|
||||
glGetShaderInfoLog(id, info_length, NULL, error_message);
|
||||
Log::error("GLWrap", error_message);
|
||||
delete[] error_message;
|
||||
}
|
||||
|
||||
glGetError();
|
||||
|
||||
return id;
|
||||
} // loadShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a transform feedback buffer shader with a given number of varying
|
||||
* parameters.
|
||||
@ -239,7 +57,7 @@ int ShaderBase::loadTFBProgram(const std::string &shader_name,
|
||||
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
char *error_message = new char[info_log_length];
|
||||
glGetProgramInfoLog(m_program, info_log_length, NULL, error_message);
|
||||
Log::error("GLWrap", error_message);
|
||||
Log::error("ShaderBase", error_message);
|
||||
delete[] error_message;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "graphics/shader_files_manager.hpp"
|
||||
#include "graphics/shared_gpu_objects.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
|
||||
@ -40,13 +41,6 @@
|
||||
*/
|
||||
class ShaderBase
|
||||
{
|
||||
private:
|
||||
// Static members
|
||||
/** Stores the context of header.txt, to avoid reading
|
||||
* this file repeatedly. */
|
||||
static std::string m_shader_header;
|
||||
|
||||
|
||||
protected:
|
||||
/** Maintains a list of all shaders. */
|
||||
static std::vector<void (*)()> m_all_kill_functions;
|
||||
@ -75,8 +69,12 @@ protected:
|
||||
void loadAndAttachShader(GLint shader_type, const std::string &name,
|
||||
Types ... args)
|
||||
{
|
||||
GLint shader_id = loadShader(name, shader_type);
|
||||
GLint shader_id = ShaderFilesManager::getInstance()
|
||||
->getShaderFile(name, shader_type);
|
||||
glAttachShader(m_program, shader_id);
|
||||
GLint is_deleted = GL_TRUE;
|
||||
glGetShaderiv(shader_id, GL_DELETE_STATUS, &is_deleted);
|
||||
if (is_deleted == GL_FALSE)
|
||||
glDeleteShader(shader_id);
|
||||
loadAndAttachShader(args...);
|
||||
} // loadAndAttachShader
|
||||
@ -89,9 +87,6 @@ protected:
|
||||
loadAndAttachShader(shader_type, std::string(name), args...);
|
||||
} // loadAndAttachShader
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
const std::string& getHeader();
|
||||
GLuint loadShader(const std::string &file, unsigned type);
|
||||
void setAttribute(AttributeType type);
|
||||
|
||||
public:
|
||||
|
@ -681,6 +681,7 @@ ShaderBasedRenderer::~ShaderBasedRenderer()
|
||||
delete m_spherical_harmonics;
|
||||
delete m_skybox;
|
||||
delete m_rtts;
|
||||
ShaderFilesManager::kill();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
228
src/graphics/shader_files_manager.cpp
Normal file
228
src/graphics/shader_files_manager.cpp
Normal file
@ -0,0 +1,228 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2016 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#include "graphics/shader_files_manager.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/shared_gpu_objects.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
std::string ShaderFilesManager::m_shader_header = "";
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a string with the content of header.txt (which contains basic
|
||||
* shader defines).
|
||||
*/
|
||||
const std::string& ShaderFilesManager::getHeader()
|
||||
{
|
||||
// Only read file first time
|
||||
if (m_shader_header.empty())
|
||||
{
|
||||
std::ifstream stream(file_manager->getShader("header.txt"),
|
||||
std::ios::in);
|
||||
if (stream.is_open())
|
||||
{
|
||||
std::string line = "";
|
||||
while (getline(stream, line))
|
||||
m_shader_header += "\n" + line;
|
||||
stream.close();
|
||||
}
|
||||
} // if m_shader_header.empty()
|
||||
|
||||
return m_shader_header;
|
||||
} // getHeader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Loads a single shader file, and add it to the loaded list
|
||||
* \param file Filename of the shader to load.
|
||||
* \param type Type of the shader.
|
||||
*/
|
||||
GLuint ShaderFilesManager::addShaderFile(const std::string &file,
|
||||
unsigned type)
|
||||
{
|
||||
GLuint id = glCreateShader(type);
|
||||
|
||||
std::ostringstream code;
|
||||
#if !defined(USE_GLES2)
|
||||
code << "#version " << CVS->getGLSLVersion()<<"\n";
|
||||
#else
|
||||
if (CVS->isGLSL())
|
||||
code << "#version 300 es\n";
|
||||
#endif
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
// Some drivers report that the compute shaders extension is available,
|
||||
// but they report only OpenGL 3.x version, and thus these extensions
|
||||
// must be enabled manually. Otherwise the shaders compilation will fail
|
||||
// because STK tries to use extensions which are available, but disabled
|
||||
// by default.
|
||||
if (type == GL_COMPUTE_SHADER)
|
||||
{
|
||||
if (CVS->isARBComputeShaderUsable())
|
||||
code << "#extension GL_ARB_compute_shader : enable\n";
|
||||
if (CVS->isARBImageLoadStoreUsable())
|
||||
code << "#extension GL_ARB_shader_image_load_store : enable\n";
|
||||
if (CVS->isARBArraysOfArraysUsable())
|
||||
code << "#extension GL_ARB_arrays_of_arrays : enable\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CVS->isAMDVertexShaderLayerUsable())
|
||||
code << "#extension GL_AMD_vertex_shader_layer : enable\n";
|
||||
|
||||
if (CVS->isARBExplicitAttribLocationUsable())
|
||||
code << "#extension GL_ARB_explicit_attrib_location : enable\n";
|
||||
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
code << "#extension GL_ARB_bindless_texture : enable\n";
|
||||
code << "#define Use_Bindless_Texture\n";
|
||||
}
|
||||
code << "//" << file << "\n";
|
||||
if (!CVS->isARBUniformBufferObjectUsable())
|
||||
code << "#define UBO_DISABLED\n";
|
||||
if (CVS->isAMDVertexShaderLayerUsable())
|
||||
code << "#define VSLayer\n";
|
||||
if (CVS->needsRGBBindlessWorkaround())
|
||||
code << "#define SRGBBindlessFix\n";
|
||||
|
||||
#if !defined(USE_GLES2)
|
||||
// shader compilation fails with some drivers if there is no precision
|
||||
// qualifier
|
||||
if (type == GL_FRAGMENT_SHADER)
|
||||
code << "precision mediump float;\n";
|
||||
#else
|
||||
int range[2], precision;
|
||||
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, range,
|
||||
&precision);
|
||||
|
||||
if (precision > 0)
|
||||
code << "precision highp float;\n";
|
||||
else
|
||||
code << "precision mediump float;\n";
|
||||
#endif
|
||||
code << "#define MAX_BONES " << SharedGPUObjects::getMaxMat4Size() << "\n";
|
||||
|
||||
code << getHeader();
|
||||
|
||||
std::ifstream stream(file_manager->getShader(file), std::ios::in);
|
||||
if (stream.is_open())
|
||||
{
|
||||
std::string line = "";
|
||||
while (getline(stream, line))
|
||||
{
|
||||
const std::string stk_include = "#stk_include";
|
||||
std::size_t pos = line.find(stk_include);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::size_t pos = line.find("\"");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
Log::error("ShaderFilesManager", "Invalid #stk_include"
|
||||
" line: '%s'.", line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string filename = line.substr(pos + 1);
|
||||
|
||||
pos = filename.find("\"");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
Log::error("ShaderFilesManager", "Invalid #stk_include"
|
||||
" line: '%s'.", line.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
filename = filename.substr(0, pos);
|
||||
|
||||
std::ifstream include_stream(file_manager->getShader(filename),
|
||||
std::ios::in);
|
||||
if (!include_stream.is_open())
|
||||
{
|
||||
Log::error("ShaderFilesManager", "Couldn't open included"
|
||||
" shader: '%s'.", filename.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string include_line = "";
|
||||
while (getline(include_stream, include_line))
|
||||
{
|
||||
code << "\n" << include_line;
|
||||
}
|
||||
include_stream.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
code << "\n" << line;
|
||||
}
|
||||
}
|
||||
|
||||
stream.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::error("ShaderFilesManager", "Can not open '%s'.", file.c_str());
|
||||
}
|
||||
|
||||
Log::info("ShaderFilesManager", "Compiling shader : %s", file.c_str());
|
||||
const std::string &source = code.str();
|
||||
char const *source_pointer = source.c_str();
|
||||
int len = source.size();
|
||||
glShaderSource(id, 1, &source_pointer, &len);
|
||||
glCompileShader(id);
|
||||
|
||||
GLint result = GL_FALSE;
|
||||
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
|
||||
if (result == GL_FALSE)
|
||||
{
|
||||
int info_length;
|
||||
Log::error("ShaderFilesManager", "Error in shader %s", file.c_str());
|
||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &info_length);
|
||||
if (info_length < 0)
|
||||
info_length = 1024;
|
||||
char *error_message = new char[info_length];
|
||||
error_message[0] = 0;
|
||||
glGetShaderInfoLog(id, info_length, NULL, error_message);
|
||||
Log::error("ShaderFilesManager", error_message);
|
||||
delete[] error_message;
|
||||
}
|
||||
|
||||
glGetError();
|
||||
m_shader_files_loaded[file] = id;
|
||||
return id;
|
||||
|
||||
} // addShaderFile
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
GLuint ShaderFilesManager::getShaderFile(const std::string &file,
|
||||
unsigned type)
|
||||
{
|
||||
std::unordered_map<std::string, GLuint>::const_iterator i =
|
||||
m_shader_files_loaded.find(file);
|
||||
if (i != m_shader_files_loaded.end())
|
||||
return i->second;
|
||||
else
|
||||
return addShaderFile(file, type);
|
||||
|
||||
} // getShaderFile
|
||||
|
||||
#endif // !SERVER_ONLY
|
59
src/graphics/shader_files_manager.hpp
Normal file
59
src/graphics/shader_files_manager.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2016 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
|
||||
#ifndef HEADER_SHADER_FILES_MANAGER_HPP
|
||||
#define HEADER_SHADER_FILES_MANAGER_HPP
|
||||
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class ShaderFilesManager : public Singleton<ShaderFilesManager>, NoCopy
|
||||
{
|
||||
private:
|
||||
/** Stores the context of header.txt, to avoid reading
|
||||
* this file repeatedly. */
|
||||
static std::string m_shader_header;
|
||||
|
||||
std::unordered_map<std::string, GLuint> m_shader_files_loaded;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
const std::string& getHeader();
|
||||
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
ShaderFilesManager() {}
|
||||
// ------------------------------------------------------------------------
|
||||
~ShaderFilesManager() { clean(); }
|
||||
// ------------------------------------------------------------------------
|
||||
void clean() { m_shader_files_loaded.clear(); }
|
||||
// ------------------------------------------------------------------------
|
||||
GLuint addShaderFile(const std::string &file, unsigned type);
|
||||
// ------------------------------------------------------------------------
|
||||
GLuint getShaderFile(const std::string &file, unsigned type);
|
||||
|
||||
}; // ShaderFilesManager
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !SERVER_ONLY
|
@ -174,69 +174,6 @@ static std::string loadHeader()
|
||||
return result;
|
||||
} // loadHeader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Mostly from shader tutorial
|
||||
GLuint loadShader(const char * file, unsigned type)
|
||||
{
|
||||
GLuint Id = glCreateShader(type);
|
||||
char versionString[20];
|
||||
#if !defined(USE_GLES2)
|
||||
sprintf(versionString, "#version %d\n", CVS->getGLSLVersion());
|
||||
#else
|
||||
if (CVS->isGLSL())
|
||||
sprintf(versionString, "#version 300 es\n");
|
||||
#endif
|
||||
std::string Code = versionString;
|
||||
if (CVS->isAMDVertexShaderLayerUsable())
|
||||
Code += "#extension GL_AMD_vertex_shader_layer : enable\n";
|
||||
if (CVS->isAZDOEnabled())
|
||||
{
|
||||
Code += "#extension GL_ARB_bindless_texture : enable\n";
|
||||
Code += "#define Use_Bindless_Texture\n";
|
||||
}
|
||||
std::ifstream Stream(file, std::ios::in);
|
||||
Code += "//" + std::string(file) + "\n";
|
||||
if (!CVS->isARBUniformBufferObjectUsable())
|
||||
Code += "#define UBO_DISABLED\n";
|
||||
if (CVS->isAMDVertexShaderLayerUsable())
|
||||
Code += "#define VSLayer\n";
|
||||
if (CVS->needsRGBBindlessWorkaround())
|
||||
Code += "#define SRGBBindlessFix\n";
|
||||
Code += loadHeader();
|
||||
if (Stream.is_open())
|
||||
{
|
||||
std::string Line = "";
|
||||
while (getline(Stream, Line))
|
||||
Code += "\n" + Line;
|
||||
Stream.close();
|
||||
}
|
||||
GLint Result = GL_FALSE;
|
||||
int InfoLogLength;
|
||||
Log::info("GLWrap", "Compiling shader : %s", file);
|
||||
char const * SourcePointer = Code.c_str();
|
||||
int length = (int)strlen(SourcePointer);
|
||||
glShaderSource(Id, 1, &SourcePointer, &length);
|
||||
glCompileShader(Id);
|
||||
|
||||
glGetShaderiv(Id, GL_COMPILE_STATUS, &Result);
|
||||
if (Result == GL_FALSE)
|
||||
{
|
||||
Log::error("GLWrap", "Error in shader %s", file);
|
||||
glGetShaderiv(Id, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
||||
if (InfoLogLength<0)
|
||||
InfoLogLength = 1024;
|
||||
char *ErrorMessage = new char[InfoLogLength];
|
||||
ErrorMessage[0] = 0;
|
||||
glGetShaderInfoLog(Id, InfoLogLength, NULL, ErrorMessage);
|
||||
Log::error("GLWrap", ErrorMessage);
|
||||
delete[] ErrorMessage;
|
||||
}
|
||||
|
||||
glGetError();
|
||||
|
||||
return Id;
|
||||
} // loadShader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Shaders::loadShaders()
|
||||
{
|
||||
|
@ -236,6 +236,7 @@ bool handleContextMenuAction(s32 cmd_id)
|
||||
case DEBUG_GRAPHICS_RELOAD_SHADERS:
|
||||
#ifndef SERVER_ONLY
|
||||
Log::info("Debug", "Reloading shaders...");
|
||||
ShaderFilesManager::getInstance()->clean();
|
||||
ShaderBase::updateShaders();
|
||||
#endif
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user