composite texture - checkerboard

This commit is contained in:
Mikulas Florek 2023-07-30 13:24:58 +02:00
parent 3b9fa5569b
commit a86741cb3b
13 changed files with 175 additions and 95 deletions

View file

@ -17,9 +17,10 @@ const ResourceType Animation::TYPE("animation");
Animation::Animation(const Path& path, ResourceManager& resource_manager, IAllocator& allocator)
: Resource(path, resource_manager, allocator)
, m_mem(allocator)
, m_translations(allocator)
, m_rotations(allocator)
, m_allocator(allocator, m_path.c_str())
, m_mem(m_allocator)
, m_translations(m_allocator)
, m_rotations(m_allocator)
{
}

View file

@ -1,5 +1,6 @@
#pragma once
#include "engine/allocators.h"
#include "engine/hash.h"
#include "engine/hash_map.h"
#include "engine/resource.h"
@ -47,70 +48,68 @@ struct BoneMask
};
struct Animation final : Resource
{
public:
static const u32 HEADER_MAGIC = 0x5f4c4146; // '_LAF'
static const ResourceType TYPE;
struct Animation final : Resource {
static const u32 HEADER_MAGIC = 0x5f4c4146; // '_LAF'
static const ResourceType TYPE;
public:
enum class CurveType : u8 {
KEYFRAMED,
SAMPLED
};
enum class CurveType : u8 {
KEYFRAMED,
SAMPLED
};
enum class Version : u32 {
FIRST = 3,
enum class Version : u32 {
FIRST = 3,
LAST
};
LAST
};
struct Header {
u32 magic;
Version version;
Time length;
u32 frame_count;
};
struct Header {
u32 magic;
Version version;
Time length;
u32 frame_count;
};
public:
Animation(const Path& path, ResourceManager& resource_manager, IAllocator& allocator);
Animation(const Path& path, ResourceManager& resource_manager, IAllocator& allocator);
ResourceType getType() const override { return TYPE; }
ResourceType getType() const override { return TYPE; }
Vec3 getTranslation(Time time, u32 curve_idx) const;
Quat getRotation(Time time, u32 curve_idx) const;
int getTranslationCurveIndex(BoneNameHash name_hash) const;
int getRotationCurveIndex(BoneNameHash name_hash) const;
void getRelativePose(Time time, Pose& pose, const Model& model, const BoneMask* mask) const;
void getRelativePose(Time time, Pose& pose, const Model& model, float weight, const BoneMask* mask) const;
Time getLength() const { return m_length; }
Vec3 getTranslation(Time time, u32 curve_idx) const;
Quat getRotation(Time time, u32 curve_idx) const;
int getTranslationCurveIndex(BoneNameHash name_hash) const;
int getRotationCurveIndex(BoneNameHash name_hash) const;
void getRelativePose(Time time, Pose& pose, const Model& model, const BoneMask* mask) const;
void getRelativePose(Time time, Pose& pose, const Model& model, float weight, const BoneMask* mask) const;
Time getLength() const { return m_length; }
private:
void unload() override;
bool load(u64 size, const u8* mem) override;
private:
void unload() override;
bool load(u64 size, const u8* mem) override;
private:
Time m_length;
struct TranslationCurve
{
BoneNameHash name;
u32 count;
const u16* times;
const Vec3* pos;
};
struct RotationCurve
{
BoneNameHash name;
u32 count;
const u16* times;
const Quat* rot;
};
Array<TranslationCurve> m_translations;
Array<RotationCurve> m_rotations;
Array<u8> m_mem;
u32 m_frame_count = 0;
struct TranslationCurve
{
BoneNameHash name;
u32 count;
const u16* times;
const Vec3* pos;
};
friend struct AnimationSampler;
struct RotationCurve
{
BoneNameHash name;
u32 count;
const u16* times;
const Quat* rot;
};
TagAllocator m_allocator;
Time m_length;
Array<TranslationCurve> m_translations;
Array<RotationCurve> m_rotations;
Array<u8> m_mem;
u32 m_frame_count = 0;
friend struct AnimationSampler;
};

View file

@ -38,7 +38,7 @@ struct LUMIX_AUDIO_API AudioDevice
virtual ~AudioDevice() {}
static UniquePtr<AudioDevice> create(Engine& engine);
static UniquePtr<AudioDevice> create(Engine& engine, IAllocator& allocator);
virtual BufferHandle createBuffer(const void* data, int size_bytes, int channels, int sample_rate, int flags) = 0;
virtual void setEcho(BufferHandle handle,

View file

@ -50,7 +50,7 @@ struct AudioSystemImpl final : AudioSystem {
void init() override
{
m_device = AudioDevice::create(m_engine);
m_device = AudioDevice::create(m_engine, m_allocator);
m_manager.create(Clip::TYPE, m_engine.getResourceManager());
}

View file

@ -576,11 +576,10 @@ struct NullAudioDevice final : AudioDevice
};
UniquePtr<AudioDevice> AudioDevice::create(Engine& engine)
UniquePtr<AudioDevice> AudioDevice::create(Engine& engine, IAllocator& allocator)
{
UniquePtr<AudioDeviceImpl> device = UniquePtr<AudioDeviceImpl>::create(engine.getAllocator());
if (!device->init(engine))
{
UniquePtr<AudioDeviceImpl> device = UniquePtr<AudioDeviceImpl>::create(allocator);
if (!device->init(engine)) {
logWarning("Using null device");
return UniquePtr<NullAudioDevice>::create(engine.getAllocator());
}

View file

@ -391,8 +391,7 @@ struct AssetCompilerImpl : AssetCompiler {
{
auto iter = m_dependencies.find(dependency);
if (!iter.isValid()) {
IAllocator& allocator = m_app.getAllocator();
m_dependencies.insert(dependency, Array<Path>(allocator));
m_dependencies.insert(dependency, Array<Path>(m_allocator));
iter = m_dependencies.find(dependency);
}
if (iter.value().indexOf(included_from) < 0) {

View file

@ -711,7 +711,7 @@ struct ProfilerUIImpl final : StudioApp::GUIPlugin {
if (stristr(tag.m_tag.c_str(), m_filter) == 0) return;
}
if (ImGui::TreeNode(&tag, "%s - %.1f MB", tag.m_tag.c_str(), tag.m_size / 1024.f / 1024.f)) {
if (ImGui::TreeNode(&tag, "%s - %.2f MB", tag.m_tag.c_str(), tag.m_size / 1024.f / 1024.f)) {
for (const AllocationTag& child : tag.m_child_tags) gui(child);
if (tag.m_child_tags.empty() || m_filter[0] || ImGui::TreeNode("allocs", "Allocations - %.1f MB", tag.m_exclusive_size / 1024.f / 1024.f)) {
ImGui::Columns(3);
@ -1476,7 +1476,7 @@ UniquePtr<StudioApp::GUIPlugin> createProfilerUI(StudioApp& app) {
allocator = allocator->getParent();
} while(allocator);
return UniquePtr<ProfilerUIImpl>::create(engine.getAllocator(), app, debug_allocator, engine);
return UniquePtr<ProfilerUIImpl>::create(app.getAllocator(), app, debug_allocator, engine);
}

View file

@ -13,7 +13,8 @@ const ResourceType LuaScript::TYPE("lua_script");
LuaScript::LuaScript(const Path& path, ResourceManager& resource_manager, IAllocator& allocator)
: Resource(path, resource_manager, allocator)
, m_source_code(allocator)
, m_allocator(allocator, m_path.c_str())
, m_source_code(m_allocator)
{
}

View file

@ -1,6 +1,7 @@
#pragma once
#include "engine/allocators.h"
#include "engine/resource.h"
#include "engine/string.h"
@ -24,6 +25,7 @@ public:
static const ResourceType TYPE;
private:
TagAllocator m_allocator;
String m_source_code;
};

View file

@ -198,7 +198,12 @@ namespace Lumix
//physx::PxPvdTransport* transport = physx::PxDefaultPvdFileTransportCreate("physx.pvd");
m_pvd_transport = physx::PxDefaultPvdSocketTransportCreate("127.0.0.1", 5425, 100);
return m_pvd->connect(*m_pvd_transport, physx::PxPvdInstrumentationFlag::eALL);
bool connected = m_pvd->connect(*m_pvd_transport, physx::PxPvdInstrumentationFlag::eALL);
if (!connected) {
m_pvd_transport->release();
m_pvd->release();
}
return connected;
}
bool cookTriMesh(Span<const Vec3> verts, Span<const u32> indices, IOutputStream& blob) override {

View file

@ -63,7 +63,8 @@ enum class CompositeTexture::NodeType : u32 {
MAX,
SQUARE,
TRIANGLE,
BLUR
BLUR,
CHECKERBOARD
};
enum { OUTPUT_FLAG = 1 << 31 };
@ -1148,11 +1149,13 @@ struct TranslateNode final : CompositeTexture::Node {
void serialize(OutputMemoryStream& blob) const override {
blob.write(x);
blob.write(y);
blob.write(wrap);
}
void deserialize(InputMemoryStream& blob) override {
blob.read(x);
blob.read(y);
blob.read(wrap);
}
bool generateInternal() override {
@ -1161,13 +1164,32 @@ struct TranslateNode final : CompositeTexture::Node {
CompositeTexture::Image& in = getInputImage(0);
CompositeTexture::Image& out = m_outputs.emplace(in.w, in.h, in.channels, m_allocator);
for (u32 j = 0; j < in.h; ++j) {
for (u32 i = 0; i < in.w; ++i) {
memcpy(&out.pixels[(((x + i) % out.w) + ((y + j) % out.h) * out.w) * out.channels]
, &in.pixels[(i + j * in.w) * in.channels]
, in.channels * sizeof(float));
const i32 tx = x < 0 ? -i32(-x % out.w) : x % out.w;
const i32 ty = y < 0 ? -i32(-y % out.h) : y % out.h;
if (wrap) {
for (i32 j = 0; j < (i32)in.h; ++j) {
const i32 src_y = (j + ty + out.h) % out.h;
for (u32 i = 0; i < (i32)in.w; ++i) {
const u32 src_x = (i + tx + out.w) % out.w;
memcpy(&out.pixels[(i + j * out.w) * out.channels]
, &in.pixels[(src_x + src_y * in.w) * in.channels]
, in.channels * sizeof(float));
}
}
}
else {
for (i32 j = 0; j < (i32)in.h; ++j) {
const u32 src_y = clamp(j + ty, 0, out.h - 1);
for (i32 i = 0; i < (i32)in.w; ++i) {
const u32 src_x = clamp(i + tx, 0, out.w - 1);
memcpy(&out.pixels[(i + j * out.w) * out.channels]
, &in.pixels[(src_x + src_y * in.w) * in.channels]
, in.channels * sizeof(float));
}
}
}
return true;
}
@ -1175,12 +1197,14 @@ struct TranslateNode final : CompositeTexture::Node {
nodeTitle("Translate");
inputSlot();
outputSlot();
bool res = ImGui::DragInt("X", (i32*)&x, 1, INT_MIN, INT_MAX);
res = ImGui::DragInt("Y", (i32*)&y, 1, INT_MIN, INT_MAX) || res;
bool res = ImGui::DragInt("X", &x, 1, INT_MIN, INT_MAX);
res = ImGui::DragInt("Y", &y, 1, INT_MIN, INT_MAX) || res;
res = ImGui::Checkbox("Wrap", &wrap) || res;
return res;
}
u32 x = 0, y = 0;
i32 x = 0, y = 0;
bool wrap = true;
};
@ -1871,6 +1895,53 @@ struct BlurNode final : CompositeTexture::Node {
u32 iterations = 4;
};
struct CheckerboardNode final : CompositeTexture::Node {
CheckerboardNode(IAllocator& allocator) : Node(allocator) {}
CompositeTexture::NodeType getType() const override { return CompositeTexture::NodeType::CHECKERBOARD; }
bool hasInputPins() const override { return false; }
bool hasOutputPins() const override { return true; }
void serialize(OutputMemoryStream& blob) const override {
blob.write(w);
blob.write(h);
blob.write(size);
}
void deserialize(InputMemoryStream& blob) override {
blob.read(w);
blob.read(h);
blob.read(size);
}
bool generateInternal() override {
CompositeTexture::Image& out = m_outputs.emplace(w, h, 1, m_allocator);
for (u32 j = 0; j < h; ++j) {
for (u32 i = 0; i < w; ++i) {
u32 color = ((i / size) + (j / size)) % 2;
out.pixels[i + j * out.w] = (float)color;
}
}
return true;
}
bool gui() override {
nodeTitle("Checkerboard");
ImGui::BeginGroup();
bool res = ImGui::DragInt("Width", (i32*)&w, 1, 1, INT_MAX);
res = ImGui::DragInt("Height", (i32*)&h, 1, 1, INT_MAX) || res;
res = ImGui::DragInt("Size", (i32*)&size, 1, 1, INT_MAX) || res;
ImGui::EndGroup();
ImGui::SameLine();
outputSlot();
return res;
}
u32 w = 256;
u32 h = 256;
u32 size = 16;
};
struct TriangleNode final : CompositeTexture::Node {
TriangleNode(IAllocator& allocator) : Node(allocator) {}
@ -2464,6 +2535,7 @@ CompositeTexture::Node* createNode(CompositeTexture::NodeType type, CompositeTex
case CompositeTexture::NodeType::SIMPLEX: node = LUMIX_NEW(allocator, SimplexNode)(allocator); break;
case CompositeTexture::NodeType::WAVE_NOISE: node = LUMIX_NEW(allocator, WaveNoiseNode)(allocator); break;
case CompositeTexture::NodeType::BLUR: node = LUMIX_NEW(allocator, BlurNode)(allocator); break;
case CompositeTexture::NodeType::CHECKERBOARD: node = LUMIX_NEW(allocator, CheckerboardNode)(allocator); break;
case CompositeTexture::NodeType::TRIANGLE: node = LUMIX_NEW(allocator, TriangleNode)(allocator); break;
case CompositeTexture::NodeType::SQUARE: node = LUMIX_NEW(allocator, SquareNode)(allocator); break;
case CompositeTexture::NodeType::CIRCLE: node = LUMIX_NEW(allocator, CircleNode)(allocator); break;
@ -2776,6 +2848,7 @@ struct CompositeTextureEditorWindow : StudioApp::GUIPlugin, NodeEditor {
void visitNodeTypes(INodeTypeVisitor& visitor) {
if (visitor.beginCategory("Generate")) {
visitor
.visitType("Checkerboard", CompositeTexture::NodeType::CHECKERBOARD)
.visitType("Circle", CompositeTexture::NodeType::CIRCLE, 'O')
.visitType("Circular splatter", CompositeTexture::NodeType::CIRCULAR_SPLATTER)
.visitType("Gradient", CompositeTexture::NodeType::GRADIENT)

View file

@ -1832,22 +1832,20 @@ struct ModelPlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
}
~ModelPlugin()
{
~ModelPlugin() {
if (m_downscale_program) m_pipeline->getRenderer().getEndFrameDrawStream().destroy(m_downscale_program);
jobs::wait(&m_subres_signal);
auto& engine = m_app.getEngine();
engine.destroyWorld(*m_world);
Engine& engine = m_app.getEngine();
if (m_world) engine.destroyWorld(*m_world);
m_pipeline.reset();
engine.destroyWorld(*m_tile.world);
if (m_tile.world) engine.destroyWorld(*m_tile.world);
m_tile.pipeline.reset();
}
void init() {
Engine& engine = m_app.getEngine();
m_renderer = static_cast<Renderer*>(engine.getSystemManager().getSystem("renderer"));
createPreviewWorld();
createTileWorld();
m_viewport.is_ortho = true;
m_viewport.near = 0.f;
m_viewport.far = 1000.f;
@ -2038,8 +2036,8 @@ struct ModelPlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
}
void createPreviewWorld()
{
void createPreviewWorld() {
ASSERT(!m_world);
Engine& engine = m_app.getEngine();
m_world = &engine.createWorld(false);
PipelineResource* pres = engine.getResourceManager().load<PipelineResource>(Path("pipelines/main.pln"));
@ -2068,6 +2066,7 @@ struct ModelPlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
void showPreview(Model& model)
{
if (!m_world) createPreviewWorld();
auto* render_module = static_cast<RenderModule*>(m_world->getModule(MODEL_INSTANCE_TYPE));
if (!render_module) return;
if (!model.isReady()) return;
@ -2853,8 +2852,8 @@ struct ModelPlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
}
void renderTile(PrefabResource* prefab)
{
void renderTile(PrefabResource* prefab) {
if (!m_tile.world) createTileWorld();
Engine& engine = m_app.getEngine();
EntityMap entity_map(m_app.getAllocator());
@ -2868,8 +2867,8 @@ struct ModelPlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
}
void renderPrefabSecondStage()
{
void renderPrefabSecondStage() {
if (!m_tile.world) createTileWorld();
AABB aabb({0, 0, 0}, {0, 0, 0});
float radius = 1;
World& world = *m_tile.world;
@ -2989,6 +2988,7 @@ struct ModelPlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
void renderTile(Model* model, const DVec3* in_pos, const Quat* in_rot)
{
if (!m_tile.world) createTileWorld();
RenderModule* render_module = (RenderModule*)m_tile.world->getModule(MODEL_INSTANCE_TYPE);
if (!render_module) return;
@ -3093,7 +3093,7 @@ struct ModelPlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
StudioApp& m_app;
Renderer* m_renderer = nullptr;
gpu::TextureHandle m_preview;
World* m_world;
World* m_world = nullptr;
Viewport m_viewport;
UniquePtr<Pipeline> m_pipeline;
EntityPtr m_mesh = INVALID_ENTITY;

View file

@ -1,10 +1,11 @@
#include "gpu.h"
#include "engine/page_allocator.h"
#include "engine/allocators.h"
#include "engine/array.h"
#include "engine/hash.h"
#include "engine/hash_map.h"
#include "engine/log.h"
#include "engine/math.h"
#include "engine/page_allocator.h"
#include "engine/stream.h"
#include "engine/sync.h"
#include "engine/os.h"
@ -113,9 +114,9 @@ struct WindowContext {
};
struct GL {
GL(IAllocator& allocator) : allocator(allocator) {}
GL(IAllocator& allocator) : allocator(allocator, "gl") {}
IAllocator& allocator;
TagAllocator allocator;
u32 frame = 0;
RENDERDOC_API_1_0_2* rdoc_api;
WindowContext contexts[64];