composite texture - pixel processor; live preview
This commit is contained in:
parent
fc0db2e970
commit
8efd537302
7 changed files with 907 additions and 486 deletions
|
@ -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);
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue