Cascade » Forums » Bite-size updates
Stas Lisetsky
25 posts / 2 projects

Ex-php dev. Working on a 2d graphics editor

#21231 Bite-size updates
1 month, 2 weeks ago Edited by Stas Lisetsky on July 7, 2019, 9:26 p.m.

Heyo. I'll be posting some quick updates here. Not everything deserves a blog post.

Currently I'm working on vector rendering and tools.

I went through making a buggy triangulation renderer, then made a scanline rasterizer (which was way too slow), then the trapezoidal rasterizer which looked reazonable

Problem with the trapezoidal r. is that it generates way too many triangles. I'm experimenting with subdividing comlex polys into simple polys, and then rendering them with triangles. (This is way more complex algorithmically than trapezoids, but will in theory produce so much less triangles, that will justify the complexity)

Also, I did some work on offset curves.
Here's i think about 60-80 offset curves

see video (2MB mp4)

Right now I took a break from vectors, and decided to tackle object tree (like the layers in photoshop).
Also, I'm working on undo/redo stuff - which requires a robust serializer. Just yesterday I made a thing that does the serialization of shapes lik this:

u32 Size;
u8 *Serialized = lsmeta_serialize(tree_node, Nodes, &Size);

I just pass the type, pointer to the root node and get back the data+size. It's pretty cool.
It uses internal buffers, so no pre-allocation of space is needed by the caller.
I still have to make the reverse process. Going to work on that in the next couple days.

I'll be posting more of these shorter updates here.

Follow me on twitter for more pictures
And feel free to leave comments. Thanks!

Stas Lisetsky
25 posts / 2 projects

Ex-php dev. Working on a 2d graphics editor

#21405 Bite-size updates
1 week, 4 days ago

July was a bit boring for Cascade. I dont even have screenshots.
But, I have 2 big 'gains', so to speak.

First, the serializer. It's really getting there. It's a very small 2k loc library that a)generates metadata for specified files and b) does serialization and deserializanion.

In mice. Ehm, I mean on a very small subset of C++.
But it's more than enough. It supports linked lists, static arrays, dynamic arrays (including specifying member variables that store the counts or the 'Next' pointers). Very convenient. And just in time for me to finally start working on history. Most of history stuff, I believe, won't require complex serialization - it's going to be just a memcopy of a single struct. But in case of tree hierarchy changes (eg for storing removed branches of objects) the serializer is very very useful.

Another use I found for the metadata I now have - is to use the actual types as tagged union tags. No extra info or enums are needed for each union, because I just have all the type info.

Second big thing is the object storage.

It's not unreasonable to assume that large projects could have thousands, maybe tens of thousands of objects.
Let's say 100K to be sure. That's at least 300K of control points - if all objects are triangles.
The storage for all that has to be fast, growable and so on...
For several reasons the point storage had to be separate from shape storage. So for points - I made a list of gap-buffer arrays. Exactly like text editors. (Point edits are mostly localized, and gap buffer works really well for that).
Shapes are stored in a linked list of arenas in depth-first order always.

There were obviously some synchronization issues, because I move memory around. For that I came up with a mix of a lookup table, indexing and pointers. it makes sense, I promise =) but it would take pages and pages to describe all the reasoning.

Anyways, I think I solved it. Not 100%, obviously, but it's a good solution to actually start building the editor.
And I did not want - in this case - to solve the problem by typing in some dumb system and fix it later.
This is kind of a core thing and without it editing and history could not really work properly. And an editor is really just a thing that does, well, editing and undo/redo of the editing. So I wanted to really think this stuff through and implement something that worked really well and scaled to huge data sizes.

Ohm and I did couple refactorings here and there. Simplified the renderer quite a bit and did some improvements to the string library (of course, I have my own string library).

So that's that. Anyways, this post is too long already, thanks for reading and I will see you next month.