Sketch ini

This commit is contained in:
Ilusha 2024-03-17 10:04:52 +03:00 committed by IlyaShurupov
parent be0177b1b0
commit b8bab2264f
16 changed files with 2510 additions and 0 deletions

View file

@ -0,0 +1,29 @@
#include "gui/Widgets.h"
#include "nodes.h"
#include "StrokesObject.h"
namespace nd {
struct StrokesWidget : Widget {
static obj::ObjectType TypeData;
static struct Vtable : Widget::Vtable {} vtable;
strokes::Renderer mRenderer;
nd::GUIdrawer::ImageHandle mImage;
nd::GUIdrawer* mDrawer = NULL;
static void constructor(StrokesWidget* self);
static void destructor(StrokesWidget* self);
static void copy(Widget* self, const Widget* in);
static void procInputs(StrokesWidget* self, nd::GUIInputs* inputs);
static void presentOutput(StrokesWidget* self, nd::GUIdrawer* drawer);
strokes::Project* getTargetProject();
static void OpsInit();
static void OpsUnInit();
static void addShortcuts(nd::NodesCore* core);
};
};

153
Sketch3D/public/strokes.h Normal file
View file

@ -0,0 +1,153 @@
#include "Buffer.hpp"
#include "List.hpp"
#include "Map.hpp"
#include "Topology.hpp"
#include "Color.hpp"
#include "Strings.hpp"
namespace strokes {
class Renderer;
class Project;
class Stroke {
friend Renderer;
public:
struct Point {
tp::vec3f pos;
tp::halnf thickness = NULL;
};
tp::Array<Point> mPoints;
tp::rgba mCol;
private:
struct GLHandles {
GLuint VertexArrayID = 0;
GLuint vertexbuffer = 0;
GLuint vbo_len = 0;
GLHandles();
void sendDataToGPU(tp::Array<Point>* mPoints);
~GLHandles();
} mGl;
public:
Stroke();
void denoisePos(tp::halni passes);
void denoiseThickness(tp::halni passes);
void compress(tp::halnf factor);
void subdiv(tp::halnf precition, tp::Camera* cam, tp::halni passes = 1);
void updateGpuBuffers();
tp::Array<Point>& buff();
tp::halni saveSize();
void save(tp::File& file);
void load(tp::File& file);
};
class Brush {
public:
tp::string mType = "equal";
Brush() {}
virtual void sample(Project* proj, tp::vec2f crs, tp::halnf pressure) {}
virtual void draw(Renderer* render, tp::Camera* camera) {}
virtual ~Brush() {}
};
class PencilBrush : public Brush {
tp::halnf mPrecision = 0.001f;
tp::halni mDenoisePassesPos = 1;
tp::halni mDenoisePassesThick = 3;
tp::halnf mCompressionFactor = 0.0001f;
tp::halni mSubdivPasses = 3;
bool mEnableCompression = true;
tp::halni mMaxPoints = 100;
Stroke* mStroke = NULL;
Stroke mShowStroke;
void unsureReady(Stroke* stroke, tp::Camera* cam, bool debug = false);
public:
tp::rgba mCol = tp::rgba(1.0f);
tp::halnf mSize = 0.01f;
PencilBrush();
virtual void sample(Project* proj, tp::vec2f crs, tp::halnf pressure) override;
virtual void draw(Renderer* render, tp::Camera* camera) override;
virtual ~PencilBrush();
};
struct EraserBrush : public Brush {
EraserBrush() { mType = "eraser"; }
virtual void sample(Project* proj, tp::vec2f crs, tp::halnf pressure) override {}
virtual void draw(Renderer* render, tp::Camera* camera) override {}
virtual ~EraserBrush() {}
};
class Project {
public:
struct Layer {
tp::string name = "new layer";
tp::List<Stroke*> strokes;
bool enabled = true;
~Layer();
};
tp::Array<Layer*> mLayers;
tp::halni mActiveLayer = -1;
tp::Camera mCamera;
tp::rgba mBackgroundColor = { 0.22f, 0.22f, 0.25f, 1.f };
tp::HashMap<Brush*, tp::string> mBrushes;
tp::string mActiveBrush;
Project();
~Project();
tp::alni saveSize();
void save(tp::File& file);
void load(tp::File& file);
};
class Renderer {
tp::ogl::fbuffer mBufferDowncast;
tp::ogl::fbuffer mBuffer;
tp::ogl::shader mShader;
// shader uniforms
GLuint mMatrixUniform = 0;
GLuint mColorUniform = 0;
GLuint mRatioUniform = 0;
GLuint mTargetUniform = 0;
GLuint mBGColUniform = 0;
public:
Renderer(tp::vec2f size);
void renderBegin();
void setViewport(tp::rectf viewport);
void drawStroke(Stroke* str, tp::Camera* camera);
void renderEnd();
void setClearCol(tp::rgba col);
tp::uhalni getTextudeId();
tp::ogl::fbuffer* getBuff();
~Renderer();
};
};

View file

@ -0,0 +1,178 @@
#pragma once
#include "strokes.h"
struct ProjectInfo {
char name[10] = {0};
char version[10] = {0};
void init(tp::alni v) {
tp::string version_s(v);
tp::memcp(name, "strokes", tp::slen("strokes"));
tp::memcp(version, version_s.cstr(), version_s.size());
}
};
namespace StrokesVersion0 {
tp::alni save_size(strokes_project* proj) {
tp::alni out = 0;
out += sizeof(tp::Camera);
out += sizeof(tp::rgba);
out += sizeof(tp::alni);
for (auto layer : proj->layers) {
for (auto stiter : layer->strokes) {
stroke* str = &stiter.data();
out += sizeof(tp::rgba);
out += sizeof(tp::alni);
out += str->points.length() * sizeof(stroke_point);
}
}
return out;
}
void save(tp::File& file, strokes_project* proj) {
file.write<tp::Camera>(&proj->cam);
file.write<tp::rgba>(&proj->canvas_color);
drawlayer base_layer;
proj->append_layers(&base_layer);
tp::alni len = base_layer.strokes.length();
file.write<tp::alni>(&len);
for (auto stiter : base_layer.strokes) {
stroke* str = &stiter.data();
tp::alni length = str->points.length();
file.write<tp::alni>(&length);
file.write<tp::rgba>(&str->mesh.color);
for (auto piter : str->points) {
file.write<stroke_point>(&piter.data());
}
}
}
void load(tp::File& file, strokes_project* proj) {
file.read<tp::Camera>(&proj->cam);
file.read<tp::rgba>(&proj->canvas_color);
drawlayer* base = proj->get_base_layer();
tp::alni len;
file.read<tp::alni>(&len);
for (tp::alni str_idx = 0; str_idx < len; str_idx++) {
stroke str = stroke();
tp::alni p_len; file.read<tp::alni>(&p_len);
tp::rgba color; file.read<tp::rgba>(&color);
str.points.reserve(p_len);
for (auto piter : str.points) {
file.read<stroke_point>(&piter.data());
}
str.mesh.color = color;
base->add_stroke(str);
}
}
};
namespace StrokesVersion1 {
tp::alni save_size(strokes_project* proj) {
tp::alni out = 0;
out += sizeof(tp::Camera);
out += sizeof(tp::halnf);
out += sizeof(tp::halnf);
out += sizeof(tp::rgba);
out += sizeof(tp::alni);
for (auto layer : proj->layers) {
out += layer->name.save_size();
out += sizeof(bool);
out += sizeof(tp::alni);
for (auto stiter : layer->strokes) {
stroke* str = &stiter.data();
out += sizeof(tp::rgba);
out += sizeof(tp::alni);
out += str->points.length() * sizeof(stroke_point);
}
}
return out;
}
void save(tp::File& file, strokes_project* proj) {
file.write<tp::Camera>(&proj->cam);
file.write<tp::halnf>(&proj->sampler.eraser_size);
file.write<tp::halnf>(&proj->sampler.screen_thikness);
file.write<tp::rgba>(&proj->canvas_color);
tp::alni lay_len = proj->layers.length();
file.write<tp::alni>(&lay_len);
for (auto layer : proj->layers) {
layer->name.save(&file);
file.write<bool>(&layer->hiden);
tp::alni len = layer->strokes.length();
file.write<tp::alni>(&len);
for (auto stiter : layer->strokes) {
stroke* str = &stiter.data();
file.write<tp::rgba>(&str->mesh.color);
tp::alni length = str->points.length();
file.write<tp::alni>(&length);
for (auto piter : str->points) {
file.write<stroke_point>(&piter.data());
}
}
}
}
void load(tp::File& file, strokes_project* proj) {
file.read<tp::Camera>(&proj->cam);
file.read<tp::halnf>(&proj->sampler.eraser_size);
file.read<tp::halnf>(&proj->sampler.screen_thikness);
file.read<tp::rgba>(&proj->canvas_color);
tp::alni layers_len;
file.read<tp::alni>(&layers_len);
for (tp::alni str_idx = 0; str_idx < layers_len; str_idx++) {
tp::string key; key.load(&file);
drawlayer* layer = new drawlayer();
layer->name = key;
proj->layers.pushBack(layer);
file.read<bool>(&layer->hiden);
tp::alni len;
file.read<tp::alni>(&len);
for (tp::alni str_idx = 0; str_idx < len; str_idx++) {
stroke str = stroke();
tp::rgba color; file.read<tp::rgba>(&color);
tp::alni p_len; file.read<tp::alni>(&p_len);
str.points.reserve(p_len);
for (auto piter : str.points) {
file.read<stroke_point>(&piter.data());
}
str.mesh.color = color;
layer->add_stroke(str);
}
}
}
};