Merge pull request #254 from MihailRis/model-batch
add models and ModelBatch + Assets refactor
This commit is contained in:
@@ -1,72 +1,8 @@
|
|||||||
#include "Assets.hpp"
|
#include "Assets.hpp"
|
||||||
|
|
||||||
#include "../audio/audio.hpp"
|
|
||||||
#include "../graphics/core/Texture.hpp"
|
|
||||||
#include "../graphics/core/Shader.hpp"
|
|
||||||
#include "../graphics/core/Atlas.hpp"
|
|
||||||
#include "../graphics/core/Font.hpp"
|
|
||||||
#include "../frontend/UiDocument.hpp"
|
|
||||||
#include "../logic/scripting/scripting.hpp"
|
|
||||||
|
|
||||||
Assets::~Assets() {
|
Assets::~Assets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture* Assets::getTexture(const std::string& name) const {
|
|
||||||
auto found = textures.find(name);
|
|
||||||
if (found == textures.end())
|
|
||||||
return nullptr;
|
|
||||||
return found->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assets::store(std::unique_ptr<Texture> texture, const std::string& name){
|
|
||||||
textures.emplace(name, std::move(texture));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Shader* Assets::getShader(const std::string& name) const{
|
|
||||||
auto found = shaders.find(name);
|
|
||||||
if (found == shaders.end())
|
|
||||||
return nullptr;
|
|
||||||
return found->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assets::store(std::unique_ptr<Shader> shader, const std::string& name){
|
|
||||||
shaders.emplace(name, std::move(shader));
|
|
||||||
}
|
|
||||||
|
|
||||||
Font* Assets::getFont(const std::string& name) const {
|
|
||||||
auto found = fonts.find(name);
|
|
||||||
if (found == fonts.end())
|
|
||||||
return nullptr;
|
|
||||||
return found->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assets::store(std::unique_ptr<Font> font, const std::string& name){
|
|
||||||
fonts.emplace(name, std::move(font));
|
|
||||||
}
|
|
||||||
|
|
||||||
Atlas* Assets::getAtlas(const std::string& name) const {
|
|
||||||
auto found = atlases.find(name);
|
|
||||||
if (found == atlases.end())
|
|
||||||
return nullptr;
|
|
||||||
return found->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assets::store(std::unique_ptr<Atlas> atlas, const std::string& name){
|
|
||||||
atlases.emplace(name, std::move(atlas));
|
|
||||||
}
|
|
||||||
|
|
||||||
audio::Sound* Assets::getSound(const std::string& name) const {
|
|
||||||
auto found = sounds.find(name);
|
|
||||||
if (found == sounds.end())
|
|
||||||
return nullptr;
|
|
||||||
return found->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assets::store(std::unique_ptr<audio::Sound> sound, const std::string& name) {
|
|
||||||
sounds.emplace(name, std::move(sound));
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<TextureAnimation>& Assets::getAnimations() {
|
const std::vector<TextureAnimation>& Assets::getAnimations() {
|
||||||
return animations;
|
return animations;
|
||||||
}
|
}
|
||||||
@@ -74,14 +10,3 @@ const std::vector<TextureAnimation>& Assets::getAnimations() {
|
|||||||
void Assets::store(const TextureAnimation& animation) {
|
void Assets::store(const TextureAnimation& animation) {
|
||||||
animations.emplace_back(animation);
|
animations.emplace_back(animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
UiDocument* Assets::getLayout(const std::string& name) const {
|
|
||||||
auto found = layouts.find(name);
|
|
||||||
if (found == layouts.end())
|
|
||||||
return nullptr;
|
|
||||||
return found->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assets::store(std::unique_ptr<UiDocument> layout, const std::string& name) {
|
|
||||||
layouts[name] = std::shared_ptr<UiDocument>(std::move(layout));
|
|
||||||
}
|
|
||||||
|
|||||||
+23
-32
@@ -7,18 +7,11 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <typeinfo>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class Texture;
|
|
||||||
class Shader;
|
|
||||||
class Font;
|
|
||||||
class Atlas;
|
|
||||||
class Assets;
|
class Assets;
|
||||||
class UiDocument;
|
|
||||||
|
|
||||||
namespace audio {
|
|
||||||
class Sound;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace assetload {
|
namespace assetload {
|
||||||
/// @brief final work to do in the main thread
|
/// @brief final work to do in the main thread
|
||||||
@@ -26,38 +19,36 @@ namespace assetload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Assets {
|
class Assets {
|
||||||
std::unordered_map<std::string, std::shared_ptr<Texture>> textures;
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<Shader>> shaders;
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<Font>> fonts;
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<Atlas>> atlases;
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<UiDocument>> layouts;
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<audio::Sound>> sounds;
|
|
||||||
std::vector<TextureAnimation> animations;
|
std::vector<TextureAnimation> animations;
|
||||||
|
|
||||||
|
using assets_map = std::unordered_map<std::string, std::shared_ptr<void>>;
|
||||||
|
std::unordered_map<std::type_index, assets_map> assets;
|
||||||
public:
|
public:
|
||||||
Assets() {}
|
Assets() {}
|
||||||
Assets(const Assets&) = delete;
|
Assets(const Assets&) = delete;
|
||||||
~Assets();
|
~Assets();
|
||||||
|
|
||||||
Texture* getTexture(const std::string& name) const;
|
|
||||||
void store(std::unique_ptr<Texture> texture, const std::string& name);
|
|
||||||
|
|
||||||
Shader* getShader(const std::string& name) const;
|
|
||||||
void store(std::unique_ptr<Shader> shader, const std::string& name);
|
|
||||||
|
|
||||||
Font* getFont(const std::string& name) const;
|
|
||||||
void store(std::unique_ptr<Font> font, const std::string& name);
|
|
||||||
|
|
||||||
Atlas* getAtlas(const std::string& name) const;
|
|
||||||
void store(std::unique_ptr<Atlas> atlas, const std::string& name);
|
|
||||||
|
|
||||||
audio::Sound* getSound(const std::string& name) const;
|
|
||||||
void store(std::unique_ptr<audio::Sound> sound, const std::string& name);
|
|
||||||
|
|
||||||
const std::vector<TextureAnimation>& getAnimations();
|
const std::vector<TextureAnimation>& getAnimations();
|
||||||
void store(const TextureAnimation& animation);
|
void store(const TextureAnimation& animation);
|
||||||
|
|
||||||
UiDocument* getLayout(const std::string& name) const;
|
template<class T>
|
||||||
void store(std::unique_ptr<UiDocument> layout, const std::string& name);
|
void store(std::unique_ptr<T> asset, const std::string& name) {
|
||||||
|
assets[typeid(T)][name].reset(asset.release());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T* get(const std::string& name) const {
|
||||||
|
const auto& mapIter = assets.find(typeid(T));
|
||||||
|
if (mapIter == assets.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const auto& map = mapIter->second;
|
||||||
|
const auto& found = map.find(name);
|
||||||
|
if (found == map.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return static_cast<T*>(found->second.get());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ASSETS_ASSETS_HPP_
|
#endif // ASSETS_ASSETS_HPP_
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths)
|
|||||||
addLoader(AssetType::atlas, assetload::atlas);
|
addLoader(AssetType::atlas, assetload::atlas);
|
||||||
addLoader(AssetType::layout, assetload::layout);
|
addLoader(AssetType::layout, assetload::layout);
|
||||||
addLoader(AssetType::sound, assetload::sound);
|
addLoader(AssetType::sound, assetload::sound);
|
||||||
|
addLoader(AssetType::model, assetload::model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetsLoader::addLoader(AssetType tag, aloader_func func) {
|
void AssetsLoader::addLoader(AssetType tag, aloader_func func) {
|
||||||
@@ -99,6 +100,7 @@ static std::string assets_def_folder(AssetType tag) {
|
|||||||
case AssetType::atlas: return TEXTURES_FOLDER;
|
case AssetType::atlas: return TEXTURES_FOLDER;
|
||||||
case AssetType::layout: return LAYOUTS_FOLDER;
|
case AssetType::layout: return LAYOUTS_FOLDER;
|
||||||
case AssetType::sound: return SOUNDS_FOLDER;
|
case AssetType::sound: return SOUNDS_FOLDER;
|
||||||
|
case AssetType::model: return MODELS_FOLDER;
|
||||||
}
|
}
|
||||||
return "<error>";
|
return "<error>";
|
||||||
}
|
}
|
||||||
@@ -155,6 +157,7 @@ void AssetsLoader::processPreloadConfig(const fs::path& file) {
|
|||||||
processPreloadList(AssetType::shader, root->list("shaders"));
|
processPreloadList(AssetType::shader, root->list("shaders"));
|
||||||
processPreloadList(AssetType::texture, root->list("textures"));
|
processPreloadList(AssetType::texture, root->list("textures"));
|
||||||
processPreloadList(AssetType::sound, root->list("sounds"));
|
processPreloadList(AssetType::sound, root->list("sounds"));
|
||||||
|
processPreloadList(AssetType::model, root->list("models"));
|
||||||
// layouts are loaded automatically
|
// layouts are loaded automatically
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +215,7 @@ bool AssetsLoader::loadExternalTexture(
|
|||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::vector<std::filesystem::path>& alternatives
|
const std::vector<std::filesystem::path>& alternatives
|
||||||
) {
|
) {
|
||||||
if (assets->getTexture(name) != nullptr) {
|
if (assets->get<Texture>(name) != nullptr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (auto& path : alternatives) {
|
for (auto& path : alternatives) {
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ enum class AssetType {
|
|||||||
font,
|
font,
|
||||||
atlas,
|
atlas,
|
||||||
layout,
|
layout,
|
||||||
sound
|
sound,
|
||||||
|
model,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResPaths;
|
class ResPaths;
|
||||||
|
|||||||
@@ -9,14 +9,17 @@
|
|||||||
#include "../coders/commons.hpp"
|
#include "../coders/commons.hpp"
|
||||||
#include "../coders/imageio.hpp"
|
#include "../coders/imageio.hpp"
|
||||||
#include "../coders/json.hpp"
|
#include "../coders/json.hpp"
|
||||||
|
#include "../coders/obj.hpp"
|
||||||
#include "../coders/GLSLExtension.hpp"
|
#include "../coders/GLSLExtension.hpp"
|
||||||
#include "../graphics/core/Shader.hpp"
|
#include "../graphics/core/Shader.hpp"
|
||||||
#include "../graphics/core/Texture.hpp"
|
#include "../graphics/core/Texture.hpp"
|
||||||
#include "../graphics/core/ImageData.hpp"
|
#include "../graphics/core/ImageData.hpp"
|
||||||
#include "../graphics/core/Atlas.hpp"
|
#include "../graphics/core/Atlas.hpp"
|
||||||
#include "../graphics/core/Font.hpp"
|
#include "../graphics/core/Font.hpp"
|
||||||
|
#include "../graphics/core/Model.hpp"
|
||||||
#include "../graphics/core/TextureAnimation.hpp"
|
#include "../graphics/core/TextureAnimation.hpp"
|
||||||
#include "../frontend/UiDocument.hpp"
|
#include "../frontend/UiDocument.hpp"
|
||||||
|
#include "../constants.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@@ -119,9 +122,9 @@ assetload::postfunc assetload::font(
|
|||||||
) {
|
) {
|
||||||
auto pages = std::make_shared<std::vector<std::unique_ptr<ImageData>>>();
|
auto pages = std::make_shared<std::vector<std::unique_ptr<ImageData>>>();
|
||||||
for (size_t i = 0; i <= 4; i++) {
|
for (size_t i = 0; i <= 4; i++) {
|
||||||
std::string name = filename + "_" + std::to_string(i) + ".png";
|
std::string pagefile = filename + "_" + std::to_string(i) + ".png";
|
||||||
name = paths->find(name).string();
|
pagefile = paths->find(pagefile).string();
|
||||||
pages->push_back(imageio::read(name));
|
pages->push_back(imageio::read(pagefile));
|
||||||
}
|
}
|
||||||
return [=](auto assets) {
|
return [=](auto assets) {
|
||||||
int res = pages->at(0)->getHeight() / 16;
|
int res = pages->at(0)->getHeight() / 16;
|
||||||
@@ -198,6 +201,30 @@ assetload::postfunc assetload::sound(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assetload::postfunc assetload::model(
|
||||||
|
AssetsLoader* loader,
|
||||||
|
const ResPaths* paths,
|
||||||
|
const std::string& file,
|
||||||
|
const std::string& name,
|
||||||
|
const std::shared_ptr<AssetCfg>&
|
||||||
|
) {
|
||||||
|
auto path = paths->find(file+".obj");
|
||||||
|
auto text = files::read_string(path);
|
||||||
|
try {
|
||||||
|
auto model = obj::parse(path.u8string(), text).release();
|
||||||
|
return [=](Assets* assets) {
|
||||||
|
for (auto& mesh : model->meshes) {
|
||||||
|
auto filename = TEXTURES_FOLDER+"/"+mesh.texture;
|
||||||
|
loader->add(AssetType::texture, filename, mesh.texture, nullptr);
|
||||||
|
}
|
||||||
|
assets->store(std::unique_ptr<model::Model>(model), name);
|
||||||
|
};
|
||||||
|
} catch (const parsing_error& err) {
|
||||||
|
std::cerr << err.errorLog() << std::endl;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void read_anim_file(
|
static void read_anim_file(
|
||||||
const std::string& animFile,
|
const std::string& animFile,
|
||||||
std::vector<std::pair<std::string, int>>& frameList
|
std::vector<std::pair<std::string, int>>& frameList
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ namespace assetload {
|
|||||||
const std::string &name,
|
const std::string &name,
|
||||||
const std::shared_ptr<AssetCfg>& settings
|
const std::shared_ptr<AssetCfg>& settings
|
||||||
);
|
);
|
||||||
|
|
||||||
postfunc sound(
|
postfunc sound(
|
||||||
AssetsLoader*,
|
AssetsLoader*,
|
||||||
const ResPaths* paths,
|
const ResPaths* paths,
|
||||||
@@ -57,6 +56,13 @@ namespace assetload {
|
|||||||
const std::string &name,
|
const std::string &name,
|
||||||
const std::shared_ptr<AssetCfg>& settings
|
const std::shared_ptr<AssetCfg>& settings
|
||||||
);
|
);
|
||||||
|
postfunc model(
|
||||||
|
AssetsLoader*,
|
||||||
|
const ResPaths* paths,
|
||||||
|
const std::string& file,
|
||||||
|
const std::string &name,
|
||||||
|
const std::shared_ptr<AssetCfg>& settings
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSETS_ASSET_LOADERS_HPP_
|
#endif // ASSETS_ASSET_LOADERS_HPP_
|
||||||
|
|||||||
@@ -163,6 +163,28 @@ void BasicParser::goBack(size_t count) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BasicParser::reset() {
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char BasicParser::peekInLine() {
|
||||||
|
while (hasNext()) {
|
||||||
|
char next = source[pos];
|
||||||
|
if (next == '\n') {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
if (is_whitespace(next)) {
|
||||||
|
pos++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pos >= source.length()) {
|
||||||
|
throw error("unexpected end");
|
||||||
|
}
|
||||||
|
return source[pos];
|
||||||
|
}
|
||||||
|
|
||||||
char BasicParser::peek() {
|
char BasicParser::peek() {
|
||||||
skipWhitespace();
|
skipWhitespace();
|
||||||
if (pos >= source.length()) {
|
if (pos >= source.length()) {
|
||||||
@@ -226,6 +248,19 @@ int64_t BasicParser::parseSimpleInt(int base) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dynamic::Value BasicParser::parseNumber() {
|
||||||
|
switch (peek()) {
|
||||||
|
case '-':
|
||||||
|
skip(1);
|
||||||
|
return parseNumber(-1);
|
||||||
|
case '+':
|
||||||
|
skip(1);
|
||||||
|
return parseNumber(1);
|
||||||
|
default:
|
||||||
|
return parseNumber(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dynamic::Value BasicParser::parseNumber(int sign) {
|
dynamic::Value BasicParser::parseNumber(int sign) {
|
||||||
char c = peek();
|
char c = peek();
|
||||||
int base = 10;
|
int base = 10;
|
||||||
|
|||||||
@@ -87,9 +87,11 @@ protected:
|
|||||||
bool isNext(const std::string& substring);
|
bool isNext(const std::string& substring);
|
||||||
void expectNewLine();
|
void expectNewLine();
|
||||||
void goBack(size_t count=1);
|
void goBack(size_t count=1);
|
||||||
|
void reset();
|
||||||
|
|
||||||
int64_t parseSimpleInt(int base);
|
int64_t parseSimpleInt(int base);
|
||||||
dynamic::Value parseNumber(int sign);
|
dynamic::Value parseNumber(int sign);
|
||||||
|
dynamic::Value parseNumber();
|
||||||
std::string parseString(char chr, bool closeRequired=true);
|
std::string parseString(char chr, bool closeRequired=true);
|
||||||
|
|
||||||
parsing_error error(const std::string& message);
|
parsing_error error(const std::string& message);
|
||||||
@@ -99,6 +101,7 @@ public:
|
|||||||
std::string parseName();
|
std::string parseName();
|
||||||
bool hasNext();
|
bool hasNext();
|
||||||
char peek();
|
char peek();
|
||||||
|
char peekInLine();
|
||||||
char peekNoJump();
|
char peekNoJump();
|
||||||
char nextChar();
|
char nextChar();
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -209,9 +209,8 @@ std::unique_ptr<List> Parser::parseList() {
|
|||||||
|
|
||||||
Value Parser::parseValue() {
|
Value Parser::parseValue() {
|
||||||
char next = peek();
|
char next = peek();
|
||||||
if (next == '-' || next == '+') {
|
if (next == '-' || next == '+' || is_digit(next)) {
|
||||||
pos++;
|
return parseNumber();
|
||||||
return parseNumber(next == '-' ? -1 : 1);
|
|
||||||
}
|
}
|
||||||
if (is_identifier_start(next)) {
|
if (is_identifier_start(next)) {
|
||||||
std::string literal = parseName();
|
std::string literal = parseName();
|
||||||
@@ -232,9 +231,6 @@ Value Parser::parseValue() {
|
|||||||
if (next == '[') {
|
if (next == '[') {
|
||||||
return List_sptr(parseList().release());
|
return List_sptr(parseList().release());
|
||||||
}
|
}
|
||||||
if (is_digit(next)) {
|
|
||||||
return parseNumber(1);
|
|
||||||
}
|
|
||||||
if (next == '"' || next == '\'') {
|
if (next == '"' || next == '\'') {
|
||||||
pos++;
|
pos++;
|
||||||
return parseString(next);
|
return parseString(next);
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
#include "obj.hpp"
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "../graphics/core/Model.hpp"
|
||||||
|
|
||||||
|
using namespace model;
|
||||||
|
|
||||||
|
class ObjParser : BasicParser {
|
||||||
|
std::vector<glm::vec3> coords {{0, 0, 0}};
|
||||||
|
std::vector<glm::vec2> uvs {{0, 0}};
|
||||||
|
std::vector<glm::vec3> normals {{0, 1, 0}};
|
||||||
|
|
||||||
|
void parseFace(Mesh& mesh) {
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
while (hasNext()) {
|
||||||
|
auto c = peekInLine();
|
||||||
|
if (c == '\n') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
uint indices[3] {};
|
||||||
|
uint i = 0;
|
||||||
|
do {
|
||||||
|
char next = peekInLine();
|
||||||
|
if (is_digit(next)) {
|
||||||
|
indices[i] = parseSimpleInt(10);
|
||||||
|
if (peekInLine() == '/') {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
} else if (next == '/') {
|
||||||
|
pos++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (peekInLine() != '\n' && ++i < 3);
|
||||||
|
|
||||||
|
vertices.push_back(Vertex {
|
||||||
|
coords[indices[0]], uvs[indices[1]], normals[indices[2]]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (peekInLine() != '\n' && hasNext()) {
|
||||||
|
skipLine();
|
||||||
|
}
|
||||||
|
if (vertices.size() >= 3) {
|
||||||
|
for (size_t j = 0; j < vertices.size() - 2; j++) {
|
||||||
|
mesh.vertices.push_back(vertices[0]);
|
||||||
|
for (size_t i = 1; i < 3; i++) {
|
||||||
|
mesh.vertices.push_back(vertices[i + j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
ObjParser(const std::string_view file, const std::string_view src) : BasicParser(file, src) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Model> parse() {
|
||||||
|
// first iteration - collecting vertex data
|
||||||
|
while (hasNext()) {
|
||||||
|
if (peek() == '#') {
|
||||||
|
skipLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto cmd = parseName();
|
||||||
|
if (cmd == "v") {
|
||||||
|
float x = dynamic::as_number(parseNumber());
|
||||||
|
float y = dynamic::as_number(parseNumber());
|
||||||
|
float z = dynamic::as_number(parseNumber());
|
||||||
|
coords.emplace_back(x, y, z);
|
||||||
|
} else if (cmd == "vt") {
|
||||||
|
float u = dynamic::as_number(parseNumber());
|
||||||
|
float v = dynamic::as_number(parseNumber());
|
||||||
|
uvs.emplace_back(u, v);
|
||||||
|
} else if (cmd == "vn") {
|
||||||
|
float x = dynamic::as_number(parseNumber());
|
||||||
|
float y = dynamic::as_number(parseNumber());
|
||||||
|
float z = dynamic::as_number(parseNumber());
|
||||||
|
normals.emplace_back(x, y, z);
|
||||||
|
} else {
|
||||||
|
skipLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// second iteration - building meshes
|
||||||
|
reset();
|
||||||
|
|
||||||
|
auto model = std::make_unique<Model>();
|
||||||
|
std::string texture;
|
||||||
|
while (hasNext()) {
|
||||||
|
if (peek() != '#' && parseName() == "usemtl") {
|
||||||
|
skipWhitespace();
|
||||||
|
texture = readUntil('\n');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
skipLine();
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
Mesh* mesh = &model->addMesh(texture);
|
||||||
|
while (hasNext()) {
|
||||||
|
if (peek() == '#') {
|
||||||
|
skipLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto cmd = parseName();
|
||||||
|
if (cmd == "usemtl") {
|
||||||
|
skipWhitespace();
|
||||||
|
texture = readUntil('\n');
|
||||||
|
mesh = &model->addMesh(texture);
|
||||||
|
break;
|
||||||
|
} else if (cmd == "f") {
|
||||||
|
parseFace(*mesh);
|
||||||
|
}
|
||||||
|
skipLine();
|
||||||
|
}
|
||||||
|
} while(hasNext());
|
||||||
|
model->clean();
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<Model> obj::parse(
|
||||||
|
const std::string_view file, const std::string_view src
|
||||||
|
) {
|
||||||
|
return ObjParser(file, src).parse();
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef CODERS_OBJ_HPP_
|
||||||
|
#define CODERS_OBJ_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
/// Wavefont OBJ files parser
|
||||||
|
|
||||||
|
namespace model {
|
||||||
|
struct Model;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace obj {
|
||||||
|
std::unique_ptr<model::Model> parse(
|
||||||
|
const std::string_view file, const std::string_view src
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CODERS_OBJ_HPP_
|
||||||
@@ -49,5 +49,6 @@ inline const std::string TEXTURES_FOLDER = "textures";
|
|||||||
inline const std::string FONTS_FOLDER = "fonts";
|
inline const std::string FONTS_FOLDER = "fonts";
|
||||||
inline const std::string LAYOUTS_FOLDER = "layouts";
|
inline const std::string LAYOUTS_FOLDER = "layouts";
|
||||||
inline const std::string SOUNDS_FOLDER = "sounds";
|
inline const std::string SOUNDS_FOLDER = "sounds";
|
||||||
|
inline const std::string MODELS_FOLDER = "models";
|
||||||
|
|
||||||
#endif // CONSTANTS_HPP_
|
#endif // CONSTANTS_HPP_
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "../typedefs.hpp"
|
#include "../typedefs.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -47,6 +48,15 @@ namespace dynamic {
|
|||||||
std::holds_alternative<integer_t>(value);
|
std::holds_alternative<integer_t>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline number_t as_number(const Value& value) {
|
||||||
|
if (auto num = std::get_if<number_t>(&value)) {
|
||||||
|
return *num;
|
||||||
|
} else if (auto num = std::get_if<integer_t>(&value)) {
|
||||||
|
return *num;
|
||||||
|
}
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
|
||||||
class List {
|
class List {
|
||||||
public:
|
public:
|
||||||
std::vector<Value> values;
|
std::vector<Value> values;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) {
|
ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) {
|
||||||
auto indices = content->getIndices();
|
auto indices = content->getIndices();
|
||||||
sideregions = std::make_unique<UVRegion[]>(indices->countBlockDefs() * 6);
|
sideregions = std::make_unique<UVRegion[]>(indices->countBlockDefs() * 6);
|
||||||
Atlas* atlas = assets->getAtlas("blocks");
|
auto atlas = assets->get<Atlas>("blocks");
|
||||||
|
|
||||||
for (uint i = 0; i < indices->countBlockDefs(); i++) {
|
for (uint i = 0; i < indices->countBlockDefs(); i++) {
|
||||||
Block* def = indices->getBlockDef(i);
|
Block* def = indices->getBlockDef(i);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ LevelFrontend::LevelFrontend(LevelController* controller, Assets* assets)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type == BlockInteraction::step) {
|
if (type == BlockInteraction::step) {
|
||||||
auto sound = assets->getSound(material->stepsSound);
|
auto sound = assets->get<audio::Sound>(material->stepsSound);
|
||||||
audio::play(
|
audio::play(
|
||||||
sound,
|
sound,
|
||||||
glm::vec3(),
|
glm::vec3(),
|
||||||
@@ -45,10 +45,10 @@ LevelFrontend::LevelFrontend(LevelController* controller, Assets* assets)
|
|||||||
audio::Sound* sound = nullptr;
|
audio::Sound* sound = nullptr;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BlockInteraction::placing:
|
case BlockInteraction::placing:
|
||||||
sound = assets->getSound(material->placeSound);
|
sound = assets->get<audio::Sound>(material->placeSound);
|
||||||
break;
|
break;
|
||||||
case BlockInteraction::destruction:
|
case BlockInteraction::destruction:
|
||||||
sound = assets->getSound(material->breakSound);
|
sound = assets->get<audio::Sound>(material->breakSound);
|
||||||
break;
|
break;
|
||||||
case BlockInteraction::step:
|
case BlockInteraction::step:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -62,6 +62,11 @@ std::shared_ptr<UINode> create_debug_panel(
|
|||||||
panel->add(create_label([](){
|
panel->add(create_label([](){
|
||||||
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
return L"meshes: " + std::to_wstring(Mesh::meshesCount);
|
||||||
}));
|
}));
|
||||||
|
panel->add(create_label([](){
|
||||||
|
int drawCalls = Mesh::drawCalls;
|
||||||
|
Mesh::drawCalls = 0;
|
||||||
|
return L"draw-calls: " + std::to_wstring(drawCalls);
|
||||||
|
}));
|
||||||
panel->add(create_label([](){
|
panel->add(create_label([](){
|
||||||
return L"speakers: " + std::to_wstring(audio::count_speakers())+
|
return L"speakers: " + std::to_wstring(audio::count_speakers())+
|
||||||
L" streams: " + std::to_wstring(audio::count_streams());
|
L" streams: " + std::to_wstring(audio::count_streams());
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ void Hud::processInput(bool visible) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pause && Events::active(BIND_DEVTOOLS_CONSOLE)) {
|
if (!pause && Events::active(BIND_DEVTOOLS_CONSOLE)) {
|
||||||
showOverlay(assets->getLayout("core:console"), false);
|
showOverlay(assets->get<UiDocument>("core:console"), false);
|
||||||
}
|
}
|
||||||
if (!Window::isFocused() && !pause && !isInventoryOpen()) {
|
if (!Window::isFocused() && !pause && !isInventoryOpen()) {
|
||||||
setPause(true);
|
setPause(true);
|
||||||
@@ -305,7 +305,7 @@ void Hud::openInventory() {
|
|||||||
|
|
||||||
inventoryOpen = true;
|
inventoryOpen = true;
|
||||||
auto inventory = player->getInventory();
|
auto inventory = player->getInventory();
|
||||||
auto inventoryDocument = assets->getLayout("core:inventory");
|
auto inventoryDocument = assets->get<UiDocument>("core:inventory");
|
||||||
inventoryView = std::dynamic_pointer_cast<InventoryView>(inventoryDocument->getRoot());
|
inventoryView = std::dynamic_pointer_cast<InventoryView>(inventoryDocument->getRoot());
|
||||||
inventoryView->bind(inventory, content);
|
inventoryView->bind(inventory, content);
|
||||||
add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false));
|
add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false));
|
||||||
@@ -460,7 +460,7 @@ void Hud::draw(const DrawContext& ctx){
|
|||||||
auto batch = ctx.getBatch2D();
|
auto batch = ctx.getBatch2D();
|
||||||
batch->begin();
|
batch->begin();
|
||||||
|
|
||||||
Shader* uishader = assets->getShader("ui");
|
auto uishader = assets->get<Shader>("ui");
|
||||||
uishader->use();
|
uishader->use();
|
||||||
uishader->uniformMatrix("u_projview", uicamera->getProjView());
|
uishader->uniformMatrix("u_projview", uicamera->getProjView());
|
||||||
|
|
||||||
@@ -468,7 +468,7 @@ void Hud::draw(const DrawContext& ctx){
|
|||||||
if (!pause && !inventoryOpen && !player->debug) {
|
if (!pause && !inventoryOpen && !player->debug) {
|
||||||
DrawContext chctx = ctx.sub();
|
DrawContext chctx = ctx.sub();
|
||||||
chctx.setBlendMode(BlendMode::inversion);
|
chctx.setBlendMode(BlendMode::inversion);
|
||||||
auto texture = assets->getTexture("gui/crosshair");
|
auto texture = assets->get<Texture>("gui/crosshair");
|
||||||
batch->texture(texture);
|
batch->texture(texture);
|
||||||
int chsizex = texture != nullptr ? texture->getWidth() : 16;
|
int chsizex = texture != nullptr ? texture->getWidth() : 16;
|
||||||
int chsizey = texture != nullptr ? texture->getHeight() : 16;
|
int chsizey = texture != nullptr ? texture->getHeight() : 16;
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ void MenuScreen::draw(float delta) {
|
|||||||
Window::setBgColor(glm::vec3(0.2f));
|
Window::setBgColor(glm::vec3(0.2f));
|
||||||
|
|
||||||
uicamera->setFov(Window::height);
|
uicamera->setFov(Window::height);
|
||||||
Shader* uishader = assets->getShader("ui");
|
auto uishader = assets->get<Shader>("ui");
|
||||||
uishader->use();
|
uishader->use();
|
||||||
uishader->uniformMatrix("u_projview", uicamera->getProjView());
|
uishader->uniformMatrix("u_projview", uicamera->getProjView());
|
||||||
|
|
||||||
uint width = Window::width;
|
uint width = Window::width;
|
||||||
uint height = Window::height;
|
uint height = Window::height;
|
||||||
|
|
||||||
auto bg = assets->getTexture("gui/menubg");
|
auto bg = assets->get<Texture>("gui/menubg");
|
||||||
batch->begin();
|
batch->begin();
|
||||||
batch->texture(bg);
|
batch->texture(bg);
|
||||||
batch->rect(
|
batch->rect(
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include "../../typedefs.hpp"
|
#include "../../typedefs.hpp"
|
||||||
|
#include "../../maths/UVRegion.hpp"
|
||||||
|
|
||||||
|
/// xyz, uv, rgba
|
||||||
inline constexpr uint B3D_VERTEX_SIZE = 9;
|
inline constexpr uint B3D_VERTEX_SIZE = 9;
|
||||||
|
|
||||||
Batch3D::Batch3D(size_t capacity)
|
Batch3D::Batch3D(size_t capacity)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#ifndef GRAPHICS_CORE_BATCH3D_HPP_
|
#ifndef GRAPHICS_CORE_BATCH3D_HPP_
|
||||||
#define GRAPHICS_CORE_BATCH3D_HPP_
|
#define GRAPHICS_CORE_BATCH3D_HPP_
|
||||||
|
|
||||||
#include "../../maths/UVRegion.hpp"
|
|
||||||
#include "../../typedefs.hpp"
|
#include "../../typedefs.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -10,6 +9,7 @@
|
|||||||
|
|
||||||
class Mesh;
|
class Mesh;
|
||||||
class Texture;
|
class Texture;
|
||||||
|
struct UVRegion;
|
||||||
|
|
||||||
class Batch3D {
|
class Batch3D {
|
||||||
std::unique_ptr<float[]> buffer;
|
std::unique_ptr<float[]> buffer;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
int Mesh::meshesCount = 0;
|
int Mesh::meshesCount = 0;
|
||||||
|
int Mesh::drawCalls = 0;
|
||||||
|
|
||||||
Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs) :
|
Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs) :
|
||||||
ibo(0),
|
ibo(0),
|
||||||
@@ -60,6 +61,7 @@ void Mesh::reload(const float* vertexBuffer, size_t vertices, const int* indexBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::draw(unsigned int primitive){
|
void Mesh::draw(unsigned int primitive){
|
||||||
|
drawCalls++;
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
if (ibo != 0) {
|
if (ibo != 0) {
|
||||||
glDrawElements(primitive, indices, GL_UNSIGNED_INT, 0);
|
glDrawElements(primitive, indices, GL_UNSIGNED_INT, 0);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public:
|
|||||||
|
|
||||||
/// @brief Total numbers of alive mesh objects
|
/// @brief Total numbers of alive mesh objects
|
||||||
static int meshesCount;
|
static int meshesCount;
|
||||||
|
static int drawCalls;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GRAPHICS_CORE_MESH_HPP_
|
#endif // GRAPHICS_CORE_MESH_HPP_
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#include "Model.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace model;
|
||||||
|
|
||||||
|
inline constexpr glm::vec3 X(1, 0, 0);
|
||||||
|
inline constexpr glm::vec3 Y(0, 1, 0);
|
||||||
|
inline constexpr glm::vec3 Z(0, 0, 1);
|
||||||
|
|
||||||
|
void Mesh::addPlane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm) {
|
||||||
|
vertices.push_back({pos-right-up, {0,0}, norm});
|
||||||
|
vertices.push_back({pos+right-up, {1,0}, norm});
|
||||||
|
vertices.push_back({pos+right+up, {1,1}, norm});
|
||||||
|
|
||||||
|
vertices.push_back({pos-right-up, {0,0}, norm});
|
||||||
|
vertices.push_back({pos+right+up, {1,1}, norm});
|
||||||
|
vertices.push_back({pos-right+up, {0,1}, norm});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::addBox(glm::vec3 pos, glm::vec3 size) {
|
||||||
|
addPlane(pos+Z*size, X*size, Y*size, Z);
|
||||||
|
addPlane(pos-Z*size, -X*size, Y*size, -Z);
|
||||||
|
|
||||||
|
addPlane(pos+Y*size, X*size, -Z*size, Y);
|
||||||
|
addPlane(pos-Y*size, X*size, Z*size, -Y);
|
||||||
|
|
||||||
|
addPlane(pos+X*size, -Z*size, Y*size, X);
|
||||||
|
addPlane(pos-X*size, Z*size, Y*size, -X);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Model::clean() {
|
||||||
|
meshes.erase(
|
||||||
|
std::remove_if(meshes.begin(), meshes.end(),
|
||||||
|
[](const Mesh& mesh){
|
||||||
|
return mesh.vertices.empty();
|
||||||
|
}),
|
||||||
|
meshes.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef GRAPHICS_CORE_MODEL_HPP_
|
||||||
|
#define GRAPHICS_CORE_MODEL_HPP_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
namespace model {
|
||||||
|
struct Vertex {
|
||||||
|
glm::vec3 coord;
|
||||||
|
glm::vec2 uv;
|
||||||
|
glm::vec3 normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Mesh {
|
||||||
|
std::string texture;
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
|
||||||
|
void addPlane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm);
|
||||||
|
void addBox(glm::vec3 pos, glm::vec3 size);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Model {
|
||||||
|
std::vector<Mesh> meshes;
|
||||||
|
|
||||||
|
/// @brief Add mesh to the model
|
||||||
|
/// @param texture texture name
|
||||||
|
/// @return writeable Mesh
|
||||||
|
Mesh& addMesh(const std::string& texture) {
|
||||||
|
meshes.push_back({texture, {}});
|
||||||
|
return meshes[meshes.size()-1];
|
||||||
|
}
|
||||||
|
/// @brief Remove all empty meshes
|
||||||
|
void clean();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GRAPHICS_CORE_MODEL_HPP_
|
||||||
@@ -126,8 +126,8 @@ std::unique_ptr<Atlas> BlocksPreview::build(
|
|||||||
size_t count = indices->countBlockDefs();
|
size_t count = indices->countBlockDefs();
|
||||||
size_t iconSize = ITEM_ICON_SIZE;
|
size_t iconSize = ITEM_ICON_SIZE;
|
||||||
|
|
||||||
Shader* shader = assets->getShader("ui3d");
|
auto shader = assets->get<Shader>("ui3d");
|
||||||
Atlas* atlas = assets->getAtlas("blocks");
|
auto atlas = assets->get<Atlas>("blocks");
|
||||||
|
|
||||||
Viewport viewport(iconSize, iconSize);
|
Viewport viewport(iconSize, iconSize);
|
||||||
DrawContext pctx(nullptr, viewport, nullptr);
|
DrawContext pctx(nullptr, viewport, nullptr);
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
#include "ModelBatch.hpp"
|
||||||
|
|
||||||
|
#include "../core/Mesh.hpp"
|
||||||
|
#include "../core/Model.hpp"
|
||||||
|
#include "../core/Texture.hpp"
|
||||||
|
#include "../../assets/Assets.hpp"
|
||||||
|
#include "../../window/Window.hpp"
|
||||||
|
#include "../../voxels/Chunks.hpp"
|
||||||
|
#include "../../lighting/Lightmap.hpp"
|
||||||
|
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
|
#include <glm/gtx/matrix_decompose.hpp>
|
||||||
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
/// xyz, uv, compressed rgba
|
||||||
|
inline constexpr uint VERTEX_SIZE = 6;
|
||||||
|
|
||||||
|
static const vattr attrs[] = {
|
||||||
|
{3}, {2}, {1}, {0}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr glm::vec3 X(1, 0, 0);
|
||||||
|
inline constexpr glm::vec3 Y(0, 1, 0);
|
||||||
|
inline constexpr glm::vec3 Z(0, 0, 1);
|
||||||
|
|
||||||
|
struct DecomposedMat4 {
|
||||||
|
glm::vec3 scale;
|
||||||
|
glm::mat3 rotation;
|
||||||
|
glm::vec3 translation;
|
||||||
|
glm::vec3 skew;
|
||||||
|
glm::vec4 perspective;
|
||||||
|
};
|
||||||
|
|
||||||
|
ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks)
|
||||||
|
: buffer(std::make_unique<float[]>(capacity * VERTEX_SIZE)),
|
||||||
|
capacity(capacity),
|
||||||
|
index(0),
|
||||||
|
mesh(std::make_unique<Mesh>(buffer.get(), 0, attrs)),
|
||||||
|
combined(1.0f),
|
||||||
|
assets(assets),
|
||||||
|
chunks(chunks)
|
||||||
|
{
|
||||||
|
ubyte pixels[] = {
|
||||||
|
255, 255, 255, 255,
|
||||||
|
};
|
||||||
|
blank = std::make_unique<Texture>(pixels, 1, 1, ImageFormat::rgba8888);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelBatch::~ModelBatch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation) {
|
||||||
|
glm::vec3 gpos = matrix * glm::vec4(glm::vec3(), 1.0f);
|
||||||
|
light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z);
|
||||||
|
glm::vec4 lights (
|
||||||
|
Lightmap::extract(light, 0) / 15.0f,
|
||||||
|
Lightmap::extract(light, 1) / 15.0f,
|
||||||
|
Lightmap::extract(light, 2) / 15.0f,
|
||||||
|
Lightmap::extract(light, 3) / 15.0f
|
||||||
|
);
|
||||||
|
setTexture(assets->get<Texture>(mesh.texture));
|
||||||
|
size_t vcount = mesh.vertices.size();
|
||||||
|
const auto& vertexData = mesh.vertices.data();
|
||||||
|
for (size_t i = 0; i < vcount / 3; i++) {
|
||||||
|
if (index + VERTEX_SIZE * 3 > capacity * VERTEX_SIZE) {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
for (size_t j = 0; j < 3; j++) {
|
||||||
|
const auto& vert = vertexData[i * 3 + j];
|
||||||
|
auto norm = rotation * vert.normal;
|
||||||
|
float d = glm::dot(norm, SUN_VECTOR);
|
||||||
|
d = 0.8f + d * 0.2f;
|
||||||
|
|
||||||
|
auto color = lights * d;
|
||||||
|
vertex(matrix * glm::vec4(vert.coord, 1.0f), vert.uv, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::draw(const model::Model* model) {
|
||||||
|
for (const auto& mesh : model->meshes) {
|
||||||
|
entries.push_back({combined, rotation, &mesh});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::render() {
|
||||||
|
std::sort(entries.begin(), entries.end(),
|
||||||
|
[](const DrawEntry& a, const DrawEntry& b) {
|
||||||
|
return a.mesh->texture < b.mesh->texture;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
for (auto& entry : entries) {
|
||||||
|
draw(*entry.mesh, entry.matrix, entry.rotation);
|
||||||
|
}
|
||||||
|
flush();
|
||||||
|
entries.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) {
|
||||||
|
if (index + 36 < capacity*VERTEX_SIZE) {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
plane(pos+Z*size, X*size, Y*size, Z, lights);
|
||||||
|
plane(pos-Z*size, -X*size, Y*size, -Z, lights);
|
||||||
|
|
||||||
|
plane(pos+Y*size, X*size, -Z*size, Y, lights);
|
||||||
|
plane(pos-Y*size, X*size, Z*size, -Y, lights);
|
||||||
|
|
||||||
|
plane(pos+X*size, -Z*size, Y*size, X, lights);
|
||||||
|
plane(pos-X*size, Z*size, Y*size, -X, lights);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::setTexture(Texture* texture) {
|
||||||
|
if (texture == nullptr) {
|
||||||
|
texture = blank.get();
|
||||||
|
}
|
||||||
|
if (texture != this->texture) {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
this->texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::flush() {
|
||||||
|
if (index == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (texture == nullptr) {
|
||||||
|
texture = blank.get();
|
||||||
|
}
|
||||||
|
texture->bind();
|
||||||
|
mesh->reload(buffer.get(), index / VERTEX_SIZE);
|
||||||
|
mesh->draw();
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static glm::mat4 extract_rotation(glm::mat4 matrix) {
|
||||||
|
DecomposedMat4 decomposed = {};
|
||||||
|
glm::quat rotation;
|
||||||
|
glm::decompose(
|
||||||
|
matrix,
|
||||||
|
decomposed.scale,
|
||||||
|
rotation,
|
||||||
|
decomposed.translation,
|
||||||
|
decomposed.skew,
|
||||||
|
decomposed.perspective
|
||||||
|
);
|
||||||
|
return glm::toMat3(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::translate(glm::vec3 vec) {
|
||||||
|
pushMatrix(glm::translate(glm::mat4(1.0f), vec));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::rotate(glm::vec3 axis, float angle) {
|
||||||
|
pushMatrix(glm::rotate(glm::mat4(1.0f), angle, axis));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::scale(glm::vec3 vec) {
|
||||||
|
pushMatrix(glm::scale(glm::mat4(1.0f), vec));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::pushMatrix(glm::mat4 matrix) {
|
||||||
|
matrices.push_back(combined);
|
||||||
|
combined = combined * matrix;
|
||||||
|
rotation = extract_rotation(combined);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelBatch::popMatrix() {
|
||||||
|
combined = matrices[matrices.size()-1];
|
||||||
|
matrices.erase(matrices.end()-1);
|
||||||
|
rotation = extract_rotation(combined);
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#ifndef GRAPHICS_RENDER_MODEL_BATCH_HPP_
|
||||||
|
#define GRAPHICS_RENDER_MODEL_BATCH_HPP_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class Mesh;
|
||||||
|
class Texture;
|
||||||
|
class Chunks;
|
||||||
|
class Assets;
|
||||||
|
|
||||||
|
namespace model {
|
||||||
|
struct Mesh;
|
||||||
|
struct Model;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModelBatch {
|
||||||
|
std::unique_ptr<float[]> const buffer;
|
||||||
|
size_t const capacity;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
std::unique_ptr<Mesh> mesh;
|
||||||
|
std::unique_ptr<Texture> blank;
|
||||||
|
|
||||||
|
glm::mat4 combined;
|
||||||
|
std::vector<glm::mat4> matrices;
|
||||||
|
glm::mat3 rotation;
|
||||||
|
|
||||||
|
Assets* assets;
|
||||||
|
Chunks* chunks;
|
||||||
|
Texture* texture = nullptr;
|
||||||
|
|
||||||
|
static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f};
|
||||||
|
|
||||||
|
inline void vertex(
|
||||||
|
glm::vec3 pos, glm::vec2 uv, glm::vec4 light
|
||||||
|
) {
|
||||||
|
float* buffer = this->buffer.get();
|
||||||
|
buffer[index++] = pos.x;
|
||||||
|
buffer[index++] = pos.y;
|
||||||
|
buffer[index++] = pos.z;
|
||||||
|
buffer[index++] = uv.x;
|
||||||
|
buffer[index++] = uv.y;
|
||||||
|
|
||||||
|
union {
|
||||||
|
float floating;
|
||||||
|
uint32_t integer;
|
||||||
|
} compressed;
|
||||||
|
|
||||||
|
compressed.integer = (static_cast<uint32_t>(light.r * 255) & 0xff) << 24;
|
||||||
|
compressed.integer |= (static_cast<uint32_t>(light.g * 255) & 0xff) << 16;
|
||||||
|
compressed.integer |= (static_cast<uint32_t>(light.b * 255) & 0xff) << 8;
|
||||||
|
compressed.integer |= (static_cast<uint32_t>(light.a * 255) & 0xff);
|
||||||
|
|
||||||
|
buffer[index++] = compressed.floating;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void plane(glm::vec3 pos, glm::vec3 right, glm::vec3 up, glm::vec3 norm, glm::vec4 lights) {
|
||||||
|
norm = rotation * norm;
|
||||||
|
float d = glm::dot(norm, SUN_VECTOR);
|
||||||
|
d = 0.8f + d * 0.2f;
|
||||||
|
|
||||||
|
auto color = lights * d;
|
||||||
|
|
||||||
|
vertex(pos-right-up, {0,0}, color);
|
||||||
|
vertex(pos+right-up, {1,0}, color);
|
||||||
|
vertex(pos+right+up, {1,1}, color);
|
||||||
|
|
||||||
|
vertex(pos-right-up, {0,0}, color);
|
||||||
|
vertex(pos+right+up, {1,1}, color);
|
||||||
|
vertex(pos-right+up, {0,1}, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation);
|
||||||
|
void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights);
|
||||||
|
void setTexture(Texture* texture);
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
struct DrawEntry {
|
||||||
|
glm::mat4 matrix;
|
||||||
|
glm::mat3 rotation;
|
||||||
|
const model::Mesh* mesh;
|
||||||
|
};
|
||||||
|
std::vector<DrawEntry> entries;
|
||||||
|
public:
|
||||||
|
ModelBatch(size_t capacity, Assets* assets, Chunks* chunks);
|
||||||
|
~ModelBatch();
|
||||||
|
|
||||||
|
void translate(glm::vec3 vec);
|
||||||
|
void rotate(glm::vec3 axis, float angle);
|
||||||
|
void scale(glm::vec3 vec);
|
||||||
|
|
||||||
|
void pushMatrix(glm::mat4 matrix);
|
||||||
|
void popMatrix();
|
||||||
|
void draw(const model::Model* model);
|
||||||
|
|
||||||
|
void render();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GRAPHICS_RENDER_MODEL_BATCH_HPP_
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "../../graphics/core/DrawContext.hpp"
|
#include "../../graphics/core/DrawContext.hpp"
|
||||||
#include "../../window/Window.hpp"
|
#include "../../window/Window.hpp"
|
||||||
#include "../../window/Camera.hpp"
|
#include "../../window/Camera.hpp"
|
||||||
|
#include "../../maths/UVRegion.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
@@ -58,7 +59,7 @@ Skybox::~Skybox() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Skybox::drawBackground(Camera* camera, Assets* assets, int width, int height) {
|
void Skybox::drawBackground(Camera* camera, Assets* assets, int width, int height) {
|
||||||
Shader* backShader = assets->getShader("background");
|
auto backShader = assets->get<Shader>("background");
|
||||||
backShader->use();
|
backShader->use();
|
||||||
backShader->uniformMatrix("u_view", camera->getView(false));
|
backShader->uniformMatrix("u_view", camera->getView(false));
|
||||||
backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(M_PI*0.5f));
|
backShader->uniform1f("u_zoom", camera->zoom*camera->getFov()/(M_PI*0.5f));
|
||||||
@@ -106,7 +107,7 @@ void Skybox::draw(
|
|||||||
DrawContext ctx = pctx.sub();
|
DrawContext ctx = pctx.sub();
|
||||||
ctx.setBlendMode(BlendMode::addition);
|
ctx.setBlendMode(BlendMode::addition);
|
||||||
|
|
||||||
Shader* shader = assets->getShader("ui3d");
|
auto shader = assets->get<Shader>("ui3d");
|
||||||
shader->use();
|
shader->use();
|
||||||
shader->uniformMatrix("u_projview", camera->getProjView(false));
|
shader->uniformMatrix("u_projview", camera->getProjView(false));
|
||||||
shader->uniformMatrix("u_apply", glm::mat4(1.0f));
|
shader->uniformMatrix("u_apply", glm::mat4(1.0f));
|
||||||
@@ -116,7 +117,7 @@ void Skybox::draw(
|
|||||||
float opacity = glm::pow(1.0f-fog, 7.0f);
|
float opacity = glm::pow(1.0f-fog, 7.0f);
|
||||||
|
|
||||||
for (auto& sprite : sprites) {
|
for (auto& sprite : sprites) {
|
||||||
batch3d->texture(assets->getTexture(sprite.texture));
|
batch3d->texture(assets->get<Texture>(sprite.texture));
|
||||||
|
|
||||||
float sangle = daytime * M_PI*2 + sprite.phase;
|
float sangle = daytime * M_PI*2 + sprite.phase;
|
||||||
float distance = sprite.distance;
|
float distance = sprite.distance;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "WorldRenderer.hpp"
|
#include "WorldRenderer.hpp"
|
||||||
|
|
||||||
#include "ChunksRenderer.hpp"
|
#include "ChunksRenderer.hpp"
|
||||||
|
#include "ModelBatch.hpp"
|
||||||
#include "Skybox.hpp"
|
#include "Skybox.hpp"
|
||||||
|
|
||||||
#include "../../assets/Assets.hpp"
|
#include "../../assets/Assets.hpp"
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
#include "../core/PostProcessing.hpp"
|
#include "../core/PostProcessing.hpp"
|
||||||
#include "../core/Shader.hpp"
|
#include "../core/Shader.hpp"
|
||||||
#include "../core/Texture.hpp"
|
#include "../core/Texture.hpp"
|
||||||
|
#include "../core/Model.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
@@ -43,11 +45,12 @@
|
|||||||
bool WorldRenderer::showChunkBorders = false;
|
bool WorldRenderer::showChunkBorders = false;
|
||||||
|
|
||||||
WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* player)
|
WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* player)
|
||||||
: engine(engine),
|
: engine(engine),
|
||||||
level(frontend->getLevel()),
|
level(frontend->getLevel()),
|
||||||
player(player),
|
player(player),
|
||||||
frustumCulling(std::make_unique<Frustum>()),
|
frustumCulling(std::make_unique<Frustum>()),
|
||||||
lineBatch(std::make_unique<LineBatch>())
|
lineBatch(std::make_unique<LineBatch>()),
|
||||||
|
modelBatch(std::make_unique<ModelBatch>(20'000, engine->getAssets(), level->chunks.get()))
|
||||||
{
|
{
|
||||||
renderer = std::make_unique<ChunksRenderer>(
|
renderer = std::make_unique<ChunksRenderer>(
|
||||||
level,
|
level,
|
||||||
@@ -65,7 +68,7 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl
|
|||||||
auto assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
skybox = std::make_unique<Skybox>(
|
skybox = std::make_unique<Skybox>(
|
||||||
settings.graphics.skyboxResolution.get(),
|
settings.graphics.skyboxResolution.get(),
|
||||||
assets->getShader("skybox_gen")
|
assets->get<Shader>("skybox_gen")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +107,7 @@ bool WorldRenderer::drawChunk(
|
|||||||
chunk->z * CHUNK_D + CHUNK_D
|
chunk->z * CHUNK_D + CHUNK_D
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!frustumCulling->IsBoxVisible(min, max))
|
if (!frustumCulling->isBoxVisible(min, max))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
glm::vec3 coord(chunk->x*CHUNK_W+0.5f, 0.5f, chunk->z*CHUNK_D+0.5f);
|
glm::vec3 coord(chunk->x*CHUNK_W+0.5f, 0.5f, chunk->z*CHUNK_D+0.5f);
|
||||||
@@ -151,9 +154,9 @@ void WorldRenderer::renderLevel(
|
|||||||
Camera* camera,
|
Camera* camera,
|
||||||
const EngineSettings& settings
|
const EngineSettings& settings
|
||||||
) {
|
) {
|
||||||
Assets* assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
Atlas* atlas = assets->getAtlas("blocks");
|
auto atlas = assets->get<Atlas>("blocks");
|
||||||
Shader* shader = assets->getShader("main");
|
auto shader = assets->get<Shader>("main");
|
||||||
|
|
||||||
auto indices = level->content->getIndices();
|
auto indices = level->content->getIndices();
|
||||||
|
|
||||||
@@ -191,6 +194,10 @@ void WorldRenderer::renderLevel(
|
|||||||
|
|
||||||
drawChunks(level->chunks.get(), camera, shader);
|
drawChunks(level->chunks.get(), camera, shader);
|
||||||
|
|
||||||
|
shader->uniformMatrix("u_model", glm::mat4(1.0f));
|
||||||
|
// draw entities here
|
||||||
|
modelBatch->render();
|
||||||
|
|
||||||
skybox->unbind();
|
skybox->unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,8 +293,8 @@ void WorldRenderer::draw(
|
|||||||
const EngineSettings& settings = engine->getSettings();
|
const EngineSettings& settings = engine->getSettings();
|
||||||
skybox->refresh(pctx, world->daytime, 1.0f+world->fog*2.0f, 4);
|
skybox->refresh(pctx, world->daytime, 1.0f+world->fog*2.0f, 4);
|
||||||
|
|
||||||
Assets* assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
Shader* linesShader = assets->getShader("lines");
|
auto linesShader = assets->get<Shader>("lines");
|
||||||
|
|
||||||
// World render scope with diegetic HUD included
|
// World render scope with diegetic HUD included
|
||||||
{
|
{
|
||||||
@@ -317,7 +324,7 @@ void WorldRenderer::draw(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rendering fullscreen quad with
|
// Rendering fullscreen quad with
|
||||||
auto screenShader = assets->getShader("screen");
|
auto screenShader = assets->get<Shader>("screen");
|
||||||
screenShader->use();
|
screenShader->use();
|
||||||
screenShader->uniform1f("u_timer", Window::time());
|
screenShader->uniform1f("u_timer", Window::time());
|
||||||
screenShader->uniform1f("u_dayTime", level->getWorld()->daytime);
|
screenShader->uniform1f("u_dayTime", level->getWorld()->daytime);
|
||||||
|
|||||||
@@ -23,8 +23,13 @@ class LevelFrontend;
|
|||||||
class Skybox;
|
class Skybox;
|
||||||
class PostProcessing;
|
class PostProcessing;
|
||||||
class DrawContext;
|
class DrawContext;
|
||||||
|
class ModelBatch;
|
||||||
struct EngineSettings;
|
struct EngineSettings;
|
||||||
|
|
||||||
|
namespace model {
|
||||||
|
struct Model;
|
||||||
|
}
|
||||||
|
|
||||||
class WorldRenderer {
|
class WorldRenderer {
|
||||||
Engine* engine;
|
Engine* engine;
|
||||||
Level* level;
|
Level* level;
|
||||||
@@ -34,6 +39,8 @@ class WorldRenderer {
|
|||||||
std::unique_ptr<ChunksRenderer> renderer;
|
std::unique_ptr<ChunksRenderer> renderer;
|
||||||
std::unique_ptr<Skybox> skybox;
|
std::unique_ptr<Skybox> skybox;
|
||||||
std::unique_ptr<Batch3D> batch3d;
|
std::unique_ptr<Batch3D> batch3d;
|
||||||
|
std::unique_ptr<ModelBatch> modelBatch;
|
||||||
|
|
||||||
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling);
|
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool culling);
|
||||||
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader);
|
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader);
|
||||||
|
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ void GUI::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
menu->setPos((wsize - menu->getSize()) / 2.0f);
|
menu->setPos((wsize - menu->getSize()) / 2.0f);
|
||||||
uicamera->setFov(wsize.y);
|
uicamera->setFov(wsize.y);
|
||||||
|
|
||||||
Shader* uishader = assets->getShader("ui");
|
auto uishader = assets->get<Shader>("ui");
|
||||||
uishader->use();
|
uishader->use();
|
||||||
uishader->uniformMatrix("u_projview", uicamera->getProjView());
|
uishader->uniformMatrix("u_projview", uicamera->getProjView());
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ void Image::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
glm::vec2 pos = calcPos();
|
glm::vec2 pos = calcPos();
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
|
|
||||||
auto texture = assets->getTexture(this->texture);
|
auto texture = assets->get<Texture>(this->texture);
|
||||||
if (texture && autoresize) {
|
if (texture && autoresize) {
|
||||||
setSize(glm::vec2(texture->getWidth(), texture->getHeight()));
|
setSize(glm::vec2(texture->getWidth(), texture->getHeight()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "../../core/Font.hpp"
|
#include "../../core/Font.hpp"
|
||||||
#include "../../core/DrawContext.hpp"
|
#include "../../core/DrawContext.hpp"
|
||||||
#include "../../core/Shader.hpp"
|
#include "../../core/Shader.hpp"
|
||||||
|
#include "../../core/Texture.hpp"
|
||||||
#include "../../render/BlocksPreview.hpp"
|
#include "../../render/BlocksPreview.hpp"
|
||||||
#include "../GUI.hpp"
|
#include "../GUI.hpp"
|
||||||
|
|
||||||
@@ -155,7 +156,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
|
|
||||||
batch->setColor(glm::vec4(1.0f));
|
batch->setColor(glm::vec4(1.0f));
|
||||||
|
|
||||||
auto previews = assets->getAtlas("block-previews");
|
auto previews = assets->get<Atlas>("block-previews");
|
||||||
auto indices = content->getIndices();
|
auto indices = content->getIndices();
|
||||||
|
|
||||||
ItemDef* item = indices->getItemDef(stack.getItemId());
|
ItemDef* item = indices->getItemDef(stack.getItemId());
|
||||||
@@ -177,10 +178,10 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
std::string name = item->icon.substr(index+1);
|
std::string name = item->icon.substr(index+1);
|
||||||
UVRegion region(0.0f, 0.0, 1.0f, 1.0f);
|
UVRegion region(0.0f, 0.0, 1.0f, 1.0f);
|
||||||
if (index == std::string::npos) {
|
if (index == std::string::npos) {
|
||||||
batch->texture(assets->getTexture(name));
|
batch->texture(assets->get<Texture>(name));
|
||||||
} else {
|
} else {
|
||||||
std::string atlasname = item->icon.substr(0, index);
|
std::string atlasname = item->icon.substr(0, index);
|
||||||
Atlas* atlas = assets->getAtlas(atlasname);
|
auto atlas = assets->get<Atlas>(atlasname);
|
||||||
if (atlas && atlas->has(name)) {
|
if (atlas && atlas->has(name)) {
|
||||||
region = atlas->get(name);
|
region = atlas->get(name);
|
||||||
batch->texture(atlas->getTexture());
|
batch->texture(atlas->getTexture());
|
||||||
@@ -194,7 +195,7 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stack.getCount() > 1) {
|
if (stack.getCount() > 1) {
|
||||||
auto font = assets->getFont("normal");
|
auto font = assets->get<Font>("normal");
|
||||||
std::wstring text = std::to_wstring(stack.getCount());
|
std::wstring text = std::to_wstring(stack.getCount());
|
||||||
|
|
||||||
int x = pos.x+slotSize-text.length()*8;
|
int x = pos.x+slotSize-text.length()*8;
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ uint Label::getLinesNumber() const {
|
|||||||
|
|
||||||
void Label::draw(const DrawContext* pctx, Assets* assets) {
|
void Label::draw(const DrawContext* pctx, Assets* assets) {
|
||||||
auto batch = pctx->getBatch2D();
|
auto batch = pctx->getBatch2D();
|
||||||
auto font = assets->getFont(fontName);
|
auto font = assets->get<Font>(fontName);
|
||||||
cache.prepare(font, static_cast<size_t>(glm::abs(getSize().x)));
|
cache.prepare(font, static_cast<size_t>(glm::abs(getSize().x)));
|
||||||
|
|
||||||
if (supplier) {
|
if (supplier) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void Plotter::draw(const DrawContext* pctx, Assets* assets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int current_point = static_cast<int>(points[index % dmwidth]);
|
int current_point = static_cast<int>(points[index % dmwidth]);
|
||||||
auto font = assets->getFont("normal");
|
auto font = assets->get<Font>("normal");
|
||||||
for (int y = 0; y < dmheight; y += labelsInterval) {
|
for (int y = 0; y < dmheight; y += labelsInterval) {
|
||||||
std::wstring string;
|
std::wstring string;
|
||||||
if (current_point/16 == y/labelsInterval) {
|
if (current_point/16 == y/labelsInterval) {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ TextBox::TextBox(std::wstring placeholder, glm::vec4 padding)
|
|||||||
void TextBox::draw(const DrawContext* pctx, Assets* assets) {
|
void TextBox::draw(const DrawContext* pctx, Assets* assets) {
|
||||||
Panel::draw(pctx, assets);
|
Panel::draw(pctx, assets);
|
||||||
|
|
||||||
font = assets->getFont(label->getFontName());
|
font = assets->get<Font>(label->getFontName());
|
||||||
|
|
||||||
if (!isFocused()) {
|
if (!isFocused()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ inline audio::speakerid_t play_sound(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto assets = scripting::engine->getAssets();
|
auto assets = scripting::engine->getAssets();
|
||||||
auto sound = assets->getSound(name);
|
auto sound = assets->get<audio::Sound>(name);
|
||||||
if (sound == nullptr) {
|
if (sound == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ struct DocumentNode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static DocumentNode getDocumentNode(lua::State*, const std::string& name, const std::string& nodeName) {
|
static DocumentNode getDocumentNode(lua::State*, const std::string& name, const std::string& nodeName) {
|
||||||
auto doc = engine->getAssets()->getLayout(name);
|
auto doc = engine->getAssets()->get<UiDocument>(name);
|
||||||
if (doc == nullptr) {
|
if (doc == nullptr) {
|
||||||
throw std::runtime_error("document '"+name+"' not found");
|
throw std::runtime_error("document '"+name+"' not found");
|
||||||
}
|
}
|
||||||
@@ -545,7 +545,7 @@ static int l_gui_setattr(lua::State* L) {
|
|||||||
|
|
||||||
static int l_gui_get_env(lua::State* L) {
|
static int l_gui_get_env(lua::State* L) {
|
||||||
auto name = lua::require_string(L, 1);
|
auto name = lua::require_string(L, 1);
|
||||||
auto doc = engine->getAssets()->getLayout(name);
|
auto doc = engine->getAssets()->get<UiDocument>(name);
|
||||||
if (doc == nullptr) {
|
if (doc == nullptr) {
|
||||||
throw std::runtime_error("document '"+std::string(name)+"' not found");
|
throw std::runtime_error("document '"+std::string(name)+"' not found");
|
||||||
}
|
}
|
||||||
@@ -566,7 +566,7 @@ static int l_gui_str(lua::State* L) {
|
|||||||
|
|
||||||
static int l_gui_reindex(lua::State* L) {
|
static int l_gui_reindex(lua::State* L) {
|
||||||
auto name = lua::require_string(L, 1);
|
auto name = lua::require_string(L, 1);
|
||||||
auto doc = engine->getAssets()->getLayout(name);
|
auto doc = engine->getAssets()->get<UiDocument>(name);
|
||||||
if (doc == nullptr) {
|
if (doc == nullptr) {
|
||||||
throw std::runtime_error("document '"+std::string(name)+"' not found");
|
throw std::runtime_error("document '"+std::string(name)+"' not found");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ static int l_hud_open_block(lua::State* L) {
|
|||||||
}
|
}
|
||||||
auto def = content->getIndices()->getBlockDef(vox->id);
|
auto def = content->getIndices()->getBlockDef(vox->id);
|
||||||
auto assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
auto layout = assets->getLayout(def->uiLayout);
|
auto layout = assets->get<UiDocument>(def->uiLayout);
|
||||||
if (layout == nullptr) {
|
if (layout == nullptr) {
|
||||||
throw std::runtime_error("block '"+def->name+"' has no ui layout");
|
throw std::runtime_error("block '"+def->name+"' has no ui layout");
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ static int l_hud_show_overlay(lua::State* L) {
|
|||||||
bool playerInventory = lua::toboolean(L, 2);
|
bool playerInventory = lua::toboolean(L, 2);
|
||||||
|
|
||||||
auto assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
auto layout = assets->getLayout(name);
|
auto layout = assets->get<UiDocument>(name);
|
||||||
if (layout == nullptr) {
|
if (layout == nullptr) {
|
||||||
throw std::runtime_error("there is no ui layout "+util::quote(name));
|
throw std::runtime_error("there is no ui layout "+util::quote(name));
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ static int l_hud_show_overlay(lua::State* L) {
|
|||||||
|
|
||||||
static UiDocument* require_layout(const char* name) {
|
static UiDocument* require_layout(const char* name) {
|
||||||
auto assets = engine->getAssets();
|
auto assets = engine->getAssets();
|
||||||
auto layout = assets->getLayout(name);
|
auto layout = assets->get<UiDocument>(name);
|
||||||
if (layout == nullptr) {
|
if (layout == nullptr) {
|
||||||
throw std::runtime_error("layout '"+std::string(name)+"' is not found");
|
throw std::runtime_error("layout '"+std::string(name)+"' is not found");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ inline int l_rotate(lua::State* L) {
|
|||||||
auto matrix = lua::tomat4(L, 1);
|
auto matrix = lua::tomat4(L, 1);
|
||||||
auto vec = lua::tovec3(L, 2);
|
auto vec = lua::tovec3(L, 2);
|
||||||
auto angle = glm::radians(static_cast<float>(lua::tonumber(L, 3)));
|
auto angle = glm::radians(static_cast<float>(lua::tonumber(L, 3)));
|
||||||
return lua::setmat4(L, 3, glm::rotate(matrix, angle, vec));
|
return lua::setmat4(L, 4, glm::rotate(matrix, angle, vec));
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
throw std::runtime_error("invalid arguments number (2, 3 or 4 expected)");
|
throw std::runtime_error("invalid arguments number (2, 3 or 4 expected)");
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public:
|
|||||||
Frustum() {};
|
Frustum() {};
|
||||||
|
|
||||||
void update(glm::mat4 projview);
|
void update(glm::mat4 projview);
|
||||||
bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const;
|
bool isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Planes
|
enum Planes
|
||||||
@@ -76,8 +76,7 @@ inline void Frustum::update(glm::mat4 m)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Frustum::IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const
|
inline bool Frustum::isBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const {
|
||||||
{
|
|
||||||
// check box outside/inside of frustum
|
// check box outside/inside of frustum
|
||||||
for (int i = 0; i < Count; i++)
|
for (int i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user