mirror of
https://github.com/harfang3d/harfang3d.git
synced 2024-06-17 12:32:33 +00:00
commit
b2ff839cbd
|
@ -101,6 +101,10 @@ if(MSVC)
|
|||
#add_compile_options(/Od /Zi /Zo)
|
||||
add_link_options(/DEBUG)
|
||||
#add_link_options(/LTCG)
|
||||
|
||||
# Don't forget to remove this as soon as CMake is fixed.
|
||||
# Tells MSVC to update __cplusplus value, otherwise it will be stuck to 199711L and libraries like bx (if updated) won't compile anymore even if we set CMAKE_CXX_STANDARD to C++14.
|
||||
add_compile_options(/Zc:__cplusplus)
|
||||
elseif(ANDROID)
|
||||
add_compile_definitions(ANDROID)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
||||
|
|
|
@ -1300,6 +1300,8 @@ def bind_scene(gen):
|
|||
|
||||
gen.bind_member(scene, 'hg::Scene::Environment environment')
|
||||
|
||||
gen.bind_method(scene, 'SetProbe', 'void', ['hg::TextureRef irradiance', 'hg::TextureRef radiance', 'hg::TextureRef brdf'])
|
||||
|
||||
#
|
||||
gen.bind_method(scene, 'GetCurrentCamera', 'hg::Node', [])
|
||||
gen.bind_method(scene, 'SetCurrentCamera', 'void', ['const hg::Node &camera'])
|
||||
|
@ -1698,13 +1700,13 @@ static void __LuaVM_DestroyScripts(hg::SceneLuaVM *vm, const std::vector<hg::Scr
|
|||
static hg::LuaObject __LuaVM_GetScriptEnv(hg::SceneLuaVM *vm, const hg::Script &script) { return vm->GetScriptEnv(script.ref); }
|
||||
|
||||
static hg::LuaObject __LuaVM_GetScriptValue(hg::SceneLuaVM *vm, const hg::Script &script, const std::string &name) { return vm->GetScriptValue(script.ref, name); }
|
||||
static bool __LuaVM_SetScriptValue(hg::SceneLuaVM *vm, const hg::Script &script, const std::string &name, const hg::LuaObject &value) { return vm->SetScriptValue(script.ref, name, value); }
|
||||
static bool __LuaVM_SetScriptValue(hg::SceneLuaVM *vm, const hg::Script &script, const std::string &name, const hg::LuaObject &value, bool notify = true) { return vm->SetScriptValue(script.ref, name, value, notify); }
|
||||
''')
|
||||
|
||||
gen.bind_method(vm, 'GetScriptEnv', 'hg::LuaObject', ['const hg::Script &script'], {'route': route_lambda('__LuaVM_GetScriptEnv')})
|
||||
|
||||
gen.bind_method(vm, 'GetScriptValue', 'hg::LuaObject', ['const hg::Script &script', 'const std::string &name'], {'route': route_lambda('__LuaVM_GetScriptValue')})
|
||||
gen.bind_method(vm, 'SetScriptValue', 'bool', ['const hg::Script &script', 'const std::string &name', 'const hg::LuaObject &value'], {'route': route_lambda('__LuaVM_SetScriptValue')})
|
||||
gen.bind_method(vm, 'SetScriptValue', 'bool', ['const hg::Script &script', 'const std::string &name', 'const hg::LuaObject &value', '?bool notify'], {'route': route_lambda('__LuaVM_SetScriptValue')})
|
||||
|
||||
gen.bind_method_overloads(vm, 'Call', expand_std_vector_proto(gen, [
|
||||
('bool', ['const hg::Script &script', 'const std::string &function', 'const std::vector<hg::LuaObject> &args', 'std::vector<hg::LuaObject> *ret_vals'], {'arg_out': ['ret_vals']})
|
||||
|
@ -2658,8 +2660,8 @@ def bind_forward_pipeline(gen):
|
|||
gen.end_class(fog)
|
||||
|
||||
# submit model to forward pipeline stage
|
||||
gen.bind_function('hg::SubmitModelToForwardPipeline', 'void', ['bgfx::ViewId &view_id', 'const hg::Model &mdl', 'const hg::ForwardPipeline &pipeline', 'const hg::PipelineProgram &prg', 'uint32_t prg_variant',
|
||||
'uint8_t pipeline_stage', 'const hg::Color &ambient', 'const hg::ForwardPipelineLights &lights', 'const hg::ForwardPipelineFog &fog', 'const hg::Mat4 &mtx'], {'arg_in_out': ['view_id']})
|
||||
#gen.bind_function('hg::SubmitModelToForwardPipeline', 'void', ['bgfx::ViewId &view_id', 'const hg::Model &mdl', 'const hg::ForwardPipeline &pipeline', 'const hg::PipelineProgram &prg', 'uint32_t prg_variant',
|
||||
#'uint8_t pipeline_stage', 'const hg::Color &ambient', 'const hg::ForwardPipelineLights &lights', 'const hg::ForwardPipelineFog &fog', 'const hg::Mat4 &mtx'], {'arg_in_out': ['view_id']})
|
||||
|
||||
def bind_file(gen):
|
||||
gen.add_include('foundation/file.h')
|
||||
|
@ -3609,11 +3611,10 @@ def bind_imgui(gen):
|
|||
|
||||
gen.bind_named_enum('ImGuiCond', ['ImGuiCond_Always', 'ImGuiCond_Once', 'ImGuiCond_FirstUseEver', 'ImGuiCond_Appearing'], 'int', namespace='')
|
||||
|
||||
gen.bind_named_enum('ImGuiMouseButton', [
|
||||
'ImGuiPopupFlags_None',
|
||||
'ImGuiPopupFlags_MouseButtonLeft', 'ImGuiPopupFlags_MouseButtonRight', 'ImGuiPopupFlags_MouseButtonMiddle',
|
||||
'ImGuiPopupFlags_NoOpenOverExistingPopup', 'ImGuiPopupFlags_NoOpenOverItems',
|
||||
'ImGuiPopupFlags_AnyPopupId', 'ImGuiPopupFlags_AnyPopupLevel', 'ImGuiPopupFlags_AnyPopup'
|
||||
gen.bind_named_enum('ImGuiMouseButton', [
|
||||
'ImGuiMouseButton_Left',
|
||||
'ImGuiMouseButton_Right',
|
||||
'ImGuiMouseButton_Middle',
|
||||
], 'int', namespace='')
|
||||
|
||||
gen.bind_named_enum('ImGuiHoveredFlags', [
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
* François Gutherz
|
||||
* Emmanuel Julien
|
||||
* Eric Kernin
|
||||
* Elie Michel
|
||||
* Thomas "Scorpheus" Simonnet
|
|
@ -1 +1 @@
|
|||
A function taking a time value as parameter with no return value, see [man.UnitSystem].
|
||||
A function taking a time value as parameter with no return value, see [man.CoordinateAndUnitSystem].
|
|
@ -61,18 +61,18 @@ This file is a JSON file listing the supported features and additional uniforms.
|
|||
|
||||
The following features are supported and have the following effect on the compilation process.
|
||||
|
||||
Feature | States | Preprocessor Directive | Uniform | Stage channel
|
||||
Feature | States | Preprocessor Directive | Uniform | Recommended channel
|
||||
------- | ----------- | ---------------------- | ------- |--------------
|
||||
OptionalBaseColorOpacityMap | 2 | USE_BASE_COLOR_OPACITY_MAP=[1 or 0] | uBaseOpacityMap | 0
|
||||
OptionalDiffuseMap | 2 | USE_DIFFUSE_MAP=[1 or 0] | uDiffuseMap | 0
|
||||
OptionalOcclusionRoughnessMetalnessMap | 2 | USE_OCCLUSION_ROUGHNESS_METALNESS_MAP=[1 or 0] | uOcclusionRoughnessMetalnessMap| 1
|
||||
OptionalDiffuseMap | 2 | USE_DIFFUSE_MAP=[1 or 0] | uDiffuseMap | 3
|
||||
OptionalSpecularMap | 2 | USE_SPECULAR_MAP=[1 or 0] | uSpecularMap | 1
|
||||
OptionalNormalMap | 2 | USE_NORMAL_MAP=[1 or 0] | uNormalMap | 2
|
||||
OptionalLightMap | 2 | USE_LIGHT_MAP=[1 or 0] | uLightMap | 3
|
||||
OptionalSelfMap | 2 | USE_SELF_MAP=[1 or 0] | uSelfMap | 4
|
||||
OptionalOpacityMap | 2 | USE_OPACITY_MAP=[1 or 0] | uOpacityMap | 5
|
||||
OptionalAmbientMap | 2 | USE_AMBIENT_MAP=[1 or 0] | uAmbientMap | 6
|
||||
OptionalReflectionMap | 2 | USE_REFLECTION_MAP=[1 or 0] | uReflectionMap | 7
|
||||
OptionalNormalMap | 2 | USE_NORMAL_MAP=[1 or 0] | uNormalMap | 2
|
||||
NormalMapInWorldSpace | 2 | NORMAL_MAP_IN_WORLD_SPACE=[1 or 0] | - | -
|
||||
DiffuseUV1 | 2 | DIFFUSE_UV_CHANNEL=[1 or 0] | - | -
|
||||
SpecularUV1 | 2 | SPECULAR_UV_CHANNEL=[1 or 0] | - | -
|
||||
|
|
|
@ -8,7 +8,7 @@ Once you have a functioning installation of Harfang for your language of choice:
|
|||
Follow the following steps:
|
||||
|
||||
1. Download the tutorials from Github [here](https://github.com/harfang3d/tutorials-hg2.git) and unzip them to your computer _(eg. in `d:/tutorials-hg2`)_.
|
||||
1. Download _assetc_ for your platform from [here](https://www.harfang3d.com/releases) to compile the tutorial resources.
|
||||
1. Download _assetc_ for your platform from [here](https://dev.harfang3d.com/releases) to compile the tutorial resources.
|
||||
1. Drag and drop the tutorial resources folder on the assetc executable **-OR-** execute assetc passing it the path to the tutorial resources folder _(eg. `assetc d:/tutorials-hg2/resources`)_.
|
||||
|
||||
![assetc drag & drop](/images/docs/${HG_VERSION}/assetc.gif)
|
||||
|
|
30
harfang/cmake/Finduuid.cmake
Normal file
30
harfang/cmake/Finduuid.cmake
Normal file
|
@ -0,0 +1,30 @@
|
|||
#[[
|
||||
Try to find libuuid
|
||||
Provides the following target and variables:
|
||||
* uuid : library target
|
||||
* UUID_FOUND : set if libuuid was found
|
||||
* UUID_INCLUDE_DIR : libuuid include diretory
|
||||
* UUID_LIBRARY : libuuid library file
|
||||
#]]
|
||||
find_path(UUID_INCLUDE_DIR
|
||||
NAMES uuid/uuid.h
|
||||
HINTS ${UUID_ROOT_DIR}
|
||||
)
|
||||
|
||||
find_library(UUID_LIBRARY
|
||||
NAMES uuid
|
||||
HINTS ${UUID_ROOT_DIR}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(uuid REQUIRED_VARS UUID_LIBRARY UUID_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(UUID_FOUND UUID_LIBRARY UUID_INCLUDE_DIR)
|
||||
|
||||
if(UUID_FOUND AND NOT TARGET uuid)
|
||||
add_library(uuid UNKNOWN IMPORTED)
|
||||
set_target_properties(uuid PROPERTIES
|
||||
IMPORTED_LOCATION "${UUID_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${UUID_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
|
@ -133,6 +133,17 @@ static bool Package_file_is_EOF(Asset_ &asset) { return asset.pkg_file.cursor >=
|
|||
//
|
||||
static generational_vector_list<Asset_> assets;
|
||||
|
||||
std::string FindAssetPath(const char *name) {
|
||||
std::lock_guard<std::mutex> lock(assets_mutex);
|
||||
|
||||
for (auto &p : assets_folders) {
|
||||
const auto asset_path = hg::PathJoin({p, name});
|
||||
if (IsFile(asset_path.c_str()))
|
||||
return asset_path;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Asset OpenAsset(const char *name, bool silent) {
|
||||
std::lock_guard<std::mutex> lock(assets_mutex);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ struct Asset {
|
|||
gen_ref ref;
|
||||
};
|
||||
|
||||
std::string FindAssetPath(const char *name);
|
||||
Asset OpenAsset(const char *name, bool silent = false);
|
||||
void Close(Asset asset);
|
||||
|
||||
|
|
|
@ -386,6 +386,10 @@ static void ALChannelSetState(ALint src, const StereoSourceState &state, bool st
|
|||
__AL_CALL(alSourcei(src, AL_LOOPING, !stream && state.repeat == SR_Loop ? AL_TRUE : AL_FALSE)); // [EJ20190512] looping is handled manually with streaming
|
||||
|
||||
__AL_CALL(alSource3f(src, AL_POSITION, state.panning, 0.f, sqrtf(1.f - state.panning * state.panning)));
|
||||
const ALfloat o[6] = {0, 0, -1, 0, 1, 0};
|
||||
__AL_CALL(alSourcefv(src, AL_ORIENTATION, o));
|
||||
const ALfloat v[3] = {0, 0, 0};
|
||||
__AL_CALL(alSourcefv(src, AL_VELOCITY, v));
|
||||
}
|
||||
|
||||
static void ALChannelSetState(ALint src, const SpatializedSourceState &state, bool stream) {
|
||||
|
|
|
@ -64,7 +64,6 @@ enum ForwardPipelineUniformTexture {
|
|||
UT_BrdfMap,
|
||||
UT_NoiseMap,
|
||||
|
||||
UT_AmbientOcclusion,
|
||||
UT_LinearShadowMap,
|
||||
UT_SpotShadowMap,
|
||||
|
||||
|
@ -176,7 +175,7 @@ void UpdateForwardPipelineProbe(
|
|||
}
|
||||
|
||||
void UpdateForwardPipelineNoise(ForwardPipeline &pipeline, Texture noise) { pipeline.uniform_textures[UT_NoiseMap].texture = noise; }
|
||||
void UpdateForwardPipelineAO(ForwardPipeline &pipeline, Texture ao) { pipeline.uniform_textures[UT_AmbientOcclusion].texture = ao; }
|
||||
void UpdateForwardPipelineAO(ForwardPipeline &pipeline, Texture ao) { /*pipeline.uniform_textures[UT_AmbientOcclusion].texture = ao;*/ }
|
||||
|
||||
//
|
||||
static float backbuffer_ratio[bgfx::BackbufferRatio::Count] = {1.f, 2.f, 4.f, 8.f, 16.f, 0.5f};
|
||||
|
@ -204,19 +203,6 @@ void UpdateForwardPipelineAAA(ForwardPipeline &pipeline, Texture ssgi, Texture s
|
|||
}
|
||||
|
||||
//
|
||||
void SubmitModelToForwardPipeline(bgfx::ViewId view_id, const Model &mdl, const ForwardPipeline &pipeline, const PipelineProgram &prg, uint32_t prg_variant,
|
||||
uint8_t pipeline_stage, const Color &ambient, const ForwardPipelineLights &lights, const ForwardPipelineFog &fog, const Mat4 &mtx) {
|
||||
const auto _mtx = to_bgfx(mtx);
|
||||
/*
|
||||
const auto pipeline_set_draw_env = [&](int mat_idx) {
|
||||
UpdateForwardPipelineUniforms(pipeline.uniforms, ambient, lights, fog);
|
||||
set_draw_env(mat_idx);
|
||||
};
|
||||
|
||||
RenderModel(view_id, mdl, prg.variants[prg_variant][pipeline_stage], pipeline_set_draw_env, mtx);
|
||||
*/
|
||||
}
|
||||
|
||||
static Mat4 ComputeCropMatrix() {
|
||||
const bgfx::Caps *caps = bgfx::getCaps();
|
||||
const float sy = caps->originBottomLeft ? 0.5f : -0.5f;
|
||||
|
@ -494,13 +480,12 @@ ForwardPipeline CreateForwardPipeline(int shadow_map_resolution, bool spot_16bit
|
|||
__ASSERT__(pipeline.uniform_values.size() == UV_Count);
|
||||
|
||||
pipeline.uniform_textures = {
|
||||
MakeUniformSetTexture("uIrradianceMap", {}, 7),
|
||||
MakeUniformSetTexture("uRadianceMap", {}, 8),
|
||||
MakeUniformSetTexture("uSSIrradianceMap", {}, 9),
|
||||
MakeUniformSetTexture("uSSRadianceMap", {}, 10),
|
||||
MakeUniformSetTexture("uBrdfMap", {}, 11),
|
||||
MakeUniformSetTexture("uNoiseMap", {}, 12),
|
||||
MakeUniformSetTexture("uAmbientOcclusion", {}, 13),
|
||||
MakeUniformSetTexture("uIrradianceMap", {}, 8),
|
||||
MakeUniformSetTexture("uRadianceMap", {}, 9),
|
||||
MakeUniformSetTexture("uSSIrradianceMap", {}, 10),
|
||||
MakeUniformSetTexture("uSSRadianceMap", {}, 11),
|
||||
MakeUniformSetTexture("uBrdfMap", {}, 12),
|
||||
MakeUniformSetTexture("uNoiseMap", {}, 13),
|
||||
MakeUniformSetTexture("uLinearShadowMap", {BGFX_TEXTURE_RT | BGFX_SAMPLER_COMPARE_LEQUAL, pipeline.textures["linear_shadow_map"]}, 14),
|
||||
MakeUniformSetTexture("uSpotShadowMap", {BGFX_TEXTURE_RT | BGFX_SAMPLER_COMPARE_LEQUAL, pipeline.textures["spot_shadow_map"]}, 15),
|
||||
};
|
||||
|
|
|
@ -96,9 +96,6 @@ const PipelineInfo &GetForwardPipelineInfo();
|
|||
//
|
||||
enum ForwardPipelineStage { FPS_AttributeBuffers, FPS_Basic, FPS_Advanced, FPS_DepthOnly };
|
||||
|
||||
void SubmitModelToForwardPipeline(bgfx::ViewId view_id, const Model &mdl, const ForwardPipeline &pipeline, const PipelineProgram &prg, uint32_t prg_variant,
|
||||
uint8_t pipeline_config_idx, const Color &ambient, const ForwardPipelineLights &lights, const ForwardPipelineFog &fog, const Mat4 &mtx);
|
||||
|
||||
//
|
||||
enum ForwardPipelineShadowPass { FPSP_Slot0LinearSplit0, FPSP_Slot0LinearSplit1, FPSP_Slot0LinearSplit2, FPSP_Slot0LinearSplit3, FPSP_Slot1Spot, FPSP_Count };
|
||||
|
||||
|
|
|
@ -35,8 +35,7 @@ static HiZ _CreateHiZ(
|
|||
hiz.pyramid_infos.format = bgfx::TextureFormat::RG32F;
|
||||
|
||||
bgfx::TextureHandle handle = rb_factory.create_texture2d(
|
||||
ratio, hiz.pyramid_infos.numMips > 0,
|
||||
hiz.pyramid_infos.numLayers, hiz.pyramid_infos.format, BGFX_TEXTURE_COMPUTE_WRITE | flags);
|
||||
ratio, hiz.pyramid_infos.numMips > 0, hiz.pyramid_infos.numLayers, hiz.pyramid_infos.format, BGFX_TEXTURE_COMPUTE_WRITE | flags);
|
||||
|
||||
hiz.pyramid = MakeTexture(handle, BGFX_TEXTURE_COMPUTE_WRITE | flags);
|
||||
hiz.prg_copy = LoadComputeProgram(ir, ip, format("%1/shader/hiz_copy_cs.sc").arg(path));
|
||||
|
@ -66,11 +65,9 @@ void DestroyHiZ(HiZ &hiz) {
|
|||
bgfx_Destroy(hiz.u_projection);
|
||||
}
|
||||
|
||||
void ComputeHiZ(
|
||||
bgfx::ViewId &view_id, const hg::iVec2 &fb_size, const iRect &rect, const Mat44 &proj, float z_thickness, const Texture &depth, HiZ &hiz) {
|
||||
void ComputeHiZ(bgfx::ViewId &view_id, const hg::iVec2 &fb_size, const iRect &rect, const Mat44 &proj, float z_thickness, const Texture &depth, HiZ &hiz) {
|
||||
__ASSERT__(IsValid(hiz));
|
||||
|
||||
|
||||
int div = 1;
|
||||
switch (hiz.ratio) {
|
||||
case bgfx::BackbufferRatio::Half:
|
||||
|
@ -88,7 +85,8 @@ void ComputeHiZ(
|
|||
default:
|
||||
div = 1;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
auto width = fb_size.x;
|
||||
auto height = fb_size.y;
|
||||
bgfx::calcTextureSize(hiz.pyramid_infos, width / div, height / div, hiz.pyramid_infos.depth, hiz.pyramid_infos.cubeMap, hiz.pyramid_infos.numMips,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_write.h"
|
||||
#include "stb_image_resize.h"
|
||||
|
||||
namespace hg {
|
||||
|
||||
|
@ -143,7 +144,13 @@ void Picture::Clear() {
|
|||
|
||||
// TODO EJ implement these
|
||||
Picture Crop(const Picture &picture, uint16_t width, uint16_t height) { return picture; }
|
||||
Picture Resize(const Picture &picture, uint16_t width, uint16_t height) { return picture; }
|
||||
Picture Resize(const Picture &picture, uint16_t width, uint16_t height) {
|
||||
Picture pic(width, height, picture.GetFormat());
|
||||
stbir_resize_uint8(picture.GetData(), picture.GetWidth(), picture.GetHeight(), picture.GetWidth() * size_of(picture.GetFormat()),
|
||||
pic.GetData(), pic.GetWidth(), pic.GetHeight(), pic.GetWidth() * size_of(pic.GetFormat()), size_of(pic.GetFormat()));
|
||||
|
||||
return pic;
|
||||
}
|
||||
|
||||
//
|
||||
Color GetPixelRGBA(const Picture &pic, uint16_t x, uint16_t y) {
|
||||
|
|
|
@ -400,7 +400,8 @@ 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.
|
||||
/// 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,
|
||||
|
@ -526,7 +527,8 @@ TextureRef LoadTextureFromAssets(const char *path, uint64_t flags, PipelineResou
|
|||
|
||||
/// 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.
|
||||
/// 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,
|
||||
|
|
|
@ -30,6 +30,14 @@ Scene::~Scene() {
|
|||
scene_ref->scene = nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
void Scene::SetProbe(TextureRef irradiance, TextureRef radiance, TextureRef brdf) {
|
||||
environment.probe = {};
|
||||
environment.probe.irradiance_map = irradiance;
|
||||
environment.probe.radiance_map = radiance;
|
||||
environment.brdf_map = brdf;
|
||||
}
|
||||
|
||||
//
|
||||
static void _ResizeComponents(std::vector<ComponentRef> &cs) {
|
||||
ptrdiff_t i;
|
||||
|
@ -2631,6 +2639,24 @@ void SetAnimableNodePropertyColor(Scene &scene, NodeRef ref, const std::string &
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
std::vector<hg::Material *> Scene::GetMaterialsWithName(const std::string &name) {
|
||||
std::vector<hg::Material *> mats;
|
||||
mats.reserve(objects.size() / 8); // guesstimate
|
||||
|
||||
for (auto ref = objects.first_ref(); objects.is_valid(ref); ref = objects.next_ref(ref)) {
|
||||
auto &obj = objects[ref.idx];
|
||||
|
||||
const auto mat_count = obj.material_infos.size();
|
||||
|
||||
for (size_t i = 0; i < mat_count; ++i)
|
||||
if (obj.material_infos[i].name == name)
|
||||
mats.push_back(&obj.materials[i]);
|
||||
}
|
||||
|
||||
return mats;
|
||||
}
|
||||
|
||||
//
|
||||
std::string GetAnimableNodePropertyString(const Scene &scene, NodeRef ref, const std::string &name) {
|
||||
if (const auto node = scene.GetNode(ref)) {
|
||||
|
|
|
@ -355,6 +355,8 @@ public:
|
|||
Object GetNodeObject(NodeRef ref) const { return {scene_ref, GetNodeObjectRef(ref)}; }
|
||||
void SetNodeObject(NodeRef ref, const Object &v) { SetNodeObject(ref, v.ref); }
|
||||
|
||||
std::vector<hg::Material *> GetMaterialsWithName(const std::string &name);
|
||||
|
||||
// light component
|
||||
Light CreateLight();
|
||||
void DestroyLight(ComponentRef ref);
|
||||
|
@ -584,6 +586,8 @@ public:
|
|||
|
||||
Environment environment{};
|
||||
|
||||
void SetProbe(TextureRef irradiance, TextureRef radiance, TextureRef brdf);
|
||||
|
||||
// scene state
|
||||
Node GetCurrentCamera() const { return {scene_ref, current_camera}; }
|
||||
void SetCurrentCamera(NodeRef ref) { current_camera = ref; }
|
||||
|
|
|
@ -257,7 +257,7 @@ void SceneBullet3Physics::NodeCreatePhysics(const Node &node, const Reader &ir,
|
|||
} else if (type == CT_Capsule) {
|
||||
shapes.push_back(new btCapsuleShape(size.x, size.y));
|
||||
} else if (type == CT_Cylinder) {
|
||||
shapes.push_back(new btCylinderShape(btVector3(size.x, size.y, size.z)));
|
||||
shapes.push_back(new btCylinderShape(btVector3(size.x, size.y * 0.5f, size.z)));
|
||||
} else if (type == CT_Mesh) {
|
||||
if (auto tree = LoadCollisionTree(ir, ip, col.GetCollisionResource().c_str()))
|
||||
shapes.push_back(tree);
|
||||
|
|
|
@ -178,13 +178,17 @@ LuaObject SceneLuaVM::GetScriptValue(ComponentRef ref, const std::string &name)
|
|||
return i == std::end(lua_scripts) ? LuaObject{} : Get(i->second, name);
|
||||
}
|
||||
|
||||
bool SceneLuaVM::SetScriptValue(ComponentRef ref, const std::string &name, const LuaObject &v) {
|
||||
bool SceneLuaVM::SetScriptValue(ComponentRef ref, const std::string &name, const LuaObject &v, bool notify) {
|
||||
auto i = lua_scripts.find(ref);
|
||||
|
||||
if (i == std::end(lua_scripts))
|
||||
return false;
|
||||
|
||||
SetForeign(i->second, name, v);
|
||||
|
||||
if (notify)
|
||||
Call(ref, "OnSetScriptValue", {MakeLuaObj(L, name)});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -312,8 +316,10 @@ std::vector<ComponentRef> SceneLuaVM::GarbageCollect(const Scene &scene) const {
|
|||
void SceneLuaVM::DestroyScripts(const std::vector<ComponentRef> &scripts) {
|
||||
for (auto ref : scripts) {
|
||||
auto i = lua_scripts.find(ref);
|
||||
if (i != std::end(lua_scripts))
|
||||
if (i != std::end(lua_scripts)) {
|
||||
Call(ref, "OnDestroy", {});
|
||||
lua_scripts.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
/// Return the value of a script variable.
|
||||
LuaObject GetScriptValue(ComponentRef script, const std::string &name) const;
|
||||
/// Set the value of a script variable.
|
||||
bool SetScriptValue(ComponentRef script, const std::string &name, const LuaObject &value);
|
||||
bool SetScriptValue(ComponentRef script, const std::string &name, const LuaObject &value, bool notify = true);
|
||||
|
||||
/// Return the VM lua state.
|
||||
lua_State *GetL() const { return L; }
|
||||
|
|
|
@ -118,16 +118,6 @@ static void CallScriptDetachFromNode(SceneLuaVM &vm, Node &node, const Script &s
|
|||
//
|
||||
static size_t SceneScriptsDestroyGarbageCall(SceneLuaVM &vm, Scene &scene) {
|
||||
const auto garbage = vm.GarbageCollect(scene);
|
||||
|
||||
for (auto s : garbage) {
|
||||
auto env = vm.GetScriptEnv(s);
|
||||
|
||||
if (auto on_destroy = Get(env, "OnDestroy")) {
|
||||
on_destroy.Push();
|
||||
hg_lua_OnDestroy(env.L(), -1);
|
||||
}
|
||||
}
|
||||
|
||||
vm.DestroyScripts(garbage);
|
||||
return garbage.size();
|
||||
}
|
||||
|
|
2631
harfang/engine/stb_image_resize.h
Normal file
2631
harfang/engine/stb_image_resize.h
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -164,6 +164,7 @@ set_property(TARGET foundation PROPERTY PUBLIC_HEADER "${HDRS}")
|
|||
set_target_properties(foundation PROPERTIES FOLDER "harfang")
|
||||
|
||||
if(NOT WIN32)
|
||||
find_package(uuid REQUIRED)
|
||||
target_link_libraries(foundation PUBLIC uuid)
|
||||
else()
|
||||
target_link_libraries(foundation PUBLIC Iphlpapi)
|
||||
|
|
|
@ -156,7 +156,7 @@ bool LineIntersectCone(const Vec3 &a, const Vec3 &v, const Vec3 &c, const Vec3 &
|
|||
if (((t0 < h0) || (t0 > h1)) && ((t1 < h0) || (t1 > h1))) {
|
||||
return false;
|
||||
}
|
||||
} else if (dvac > h) {
|
||||
} else if (ddac > h) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ static bool log_is_detailed = false;
|
|||
|
||||
void set_log_level(int level) { log_level = level; }
|
||||
void set_log_detailed(bool is_detailed) { log_is_detailed = is_detailed; }
|
||||
int get_log_level() { return log_level; }
|
||||
bool get_log_detailed() { return log_is_detailed; }
|
||||
|
||||
|
||||
//
|
||||
static void default_log_hook(const char *msg, int mask, const char *details, void *user) {
|
||||
|
|
|
@ -17,5 +17,7 @@ void set_log_hook(void (*on_log)(const char *msg, int mask, const char *details,
|
|||
void set_log_level(int log_level);
|
||||
/// Enable detailed log output.
|
||||
void set_log_detailed(bool is_detailed);
|
||||
int get_log_level();
|
||||
bool get_log_detailed();
|
||||
|
||||
} // namespace hg
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <cctype>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
#include <codecvt>
|
||||
|
||||
|
|
|
@ -221,6 +221,14 @@ bool SaveFileDialog(const std::string &title, const std::vector<hg::FileFilter>
|
|||
}
|
||||
pFileSave->Release();
|
||||
}
|
||||
|
||||
// ensure extension is present
|
||||
const auto ext = hg::GetFileExtension(output);
|
||||
|
||||
if (ext.empty() && !filters.empty())
|
||||
if (filters[0].pattern.size() > 2)
|
||||
output += &filters[0].pattern[1];
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
|
|
|
@ -129,6 +129,7 @@ TEST(BGFX, RenderModelNoPipeline) {
|
|||
}
|
||||
|
||||
//
|
||||
/*
|
||||
TEST(BGFX, SubmitModelToForwardPipeline) {
|
||||
InputInit();
|
||||
|
||||
|
@ -192,6 +193,7 @@ TEST(BGFX, SubmitModelToForwardPipeline) {
|
|||
RenderShutdown();
|
||||
DestroyWindow(window);
|
||||
}
|
||||
*/
|
||||
|
||||
//
|
||||
TEST(BGFX, AddModelToSceneAndSubmitToForwardPipeline) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
3.2.2
|
||||
3.2.3
|
|
@ -13,7 +13,7 @@ See https://www.harfang3d.com/license for licensing terms.
|
|||
| **Quickstart**
|
||||
|
||||
1. Download the tutorials https://github.com/harfang3d/tutorials-hg2 and unzip them to your computer (eg. *d:/tutorials-hg2*).
|
||||
2. To compile the tutorial resources, download **assetc** for your platform: https://www.harfang3d.com/releases/
|
||||
2. To compile the tutorial resources, download **assetc** for your platform: https://dev.harfang3d.com/releases/
|
||||
3. Drag and drop the tutorial resources folder on the **`assetc** executable -OR- execute **assetc** passing it the path to the tutorial resources folder (eg. *assetc d:/tutorials-hg2/resources*).
|
||||
|
||||
.. image:: https://raw.githubusercontent.com/harfang3d/image-storage/main/tutorials/assetc.gif
|
||||
|
|
|
@ -56,6 +56,12 @@ Physics API
|
|||
Audio API
|
||||
* Play/stream WAV/OGG formats
|
||||
* 3D audio spatialization
|
||||
|
||||
Languages supported
|
||||
* C++
|
||||
* Python _(3.2+)_
|
||||
* Lua _(5.3)_
|
||||
* Go _(1+, experimental)_
|
||||
<a name="subsection_1b"></a>
|
||||
## Screenshots
|
||||
|
||||
|
@ -84,6 +90,7 @@ https://dev.harfang3d.com/releases
|
|||
* CPython 3.2+
|
||||
* Go 1+ _(for Harfang Go module)_
|
||||
* Doxygen _(for Harfang C++ SDK documentation)_
|
||||
* Autodesk FBX SDK _(for FBX Converter)_
|
||||
|
||||
### Windows
|
||||
* Visual Studio 2019 _(C++ compiler and IDE)_
|
||||
|
|
|
@ -1,3 +1,49 @@
|
|||
# [3.2.3] - 2022-08-13
|
||||
|
||||
This minor release brings several fixes to the rendering, physics, engine, foundation and tools.
|
||||
|
||||
### Framework integration and source code maintenance
|
||||
|
||||
- Added a CMake option to force MSVC to use updated __cplusplus macro.
|
||||
- Build fixes for GCC 12.
|
||||
|
||||
### Toolchain
|
||||
|
||||
- Added a way to select the input channel from an input texture within a `construct` when processing textures in **Assetc**.
|
||||
- Changed `BC6H_UF16` into `BC6H_SF16` to produce a valid DDS from a HDR file.
|
||||
- **Assetc** now parses the shaders to check their dependencies for any modification and triggers a rebuild if needed.
|
||||
- Properly quote **Luac** and **Recastc** invocations to support space in arguments.
|
||||
|
||||
### Binding
|
||||
|
||||
- Fixed `ImGuiMouseButton` enums (`ImGuiMouseButton_Left`, `ImGuiMouseButton_Right`, `ImGuiMouseButton_Middle`).
|
||||
- Added a `SetProbe` function to set the radiance and irradiance map to a scene.
|
||||
- :warning: Deprecated `SubmitModelToForwardPipeline`.
|
||||
|
||||
### Engine
|
||||
|
||||
- Added `GetMaterialsWithName`.
|
||||
- Added `GetFullPathAsset`
|
||||
- Added `get_log_level`, `get_log_detailed` functions.
|
||||
- Fixed the ray/cone intersection.
|
||||
- Ensure an extension is specified before returning output path from `SaveFileDialog`.
|
||||
- Fixed the reserved texture units used by the **AAA** pipeline (see https://dev.harfang3d.com/docs/3.2.3/man.pipelineshader/). As a consequence, the `core\` folder will need to be updated if your project is using the **Forward** or **AAA** rendering pipelines.
|
||||
- Fixed a nasty issue in forward pipeline texture table.
|
||||
- :warning: Deprecated `UpdateForwardPipelineAO` and `UT_AmbientOcclusion`.
|
||||
|
||||
### Physics
|
||||
|
||||
- Fixed #14, Bullet uses half extend for cylinders.
|
||||
|
||||
### Audio
|
||||
|
||||
- Fixed #13, properly reset OpenAL source velocity when starting a stereo sound.
|
||||
|
||||
### Documentation
|
||||
|
||||
- Fixed a dead link in the API documentation.
|
||||
- URLs updates (Quickstart, Wheel description, Readme file).
|
||||
|
||||
# [3.2.2] - 2022-06-03
|
||||
|
||||
This minor release brings several fixes, a better implementation of the AAA rendering pipeline including probe reprojection and a more stable screen space raytracer.<br>
|
||||
|
|
|
@ -714,7 +714,7 @@ static std::string Get_texconv_Format(const std::string &f) {
|
|||
if (f == "BC5")
|
||||
return "BC5_UNORM";
|
||||
if (f == "BC6H")
|
||||
return "BC6H_UF16";
|
||||
return "BC6H_SF16";
|
||||
if (f == "BC7")
|
||||
return "BC7_UNORM";
|
||||
return "";
|
||||
|
@ -743,6 +743,10 @@ static bool PreprocessTexture(const json &i_preprocess_texture, std::map<std::st
|
|||
dependencies.insert(path); // swizzle from input texture
|
||||
else
|
||||
dependencies.insert(channel_v); // swizzle from foreign texture
|
||||
} else if (v.is_object()) { // channel or texture path
|
||||
const auto dep_path = v["path"].get<std::string>();
|
||||
const auto channel_v = v["channel"].get<std::string>();
|
||||
dependencies.insert(dep_path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -785,8 +789,8 @@ static bool PreprocessTexture(const json &i_preprocess_texture, std::map<std::st
|
|||
// conform dependencies
|
||||
for (auto i : picture_dependencies)
|
||||
if (i.second.GetWidth() != out_width && i.second.GetHeight() != out_height) {
|
||||
error(format("Cannot construct '%1' due to dependency '%2' with incompatible resolution").arg(path).arg(i.first));
|
||||
return false;
|
||||
// resize
|
||||
picture_dependencies[i.first] = hg::Resize(i.second, out_width, out_height);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -872,6 +876,35 @@ static bool PreprocessTexture(const json &i_preprocess_texture, std::map<std::st
|
|||
in_stride = size_of(in_pic.GetFormat());
|
||||
}
|
||||
|
||||
for (uint16_t y = 0; y < out_height; ++y)
|
||||
for (uint16_t x = 0; x < out_width; ++x) {
|
||||
*out = *in;
|
||||
in += in_stride;
|
||||
out += out_stride;
|
||||
}
|
||||
|
||||
} else if (v.is_object()) { // channel and texture path
|
||||
|
||||
const auto dep_path = v["path"].get<std::string>();
|
||||
auto &in_pic = picture_dependencies[dep_path];
|
||||
|
||||
const char *channel_names[] = {"R", "G", "B", "A"};
|
||||
const auto input_channel_v = v["channel"].get<std::string>();
|
||||
size_t input_channel = 5;
|
||||
for (size_t c = 0; c < 4; ++c)
|
||||
if (input_channel_v == channel_names[c]) {
|
||||
input_channel = c;
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetChannelCount(in_pic.GetFormat()) <= input_channel) {
|
||||
error(format("Cannot construct '%1' due to '%2' missing %3 channel").arg(path).arg(dep_path).arg(input_channel));
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t *in = in_pic.GetData() + input_channel;
|
||||
size_t in_stride = size_of(in_pic.GetFormat());
|
||||
|
||||
for (uint16_t y = 0; y < out_height; ++y)
|
||||
for (uint16_t x = 0; x < out_width; ++x) {
|
||||
*out = *in;
|
||||
|
@ -1096,6 +1129,28 @@ void Geometry(std::map<std::string, Hash> &hashes, const std::string &path) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
void GatherShaderDependencies(const std::string &path, std::set<std::string> &deps, const std::string &base) {
|
||||
const auto rel_path = base + path;
|
||||
|
||||
if (deps.find(rel_path) != std::end(deps))
|
||||
return; // processed already, don't need no cyclic references
|
||||
|
||||
deps.insert(rel_path);
|
||||
const auto src = hg::FileToString(FullInputPath(rel_path).c_str());
|
||||
|
||||
static std::regex include_regex("#include\\s*(?:\"|<)(.+)(?:\"|>)");
|
||||
|
||||
const auto base_path = hg::GetFilePath(rel_path); // #include directives are relative to the current source
|
||||
for (std::sregex_iterator i = std::sregex_iterator(src.begin(), src.end(), include_regex); i != std::sregex_iterator(); ++i)
|
||||
GatherShaderDependencies((*i)[1], deps, base_path); // recurse down the dependency tree
|
||||
}
|
||||
|
||||
void GatherShaderDependencies(const std::set<std::string> &paths, std::set<std::string> &deps) {
|
||||
for (const auto &path : paths)
|
||||
GatherShaderDependencies(path, deps, "");
|
||||
}
|
||||
|
||||
//
|
||||
static void BuildComputeShader(std::map<std::string, Hash> &hashes, const std::string &cs_path, const std::string &defines) {
|
||||
ProfilerPerfSection perf("Command/ComputeShader");
|
||||
|
@ -1128,7 +1183,10 @@ static void BuildComputeShader(std::map<std::string, Hash> &hashes, const std::s
|
|||
if (toolchain.shaderc.empty()) {
|
||||
warn(" Skipping, no compiler found for compute resource");
|
||||
} else {
|
||||
if (NeedsCompilation(hashes, {cs_path}, {cs_path}, cs_build_ctx)) {
|
||||
std::set<std::string> inputs;
|
||||
GatherShaderDependencies({cs_path}, inputs);
|
||||
|
||||
if (NeedsCompilation(hashes, inputs, {cs_path}, cs_build_ctx)) {
|
||||
if (!cs_profile.empty()) // GLES profile must be empty...
|
||||
cs_profile = "-p " + cs_profile;
|
||||
|
||||
|
@ -1194,7 +1252,10 @@ static void BuildShader(std::map<std::string, Hash> &hashes, const std::string &
|
|||
if (toolchain.shaderc.empty()) {
|
||||
warn(" Skipping, no compiler found for shader resource");
|
||||
} else {
|
||||
if (NeedsCompilation(hashes, {vs_path, varying_path}, {vs_name}, vs_build_ctx)) {
|
||||
std::set<std::string> inputs;
|
||||
GatherShaderDependencies({vs_path, varying_path}, inputs);
|
||||
|
||||
if (NeedsCompilation(hashes, inputs, {vs_name}, vs_build_ctx)) {
|
||||
if (!vs_profile.empty()) // GLES profile must be empty...
|
||||
vs_profile = "-p " + vs_profile;
|
||||
|
||||
|
@ -1232,7 +1293,10 @@ static void BuildShader(std::map<std::string, Hash> &hashes, const std::string &
|
|||
if (toolchain.shaderc.empty()) {
|
||||
warn(" Skipping, no compiler found for shader resource");
|
||||
} else {
|
||||
if (NeedsCompilation(hashes, {fs_path, varying_path}, {fs_name}, fs_build_ctx)) {
|
||||
std::set<std::string> inputs;
|
||||
GatherShaderDependencies({fs_path, varying_path}, inputs);
|
||||
|
||||
if (NeedsCompilation(hashes, inputs, {fs_name}, fs_build_ctx)) {
|
||||
if (!fs_profile.empty())
|
||||
fs_profile = "-p " + fs_profile;
|
||||
|
||||
|
@ -1387,7 +1451,7 @@ static void LuaScript(std::map<std::string, Hash> &hashes, const std::string &pa
|
|||
MkOutputTree(path);
|
||||
CleanOutputs({path});
|
||||
|
||||
const auto cmd = format("%1 -o %3 -s %2").arg(toolchain.luac).arg(src).arg(dst);
|
||||
const auto cmd = format("%1 -o \"%3\" -s \"%2\"").arg(toolchain.luac).arg(src).arg(dst);
|
||||
PushAsyncProcessTask(path, cmd, cwd);
|
||||
} else {
|
||||
debug(" [O] Lua script up to date");
|
||||
|
@ -1418,7 +1482,7 @@ static void PathFinding(std::map<std::string, Hash> &hashes, const std::string &
|
|||
MkOutputTree(path);
|
||||
CleanOutputs({path});
|
||||
|
||||
const auto cmd = format("%1 %2 %3 -root %4").arg(toolchain.recastc).arg(src).arg(dst).arg(input_dir);
|
||||
const auto cmd = format("%1 \"%2\" \"%3\" -root \"%4\"").arg(toolchain.recastc).arg(src).arg(dst).arg(input_dir);
|
||||
PushAsyncProcessTask(path, cmd, GetCurrentWorkingDirectory());
|
||||
} else {
|
||||
debug(" [O] Pathfinding resource up to date");
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user