mirror of
https://github.com/harfang3d/harfang3d.git
synced 2024-06-01 14:02:16 +00:00
728 lines
34 KiB
C++
728 lines
34 KiB
C++
// HARFANG(R) Copyright (C) 2021 Emmanuel Julien, NWNC HARFANG. Released under GPL/LGPL/Commercial Licence, see licence.txt for details.
|
|
|
|
#pragma once
|
|
|
|
#include "engine/meta.h"
|
|
#include "engine/picture.h"
|
|
#include "engine/resource_cache.h"
|
|
|
|
#include "foundation/cext.h"
|
|
#include "foundation/color.h"
|
|
#include "foundation/data.h"
|
|
#include "foundation/frustum.h"
|
|
#include "foundation/generational_vector_list.h"
|
|
#include "foundation/matrix4.h"
|
|
#include "foundation/matrix44.h"
|
|
#include "foundation/minmax.h"
|
|
#include "foundation/rw_interface.h"
|
|
#include "foundation/time.h"
|
|
#include "foundation/vector2.h"
|
|
|
|
#include <bgfx/bgfx.h>
|
|
#include <bimg/bimg.h>
|
|
|
|
#include <deque>
|
|
#include <functional>
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#if WIN32
|
|
#undef GetObject // stop Windows.h from polluting global namespace
|
|
#endif
|
|
|
|
namespace hg {
|
|
|
|
class Data;
|
|
|
|
static constexpr int max_skinned_model_matrix_count = 32; // make sure this stays in sync with bgfx_shader.sh
|
|
|
|
using bgfxMatrix3 = std::array<float, 9>;
|
|
using bgfxMatrix4 = std::array<float, 16>;
|
|
|
|
bgfxMatrix3 to_bgfx(const Mat3 &m);
|
|
bgfxMatrix4 to_bgfx(const Mat4 &m);
|
|
bgfxMatrix4 to_bgfx(const Mat44 &m);
|
|
|
|
#define bgfx_Destroy(V) \
|
|
{ \
|
|
if (bgfx::isValid(V)) \
|
|
bgfx::destroy(V); \
|
|
V = BGFX_INVALID_HANDLE; \
|
|
}
|
|
|
|
//
|
|
struct ViewState {
|
|
Frustum frustum;
|
|
Mat44 proj;
|
|
Mat4 view;
|
|
};
|
|
|
|
ViewState ComputeOrthographicViewState(const Mat4 &world, float size, float znear, float zfar, const Vec2 &aspect_ratio, const Vec2 &offset = {});
|
|
ViewState ComputePerspectiveViewState(const Mat4 &world, float fov, float znear, float zfar, const Vec2 &aspect_ratio, const Vec2 &offset = {}, const Vec2 ¢er_offset = {});
|
|
|
|
Mat4 ComputeBillboardMat4(const Vec3 &pos, const ViewState &view_state, const Vec3 &scale = {1, 1, 1});
|
|
|
|
//
|
|
struct Window;
|
|
|
|
bool RenderInit(Window *window, bgfx::RendererType::Enum type, bgfx::CallbackI *callback = nullptr);
|
|
bool RenderInit(Window *window, bgfx::CallbackI *callback = nullptr);
|
|
|
|
Window *RenderInit(int width, int height, bgfx::RendererType::Enum type, uint32_t reset_flags = 0,
|
|
bgfx::TextureFormat::Enum format = bgfx::TextureFormat::Count, uint32_t debug_flags = 0, bgfx::CallbackI *callback = nullptr);
|
|
Window *RenderInit(int width, int height, uint32_t reset_flags = 0, bgfx::TextureFormat::Enum format = bgfx::TextureFormat::Count, uint32_t debug_flags = 0,
|
|
bgfx::CallbackI *callback = nullptr);
|
|
Window *RenderInit(const char *window_title, int width, int height, bgfx::RendererType::Enum type, uint32_t reset_flags = 0,
|
|
bgfx::TextureFormat::Enum format = bgfx::TextureFormat::Count, uint32_t debug_flags = 0, bgfx::CallbackI *callback = nullptr);
|
|
Window *RenderInit(const char *window_title, int width, int height, uint32_t reset_flags = 0, bgfx::TextureFormat::Enum format = bgfx::TextureFormat::Count,
|
|
uint32_t debug_flags = 0, bgfx::CallbackI *callback = nullptr);
|
|
|
|
void RenderShutdown();
|
|
|
|
bool IsRenderUp();
|
|
|
|
/// Fit the backbuffer to the specified window client area dimensions, return true if resizing was carried out.
|
|
bool RenderResetToWindow(Window *win, int &width, int &height, uint32_t reset_flags = 0);
|
|
|
|
void SetView2D(bgfx::ViewId id, int x, int y, int res_x, int res_y, float znear = -1.f, float zfar = 1.f,
|
|
uint16_t clear_flags = BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, const Color &clear_color = Color::Black, float depth = 1.f, uint8_t stencil = 0,
|
|
bool y_up = false);
|
|
void SetViewPerspective(bgfx::ViewId id, int x, int y, int res_x, int res_y, const Mat4 &world, float znear = 0.01f, float zfar = 1000.f,
|
|
float zoom_factor = 1.8, uint16_t clear_flags = BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, const Color &clear_color = Color::Black, float depth = 1.f,
|
|
uint8_t stencil = 0, const Vec2 &aspect_ratio = {});
|
|
void SetViewOrthographic(bgfx::ViewId id, int x, int y, int res_x, int res_y, const Mat4 &world, float znear = 0.01f, float zfar = 1000.f, float size = 1.f,
|
|
uint16_t clear_flags = BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, const Color &clear_color = Color::Black, float depth = 1.f, uint8_t stencil = 0,
|
|
const Vec2 &aspect_ratio = {});
|
|
|
|
//
|
|
bgfx::ProgramHandle LoadProgram(const Reader &ir, const ReadProvider &ip, const char *vs_name, const char *fs_name, bool silent = false);
|
|
bgfx::ProgramHandle LoadProgram(const Reader &ir, const ReadProvider &ip, const char *name, bool silent = false);
|
|
bgfx::ProgramHandle LoadComputeProgram(const Reader &ir, const ReadProvider &ip, const char *cs_name, bool silent = false);
|
|
|
|
bgfx::ProgramHandle LoadProgramFromFile(const char *vs_path, const char *fs_path, bool silent = false);
|
|
bgfx::ProgramHandle LoadProgramFromAssets(const char *vs_name, const char *fs_name, bool silent = false);
|
|
bgfx::ProgramHandle LoadProgramFromFile(const char *path, bool silent = false);
|
|
bgfx::ProgramHandle LoadProgramFromAssets(const char *name, bool silent = false);
|
|
bgfx::ProgramHandle LoadComputeProgramFromFile(const char *cs_path, bool silent = false);
|
|
bgfx::ProgramHandle LoadComputeProgramFromAssets(const char *cs_name, bool silent = false);
|
|
|
|
//
|
|
std::vector<bgfx::ShaderHandle> GetProgramShaders(bgfx::ProgramHandle prg_h);
|
|
|
|
//
|
|
json LoadResourceMeta(const Reader &ir, const ReadProvider &ip, const std::string &name);
|
|
json LoadResourceMetaFromFile(const std::string &path);
|
|
json LoadResourceMetaFromAssets(const std::string &name);
|
|
|
|
bool SaveResourceMetaToFile(const std::string &path, const json &meta);
|
|
|
|
//
|
|
struct PipelineInfo {
|
|
std::string name;
|
|
std::vector<std::vector<std::string>> configs;
|
|
};
|
|
|
|
struct PipelineResources;
|
|
|
|
//
|
|
enum PipelineProgramFeature {
|
|
OptionalBaseColorOpacityMap, // USE_BASE_COLOR_OPACITY_MAP
|
|
OptionalOcclusionRoughnessMetalnessMap, // USE_OCCLUSION_ROUGHNESS_METALNESS_MAP
|
|
|
|
OptionalDiffuseMap, // USE_DIFFUSE_MAP
|
|
OptionalSpecularMap, // USE_SPECULAR_MAP
|
|
OptionalLightMap, // USE_LIGHT_MAP
|
|
OptionalSelfMap, // USE_SELF_MAP
|
|
OptionalOpacityMap, // USE_OPACITY_MAP
|
|
OptionalAmbientMap, // USE_AMBIENT_MAP
|
|
OptionalReflectionMap, // USE_REFLECTION_MAP
|
|
OptionalNormalMap, // USE_NORMAL_MAP
|
|
|
|
NormalMapInWorldSpace, // NORMAL_MAP_IN_WORLD_SPACE
|
|
|
|
DiffuseUV1, // DIFFUSE_UV_CHANNEL=N
|
|
SpecularUV1, // SPECULAR_UV_CHANNEL=N
|
|
AmbientUV1, // AMBIENT_UV_CHANNEL=N
|
|
|
|
OptionalSkinning, // ENABLE_SKINNING
|
|
OptionalAlphaCut, // ENABLE_ALPHA_CUT
|
|
|
|
Count,
|
|
};
|
|
|
|
std::vector<PipelineProgramFeature> LoadPipelineProgramFeatures(const Reader &ir, const ReadProvider &ip, const char *name, bool &success, bool silent = false);
|
|
std::vector<PipelineProgramFeature> LoadPipelineProgramFeaturesFromFile(const char *path, bool &success, bool silent = false);
|
|
std::vector<PipelineProgramFeature> LoadPipelineProgramFeaturesFromAssets(const char *name, bool &success, bool silent = false);
|
|
|
|
//
|
|
struct PipelineProgram;
|
|
struct Material;
|
|
struct Texture;
|
|
struct Model;
|
|
|
|
using PipelineProgramRef = ResourceRef<PipelineProgram>;
|
|
using MaterialRef = ResourceRef<Material>;
|
|
using TextureRef = ResourceRef<Texture>;
|
|
using ModelRef = ResourceRef<Model>;
|
|
|
|
static const PipelineProgramRef InvalidPipelineProgramRef;
|
|
static const MaterialRef InvalidMaterialRef;
|
|
static const TextureRef InvalidTextureRef;
|
|
static const ModelRef InvalidModelRef;
|
|
|
|
//
|
|
struct ProgramHandle {
|
|
bgfx::ProgramHandle handle = BGFX_INVALID_HANDLE;
|
|
bool loaded{false};
|
|
};
|
|
|
|
struct TextureUniform {
|
|
bgfx::UniformHandle handle;
|
|
TextureRef tex_ref;
|
|
uint8_t channel{0xff};
|
|
};
|
|
|
|
struct Vec4Uniform {
|
|
bgfx::UniformHandle handle;
|
|
Vec4 value = {1.f, 1.f, 1.f, 1.f};
|
|
bool is_color = false;
|
|
};
|
|
|
|
struct PipelineProgram {
|
|
std::vector<PipelineProgramFeature> features; // features imply associated uniforms
|
|
std::vector<TextureUniform> texture_uniforms; // naked texture uniforms
|
|
std::vector<Vec4Uniform> vec4_uniforms; // naked vec4/color uniforms
|
|
std::vector<ProgramHandle> programs; // program variants (dependent on feature set)
|
|
|
|
std::string name;
|
|
PipelineInfo pipeline;
|
|
ReadProvider ip;
|
|
Reader ir;
|
|
};
|
|
|
|
PipelineProgram LoadPipelineProgram(
|
|
const Reader &ir, const ReadProvider &ip, const char *name, PipelineResources &resources, const PipelineInfo &pipeline, bool silent = false);
|
|
PipelineProgram LoadPipelineProgramFromFile(const char *path, PipelineResources &resources, const PipelineInfo &pipeline, bool silent = false);
|
|
PipelineProgram LoadPipelineProgramFromAssets(const char *name, PipelineResources &resources, const PipelineInfo &pipeline, bool silent = false);
|
|
|
|
void Destroy(PipelineProgram &pipeline_program);
|
|
|
|
//
|
|
bool LoadPipelineProgramUniforms(const Reader &ir, const ReadProvider &ip, const char *name, std::vector<TextureUniform> &texs, std::vector<Vec4Uniform> &vecs,
|
|
PipelineResources &resources, bool silent = false);
|
|
bool LoadPipelineProgramUniformsFromFile(
|
|
const char *path, std::vector<TextureUniform> &texs, std::vector<Vec4Uniform> &vecs, PipelineResources &resources, bool silent = false);
|
|
bool LoadPipelineProgramUniformsFromAssets(
|
|
const char *name, std::vector<TextureUniform> &texs, std::vector<Vec4Uniform> &vecs, PipelineResources &resources, bool silent = false);
|
|
|
|
//
|
|
struct DisplayList { // 4B
|
|
bgfx::IndexBufferHandle index_buffer;
|
|
bgfx::VertexBufferHandle vertex_buffer;
|
|
std::vector<uint16_t> bones_table;
|
|
};
|
|
|
|
/// Create an empty texture.
|
|
/// @see CreateTextureFromPicture and UpdateTextureFromPicture.
|
|
Texture CreateTexture(int width, int height, const char *name, uint64_t flags, bgfx::TextureFormat::Enum format = bgfx::TextureFormat::RGBA8);
|
|
/// Create a texture from a picture.
|
|
/// @see Picture, CreateTexture and UpdateTextureFromPicture.
|
|
Texture CreateTextureFromPicture(const Picture &pic, const char *name, uint64_t flags, bgfx::TextureFormat::Enum format = bgfx::TextureFormat::RGBA8);
|
|
|
|
void UpdateTextureFromPicture(Texture &tex, const Picture &pic);
|
|
|
|
uint64_t LoadTextureFlags(const Reader &ir, const ReadProvider &ip, const std::string &name, bool silent = false);
|
|
uint64_t LoadTextureFlagsFromFile(const std::string &path, bool silent = false);
|
|
uint64_t LoadTextureFlagsFromAssets(const std::string &name, bool silent = false);
|
|
|
|
Texture LoadTexture(const Reader &ir, const ReadProvider &ip, const char *name, uint64_t flags, bgfx::TextureInfo *info = nullptr,
|
|
bimg::Orientation::Enum *orientation = nullptr, bool silent = false);
|
|
Texture LoadTextureFromFile(
|
|
const char *path, uint64_t flags, bgfx::TextureInfo *info = nullptr, bimg::Orientation::Enum *orientation = nullptr, bool silent = false);
|
|
Texture LoadTextureFromAssets(
|
|
const char *name, uint64_t flags, bgfx::TextureInfo *info = nullptr, bimg::Orientation::Enum *orientation = nullptr, bool silent = false);
|
|
|
|
void Destroy(Texture &texture);
|
|
|
|
struct Texture { // 8B
|
|
uint64_t flags = BGFX_TEXTURE_NONE | BGFX_SAMPLER_NONE;
|
|
bgfx::TextureHandle handle = BGFX_INVALID_HANDLE;
|
|
};
|
|
|
|
inline Texture MakeTexture(bgfx::TextureHandle handle, uint64_t flags = BGFX_TEXTURE_NONE | BGFX_SAMPLER_NONE) { return {flags, handle}; }
|
|
|
|
// for engine internal use
|
|
struct RenderBufferResourceFactory {
|
|
std::function<bgfx::TextureHandle(bgfx::BackbufferRatio::Enum ratio, bool hasMips, uint16_t numLayers, bgfx::TextureFormat::Enum format, uint64_t flags)>
|
|
create_texture2d;
|
|
|
|
std::function<bgfx::FrameBufferHandle(bgfx::BackbufferRatio::Enum ratio, bgfx::TextureFormat::Enum format, uint64_t textureFlags)> create_framebuffer;
|
|
|
|
// resources will be created in terms of this custom size
|
|
static RenderBufferResourceFactory Custom(uint16_t width, uint16_t height);
|
|
|
|
// resources will be created in terms of the backbuffer's size
|
|
static RenderBufferResourceFactory Backbuffer();
|
|
};
|
|
|
|
//
|
|
struct UniformSetValue { // burn it with fire, complete insanity
|
|
UniformSetValue() = default;
|
|
UniformSetValue(const UniformSetValue &v);
|
|
UniformSetValue &operator=(const UniformSetValue &v);
|
|
~UniformSetValue();
|
|
|
|
bgfx::UniformHandle uniform = BGFX_INVALID_HANDLE;
|
|
std::vector<float> value;
|
|
uint16_t count{1};
|
|
};
|
|
|
|
UniformSetValue MakeUniformSetValue(const char *name, float v, uint16_t count = 1);
|
|
UniformSetValue MakeUniformSetValue(const char *name, const Vec2 &v, uint16_t count = 1);
|
|
UniformSetValue MakeUniformSetValue(const char *name, const Vec3 &v, uint16_t count = 1);
|
|
UniformSetValue MakeUniformSetValue(const char *name, const Vec4 &v, uint16_t count = 1);
|
|
UniformSetValue MakeUniformSetValue(const char *name, const Mat3 &mtx, uint16_t count = 1);
|
|
UniformSetValue MakeUniformSetValue(const char *name, const Mat4 &mtx, uint16_t count = 1);
|
|
UniformSetValue MakeUniformSetValue(const char *name, const Mat44 &mtx, uint16_t count = 1);
|
|
|
|
struct UniformSetTexture { // burn it with fire, complete insanity
|
|
UniformSetTexture() = default;
|
|
UniformSetTexture(const UniformSetTexture &v);
|
|
UniformSetTexture &operator=(const UniformSetTexture &v);
|
|
~UniformSetTexture();
|
|
|
|
bgfx::UniformHandle uniform = BGFX_INVALID_HANDLE;
|
|
Texture texture;
|
|
uint8_t stage{0};
|
|
};
|
|
|
|
UniformSetTexture MakeUniformSetTexture(const char *name, const Texture &texture, uint8_t stage);
|
|
|
|
//
|
|
struct RenderState {
|
|
uint64_t state{BGFX_STATE_DEFAULT};
|
|
uint32_t rgba{0};
|
|
};
|
|
|
|
//
|
|
static const int MF_EnableSkinning = 0x01;
|
|
static const int MF_DiffuseUV1 = 0x02;
|
|
static const int MF_SpecularUV1 = 0x04;
|
|
static const int MF_AmbientUV1 = 0x08;
|
|
static const int MF_NormalMapInWorldSpace = 0x10;
|
|
static const int MF_EnableAlphaCut = 0x20;
|
|
|
|
struct Material { // 56B
|
|
PipelineProgramRef program;
|
|
uint32_t variant_idx{0};
|
|
|
|
struct Value {
|
|
bgfx::UniformType::Enum type{bgfx::UniformType::Vec4};
|
|
std::vector<float> value;
|
|
uint16_t count{1};
|
|
|
|
bgfx::UniformHandle uniform = BGFX_INVALID_HANDLE;
|
|
};
|
|
|
|
std::map<std::string, Value> values;
|
|
|
|
struct Texture {
|
|
TextureRef texture;
|
|
uint8_t channel{0};
|
|
|
|
bgfx::UniformHandle uniform = BGFX_INVALID_HANDLE;
|
|
};
|
|
|
|
std::map<std::string, Texture> textures;
|
|
|
|
RenderState state;
|
|
|
|
uint8_t flags{0};
|
|
};
|
|
|
|
Material CreateMaterial(PipelineProgramRef prg);
|
|
Material CreateMaterial(PipelineProgramRef prg, const char *value_name, const Vec4 &value);
|
|
Material CreateMaterial(PipelineProgramRef prg, const char *value_name_0, const Vec4 &value_0, const char *value_name_1, const Vec4 &value_1);
|
|
|
|
void SetMaterialProgram(Material &mat, PipelineProgramRef prg);
|
|
|
|
void SetMaterialValue(Material &mat, const char *name, float v);
|
|
void SetMaterialValue(Material &mat, const char *name, const Vec2 &v);
|
|
void SetMaterialValue(Material &mat, const char *name, const Vec3 &v);
|
|
void SetMaterialValue(Material &mat, const char *name, const Vec4 &v);
|
|
void SetMaterialValue(Material &mat, const char *name, const Mat3 &m);
|
|
void SetMaterialValue(Material &mat, const char *name, const Mat4 &m);
|
|
void SetMaterialValue(Material &mat, const char *name, const Mat44 &m);
|
|
|
|
void SetMaterialTexture(Material &mat, const char *name, TextureRef tex, uint8_t stage);
|
|
bool SetMaterialTextureRef(Material &mat, const char *name, TextureRef tex);
|
|
|
|
TextureRef GetMaterialTexture(Material &mat, const char *name);
|
|
std::vector<std::string> GetMaterialTextures(Material &mat);
|
|
|
|
std::vector<std::string> GetMaterialValues(Material &mat);
|
|
|
|
enum FaceCulling { FC_Disabled, FC_Clockwise, FC_CounterClockwise };
|
|
|
|
FaceCulling GetMaterialFaceCulling(const Material &mat);
|
|
void SetMaterialFaceCulling(Material &mat, FaceCulling mode);
|
|
|
|
enum DepthTest { DT_Less, DT_LessEqual, DT_Equal, DT_GreaterEqual, DT_Greater, DT_NotEqual, DT_Never, DT_Always, DT_Disabled };
|
|
|
|
DepthTest GetMaterialDepthTest(const Material &mat);
|
|
void SetMaterialDepthTest(Material &mat, DepthTest test);
|
|
|
|
/// Control the compositing mode used to draw primitives.
|
|
enum BlendMode { BM_Additive, BM_Alpha, BM_Darken, BM_Lighten, BM_Multiply, BM_Opaque, BM_Screen, BM_LinearBurn, BM_AlphaRGB_AddAlpha, BM_Undefined };
|
|
|
|
BlendMode GetMaterialBlendMode(const Material &mat);
|
|
void SetMaterialBlendMode(Material &mat, BlendMode mode);
|
|
|
|
void GetMaterialWriteRGBA(const Material &m_, bool &write_r, bool &write_g, bool &write_b, bool &write_a);
|
|
void SetMaterialWriteRGBA(Material &m_, bool write_r, bool write_g, bool write_b, bool write_a);
|
|
|
|
bool GetMaterialWriteZ(const Material &m);
|
|
void SetMaterialWriteZ(Material &m, bool enable);
|
|
|
|
bool GetMaterialNormalMapInWorldSpace(const Material &m);
|
|
void SetMaterialNormalMapInWorldSpace(Material &m, bool enable);
|
|
|
|
bool GetMaterialDiffuseUsesUV1(const Material &m);
|
|
void SetMaterialDiffuseUsesUV1(Material &m, bool enable);
|
|
bool GetMaterialSpecularUsesUV1(const Material &m);
|
|
void SetMaterialSpecularUsesUV1(Material &m, bool enable);
|
|
bool GetMaterialAmbientUsesUV1(const Material &m);
|
|
void SetMaterialAmbientUsesUV1(Material &m, bool enable);
|
|
|
|
bool GetMaterialSkinning(const Material &m);
|
|
void SetMaterialSkinning(Material &m, bool enable);
|
|
bool GetMaterialAlphaCut(const Material &m);
|
|
void SetMaterialAlphaCut(Material &m, bool enable);
|
|
|
|
/// Compute a render state to control subsequent render calls culling mode, blending mode, Z mask, etc... The same render state can be used by different render
|
|
/// calls.
|
|
/// @see DrawLines, DrawTriangles and DrawModel.
|
|
RenderState ComputeRenderState(BlendMode blend, bool write_z, bool write_r = true, bool write_g = true, bool write_b = true, bool write_a = true);
|
|
RenderState ComputeRenderState(BlendMode blend, DepthTest test = DT_Less, FaceCulling culling = FC_Clockwise, bool write_z = true, bool write_r = true,
|
|
bool write_g = true, bool write_b = true, bool write_a = true);
|
|
|
|
//
|
|
bgfx::VertexLayout VertexLayoutPosFloatNormFloat();
|
|
bgfx::VertexLayout VertexLayoutPosFloatNormUInt8();
|
|
bgfx::VertexLayout VertexLayoutPosFloatColorFloat();
|
|
bgfx::VertexLayout VertexLayoutPosFloatColorUInt8();
|
|
bgfx::VertexLayout VertexLayoutPosFloatTexCoord0UInt8();
|
|
bgfx::VertexLayout VertexLayoutPosFloatNormUInt8TexCoord0UInt8();
|
|
|
|
//
|
|
struct Model { // 96B (+heap)
|
|
std::vector<MinMax> bounds; // minmax/list
|
|
std::vector<DisplayList> lists;
|
|
std::vector<uint16_t> mats; // material/list
|
|
std::vector<Mat4> bind_pose; // bind pose matrices
|
|
};
|
|
|
|
struct ModelInfo {
|
|
bgfx::VertexLayout vs_decl{};
|
|
uint32_t tri_count{};
|
|
};
|
|
|
|
Model LoadModel(const Reader &ir, const Handle &h, const char *name, ModelInfo *info = nullptr, bool silent = false);
|
|
Model LoadModelFromFile(const char *path, ModelInfo *info = nullptr, bool silent = false);
|
|
Model LoadModelFromAssets(const char *name, ModelInfo *info = nullptr, bool silent = false);
|
|
|
|
size_t GetModelMaterialCount(const Model &model);
|
|
|
|
//
|
|
void Destroy(Model &model);
|
|
void Destroy(Material &material);
|
|
|
|
//
|
|
struct TextureLoad {
|
|
Reader ir;
|
|
ReadProvider ip;
|
|
TextureRef ref;
|
|
};
|
|
|
|
struct ModelLoad {
|
|
Reader ir;
|
|
ReadProvider ip;
|
|
ModelRef ref;
|
|
};
|
|
|
|
struct PipelineResources {
|
|
PipelineResources() : programs(Destroy), textures(Destroy), materials(Destroy), models(Destroy) {}
|
|
~PipelineResources() { DestroyAll(); }
|
|
|
|
ResourceCache<PipelineProgram, PipelineProgramRef> programs;
|
|
ResourceCache<Texture, TextureRef> textures;
|
|
ResourceCache<Material, MaterialRef> materials;
|
|
ResourceCache<Model, ModelRef> models;
|
|
|
|
std::deque<TextureLoad> texture_loads;
|
|
std::map<gen_ref, bgfx::TextureInfo> texture_infos;
|
|
|
|
std::deque<ModelLoad> model_loads;
|
|
std::map<gen_ref, ModelInfo> model_infos;
|
|
|
|
void DestroyAll();
|
|
};
|
|
|
|
//
|
|
size_t ProcessTextureLoadQueue(PipelineResources &resources, time_ns t_budget = time_from_ms(4), bool silent = false);
|
|
|
|
TextureRef QueueLoadTexture(const Reader &ir, const ReadProvider &ip, const char *name, uint64_t flags, PipelineResources &resources);
|
|
TextureRef QueueLoadTextureFromFile(const char *path, uint64_t flags, PipelineResources &resources);
|
|
TextureRef QueueLoadTextureFromAssets(const char *name, uint64_t flags, PipelineResources &resources);
|
|
|
|
TextureRef SkipLoadOrQueueTextureLoad(
|
|
const Reader &ir, const ReadProvider &ip, const char *path, PipelineResources &resources, bool queue_load, bool do_not_load, bool silent = false);
|
|
|
|
//
|
|
size_t ProcessModelLoadQueue(PipelineResources &resources, time_ns t_budget = time_from_ms(4), bool silent = false);
|
|
ModelRef QueueLoadModel(const Reader &ir, const ReadProvider &ip, const char *name, PipelineResources &resources);
|
|
|
|
ModelRef QueueLoadModelFromFile(const char *path, PipelineResources &resources);
|
|
ModelRef QueueLoadModelFromAssets(const char *name, PipelineResources &resources);
|
|
|
|
ModelRef SkipLoadOrQueueModelLoad(
|
|
const Reader &ir, const ReadProvider &ip, const char *path, PipelineResources &resources, bool queue_load, bool do_not_load, bool silent = false);
|
|
|
|
//
|
|
Material LoadMaterial(const json &js, const Reader &deps_ir, const ReadProvider &deps_ip, PipelineResources &resources, const PipelineInfo &pipeline,
|
|
bool queue_texture_loads, bool do_not_load_resources, bool silent = false);
|
|
Material LoadMaterial(const Reader &ir, const Handle &h, const Reader &deps_ir, const ReadProvider &deps_ip, PipelineResources &resources,
|
|
const PipelineInfo &pipeline, bool queue_texture_loads, bool do_not_load_resources, bool silent = false);
|
|
Material LoadMaterialFromFile(
|
|
const char *path, PipelineResources &resources, const PipelineInfo &pipeline, bool queue_texture_loads, bool do_not_load_resources, bool silent = false);
|
|
Material LoadMaterialFromAssets(
|
|
const char *path, PipelineResources &resources, const PipelineInfo &pipeline, bool queue_texture_loads, bool do_not_load_resources, bool silent = false);
|
|
|
|
bool SaveMaterial(const Material &mat, json &js, const PipelineResources &resources);
|
|
bool SaveMaterial(const Material &mat, const Writer &iw, const Handle &h, const PipelineResources &resources);
|
|
bool SaveMaterialToFile(const char *path, const Material &m, const PipelineResources &resources);
|
|
|
|
//
|
|
PipelineProgramRef LoadPipelineProgramRef(
|
|
const Reader &ir, const ReadProvider &ip, const char *name, PipelineResources &resources, const PipelineInfo &pipeline, bool silent = false);
|
|
PipelineProgramRef LoadPipelineProgramRefFromFile(const char *path, PipelineResources &resources, const PipelineInfo &pipeline, bool silent = false);
|
|
PipelineProgramRef LoadPipelineProgramRefFromAssets(const char *name, PipelineResources &resources, const PipelineInfo &pipeline, bool silent = false);
|
|
|
|
ModelRef LoadModel(const Reader &ir, const ReadProvider &ip, const char *path, PipelineResources &resources, bool silent = false);
|
|
ModelRef LoadModelFromFile(const char *path, PipelineResources &resources, bool silent = false);
|
|
ModelRef LoadModelFromAssets(const char *path, PipelineResources &resources, bool silent = false);
|
|
|
|
struct TextureMeta {
|
|
uint64_t flags{};
|
|
};
|
|
|
|
TextureMeta LoadTextureMeta(const Reader &ir, const ReadProvider &ip, const std::string &name, bool silent = false);
|
|
TextureMeta LoadTextureMetaFromFile(const std::string &path, bool silent = false);
|
|
TextureMeta LoadTextureMetaFromAssets(const std::string &name, bool silent = false);
|
|
|
|
TextureRef LoadTexture(const Reader &ir, const ReadProvider &ip, const char *path, uint64_t flags, PipelineResources &resources, bool silent = false);
|
|
TextureRef LoadTextureFromFile(const char *path, uint64_t flags, PipelineResources &resources, bool silent = false);
|
|
TextureRef LoadTextureFromAssets(const char *path, uint64_t flags, PipelineResources &resources, bool silent = false);
|
|
|
|
/// Capture a texture content to a Picture. Return the frame counter at which the capture will be complete.
|
|
/// A Picture object can be accessed by the CPU.
|
|
/// This function is asynchronous and its result will not be available until the returned frame counter is equal or greater to the frame counter returned by
|
|
/// Frame.
|
|
uint32_t CaptureTexture(const PipelineResources &resources, const TextureRef &t, Picture &pic);
|
|
|
|
MaterialRef LoadMaterialRef(const Reader &ir, const Handle &h, const char *path, const Reader &deps_ir, const ReadProvider &deps_ip,
|
|
PipelineResources &resources, const PipelineInfo &pipeline, bool queue_texture_loads, bool do_not_load_resources, bool silent = false);
|
|
MaterialRef LoadMaterialRefFromFile(
|
|
const char *path, PipelineResources &resources, const PipelineInfo &pipeline, bool queue_texture_loads, bool do_not_load_resources, bool silent = false);
|
|
MaterialRef LoadMaterialRefFromAssets(
|
|
const char *path, PipelineResources &resources, const PipelineInfo &pipeline, bool queue_texture_loads, bool do_not_load_resources, bool silent = false);
|
|
|
|
//
|
|
size_t GetQueuedResourceCount(const PipelineResources &res);
|
|
size_t ProcessLoadQueues(PipelineResources &res, time_ns t_budget = time_from_ms(4), bool silent = false);
|
|
|
|
//
|
|
std::vector<int> GetMaterialPipelineProgramFeatureStates(const Material &mat, const std::vector<PipelineProgramFeature> &features);
|
|
std::string GetPipelineProgramVariantName(const char *name, const std::vector<PipelineProgramFeature> &features, const std::vector<int> &states);
|
|
|
|
int GetPipelineProgramFeatureStateCount(PipelineProgramFeature feat);
|
|
|
|
int GetPipelineProgramVariantCount(const std::vector<PipelineProgramFeature> &feats);
|
|
int GetPipelineProgramVariantIndex(const std::vector<PipelineProgramFeature> &feats, const std::vector<int> &states);
|
|
|
|
void UpdateMaterialPipelineProgramVariant(Material &mat, const PipelineResources &resources);
|
|
|
|
void CreateMissingMaterialProgramValues(Material &mat, PipelineResources &resources, const Reader &ir, const ReadProvider &ip);
|
|
void CreateMissingMaterialProgramValuesFromFile(Material &mat, PipelineResources &resources);
|
|
void CreateMissingMaterialProgramValuesFromAssets(Material &mat, PipelineResources &resources);
|
|
|
|
/// Compute a sorting key to control the rendering order of a display list, `view_depth` is expected in view space.
|
|
uint32_t ComputeSortKey(float view_depth);
|
|
|
|
/// Compute a sorting key to control the rendering order of a display list.
|
|
uint32_t ComputeSortKeyFromWorld(const Vec3 &T, const Mat4 &view);
|
|
uint32_t ComputeSortKeyFromWorld(const Vec3 &T, const Mat4 &view, const Mat4 &model);
|
|
|
|
//
|
|
void DrawDisplayList(bgfx::ViewId view_id, bgfx::IndexBufferHandle idx, bgfx::VertexBufferHandle vtx, bgfx::ProgramHandle prg,
|
|
const std::vector<UniformSetValue> &values = {}, const std::vector<UniformSetTexture> &textures = {}, RenderState state = {}, uint32_t depth = 0);
|
|
|
|
/// Draw a model to the specified view.
|
|
/// @see UniformSetValueList and UniformSetTextureList to pass uniform values to the shader program.
|
|
void DrawModel(bgfx::ViewId view_id, const Model &mdl, bgfx::ProgramHandle prg, const std::vector<UniformSetValue> &values,
|
|
const std::vector<UniformSetTexture> &textures, const Mat4 *mtxs, size_t mtx_count = 1, RenderState state = {}, uint32_t depth = 0);
|
|
|
|
//
|
|
struct ModelDisplayList { // 16B
|
|
const Material *mat; // 8
|
|
uint32_t mtx_idx; // 4
|
|
uint16_t mdl_idx; // 2
|
|
uint16_t lst_idx; // 2
|
|
};
|
|
|
|
void CullModelDisplayLists(const Frustum &frustum, std::vector<ModelDisplayList> &display_lists, const std::vector<Mat4> &mtxs, const PipelineResources &res);
|
|
|
|
void DrawModelDisplayLists(bgfx::ViewId view_id, const std::vector<ModelDisplayList> &display_lists, uint8_t pipeline_config_idx,
|
|
const std::vector<UniformSetValue> &values, const std::vector<UniformSetTexture> &textures, const std::vector<Mat4> &mtxs, const PipelineResources &res);
|
|
void DrawModelDisplayLists(bgfx::ViewId view_id, const std::vector<ModelDisplayList> &display_lists, const std::vector<uint32_t> &depths,
|
|
uint8_t pipeline_config_idx, const std::vector<UniformSetValue> &values, const std::vector<UniformSetTexture> &textures, const std::vector<Mat4> &mtxs,
|
|
const PipelineResources &res);
|
|
void DrawModelDisplayLists(bgfx::ViewId view_id, const std::vector<ModelDisplayList> &display_lists, uint8_t pipeline_config_idx,
|
|
const std::vector<UniformSetValue> &values, const std::vector<UniformSetTexture> &textures, const std::vector<Mat4> &mtxs,
|
|
const std::vector<Mat4> &prv_mtxs, const PipelineResources &res);
|
|
|
|
//
|
|
struct SkinnedModelDisplayList { // 782B
|
|
const Material *mat; // 8
|
|
uint32_t mtx_idxs[max_skinned_model_matrix_count]; // 384
|
|
uint32_t bones_idxs[max_skinned_model_matrix_count]; // 384
|
|
uint16_t bone_count; // 2
|
|
uint16_t mdl_idx; // 2
|
|
uint16_t lst_idx; // 2
|
|
};
|
|
|
|
void DrawSkinnedModelDisplayLists(bgfx::ViewId view_id, const std::vector<SkinnedModelDisplayList> &display_lists, uint8_t pipeline_config_idx,
|
|
const std::vector<UniformSetValue> &values, const std::vector<UniformSetTexture> &textures, const std::vector<Mat4> &mtxs, const PipelineResources &res);
|
|
void DrawSkinnedModelDisplayLists(bgfx::ViewId view_id, const std::vector<SkinnedModelDisplayList> &display_lists, const std::vector<uint32_t> &depths,
|
|
uint8_t pipeline_config_idx, const std::vector<UniformSetValue> &values, const std::vector<UniformSetTexture> &textures, const std::vector<Mat4> &mtxs,
|
|
const PipelineResources &res);
|
|
void DrawSkinnedModelDisplayLists(bgfx::ViewId view_id, const std::vector<SkinnedModelDisplayList> &display_lists, uint8_t pipeline_config_idx,
|
|
const std::vector<UniformSetValue> &values, const std::vector<UniformSetTexture> &textures, const std::vector<Mat4> &mtxs,
|
|
const std::vector<Mat4> &prv_mtxs, const PipelineResources &res);
|
|
|
|
//
|
|
using Indices = std::vector<uint16_t>;
|
|
|
|
struct Vertices {
|
|
Vertices(const bgfx::VertexLayout &decl, size_t count);
|
|
|
|
const bgfx::VertexLayout &GetDecl() const { return decl; }
|
|
|
|
Vertices &Begin(size_t i);
|
|
Vertices &SetPos(const Vec3 &pos);
|
|
Vertices &SetNormal(const Vec3 &normal);
|
|
Vertices &SetTangent(const Vec3 &tangent);
|
|
Vertices &SetBinormal(const Vec3 &binormal);
|
|
Vertices &SetTexCoord0(const Vec2 &uv);
|
|
Vertices &SetTexCoord1(const Vec2 &uv);
|
|
Vertices &SetTexCoord2(const Vec2 &uv);
|
|
Vertices &SetTexCoord3(const Vec2 &uv);
|
|
Vertices &SetTexCoord4(const Vec2 &uv);
|
|
Vertices &SetTexCoord5(const Vec2 &uv);
|
|
Vertices &SetTexCoord6(const Vec2 &uv);
|
|
Vertices &SetTexCoord7(const Vec2 &uv);
|
|
Vertices &SetColor0(const Color &color);
|
|
Vertices &SetColor1(const Color &color);
|
|
Vertices &SetColor2(const Color &color);
|
|
Vertices &SetColor3(const Color &color);
|
|
void End(bool validate = false);
|
|
|
|
void Clear();
|
|
|
|
void Reserve(size_t count);
|
|
void Resize(size_t count);
|
|
|
|
const void *GetData() const { return data.data(); }
|
|
|
|
size_t GetSize() const { return data.size(); }
|
|
size_t GetCount() const { return data.size() / decl.getStride(); }
|
|
size_t GetCapacity() const { return data.capacity() / decl.getStride(); }
|
|
|
|
private:
|
|
bgfx::VertexLayout decl;
|
|
std::vector<char> data;
|
|
|
|
int idx{-1};
|
|
uint32_t vtx_attr_flag{};
|
|
};
|
|
|
|
//
|
|
void SetTransform(const Mat4 &world);
|
|
void SetUniforms(const std::vector<UniformSetValue> &values, const std::vector<UniformSetTexture> &textures);
|
|
|
|
/// Draw a list of lines to the specified view.
|
|
/// @see UniformSetValueList and UniformSetTextureList to pass uniform values to the shader program.
|
|
void DrawLines(bgfx::ViewId view_id, const Vertices &vtx, bgfx::ProgramHandle prg, RenderState = {}, uint32_t depth = 0);
|
|
void DrawLines(bgfx::ViewId view_id, const Vertices &vtx, bgfx::ProgramHandle prg, const std::vector<UniformSetValue> &values,
|
|
const std::vector<UniformSetTexture> &textures, RenderState = {}, uint32_t depth = 0);
|
|
void DrawLines(bgfx::ViewId view_id, const Indices &idx, const Vertices &vtx, bgfx::ProgramHandle prg, const std::vector<UniformSetValue> &values,
|
|
const std::vector<UniformSetTexture> &textures, RenderState = {}, uint32_t depth = 0);
|
|
/*!
|
|
Draw a list of sprites to the specified view.
|
|
@see UniformSetValueList and UniformSetTextureList to pass uniform values to the shader program.
|
|
@note This function prepares the sprite on the CPU before submitting them all to the GPU as a single draw call.
|
|
*/
|
|
void DrawSprites(bgfx::ViewId view_id, const Mat3 &inv_view_R, bgfx::VertexLayout &decl, const std::vector<Vec3> &pos, const Vec2 &size,
|
|
bgfx::ProgramHandle prg, RenderState state = {}, uint32_t depth = 0);
|
|
|
|
/// Draw a list of triangles to the specified view.
|
|
/// @see UniformSetValueList and UniformSetTextureList to pass uniform values to the shader program.
|
|
void DrawTriangles(bgfx::ViewId view_id, const Vertices &vtx, bgfx::ProgramHandle prg, RenderState = {}, uint32_t depth = 0);
|
|
void DrawTriangles(bgfx::ViewId view_id, const Vertices &vtx, bgfx::ProgramHandle prg, const std::vector<UniformSetValue> &values,
|
|
const std::vector<UniformSetTexture> &textures, RenderState = {}, uint32_t depth = 0);
|
|
void DrawTriangles(bgfx::ViewId view_id, const Indices &idx, const Vertices &vtx, bgfx::ProgramHandle prg, const std::vector<UniformSetValue> &values,
|
|
const std::vector<UniformSetTexture> &textures, RenderState = {}, uint32_t depth = 0);
|
|
void DrawSprites(bgfx::ViewId view_id, const Mat3 &inv_view_R, bgfx::VertexLayout &decl, const std::vector<Vec3> &pos, const Vec2 &size,
|
|
bgfx::ProgramHandle prg, const std::vector<UniformSetValue> &values, const std::vector<UniformSetTexture> &textures, RenderState state = {},
|
|
uint32_t depth = 0);
|
|
|
|
//
|
|
static const float default_shadow_bias = 0.0001f;
|
|
static const Vec4 default_pssm_split = {10.f, 50.f, 100.f, 500.f};
|
|
|
|
//
|
|
struct Pipeline {
|
|
std::map<std::string, bgfx::TextureHandle> textures;
|
|
std::map<std::string, bgfx::FrameBufferHandle> framebuffers;
|
|
|
|
std::vector<UniformSetValue> uniform_values;
|
|
std::vector<UniformSetTexture> uniform_textures;
|
|
};
|
|
|
|
void DestroyPipeline(Pipeline &pipeline);
|
|
|
|
//
|
|
struct FrameBuffer {
|
|
bgfx::FrameBufferHandle handle = BGFX_INVALID_HANDLE;
|
|
};
|
|
|
|
FrameBuffer CreateFrameBuffer(const Texture &color, const Texture &depth, const char *name);
|
|
FrameBuffer CreateFrameBuffer(bgfx::TextureFormat::Enum color_format, bgfx::TextureFormat::Enum depth_format, int aa, const char *name);
|
|
FrameBuffer CreateFrameBuffer(int width, int height, bgfx::TextureFormat::Enum color_format, bgfx::TextureFormat::Enum depth_format, int aa, const char *name);
|
|
|
|
Texture GetColorTexture(FrameBuffer &frameBuffer);
|
|
Texture GetDepthTexture(FrameBuffer &frameBuffer);
|
|
|
|
/// Destroy a frame buffer and its resources.
|
|
void DestroyFrameBuffer(FrameBuffer &frameBuffer);
|
|
|
|
bool CreateFullscreenQuad(bgfx::TransientIndexBuffer &idx, bgfx::TransientVertexBuffer &vtx);
|
|
|
|
bimg::ImageContainer *LoadImage(const Reader &ir, const ReadProvider &ip, const char *name);
|
|
bimg::ImageContainer *LoadImageFromFile(const char *name);
|
|
bimg::ImageContainer *LoadImageFromAssets(const char *name);
|
|
void UpdateTextureFromImage(Texture &tex, bimg::ImageContainer *img, bool auto_delete = true);
|
|
|
|
} // namespace hg
|