Commit 6cb47e4d authored by Johannes Braun's avatar Johannes Braun
Browse files

custom shader includes

parent 3d900863
......@@ -44,7 +44,7 @@
{
"name": "Max Speed Release",
"generator": "Ninja",
"configurationType" : "MinSizeRel",
"configurationType" : "MaxSpeedRel",
"inheritEnvironments": [ "msvc_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"cmakeCommandArgs": "",
......
......@@ -5,11 +5,11 @@ Collapsed=0
[Scene]
Pos=29,64
Size=322,270
Collapsed=1
Size=312,787
Collapsed=0
[Settings]
Pos=173,7
Pos=1117,12
Size=311,899
Collapsed=1
Collapsed=0
<linespace version="1.0">
<item name="subdivisions" value="16"/>
<item name="grid-subdivisions" value="8"/>
<item name="subdivisions" value="8"/>
<item name="grid-subdivisions" value="4"/>
<item name="radial-subdivision" value="50"/>
<item name="generator" value="gpu"/>
</linespace>
......@@ -86,6 +86,7 @@ LightData sampleLight(const in Light light, const in Vertex vertex, const in vec
result.sample_succeeded = sampleLightRoutines[i](light, vertex.position.xyz, result.point_on_light, result.light_color, random_sample);
}
}
kleklekle;
vec3 non_normal_direction = result.point_on_light - vertex.position.xyz;
result.testing_distance = length(non_normal_direction);
result.shadow_test.direction = normalize(non_normal_direction);
......@@ -215,7 +216,7 @@ void main()
for (bounce.count = 1; bounce.shade() && bounce.count <= bounce_count; ++bounce.count) {
scene.nearestIntersection(bounce.ray, bounce.hit, shouldUseBvh(bounce));
}
ivec2 pixel = ivec2(bounce.ray.px, bounce.ray.py);
vec4 color = render_target.imageLoad(pixel);
......
#version 430
#line 3 "center_texture.frag"
#extension GL_ARB_bindless_texture : require
//in vec2 out_texcoord;
......
......@@ -51,6 +51,7 @@ void drawSceneWindow();
// Implementation
int main(int argc, char* argv[])
{
core::Context::createAsCurrent(engine_settings_path);
core::Context::current().callbacks().addKeyDownCallback("main_application", keyPress);
......
#include <raytrace/data/grid_linespace.h>
#include "glsl.h"
#include <util/log.h>
#include "core/state.h"
#include <core/numeric/geometry.h>
#include <core/state.h>
int main(int argc, char* argv[])
{
if (float f = 0; f < 210)
{
Log_Debug << f;
}
glare::core::Context::createAsCurrent(files::asset("/preferences/default.xml"));
glare::core::GLSLParser parser(files::asset("shaders/pathtracer/pathtracer.comp"));
std::string src = parser.get();
auto shader = std::make_shared<glare::core::Shader>(gl::ShaderType::eCompute, parser.get(), "pathtracer");
glare::core::Program program(shader);
return 0;
}
\ No newline at end of file
}
......@@ -30,6 +30,8 @@ namespace glare::component
const std::string build_type = "Debug build | ";
#elif NDEBUG
const std::string build_type = "Release build | ";
#else
const std::string build_type = "UNKNOWN build | ";
#endif
ImGui::Begin("Debug");
......
......@@ -3,7 +3,7 @@
#include <util/log.h>
#include <util/files.h>
#include "shader_system.h"
#include "glsl.h"
#include <GLFW/glfw3.h>
......@@ -14,7 +14,7 @@ namespace glare::core
{}
Shader::Shader(gl::ShaderType shader_type, const fs::path& path)
: Shader(shader_type, files::loadText(path), path.string())
: Shader(shader_type, GLSLParser(path).get(), path.string())
{}
Shader::Shader(gl::ShaderType shader_type, const std::string &source, const std::string& identifier)
......@@ -33,20 +33,23 @@ namespace glare::core
m_identifier = identifier;
std::string precompiled = source;
ShaderSystem::precompile(precompiled);
const char *source_chars = precompiled.c_str();
gl::shaderSource(m_handle, 1, &source_chars, nullptr);
static auto root = "/.";
//const char* root[2]{ "/.", "/screenshader/gbuffer" };
/* auto root = files::asset("shaders").string();
std::replace(root.begin(), root.end(), '\\', '/');
root = "/" + root;
const char* ptr = root.c_str();
if (glfwExtensionSupported("GL_ARB_shading_language_include")) {
gl::compileShaderInclude(m_handle, 1, &root, nullptr);
gl::compileShaderInclude(m_handle, 1, &ptr, nullptr);
}
else
{
{*/
gl::compileShader(m_handle);
}
// }
int success = 0;
gl::getShaderiv(m_handle, gl::GetShaderParameter::eCompileStatus, &success);
......
#include "shader_system.h"
#include <sstream>
#include <map>
#include <util/log.h>
#include <util/files.h>
#include <util/console.h>
#include <util/opengl.h>
#include "GLFW/glfw3.h"
namespace glare::core
{
std::vector<std::string> ShaderSystem::m_named_strings;
std::vector<int> ShaderSystem::m_named_string_lengths;
void ShaderSystem::initialize()
{
if (!glfwExtensionSupported("GL_ARB_shading_language_include")) {
Log_Warn << "Extension GL_ARB_shading_language_include not supported. GL header files will not be loaded.";
return;
}
const fs::path include_path = files::asset("shaders/");
fs::recursive_directory_iterator it(include_path);
for (const auto &file : it)
{
auto path = fs::path(file);
if (path.extension() == ".glsl" || path.extension() == ".comp" || path.extension() == ".vert" || path.extension() == ".geom" || path.extension() == ".frag")
{
const auto relative = files::relative(include_path, path);
std::string content = files::loadText(path);
precompile(content);
gl::namedString(gl::NamedStringType::eShaderInclude, relative.string(), content);
m_named_strings.push_back(relative.string());
m_named_string_lengths.push_back(static_cast<int>(relative.string().size()));
}
}
}
void ShaderSystem::precompile(std::string &source)
{
checkExtensions(source);
format(source);
}
void ShaderSystem::checkExtensions(const std::string &source)
{
ExtensionParseState state = ExtensionParseState::eNone;
std::stringstream input_stream;
std::stringstream requirement_stream;
unsigned char current_requirement_position = 0;
std::map<std::string, ExtensionRequirement> extensions;
static std::string str_enabled = "enable";
static std::string str_required = "require";
std::string current_requirement = "";
for (const auto &character : source)
{
if (character == '#')
{
if (state != ExtensionParseState::eNone)
{
Log_Error << "Malformed extension statement.";
break;
}
state = ExtensionParseState::eKeyword;
continue;
}
bool close_loop = false;
switch (state)
{
case ExtensionParseState::eKeyword:
if (character == ' ' || character == '\n')
{
if (input_stream.str() == "extension")
{
state = ExtensionParseState::eExtName;
}
else
{
state = ExtensionParseState::eNone;
}
input_stream.str(std::string());
break;
}
input_stream << character;
break;
case ExtensionParseState::eExtName:
if (character == ' ' || character == '\t')
{
state = ExtensionParseState::eRequirementCheck;
break;
}
else if (character == ':')
{
state = ExtensionParseState::eRequirementCheck;
break;
}
else if (character == '\n')
{
Log_Error << "Malformed extension name or requirement.";
input_stream.str(std::string());
close_loop = true;
break;
}
input_stream << character;
break;
case ExtensionParseState::eRequirementCheck:
//The last char was a space or a ':'. Now wait until you find an 'e' or 'r' which indicates a requirement label.
if (character == 'e' || character == 'r')
{
requirement_stream << character;
state = ExtensionParseState::eRequirementCheckForm;
current_requirement = character == 'e' ? str_enabled : str_required;
current_requirement_position = 0;
break;
}
break;
case ExtensionParseState::eRequirementCheckForm:
if (++current_requirement_position < current_requirement.size() && character == current_requirement[current_requirement_position])
{
requirement_stream << character;
break;
}
if (requirement_stream.str() == str_enabled)
{
if (extensions.count(input_stream.str()) == 0)
{
//Add to map only if there is none at all or none with a higher requirement state.
std::string extension_name = input_stream.str();
if (!glfwExtensionSupported(extension_name.c_str()))
{
Log_Warn << "Extension enabled, but not supported: " << extension_name;
}
extensions.emplace(extension_name, ExtensionRequirement::eEnabled);
}
input_stream.str(std::string());
requirement_stream.str(std::string());
state = ExtensionParseState::eNone;
break;
}
if (requirement_stream.str() == str_required)
{
std::string extension_name = input_stream.str();
if (!glfwExtensionSupported(extension_name.c_str()))
{
Log_Error << "Extension required, but not supported: " << extension_name;
console::prompt(1);
return;
}
extensions.emplace(extension_name, ExtensionRequirement::eRequired);
input_stream.str(std::string());
requirement_stream.str(std::string());
state = ExtensionParseState::eNone;
break;
}
//Uhm... not inside the requirement string, nor at the current req. string position, nor equal to any requirement.
//So clearly malformed.
Log_Error << "Extension malformed.";
close_loop = true;
break;
default:
break;
}
if (close_loop)
break;
}
}
bool ShaderSystem::endOfCall(char c, bool backtrace)
{
return (c == ';' || c == '=' || c == '?' || c == '!' || c == ' ' || c == '\n' || c == ':' || c == ',' || c == '<' || c == '>' || (backtrace && (c == '(')) || (!backtrace && (c == '[' || c == ']')) || c == ')' || c == '%' || c == '/' || c == '+' || c == '-' || c == '*');
}
void ShaderSystem::format(std::string &source)
{
std::string &content = source;
enum class state_t
{
eIdle = 0,
eExpression = 1
};
state_t state = state_t::eIdle;
std::string expression_name = "";
for (unsigned pos = 0; pos < content.length(); ++pos)
{
const char c = content[pos];
if (c == '.') {
state = state_t::eExpression;
expression_name.clear();
continue;
}
if (state == state_t::eExpression) {
if (endOfCall(c, false)) {
state = state_t::eIdle;
}
else if (c == '(' && expression_name != "length")
{
const bool empty_call = content[pos + 1] == ')';
const size_t exp_length = expression_name.length();
unsigned temp_pos = pos - 2 - static_cast<unsigned>(exp_length);
char last = content[temp_pos];
std::string object;
while (!endOfCall(last, true)) {
object = last + object;
last = content[--temp_pos];
}
content = content.erase(temp_pos + 1, object.length() + 1);
content = content.insert(temp_pos + 2 + exp_length, object + (empty_call ? "" : ","));
pos = temp_pos;
state = state_t::eIdle;
}
else
{
expression_name += c;
}
continue;
}
}
}
}
#ifndef INCLUDE_SHADER_SYSTEM_H
#define INCLUDE_SHADER_SYSTEM_H
#include <vector>
namespace glare::core
{
/**
* \brief A kind of helper class for loading shader includes, checking extensions and precompiling shader code.
*/
class ShaderSystem
{
public:
/**
* \brief Loads all shaders from the shader directory and constructs as many named strings.
*/
static void initialize();
/**
* \brief Reformats the code in a suitable way to be compiled. Also checks the extensions used in the source code.
*/
static void precompile(std::string &source);
private:
enum class ExtensionParseState
{
eNone = 0,
eKeyword = 1,
eExtName = 2,
eRequirementCheck = 3,
eRequirementCheckForm = 4
};
enum class ExtensionRequirement
{
eEnabled,
eRequired
};
static void checkExtensions(const std::string &source);
static bool endOfCall(char c, bool backtrace);
static void format(std::string &source);
static std::vector<std::string> m_named_strings;
static std::vector<int> m_named_string_lengths;
};
}
#endif //INCLUDE_SHADER_SYSTEM_H
......@@ -3,18 +3,18 @@
#include <util/opengl.h>
#include <core/numeric/flags.h>
#include <core/base/shader_system.h>
#include "time.h"
namespace glare::core{
Window::Window(unsigned int width, unsigned int height, std::string title) { initialize(width, height, title); }
Window::Window() : m_main_window(nullptr), m_vsync(VSync::eOn60), m_width(0), m_height(0) {
} void Window::initialize(unsigned int width, unsigned int height, std::string title) { m_width = width; m_height = height;
} void Window::initialize(unsigned int width, unsigned int height, std::string title) {
m_width = width; m_height = height;
glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
// To enable some more debug messages and hints glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
// To enable robust buffer access on out-of-bounds accesses. glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, GLFW_NO_RESET_NOTIFICATION);
if (width * height == 0) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
m_main_window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
glfwMakeContextCurrent(m_main_window); glewExperimental = true; glewInit(); ShaderSystem::initialize(); glfwMakeContextCurrent(nullptr); }
glfwMakeContextCurrent(m_main_window); glewExperimental = true; glewInit(); glfwMakeContextCurrent(nullptr); }
void Window::makeCurrent() const
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment