Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2793956be4 | ||
|
|
51c5874318 |
@@ -17,16 +17,16 @@
|
||||
#include "inferno/event/keyevent.h"
|
||||
#include "inferno/event/mouseevent.h"
|
||||
// #include "inferno/io/gltffile.h"
|
||||
#include "inferno/asset/font.h"
|
||||
#include "inferno/io/input.h"
|
||||
#include "inferno/keycodes.h"
|
||||
#include "inferno/render/buffer.h"
|
||||
#include "inferno/render/context.h"
|
||||
#include "inferno/render/font.h"
|
||||
// #include "inferno/render/gltf.h"
|
||||
#include "inferno/asset/shader.h"
|
||||
#include "inferno/asset/texture.h"
|
||||
#include "inferno/render/render-command.h"
|
||||
#include "inferno/render/renderer.h"
|
||||
#include "inferno/render/shader.h"
|
||||
#include "inferno/render/texture.h"
|
||||
#include "inferno/scene/scene.h"
|
||||
#include "inferno/settings.h"
|
||||
#include "inferno/time.h"
|
||||
@@ -78,13 +78,11 @@ Application::~Application()
|
||||
{
|
||||
m_scene->destroy();
|
||||
|
||||
FontManager::destroy();
|
||||
RendererFont::destroy();
|
||||
Renderer2D::destroy();
|
||||
RendererCubemap::destroy();
|
||||
RenderCommand::destroy();
|
||||
TextureManager::destroy();
|
||||
ShaderManager::destroy();
|
||||
AssetManager::destroy();
|
||||
// Input::destroy();
|
||||
|
||||
Settings::destroy();
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Riyyi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <memory> // std::shared_ptr, std::static_pointer_cast
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "ruc/format/log.h"
|
||||
|
||||
#include "inferno/asset/asset-manager.h"
|
||||
#include "inferno/asset/shader.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
AssetManager::AssetManager(s)
|
||||
{
|
||||
ruc::info("AssetManager initialized");
|
||||
}
|
||||
|
||||
AssetManager::~AssetManager()
|
||||
{
|
||||
}
|
||||
|
||||
void AssetManager::add(std::string_view path, std::shared_ptr<Asset> asset)
|
||||
{
|
||||
// Construct (key, value) pair and insert it into the unordered_map
|
||||
auto stringPath = std::string(path.begin(), path.end());
|
||||
m_assetList.emplace(std::move(stringPath), std::move(asset));
|
||||
}
|
||||
|
||||
bool AssetManager::exists(std::string_view path)
|
||||
{
|
||||
return m_assetList.find(path.data()) != m_assetList.end();
|
||||
}
|
||||
|
||||
void AssetManager::remove(std::string_view path)
|
||||
{
|
||||
if (exists(path)) {
|
||||
m_assetList.erase(path.data());
|
||||
}
|
||||
}
|
||||
|
||||
void AssetManager::remove(std::shared_ptr<Asset> asset)
|
||||
{
|
||||
if (exists(asset->path())) {
|
||||
m_assetList.erase(asset->path());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Inferno
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Riyyi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "ruc/meta/assert.h"
|
||||
#include "ruc/meta/types.h"
|
||||
#include "ruc/singleton.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
class Asset {
|
||||
public:
|
||||
virtual ~Asset() = default;
|
||||
|
||||
std::string path() const { return m_path; }
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
std::string className() const { return typeid(*this).name(); }
|
||||
|
||||
template<typename T>
|
||||
bool fastIs() const = delete;
|
||||
|
||||
virtual bool isFont() const { return false; }
|
||||
virtual bool isShader() const { return false; }
|
||||
virtual bool isTexture() const { return false; }
|
||||
virtual bool isTexture2D() const { return false; }
|
||||
virtual bool isTextureCubemap() const { return false; }
|
||||
|
||||
protected:
|
||||
Asset(std::string_view path)
|
||||
: m_path(std::string(path.begin(), path.end()))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string m_path;
|
||||
};
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
template<typename T>
|
||||
concept IsAsset = std::same_as<Asset, T> || std::derived_from<T, Asset>;
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
class AssetManager : public ruc::Singleton<AssetManager> {
|
||||
public:
|
||||
AssetManager(s);
|
||||
virtual ~AssetManager();
|
||||
|
||||
void add(std::string_view path, std::shared_ptr<Asset> asset);
|
||||
bool exists(std::string_view path);
|
||||
void remove(std::string_view path);
|
||||
void remove(std::shared_ptr<Asset> asset);
|
||||
|
||||
template<IsAsset T>
|
||||
std::shared_ptr<T> get(std::string_view path)
|
||||
{
|
||||
if (!exists(path)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto asset = m_assetList.at(path.data());
|
||||
VERIFY(is<T>(asset.get()), "expected asset {}, got {}", typeid(T).name(), asset->className());
|
||||
return std::static_pointer_cast<T>(asset);
|
||||
}
|
||||
|
||||
template<IsAsset T>
|
||||
std::shared_ptr<T> load(std::string_view path)
|
||||
{
|
||||
if (exists(path)) {
|
||||
return get<T>(path);
|
||||
}
|
||||
|
||||
auto asset = T::create(path);
|
||||
add(path, asset);
|
||||
return asset;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<Asset>> m_assetList;
|
||||
};
|
||||
|
||||
} // namespace Inferno
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Riyyi
|
||||
* Copyright (C) 2022-2024 Riyyi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
@@ -7,32 +7,32 @@
|
||||
#include <array> // std::array
|
||||
#include <charconv> // std;:from_chars
|
||||
#include <cstdint> // int32_t, uint32_t
|
||||
#include <limits> // std::numeric_limits
|
||||
#include <ranges> // std::views::split
|
||||
#include <string> // std::getline
|
||||
#include <utility> // std::move
|
||||
|
||||
#include "ruc/file.h"
|
||||
#include "ruc/format/log.h"
|
||||
#include "ruc/meta/assert.h"
|
||||
#include "ruc/meta/concepts.h"
|
||||
|
||||
#include "inferno/render/font.h"
|
||||
#include "inferno/render/texture.h"
|
||||
#include "inferno/util/integer.h"
|
||||
#include "inferno/asset/font.h"
|
||||
#include "inferno/asset/texture.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
Font::Font(const std::string& name)
|
||||
: m_name(std::move(name))
|
||||
std::shared_ptr<Font> Font::create(std::string_view path)
|
||||
{
|
||||
std::string path = name + ".fnt";
|
||||
std::string image = name + ".png";
|
||||
auto result = std::shared_ptr<Font>(new Font(path));
|
||||
|
||||
std::string font = ruc::File(path).data();
|
||||
parseFont(font);
|
||||
auto stringPath = std::string(path);
|
||||
std::string file = stringPath + ".fnt";
|
||||
std::string image = stringPath + ".png";
|
||||
|
||||
m_texture = Texture2D::create(image);
|
||||
std::string font = ruc::File(file).data();
|
||||
result->parseFont(font);
|
||||
|
||||
result->m_texture = Texture2D::create(image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: Move this to ruc
|
||||
@@ -167,58 +167,6 @@ std::string Font::findValue(const std::string& key, const std::vector<std::strin
|
||||
return "";
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
FontManager::FontManager(s)
|
||||
{
|
||||
ruc::info("FontManager initialized");
|
||||
}
|
||||
|
||||
FontManager::~FontManager()
|
||||
{
|
||||
}
|
||||
|
||||
void FontManager::add(const std::string& name, std::shared_ptr<Font> font)
|
||||
{
|
||||
// Construct (key, value) pair and insert it into the unordered_map
|
||||
m_fontList.emplace(std::move(name), std::move(font));
|
||||
}
|
||||
|
||||
std::shared_ptr<Font> FontManager::load(const std::string& name)
|
||||
{
|
||||
if (exists(name)) {
|
||||
return get(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<Font> font = std::make_shared<Font>(name);
|
||||
add(name, font);
|
||||
return get(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<Font> FontManager::get(const std::string& name)
|
||||
{
|
||||
return exists(name) ? m_fontList.at(name) : nullptr;
|
||||
}
|
||||
|
||||
bool FontManager::exists(const std::string& name)
|
||||
{
|
||||
return m_fontList.find(name) != m_fontList.end();
|
||||
}
|
||||
|
||||
void FontManager::remove(const std::string& name)
|
||||
{
|
||||
if (exists(name)) {
|
||||
m_fontList.erase(name);
|
||||
}
|
||||
}
|
||||
|
||||
void FontManager::remove(std::shared_ptr<Font> font)
|
||||
{
|
||||
if (exists(font->name())) {
|
||||
m_fontList.erase(font->name());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Inferno
|
||||
|
||||
void ruc::format::Formatter<glm::ivec2>::format(Builder& builder, glm::ivec2 value) const
|
||||
@@ -1,22 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Riyyi
|
||||
* Copyright (C) 2022-2024 Riyyi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array> // std::array
|
||||
#include <cstdint> // int32_t, uint32_t
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <string> // std::string
|
||||
#include <array> // std::array
|
||||
#include <cstdint> // int32_t, uint32_t
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <string> // std::string
|
||||
#include <string_view>
|
||||
#include <unordered_map> // std::unordered_map
|
||||
#include <vector> // std::vector
|
||||
|
||||
#include "glm/ext/vector_int2.hpp" // glm::ivec2
|
||||
#include "glm/ext/vector_uint2.hpp" // glm::uvec2
|
||||
#include "ruc/format/format.h"
|
||||
#include "ruc/singleton.h"
|
||||
|
||||
#include "inferno/asset/asset-manager.h"
|
||||
|
||||
#define PADDING 3
|
||||
|
||||
@@ -35,11 +37,13 @@ struct Symbol {
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
class Font {
|
||||
class Font final : public Asset {
|
||||
public:
|
||||
Font(const std::string& name);
|
||||
virtual ~Font() {}
|
||||
|
||||
// Factory function
|
||||
static std::shared_ptr<Font> create(std::string_view path);
|
||||
|
||||
enum Padding {
|
||||
Top = 0,
|
||||
Right,
|
||||
@@ -47,7 +51,6 @@ public:
|
||||
Left,
|
||||
};
|
||||
|
||||
inline std::string name() const { return m_name; }
|
||||
inline uint32_t size() const { return m_size; }
|
||||
inline uint32_t lineSpacing() const { return m_lineSpacing; }
|
||||
inline std::shared_ptr<Texture> texture() const { return m_texture; }
|
||||
@@ -56,12 +59,19 @@ public:
|
||||
inline std::shared_ptr<Symbol> operator[](unsigned char c) const { return m_symbolList.at(c); }
|
||||
|
||||
private:
|
||||
Font(std::string_view path)
|
||||
: Asset(path)
|
||||
{
|
||||
}
|
||||
|
||||
void parseFont(const std::string& font);
|
||||
std::string findAction(const std::string& line) const;
|
||||
std::vector<std::string> findColumns(const std::string& line) const;
|
||||
std::string findValue(const std::string& key, const std::vector<std::string>& columns) const;
|
||||
|
||||
std::string m_name;
|
||||
virtual bool isFont() const override { return true; }
|
||||
|
||||
private:
|
||||
unsigned char m_size = { 0 };
|
||||
uint32_t m_lineSpacing = { 0 };
|
||||
std::array<uint32_t, 4> m_padding = { 0 };
|
||||
@@ -69,24 +79,12 @@ private:
|
||||
std::unordered_map<unsigned char, std::shared_ptr<Symbol>> m_symbolList;
|
||||
};
|
||||
|
||||
// -------------------------------------
|
||||
// -----------------------------------------
|
||||
|
||||
class FontManager final : public ruc::Singleton<FontManager> {
|
||||
public:
|
||||
FontManager(s);
|
||||
virtual ~FontManager();
|
||||
|
||||
void add(const std::string& name, std::shared_ptr<Font> font);
|
||||
std::shared_ptr<Font> load(const std::string& name);
|
||||
std::shared_ptr<Font> get(const std::string& name);
|
||||
bool exists(const std::string& name);
|
||||
|
||||
void remove(const std::string& name);
|
||||
void remove(std::shared_ptr<Font> font);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<Font>> m_fontList;
|
||||
};
|
||||
// clang-format off
|
||||
template<>
|
||||
inline bool Asset::fastIs<Font>() const { return isFont(); }
|
||||
// clang-format on
|
||||
|
||||
} // namespace Inferno
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Riyyi
|
||||
* Copyright (C) 2022,2024 Riyyi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <utility> // std::move
|
||||
#include <vector> // std::vector
|
||||
#include <vector> // std::vector
|
||||
|
||||
#include "glad/glad.h"
|
||||
#include "glm/gtc/type_ptr.hpp" // glm::value_ptr
|
||||
@@ -13,32 +12,34 @@
|
||||
#include "ruc/format/log.h"
|
||||
#include "ruc/meta/assert.h"
|
||||
|
||||
#include "inferno/core.h"
|
||||
#include "inferno/render/shader.h"
|
||||
#include "inferno/asset/shader.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
Shader::Shader(const std::string& name)
|
||||
: m_name(std::move(name))
|
||||
, m_id(0)
|
||||
std::shared_ptr<Shader> Shader::create(std::string_view path)
|
||||
{
|
||||
auto result = std::shared_ptr<Shader>(new Shader(path));
|
||||
|
||||
// Get file contents
|
||||
std::string vertexSrc = ruc::File(name + ".vert").data();
|
||||
std::string fragmentSrc = ruc::File(name + ".frag").data();
|
||||
auto stringPath = std::string(path);
|
||||
std::string vertexSrc = ruc::File(stringPath + ".vert").data();
|
||||
std::string fragmentSrc = ruc::File(stringPath + ".frag").data();
|
||||
|
||||
// Compile shaders
|
||||
uint32_t vertexID = compileShader(GL_VERTEX_SHADER, vertexSrc.c_str());
|
||||
uint32_t fragmentID = compileShader(GL_FRAGMENT_SHADER, fragmentSrc.c_str());
|
||||
uint32_t vertexID = result->compileShader(GL_VERTEX_SHADER, vertexSrc.c_str());
|
||||
uint32_t fragmentID = result->compileShader(GL_FRAGMENT_SHADER, fragmentSrc.c_str());
|
||||
|
||||
// Link shaders
|
||||
if (vertexID > 0 && fragmentID > 0) {
|
||||
m_id = linkShader(vertexID, fragmentID);
|
||||
result->m_id = result->linkShader(vertexID, fragmentID);
|
||||
}
|
||||
// Clear resources
|
||||
else if (vertexID > 0)
|
||||
glDeleteShader(vertexID);
|
||||
else if (fragmentID > 0)
|
||||
glDeleteShader(fragmentID);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
@@ -49,62 +50,62 @@ Shader::~Shader()
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Shader::findUniform(const std::string& name) const
|
||||
int32_t Shader::findUniform(std::string_view name) const
|
||||
{
|
||||
int32_t location = glGetUniformLocation(m_id, name.c_str());
|
||||
int32_t location = glGetUniformLocation(m_id, name.data());
|
||||
VERIFY(location != -1, "Shader could not find uniform '{}'", name);
|
||||
return location;
|
||||
}
|
||||
|
||||
void Shader::setInt(const std::string& name, int value)
|
||||
void Shader::setInt(std::string_view name, int value)
|
||||
{
|
||||
// Set uniform int
|
||||
glUniform1i(findUniform(name), value);
|
||||
}
|
||||
|
||||
void Shader::setInt(const std::string& name, int* values, uint32_t count)
|
||||
void Shader::setInt(std::string_view name, int* values, uint32_t count)
|
||||
{
|
||||
// Set uniform int array
|
||||
glUniform1iv(findUniform(name), count, values);
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string& name, float value) const
|
||||
void Shader::setFloat(std::string_view name, float value) const
|
||||
{
|
||||
// Set uniform float
|
||||
glUniform1f(findUniform(name), value);
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string& name, float v1, float v2, float v3, float v4) const
|
||||
void Shader::setFloat(std::string_view name, float v1, float v2, float v3, float v4) const
|
||||
{
|
||||
// Set uniform vec4 data
|
||||
glUniform4f(findUniform(name), v1, v2, v3, v4);
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string& name, glm::vec2 value) const
|
||||
void Shader::setFloat(std::string_view name, glm::vec2 value) const
|
||||
{
|
||||
// Set uniform vec2 data
|
||||
glUniform2f(findUniform(name), value.x, value.y);
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string& name, glm::vec3 value) const
|
||||
void Shader::setFloat(std::string_view name, glm::vec3 value) const
|
||||
{
|
||||
// Set uniform vec3 data
|
||||
glUniform3f(findUniform(name), value.x, value.y, value.z);
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string& name, glm::vec4 value) const
|
||||
void Shader::setFloat(std::string_view name, glm::vec4 value) const
|
||||
{
|
||||
// Set uniform vec4 data
|
||||
glUniform4f(findUniform(name), value.x, value.y, value.z, value.w);
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string& name, glm::mat3 matrix) const
|
||||
void Shader::setFloat(std::string_view name, glm::mat3 matrix) const
|
||||
{
|
||||
// Set uniform mat3 data
|
||||
glUniformMatrix3fv(findUniform(name), 1, GL_FALSE, glm::value_ptr(matrix));
|
||||
}
|
||||
|
||||
void Shader::setFloat(const std::string& name, glm::mat4 matrix) const
|
||||
void Shader::setFloat(std::string_view name, glm::mat4 matrix) const
|
||||
{
|
||||
// Set uniform mat4 data
|
||||
glUniformMatrix4fv(findUniform(name), 1, GL_FALSE, glm::value_ptr(matrix));
|
||||
@@ -199,80 +200,4 @@ int32_t Shader::checkStatus(uint32_t check, bool isProgram) const
|
||||
return success;
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
ShaderManager::ShaderManager(s)
|
||||
{
|
||||
ruc::info("ShaderManager initialized");
|
||||
}
|
||||
|
||||
ShaderManager::~ShaderManager()
|
||||
{
|
||||
}
|
||||
|
||||
void ShaderManager::add(const std::string& name, std::shared_ptr<Shader> shader)
|
||||
{
|
||||
// Construct (key, value) pair and insert it into the unordered_map
|
||||
m_shaderList.emplace(std::move(name), std::move(shader));
|
||||
}
|
||||
|
||||
std::shared_ptr<Shader> ShaderManager::load(const std::string& name)
|
||||
{
|
||||
if (exists(name)) {
|
||||
return get(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<Shader> shader = std::make_shared<Shader>(name);
|
||||
add(name, shader);
|
||||
return get(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<Shader> ShaderManager::load(const std::string& vertexSource,
|
||||
const std::string& fragmentSource)
|
||||
{
|
||||
std::string name = computeName(vertexSource, fragmentSource);
|
||||
return load(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<Shader> ShaderManager::get(const std::string& name)
|
||||
{
|
||||
return exists(name) ? m_shaderList.at(name) : nullptr;
|
||||
}
|
||||
|
||||
bool ShaderManager::exists(const std::string& name)
|
||||
{
|
||||
return m_shaderList.find(name) != m_shaderList.end();
|
||||
}
|
||||
|
||||
void ShaderManager::remove(const std::string& name)
|
||||
{
|
||||
if (exists(name)) {
|
||||
m_shaderList.erase(name);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManager::remove(std::shared_ptr<Shader> shader)
|
||||
{
|
||||
if (exists(shader->name())) {
|
||||
m_shaderList.erase(shader->name());
|
||||
}
|
||||
}
|
||||
|
||||
std::string ShaderManager::computeName(const std::string& vertexSource,
|
||||
const std::string& fragmentSource)
|
||||
{
|
||||
auto vertexPos = vertexSource.find_last_of('.');
|
||||
auto fragmentPos = fragmentSource.find_last_of('.');
|
||||
|
||||
VERIFY(vertexPos != std::string::npos, "Shader did not have file extension: '{}'", vertexSource);
|
||||
VERIFY(fragmentPos != std::string::npos, "Shader did not have file extension: '{}'", fragmentSource);
|
||||
|
||||
auto vertexName = vertexSource.substr(0, vertexPos);
|
||||
auto fragmentName = vertexSource.substr(0, fragmentPos);
|
||||
|
||||
VERIFY(vertexName == fragmentName, "Shader names did not match: {} {}", vertexSource, fragmentSource);
|
||||
|
||||
return vertexName;
|
||||
}
|
||||
|
||||
} // namespace Inferno
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2022,2024 Riyyi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <cstdint> // int32_t, uint32_t
|
||||
#include <string_view>
|
||||
|
||||
#include "glm/fwd.hpp" // glm::mat3, glm::mat4, glm::vec2, glm::vec3
|
||||
|
||||
#include "inferno/asset/asset-manager.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
class Shader : public Asset {
|
||||
public:
|
||||
virtual ~Shader();
|
||||
|
||||
// Factory function
|
||||
static std::shared_ptr<Shader> create(std::string_view path);
|
||||
|
||||
int32_t findUniform(std::string_view name) const;
|
||||
|
||||
void setInt(std::string_view name, int value);
|
||||
void setInt(std::string_view name, int* values, uint32_t count);
|
||||
void setFloat(std::string_view name, float value) const;
|
||||
void setFloat(std::string_view name, float v1, float v2, float v3, float v4) const;
|
||||
void setFloat(std::string_view name, glm::vec2 value) const;
|
||||
void setFloat(std::string_view name, glm::vec3 value) const;
|
||||
void setFloat(std::string_view name, glm::vec4 value) const;
|
||||
void setFloat(std::string_view name, glm::mat3 matrix) const;
|
||||
void setFloat(std::string_view name, glm::mat4 matrix) const;
|
||||
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
|
||||
uint32_t id() const { return m_id; }
|
||||
|
||||
protected:
|
||||
uint32_t compileShader(int32_t type, const char* shaderSource) const;
|
||||
uint32_t linkShader(uint32_t vertex, uint32_t fragment) const;
|
||||
int32_t checkStatus(uint32_t check, bool isProgram = false) const;
|
||||
|
||||
private:
|
||||
Shader(std::string_view path)
|
||||
: Asset(path)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool isShader() const override { return true; }
|
||||
|
||||
private:
|
||||
uint32_t m_id { 0 };
|
||||
};
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
// clang-format off
|
||||
template<>
|
||||
inline bool Asset::fastIs<Shader>() const { return isShader(); }
|
||||
// clang-format on
|
||||
|
||||
} // namespace Inferno
|
||||
@@ -7,15 +7,13 @@
|
||||
#include <climits> // UINT_MAX
|
||||
#include <cstdint> // uint8_t, uint32_t
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <utility> // std::move
|
||||
|
||||
#include "glad/glad.h"
|
||||
#include "ruc/format/log.h"
|
||||
#include "ruc/meta/assert.h"
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb/stb_image.h"
|
||||
|
||||
#include "inferno/render/texture.h"
|
||||
#include "inferno/asset/texture.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
@@ -35,10 +33,9 @@ void Texture::init(uint32_t width, uint32_t height, uint8_t channels)
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
std::shared_ptr<Texture> Texture2D::create(const std::string& path)
|
||||
std::shared_ptr<Texture2D> Texture2D::create(std::string_view path)
|
||||
{
|
||||
auto result = std::shared_ptr<Texture2D>(new Texture2D);
|
||||
result->m_path = path;
|
||||
auto result = std::shared_ptr<Texture2D>(new Texture2D(path));
|
||||
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
@@ -47,7 +44,7 @@ std::shared_ptr<Texture> Texture2D::create(const std::string& path)
|
||||
|
||||
// Load image data
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
data = stbi_load(path.c_str(), &width, &height, &channels, STBI_default);
|
||||
data = stbi_load(path.data(), &width, &height, &channels, STBI_default);
|
||||
VERIFY(data, "failed to load image: '{}'", path);
|
||||
|
||||
result->init(width, height, channels);
|
||||
@@ -115,10 +112,9 @@ void Texture2D::create(unsigned char* data)
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
std::shared_ptr<Texture> TextureCubemap::create(const std::string& path)
|
||||
std::shared_ptr<TextureCubemap> TextureCubemap::create(std::string_view path)
|
||||
{
|
||||
auto result = std::shared_ptr<TextureCubemap>(new TextureCubemap);
|
||||
result->m_path = path;
|
||||
auto result = std::shared_ptr<TextureCubemap>(new TextureCubemap(path));
|
||||
|
||||
result->create();
|
||||
|
||||
@@ -201,57 +197,7 @@ void TextureCubemap::create()
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
TextureManager::TextureManager(s)
|
||||
{
|
||||
ruc::info("TextureManager initialized");
|
||||
}
|
||||
|
||||
TextureManager::~TextureManager()
|
||||
{
|
||||
}
|
||||
|
||||
void TextureManager::add(const std::string& path, std::shared_ptr<Texture> texture)
|
||||
{
|
||||
// Construct (key, value) pair and insert it into the unordered_map
|
||||
m_textureList.emplace(std::move(path), std::move(texture));
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> TextureManager::load(const std::string& path, Texture::Type type)
|
||||
{
|
||||
if (exists(path)) {
|
||||
return get(path);
|
||||
}
|
||||
|
||||
auto texture = (type == Texture::TwoDimensional) ? Texture2D::create(path) : TextureCubemap::create(path);
|
||||
add(path, texture);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> TextureManager::get(const std::string& path)
|
||||
{
|
||||
return exists(path) ? m_textureList.at(path) : nullptr;
|
||||
}
|
||||
|
||||
bool TextureManager::exists(const std::string& path)
|
||||
{
|
||||
return m_textureList.find(path) != m_textureList.end();
|
||||
}
|
||||
|
||||
void TextureManager::remove(const std::string& path)
|
||||
{
|
||||
if (exists(path)) {
|
||||
m_textureList.erase(path);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureManager::remove(std::shared_ptr<Texture> texture)
|
||||
{
|
||||
if (exists(texture->path())) {
|
||||
m_textureList.erase(texture->path());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Inferno
|
||||
|
||||
// FIXME
|
||||
// auto texture = (type == Texture::TwoDimensional) ? Texture2D::create(path) : TextureCubemap::create(path);
|
||||
@@ -6,33 +6,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint> // uint8_t, uint32_t
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <string> // std::string
|
||||
#include <unordered_map> // std::unordered_map
|
||||
#include <cstdint> // uint8_t, uint32_t
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <string_view>
|
||||
|
||||
#include "ruc/singleton.h"
|
||||
#include "inferno/asset/asset-manager.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
class Texture2D;
|
||||
class TextureCubemap;
|
||||
|
||||
class Texture {
|
||||
class Texture : public Asset {
|
||||
public:
|
||||
virtual ~Texture();
|
||||
|
||||
enum Type : uint8_t {
|
||||
TwoDimensional = 0,
|
||||
Cubemap,
|
||||
};
|
||||
|
||||
void init(uint32_t width, uint32_t height, uint8_t channels);
|
||||
|
||||
virtual void bind(uint32_t unit = 0) const = 0;
|
||||
virtual void unbind() const = 0;
|
||||
|
||||
std::string path() const { return m_path; }
|
||||
uint32_t width() const { return m_width; }
|
||||
uint32_t height() const { return m_height; }
|
||||
uint32_t id() const { return m_id; }
|
||||
@@ -40,21 +33,26 @@ public:
|
||||
uint32_t dataFormat() const { return m_dataFormat; }
|
||||
|
||||
virtual bool is2D() const { return false; }
|
||||
virtual bool isCubeMap() const { return false; }
|
||||
virtual bool isCubemap() const { return false; }
|
||||
|
||||
friend Texture2D;
|
||||
friend TextureCubemap;
|
||||
|
||||
protected:
|
||||
Texture() {}
|
||||
Texture(std::string_view path)
|
||||
: Asset(path)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string m_path;
|
||||
uint32_t m_width { 0 };
|
||||
uint32_t m_height { 0 };
|
||||
uint32_t m_id { 0 };
|
||||
uint32_t m_internalFormat { 0 };
|
||||
uint32_t m_dataFormat { 0 };
|
||||
|
||||
private:
|
||||
virtual bool isTexture() const override { return true; }
|
||||
};
|
||||
|
||||
// -------------------------------------
|
||||
@@ -64,15 +62,18 @@ public:
|
||||
virtual ~Texture2D() = default;
|
||||
|
||||
// Factory function
|
||||
static std::shared_ptr<Texture> create(const std::string& path);
|
||||
static std::shared_ptr<Texture2D> create(std::string_view path);
|
||||
|
||||
virtual void bind(uint32_t unit = 0) const override;
|
||||
virtual void unbind() const override;
|
||||
|
||||
private:
|
||||
Texture2D() {}
|
||||
Texture2D(std::string_view path)
|
||||
: Texture(path)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool is2D() const override { return true; }
|
||||
virtual bool isTexture2D() const override { return true; }
|
||||
|
||||
private:
|
||||
void create(unsigned char* data);
|
||||
@@ -85,37 +86,34 @@ public:
|
||||
virtual ~TextureCubemap() = default;
|
||||
|
||||
// Factory function
|
||||
static std::shared_ptr<Texture> create(const std::string& path);
|
||||
static std::shared_ptr<TextureCubemap> create(std::string_view path);
|
||||
|
||||
virtual void bind(uint32_t unit = 0) const override;
|
||||
virtual void unbind() const override;
|
||||
|
||||
private:
|
||||
TextureCubemap() {};
|
||||
TextureCubemap(std::string_view path)
|
||||
: Texture(path)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool isCubeMap() const override { return true; }
|
||||
virtual bool isTextureCubemap() const override { return true; }
|
||||
|
||||
private:
|
||||
void create();
|
||||
};
|
||||
|
||||
// -------------------------------------
|
||||
// -----------------------------------------
|
||||
|
||||
class TextureManager final : public ruc::Singleton<TextureManager> {
|
||||
public:
|
||||
TextureManager(s);
|
||||
~TextureManager();
|
||||
// clang-format off
|
||||
template<>
|
||||
inline bool Asset::fastIs<Texture>() const { return isTexture(); }
|
||||
|
||||
void add(const std::string& path, std::shared_ptr<Texture> texture);
|
||||
std::shared_ptr<Texture> load(const std::string& path, Texture::Type type = Texture::Type::TwoDimensional);
|
||||
std::shared_ptr<Texture> get(const std::string& path);
|
||||
bool exists(const std::string& path);
|
||||
template<>
|
||||
inline bool Asset::fastIs<Texture2D>() const { return isTexture2D(); }
|
||||
|
||||
void remove(const std::string& path);
|
||||
void remove(std::shared_ptr<Texture> texture);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<Texture>> m_textureList;
|
||||
};
|
||||
template<>
|
||||
inline bool Asset::fastIs<TextureCubemap>() const { return isTextureCubemap(); }
|
||||
// clang-format on
|
||||
|
||||
} // namespace Inferno
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
#include "ruc/json/json.h"
|
||||
|
||||
#include "inferno/asset/texture.h"
|
||||
#include "inferno/component/cubemap-component.h"
|
||||
#include "inferno/component/spritecomponent.h" // TODO: Move glm::x toJson/fromJson to separate file
|
||||
#include "inferno/render/texture.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
@@ -20,7 +20,7 @@ void fromJson(const ruc::Json& json, CubemapComponent& value)
|
||||
json.at("color").getTo(value.color);
|
||||
}
|
||||
if (json.exists("texture") && json.at("texture").type() == ruc::Json::Type::String) {
|
||||
value.texture = TextureManager::the().load(json.at("texture").asString(), Texture::Type::Cubemap);
|
||||
value.texture = AssetManager::the().load<TextureCubemap>(json.at("texture").asString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "glm/ext/vector_float4.hpp" // glm::vec4
|
||||
#include "ruc/json/json.h"
|
||||
|
||||
#include "inferno/render/texture.h"
|
||||
#include "inferno/asset/texture.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
*/
|
||||
|
||||
#include "inferno/component/spritecomponent.h"
|
||||
#include "inferno/render/texture.h"
|
||||
#include "inferno/asset/asset-manager.h"
|
||||
#include "inferno/asset/texture.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
@@ -17,7 +18,7 @@ void fromJson(const ruc::Json& json, SpriteComponent& value)
|
||||
json.at("color").getTo(value.color);
|
||||
}
|
||||
if (json.exists("texture") && json.at("texture").type() == ruc::Json::Type::String) {
|
||||
value.texture = TextureManager::the().load(json.at("texture").asString());
|
||||
value.texture = AssetManager::the().load<Texture2D>(json.at("texture").asString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "glm/ext/vector_float4.hpp" // glm::vec4
|
||||
#include "ruc/json/json.h"
|
||||
|
||||
#include "inferno/render/texture.h"
|
||||
#include "inferno/asset/texture.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
#include "glad/glad.h"
|
||||
#include "ruc/format/log.h"
|
||||
|
||||
#include "inferno/asset/asset-manager.h"
|
||||
#include "inferno/asset/shader.h"
|
||||
#include "inferno/asset/texture.h"
|
||||
#include "inferno/component/transformcomponent.h"
|
||||
#include "inferno/render/buffer.h"
|
||||
#include "inferno/render/render-command.h"
|
||||
#include "inferno/render/renderer.h"
|
||||
#include "inferno/render/shader.h"
|
||||
#include "inferno/render/texture.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
@@ -271,7 +272,7 @@ void Renderer2D::drawQuad(const TransformComponent& transform, glm::mat4 color,
|
||||
|
||||
void Renderer2D::loadShader()
|
||||
{
|
||||
m_shader = ShaderManager::the().load("assets/glsl/batch-quad");
|
||||
m_shader = AssetManager::the().load<Shader>("assets/glsl/batch-quad");
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
@@ -384,7 +385,7 @@ void RendererCubemap::drawCubemap(const TransformComponent& transform, glm::mat4
|
||||
|
||||
void RendererCubemap::loadShader()
|
||||
{
|
||||
m_shader = ShaderManager::the().load("assets/glsl/batch-cubemap");
|
||||
m_shader = AssetManager::the().load<Shader>("assets/glsl/batch-cubemap");
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
@@ -455,7 +456,7 @@ void RendererFont::drawSymbol(std::array<SymbolVertex, vertexPerQuad>& symbolQua
|
||||
|
||||
void RendererFont::loadShader()
|
||||
{
|
||||
m_shader = ShaderManager::the().load("assets/glsl/batch-font");
|
||||
m_shader = AssetManager::the().load<Shader>("assets/glsl/batch-font");
|
||||
}
|
||||
|
||||
} // namespace Inferno
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Riyyi
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint> // int32_t, uint32_t
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <string> // std::string
|
||||
#include <unordered_map> // std::unordered_map
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "ruc/singleton.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
Shader(const std::string& name);
|
||||
virtual ~Shader();
|
||||
|
||||
int32_t findUniform(const std::string& name) const;
|
||||
|
||||
void setInt(const std::string& name, int value);
|
||||
void setInt(const std::string& name, int* values, uint32_t count);
|
||||
void setFloat(const std::string& name, float value) const;
|
||||
void setFloat(const std::string& name, float v1, float v2, float v3, float v4) const;
|
||||
void setFloat(const std::string& name, glm::vec2 value) const;
|
||||
void setFloat(const std::string& name, glm::vec3 value) const;
|
||||
void setFloat(const std::string& name, glm::vec4 value) const;
|
||||
void setFloat(const std::string& name, glm::mat3 matrix) const;
|
||||
void setFloat(const std::string& name, glm::mat4 matrix) const;
|
||||
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
|
||||
inline std::string name() const { return m_name; }
|
||||
inline uint32_t id() const { return m_id; }
|
||||
|
||||
protected:
|
||||
uint32_t compileShader(int32_t type, const char* shaderSource) const;
|
||||
uint32_t linkShader(uint32_t vertex, uint32_t fragment) const;
|
||||
int32_t checkStatus(uint32_t check, bool isProgram = false) const;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
uint32_t m_id;
|
||||
};
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
class ShaderManager final : public ruc::Singleton<ShaderManager> {
|
||||
public:
|
||||
ShaderManager(s);
|
||||
virtual ~ShaderManager();
|
||||
|
||||
void add(const std::string& name, std::shared_ptr<Shader> shader);
|
||||
std::shared_ptr<Shader> load(const std::string& name);
|
||||
std::shared_ptr<Shader> load(const std::string& vertexSource,
|
||||
const std::string& fragmentSource);
|
||||
std::shared_ptr<Shader> get(const std::string& name);
|
||||
bool exists(const std::string& name);
|
||||
|
||||
void remove(const std::string& name);
|
||||
void remove(std::shared_ptr<Shader> shader);
|
||||
|
||||
protected:
|
||||
std::string computeName(const std::string& vertexSource,
|
||||
const std::string& fragmentSource);
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::shared_ptr<Shader>> m_shaderList;
|
||||
};
|
||||
|
||||
} // namespace Inferno
|
||||
@@ -4,17 +4,15 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <algorithm> // std::max
|
||||
|
||||
#include "ruc/format/log.h"
|
||||
#include "ruc/meta/assert.h"
|
||||
|
||||
#include "inferno/application.h"
|
||||
#include "inferno/asset/font.h"
|
||||
#include "inferno/asset/texture.h"
|
||||
#include "inferno/component/textareacomponent.h"
|
||||
#include "inferno/component/transformcomponent.h"
|
||||
#include "inferno/render/font.h"
|
||||
#include "inferno/render/renderer.h"
|
||||
#include "inferno/render/texture.h"
|
||||
#include "inferno/scene/scene.h"
|
||||
#include "inferno/system/textareasystem.h"
|
||||
#include "inferno/window.h"
|
||||
@@ -46,7 +44,7 @@ void TextAreaSystem::render()
|
||||
// Calculate symbol quad
|
||||
// Submit symbol quad for rendering
|
||||
|
||||
std::shared_ptr<Font> font = FontManager::the().load(textarea.font);
|
||||
std::shared_ptr<Font> font = AssetManager::the().load<Font>(textarea.font);
|
||||
// glm::mat4 translate = transform.translate;
|
||||
|
||||
m_symbols.clear();
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint> // std::uint32_t
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <optional> // std::optional
|
||||
#include <vector> // std::vector
|
||||
|
||||
#include "glm/ext/vector_float3.hpp" // glm::vec3
|
||||
#include "ruc/singleton.h"
|
||||
|
||||
#include "inferno/render/font.h"
|
||||
#include "inferno/asset/font.h"
|
||||
#include "inferno/render/renderer.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
Vendored
+63
@@ -0,0 +1,63 @@
|
||||
The glad source code:
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2022 David Herberth
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
The Khronos Specifications:
|
||||
|
||||
Copyright (c) 2013-2020 The Khronos Group Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
The EGL Specification and various headers:
|
||||
|
||||
Copyright (c) 2007-2016 The Khronos Group Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and/or associated documentation files (the
|
||||
"Materials"), to deal in the Materials without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
permit persons to whom the Materials are furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Materials.
|
||||
|
||||
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
Vendored
+1
-1
Submodule vendor/ruc updated: 07c9f9959d...8520952235
Reference in New Issue
Block a user