composite texture - pixel processor; live preview

This commit is contained in:
Mikulas Florek 2023-07-28 00:47:09 +02:00
parent fc0db2e970
commit 8efd537302
7 changed files with 907 additions and 486 deletions

View file

@ -697,7 +697,7 @@ void NodeEditor::nodeEditorGUI(Span<NodeEditorNode*> nodes, Array<NodeEditorLink
links.eraseItems([&](const NodeEditorLink& link) { return link.to == end_attr; });
links.push({u32(start_attr) & ~OUTPUT_FLAG, u32(end_attr)});
pushUndo(SimpleUndoRedo::NO_MERGE_UNDO);
pushUndo(NO_MERGE_UNDO);
}
}
@ -706,7 +706,7 @@ void NodeEditor::nodeEditorGUI(Span<NodeEditorNode*> nodes, Array<NodeEditorLink
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0)) {
if (ImGui::GetIO().KeyAlt && hovered_link != -1) {
links.erase(hovered_link);
pushUndo(SimpleUndoRedo::NO_MERGE_UNDO);
pushUndo(NO_MERGE_UNDO);
}
else {
onCanvasClicked(ImGui::GetMousePos() - origin - m_offset, hovered_link);

View file

@ -25,6 +25,7 @@ template <typename T> struct Array {
Array<T>&& move() { return static_cast<Array<T>&&>(*this); }
T* data() const { return m_data; }
T* begin() const { return m_data; }
T* end() const { return m_data ? m_data + m_size : nullptr; }
@ -320,6 +321,7 @@ template <typename T> struct Array {
}
u32 capacity() const { return m_capacity; }
IAllocator& getAllocator() const { return m_allocator; }
protected:
void grow() { reserve(m_capacity < 4 ? 4 : m_capacity + m_capacity / 2); }

View file

@ -314,7 +314,10 @@ void Vec4::operator/=(float rhs)
*this *= 1.0f / rhs;
}
Vec4 Vec4::operator*(const Vec4& v) { return Vec4(x * v.x, y * v.y, z * v.z, w * v.w); }
Vec4 Vec4::operator*(float s) { return Vec4(x * s, y * s, z * s, w * s); }
Vec4 Vec4::operator/(const Vec4& v) { return Vec4(x / v.x, y / v.y, z / v.z, w / v.w); }
Vec4 Vec4::operator/(float s) { return Vec4(x / s, y / s, z / s, w / s); }
void Vec4::operator*=(float rhs)
{

View file

@ -198,7 +198,10 @@ struct LUMIX_ENGINE_API Vec4 {
void operator+=(const Vec4& rhs);
void operator-=(const Vec4& rhs);
void operator/=(float rhs);
Vec4 operator/(float s);
Vec4 operator/(const Vec4& v);
Vec4 operator*(float s);
Vec4 operator*(const Vec4& v);
void operator*=(float rhs);
union {
@ -425,6 +428,15 @@ LUMIX_FORCE_INLINE Vec3 minimum(const Vec3& a, const Vec3& b) {
};
}
LUMIX_FORCE_INLINE Vec4 minimum(const Vec4& a, const Vec4& b) {
return {
minimum(a.x, b.x),
minimum(a.y, b.y),
minimum(a.z, b.z),
minimum(a.w, b.w)
};
}
template <typename T1, typename... T2> LUMIX_FORCE_INLINE T1 minimum(T1 a, T2... b) {
T1 min_b = minimum(b...);
return minimum(a, min_b);
@ -469,6 +481,15 @@ LUMIX_FORCE_INLINE Vec3 maximum(const Vec3& a, const Vec3& b) {
};
}
LUMIX_FORCE_INLINE Vec4 maximum(const Vec4& a, const Vec4& b) {
return {
maximum(a.x, b.x),
maximum(a.y, b.y),
maximum(a.z, b.z),
maximum(a.w, b.w)
};
}
template <typename T> LUMIX_FORCE_INLINE T signum(T a) {
return a > 0 ? (T)1 : (a < 0 ? (T)-1 : 0);
}

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,11 @@
#pragma once
#include "engine/array.h"
#include "engine/math.h"
#include "engine/path.h"
#include "editor/studio_app.h"
#include "editor/utils.h"
#include "renderer/gpu/gpu.h"
namespace Lumix {
@ -11,8 +13,11 @@ struct CompositeTexture {
enum class NodeType : u32;
struct PixelData {
PixelData(IAllocator& allocator) : pixels(allocator) {}
OutputMemoryStream pixels;
PixelData(IAllocator& allocator);
PixelData(u32 w, u32 h, u32 channels, IAllocator& allocator);
void init(u32 w, u32 h, u32 channels);
OutputMemoryStream asU8() const;
Array<float> pixels;
u32 channels = 4;
u32 w;
u32 h;
@ -24,34 +29,69 @@ struct CompositeTexture {
bool is_cubemap;
};
struct PixelContext {
const PixelData* image;
Vec4 color;
u32 x;
u32 y;
};
struct ValueResult {
ValueResult() {}
ValueResult(Vec4 v) : value(v), channels(4) {}
ValueResult(float v) : value(v), channels(1) {}
u32 channels = 0;
Vec4 value;
bool isValid() const { return channels != 0; }
bool isFloat() const { return channels == 1; }
};
struct Node : NodeEditorNode {
Node(IAllocator& allocator) : m_error(allocator) {}
Node(IAllocator& allocator) : m_allocator(allocator), m_error(allocator), m_outputs(allocator) {}
virtual NodeType getType() const = 0;
virtual bool gui() = 0;
virtual bool getPixelData(PixelData* data, u32 output_idx) = 0;
virtual bool generateInternal() = 0;
virtual ValueResult getValue(const PixelContext& ctx) { ASSERT(false); return {}; }
virtual void serialize(OutputMemoryStream& blob) const {}
virtual void deserialize(InputMemoryStream& blob) {}
bool nodeGUI() override;
bool generate();
void markDirty();
void inputSlot();
void outputSlot();
struct Input;
Input getInput(u32 pin_idx) const;
PixelData& getInputPixelData(u32 pin_idx) const;
bool generateInput(u32 pin_idx);
bool getInputPixelData(u32 pin_idx, PixelData* pd);
ValueResult getInputValue(u32 pin_idx, const CompositeTexture::PixelContext& ctx);
ValueResult errorValue(const char* msg) {
m_error = msg;
return {};
}
bool error(const char* msg) {
m_outputs.clear();
m_error = msg;
return false;
}
IAllocator& m_allocator;
Array<PixelData> m_outputs;
bool m_selected = false;
bool m_reachable = false;
bool m_dirty = true;
u32 m_input_counter;
u32 m_output_counter;
CompositeTexture* m_resource;
String m_error;
gpu::TextureHandle m_preview = gpu::INVALID_TEXTURE;
};
using Link = NodeEditorLink;

View file

@ -1176,7 +1176,7 @@ struct TexturePlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
return;
}
stbir_resize_uint8(layer0.pixels.data(),
stbir_resize_uint8(layer0.asU8().data(),
layer0.w,
layer0.h,
0,
@ -1290,7 +1290,8 @@ struct TexturePlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
if (layer.channels != 4) {
TextureCompressor::Input::Image& tmp = input.add(img.is_cubemap ? idx : 0, input.is_cubemap ? 0 : idx, 0);
tmp.pixels.resize(layer.w * layer.h * 4);
const u8* src = layer.pixels.data();
OutputMemoryStream pixels = layer.asU8();
const u8* src = pixels.data();
u8* dst = tmp.pixels.getMutableData();
for(u32 i = 0; i < layer.w * layer.h; ++i) {
@ -1301,8 +1302,7 @@ struct TexturePlugin final : AssetBrowser::Plugin, AssetCompiler::IPlugin
}
}
else {
Span<const u8> span(layer.pixels.data(), (u32)layer.pixels.size());
input.add(span, img.is_cubemap ? idx : 0, input.is_cubemap ? 0 : idx, 0);
input.add(layer.asU8(), img.is_cubemap ? idx : 0, input.is_cubemap ? 0 : idx, 0);
}
}