[HN Gopher] Making a 3D modeler in C in a week
___________________________________________________________________
Making a 3D modeler in C in a week
Author : jasim
Score : 637 points
Date : 2024-05-02 17:48 UTC (2 days ago)
(HTM) web link (danielchasehooper.com)
(TXT) w3m dump (danielchasehooper.com)
| dhooper wrote:
| Thanks for the share!
| netule wrote:
| I agree entirely with the author on the limitations of Raylib.
| I'm currently working on a tower-defense style game that I
| started in Raylib, but I'm running into many of the same
| limitations (and more). Things such as toggling fullscreen not
| working consistently across platforms, not being able to
| enumerate screen modes, toggling rendering features at runtime,
| saving compiled shaders etc., etc. Having said that, I appreciate
| Ray's work on this library and will continue to sponsor him.
| Raylib is great for quickly banging out a prototype, but not much
| beyond that unless you're okay with living with severe
| limitations.
|
| Lesson learned, for sure, but I'm too far into the development to
| swap all of the Raylib stuff out for SDL (or something else) now.
| rwbt wrote:
| Raylib is easy to get started but once the project gets a
| little complex it bites back. SDL on the other hand takes more
| time to setup everything but scales extremely well as the
| project gets bigger and bigger. Also, SDL is exceptionally well
| written code.
| visil wrote:
| And an exceptionally well written documentation, too! One of
| the first big-ish projects of mine was a raytracer I wrote in
| C with SDL.
| throwaway2046 wrote:
| Got a link to that raytracer?
| z3phyr wrote:
| It would be like a regular raytracer, but instead of
| writing pixels to a file, you write them to your
| buffer/texture.
| sgt wrote:
| This made me want to look at raylib. It comes with some cute
| examples that run using WebAssembly:
| https://www.raylib.com/examples.html
|
| One thing that's always bothered me about Wasm and browser
| 3d/2d graphics is that I often find minor issues such as
| scrolling. Look at the example called "Background scrolling &
| parallax" here: https://www.raylib.com/examples.html
|
| I've tested on several devices and it's definitely not smooth
| scrolling, unless there's something wrong with my eyes.
|
| How can 2D smooth scrolling not be a solved problem in 2024?
| dekhn wrote:
| the answer to your last question is "inner platform effect"
| and "second system effect".
| modeless wrote:
| In that sample the foreground scrolls perfectly smoothly for
| me, but the background looks jittery. This indicates to me
| that it's not a platform issue at all. That sample is just
| doing something weird with the background.
| sgt wrote:
| Yes, the background is odd but the foreground is definitely
| not smooth. I see small little jitters occasionally. At one
| point I had to wait 15 seconds for it to jitter, though.
| jay_kyburz wrote:
| Yes the back and foreground is quite jittery for me on
| Firefox, and I'm almost certain its the browsers own
| requestAnimationFrame that's the problem.
|
| Update: Although, having a closer look at the scene, I
| see its pixel art, so I bet the author is snapping
| floating point positions to a pixel point to prevent sub
| pixel blurring.
|
| Another small update: I was sure requestAnimationFrame
| was locked to 60fps, but I noticed on Chrome the other
| day it was 144hz, the full speed of my monitor.
| kragen wrote:
| yeah, http://canonical.org/~kragen/sw/dev3/qvaders is
| unplayable on 120-hertz monitors because i'm running the
| game physics from raf ;)
| sgt wrote:
| Also noting that it's choppy on iPhone, but it's really
| barely noticable. Cool little game!
| kragen wrote:
| thanks! the choppiness is for the same reason; if the
| frame rate drops temporarily due to cpu load or whatever,
| the vaders move slower
| joeld42 wrote:
| This jitteryness is because the sample doesn't have
| antialiasing enabled (since it's pixel art) and the
| background scrolling is 0.1pixels per frame, which means
| every 10 frames it snaps 1 pixel. The scrolling is also
| updating on fixed amount per frame instead of looking at
| deltaTime, so if there are lags or small differences in
| frame time this might look choppy.
|
| But I think it's more meant to demonstrate drawing parallax
| layers rather than subpixel scrolling.
| sgt wrote:
| So by modifying it to look at delta time it would be
| smooth?
| flohofwoe wrote:
| Because it's a surprisingly tricky topic on modern operating
| systems [1], and even trickier in web browsers (smooth
| scrolling was actually _much_ easier to achieve on hard-
| realtime systems like the 8- and 16-bit home computers of the
| 80 's and early 90s).
|
| TL;DR: if you base your animation- or scroll-speed on the
| 'raw' measured time between two frames, you'll get micro-
| stutter because it's pretty much impossible to obtain a non-
| jittery frame duration on modern operating systems or web
| browsers, all you can do is try to remove the noise via
| filtering, or 'align' your measured frame duration with the
| display refresh interval, which on some platforms cannot be
| queried.
|
| In web browsers the most important problem is that you can't
| measure the exact frame duration (which is fallout from
| Spectre/Meltdown), or obtain a precise 'presentation
| timestamp', or even query the display refresh frequency.
|
| Even in the native OS APIs that provide a presentation
| timestamp (like DXGI on Windows or CVDisplayLink on macOS)
| that timestamp has considerable jitter and has not much to do
| with the _actual_ presentation time when the frame becomes
| visible to the user.
|
| And as soon as you base your animation timings on such a
| jittery timestamp you'll get micro-stutter (the easiest way
| to get smooth animation is actually to assume a fixed frame
| duration, but then your animation speed will be tied to the
| display refresh rate).
|
| It's often possible to eliminate the timing jitter with
| 'noise removal' filters or just tracking an average over the
| last couple dozen frames, but those then may behave funny in
| situations where the frame duration changes drastically (such
| as moving a window between displays with different refresh
| rate, or when rendering stops and then resumes because the
| window or browser tab is fully obscured and then becomes
| visible again).
|
| PS: Raylib's frame pacing code on the web is also a bit on
| the crude side [2].
|
| ...e.g. it just sleeps for 16 milliseconds, and relies on
| ASYNCIFY to enable a traditional render loop in browsers. It
| would actually be better to use a frame callback via
| requestAnimationFrame (or the Emscripten wrapper function
| emscripten_request_animation_frame), but this means giving up
| the cross-platform 'own the game loop' application model. Not
| that requestAnimationFrame alone solves any of the above
| mentioned time jitter problems though.
|
| [1] https://medium.com/@alen.ladavac/the-elusive-frame-
| timing-16...
|
| [2[ https://github.com/raysan5/raylib/blob/f1007554a0a8145060
| 797...
| samiv wrote:
| Thanks for this comment, this thing you mentioned "micro
| stutter" is something that has had me really scratching my
| head in my game engine project!
|
| Do you have any comment whether frame blending (actually
| using a mix of two frame states to produce the rendering)
| would be a workable solution?
|
| https://github.com/ensisoft/detonator
| sgt wrote:
| This is a great answer, by the way. I know have better
| insight into what happens in these animation loops.
| oersted wrote:
| Quick appreciation for the detail that Raylib is named after
| the creator's name Ray and not ray-tracing, fun.
|
| Things Unexpectedly Named After People:
| https://notes.rolandcrosby.com/posts/unexpectedly-eponymous/
| airstrike wrote:
| Such a good list.. worth a submission of its own IMHO
| WJW wrote:
| I wish they'd add French drains.
| oersted wrote:
| It got good traction a couple times before, many more fun
| examples in the comments.
|
| https://news.ycombinator.com/item?id=39462516
|
| https://news.ycombinator.com/item?id=23888725
| TrainedMonkey wrote:
| How do you know Ray was not named after ray-tracing?
| dymk wrote:
| The author's name is the first hint, and the lack of ray
| tracing the second
| oersted wrote:
| I choose to interpret it as: How do you know that *the
| author* was not named after ray-tracing?
|
| Which is amusing :)
| linkdd wrote:
| You missed the joke, so let me ruin it by explaining it:
|
| What if Ray the person was named after ray-tracing by his
| parents?
| MenhirMike wrote:
| Plot twist: Ray Tracing was the name of a person that was
| very important to both of them and unfortunately passed
| away, so they named their son Ray as a tribute.
| miuramxciii wrote:
| I can confirm that. And Ms. Litre went to the same school
| and was best friends with Mr. Tracing.
| [https://en.wikipedia.org/wiki/Claude_%C3%89mile_Jean-
| Baptist...]
| dymk wrote:
| Ah shit, I was That Guy on the internet, sorry. I guess
| it happens to everyone eventually.
| mohas wrote:
| plot twist: that Ray person was implementation of optical
| ray tracing made by his parents in a week
| pests wrote:
| IIRC it defines some common words too like all the color names
| and uses a lot of names that should be prefixed. Good
| otherwise.
| diath wrote:
| At least they're all-caps, but as somebody that writes C++
| and uses Raylib, I just wrapped it in a namespace in my
| project that I include, like so (note that cstdio must be
| included before raylib if you're using it from C++):
| #pragma once #include <cstdio>
| namespace raylib { #include <raylib.h> }
| vsuperpower2020 wrote:
| Raylib has a lot of issues that are never going to be fixed,
| but I wouldn't blame fullscreen on it. Fullscreen is just
| absolutely unusably FUBARed on windows and has been for
| decades. It's probably the same for other platforms. The modern
| strategy is to just do borderless windowed and pretend true
| fullscreen doesn't exist.
| netule wrote:
| True, it's just one of the many issues that came to mind
| while writing this.
|
| My solution to the issue is also full screen borderless
| combined with resolution scaling.
| spacechild1 wrote:
| > just do borderless windowed and pretend true fullscreen
| doesn't exist.
|
| Hah, good to know I am not the only one.
| keyle wrote:
| I do the same, I do wonder however, if there are performance
| issue at the OS level, from running (on a 4K screen) 4K
| borderless vs. 4K fullscreen.
|
| Like, the whole giving the application maximum priority would
| work the same?
| Just_Harry wrote:
| Whether there's a performance detriment from borderless-
| fullscreen vs exclusive-fullscreen depends on how a program
| presents its frames (and on the OS, of course).
|
| On Windows, under ideal circumstances borderless-fullscreen
| performs identically to exclusive-fullscreen as Windows
| will let the program skip the compositor and present its
| frames more-or-less directly to the display. (Under really
| ideal circumstances the same applies to bordered non-
| fullscreen windows.)
|
| If the compositor can't be skipped, borderless-fullscreen
| can be a bit brutal on performance: on a 4K 160Hz screen
| I've experienced an additional 40-milliseconds+ of frame-
| latency purely from borderless-fullscreen being used.
|
| The Special K wiki has some pages that go into more detail
| about the situation on Windows:
| https://wiki.special-k.info/SwapChain,
| https://wiki.special-k.info/Presentation_Model
| ImHereToVote wrote:
| This is absolutely bonkers.
| spookie wrote:
| At least on Xorg it isn't an issue, but to ensure cross-
| compatibility your solution trumps all. I cannot comment on
| other platforms.
| Maken wrote:
| In Xorg it is definitely an issue. Virtually all games use
| a borderless window because actual X11 fullscreen is awful:
| it captures all input events and changes the system's
| screen resolution to whatever the application is running
| at.
| badsectoracula wrote:
| There is no all-encompassing "actual X11 fullscreen", X11
| does not have an API for applications to have control
| over the entire screen like you'd find in, e.g, DirectX 9
| (what most people think of with "real fullscreen" in
| Windows). What games (and SDL1) ages ago did was to use
| APIs that changed the video mode and APIs that captured
| input, both of which are completely separate (they're
| even from different sources: the video mode API is from
| an extension, the capture API is from the core protocol)
| - and then created a borderless window the normal way.
|
| There are three different aspects here, each one can be
| done differently and all can be (and have been) mixed or
| ignored:
|
| 1. Set the video mode. You can either do that or not and
| use whatever the desktop is running at. You may want to
| change the video mode not just for resolution but for
| using a different refresh rate. Both native games (like,
| e.g. Quake source ports using SDL2) and Wine still do
| that (you can disable the modesetting in Wine via the
| registry so that games only see the desktop resolution as
| the only available one).
|
| 2. Create a fullscreen window. There are two ways to do
| that: either create a window that bypasses redirection
| ("redirection" here means that the window manager wont
| manage it, it has nothing to do with compositing - if a
| compositor is used - though some compositors also use it
| as a hint for that) and have it cover the entire desktop
| area (you may want to use randr to figure out the monitor
| area for multiple monitors) or alternatively use the
| fullscreen hint on the window and let the window manager
| handle this. Note that some window managers may not
| support this or have bugs with it.
|
| 3. Handle input. X11 provides an API to capture mouse
| and/or keyboard input, though strictly speaking this is
| not really required and TBH i do not see why games ever
| did that (i can only think of conflicts with other
| programs but i'd expect this to be something for the user
| to deal with). In any case, it is rare for games to do
| that these days. You can just handle input "normally"
| like any other program. You can provide a (by default
| disabled) option if you really want to though as the API
| for capturing is trivial.
|
| For my last game engine i did #1 (with an option to use
| whatever the desktop resolution is) and #2 (using the
| fullscreen flag by default with the redirect flag as an
| alternative for window managers that had issues with the
| fullscreen flag) but i didn't bother with #3.
| duxup wrote:
| I have no knowledge about such things but...
|
| > The modern strategy is to just do borderless windowed and
| pretend true fullscreen doesn't exist.
|
| This explains a lot as to why I experienced some interesting
| inconsistency going full screen in different applications in
| Windows ;)
| sph wrote:
| In Linux/Wayland, Windows-style fullscreen does not exist
| and has no reason to exist either.
|
| In a composited environment, fullscreen windows are just
| maximized windows without a border, which triggers some
| heuristic to unredirect windows (i.e. does not have to pay
| the price of compositing) when they are the sole thing that
| is drawn on the screen.
|
| So, on Linux, fullscreen and maximized borderless are the
| same. Given that Windows is a fully compositing desktop as
| well, I wonder why the difference still exists.
| easyThrowaway wrote:
| > I wonder why the difference still exists.
|
| Some legacy apps (that is, games) react very badly when
| they're not in full control of their window sizing,
| priority, input and device polling, ecc.
| Joker_vD wrote:
| But what does "Windows-style fullscreen" actually _do_?
| It feels like it switches into a different video mode
| (even if the resolution is the same), and back when my
| monitor was a CRT, I could even _hear_ a faint click
| inside it whenever a game entered /exited the full-screen
| mode. So there was definitely something special going on,
| but what?
| lelandbatey wrote:
| Windows style fullscreen made it so that the game
| controlled the resolution being sent "over the wire" to
| the display, and as I understand it, basically gave
| exclusive display access to the game. This had the
| interesting effect of delegating all resolution scaling
| to the display, which was great for CRTs and often very
| bad on digital displays which (usually) do very muddy
| bilinear scaling even if being sent a resolution that was
| an exact integer division of the total display
| resolution.
|
| The current day approach is to instead do the "large
| borderless window" and then do software scaling of the
| image in order to match the display resolution. One cool
| result of this is you can get much better scaling than
| your display would do naively. Low-res games really
| benefit from software integer scaling instead of
| "whatever scaling the display firmware does, usually
| making all the edges blurry".
|
| Rescaling in software is so fast now that some
| graphically intense games can do per-frame scaling in
| order to keep per-frame latencies below a particular goal
| threshold, at the cost of your game losing fidelity
| (getting blurier). It's so common that most big-name
| titles now do this.
| diath wrote:
| Kind of share the same feeling, started a project about 2
| months ago and chose to use Raylib, and while the basic stuff
| is really simple to get going, the more you use it, the more
| random minor inconveniences you run into, but at this point
| I've invested too much into this project to back out of using
| Raylib. My biggest issue with it right now is the font handling
| and text rendering, I think I'll have to switch from TTF fonts
| to pre-baked bitmap fonts for it (which will suck for
| localization later). The biggest two features I'm missing after
| switching from Love2D is being able to render multi-color text
| (with Raylib, you have to manually split up the text into
| chunks based on color markup, then apply width offset, then
| call the draw function for each chunk, while also taking into
| account things like linebreaks and such), not to mention that
| it seems to tank the FPS a lot when you try to draw a lot of
| text on the screen (perhaps the draw call batching is broken
| for text?) and being able to easily chop up textures and make
| them wrap or tile, Raylib used to have tiled texture draw
| function in the past but for some reason they removed it.
| abnercoimbre wrote:
| I'm the organizer for the conference [0] mentioned in TFA.
|
| We had a professional UI/UX designer react to ShapeUp [1],
| and one of the things she commented on was the font being
| hard to visually parse.
|
| I laughed a little when the author yelled "raylib!" to make
| sure blame was assigned appropriately XD. I'm currently the
| top GitHub sponsor for raylib, so there's no hate, but I wish
| he changed some of his defaults.
|
| [0] https://handmadecities.com/seattle
|
| [1] https://vimeo.com/887532756/2972a82e55#t=49m58s
| (timestamped)
| edflsafoiewq wrote:
| Why did you switch from Love2D?
| diath wrote:
| I need multithreading, async TCP, and have to implement
| systems that benefit from type safety. Though, I do still
| use Lua (using sol2), for interface modules, but I miss the
| features that Love2D provided on the framework level.
| nextaccountic wrote:
| > I agree entirely with the author on the limitations of
| Raylib.
|
| Wow this is kind of insane. About this
|
| > Raylib doesn't do basic parameter validation, by design. This
| function segfaults when dataSize is null: (...)
|
| The developer answered this
|
| > For most of the raylib functions is up to the user to
| validate the inputs, if raylib should consider all possible
| bad-use scenarios it would require reviewing most of the
| library functions and it will increase source-code complexity.
| kragen wrote:
| in c and c++ this is not just normal but almost unavoidable.
| if your function takes a t* and someone casts a random int to
| a t* and pass it in, it is gonna segfault. no possible way to
| validate it, though in theory you could open /proc/self/maps
| and iterate through it to catch the segfault cases, or
| install a segfault handler
| lelanthran wrote:
| > if your function takes a t* and someone casts a random
| int to a t* and pass it in, it is gonna segfault.
|
| True, that is not something a function ought to defend
| against.
|
| However, the complaint was not about that, though, it was
| about not checking if the dataSize parameter is NULL.
|
| I don't really have a problem with functions that segfault
| when given NULL pointer parameters _as long as this is
| clearly documented!_
|
| Sometime, however, you just need to be familiar with enough
| projects in C that common-sense gets built. In the
| specified example: unsigned char
| *LoadFileData(const char *fileName, int *dataSize);
|
| I _expected_ that a function that returns an array needs to
| tell the caller how large that array is. This specific
| function is not one I would complain about.
|
| These things are usually documented in the headers. In this
| case it says: // Load file data as byte
| array (read)
|
| So, yeah, it's pretty clear to me that the number of bytes
| has to be returned _somewhere_ , and there's only one
| parameter called `dataSize`, so this isn't something I
| consider to be a valid complaint.
|
| [EDIT: Escaped pointers, and added last paragraph]
| defrost wrote:
| > unsigned char
|
| _WARNING_ unpaired | unescaped * 's !! :-)
|
| _grrr, markup_
| lelanthran wrote:
| Thanks, fixed.
| naasking wrote:
| > Sometime, however, you just need to be familiar with
| enough projects in C that common-sense gets built.
|
| And if every C project takes this same philosophy to poor
| documentation, how exactly is a new person learning C
| supposed to build that common sense? Brushing off poor
| documentation with "you just need more experience" is not
| a valid response. The documentation for that function
| could be much more clearer without being much longer.
| lelanthran wrote:
| My point is not that it was good or acceptable, my point
| is that, while not perfect, it isn't bad enough to
| warrant the moniker of `insane`.
| kragen wrote:
| yeah. unlike an arbitrary garbage pointer, a null pointer
| is something the callee _could_ detect. but on linux or
| windows the operating system will reliably detect it for
| you, and in a way that makes it a lot easier to debug: it
| segfaults, making it obvious that there 's a bug, and
| your debugger will show you the stack trace leading up to
| the LoadFileData call with the null pointer parameter.
| and, as you point out in your other comment, in the very
| next line after your call to LoadFileData, you need the
| data size, and if you passed in a statically null
| pointer, you don't have it, so you realize you're going
| to need to pass in a pointer to an actual int
|
| so, while the documentation could and should be more
| explicit than the single telegraphic line you quote, the
| function's behavior is fine, and detecting and trying to
| handle the null pointer would make its behavior worse and
| harder to debug (except on like an arduino or ms-dos or
| something)
|
| not every c api description needs to be an introductory
| tutorial for c
| pjmlp wrote:
| Even that isn't fullproof.
|
| Microsoft has deprecated all pointer validation functions
| on Windows, because there were plenty of corner cases
| regarding pointer validation.
| kragen wrote:
| aha, thanks. yeah obviously /proc/self/maps won't help
| much there
| lelanthran wrote:
| I think the word 'insane' is going to far to describe the
| behaviour of the specified function.
|
| It returns an array of bytes. If you, the programmer, wrote a
| line that called that function, _on the very next line_ you
| are going to try to use the array, realise that you don 't
| know the length, and realise that the `NULL` that passed in
| on the line above is probably the output _for the length!_
|
| In order to actually write a call with `NULL` for the
| dataSize argument, the programmer needs to be clueless about
| how to write a for loop.
|
| So, no, I can't easily see a situation where a programmer
| accidentally uses a `dataSize` parameter of `NULL`, because
| that would mean they don't know that arrays in C have no
| length information, which is C 101.
| uecker wrote:
| Arrays in C have length information. Pointers do not.
| lelanthran wrote:
| > Arrays in C have length information. Pointers do not.
|
| Sure, but they don't carry that length information when
| being returned from a function.
| SJC_Hacker wrote:
| > Arrays in C have length information.
|
| Not in any sense that is actually useful to the
| programmer, at runtime at least. You cannot ask an array
| how big it is.
|
| Pointers actually do have length information as well,
| otherwise free() would not work. But its the same deal
| with arrays - there is no way to access it outside of
| compile time constants, if those are even present.
| jstimpfle wrote:
| Not every pointer works with free(). Most don't.
| shric wrote:
| > Arrays in C have length information. Pointers do not.
|
| This is 100% correct. The parent of the parent is
| confused (or is just using terminology incorrectly) as
| are the current siblings to my comment.
|
| One post claims pointers carry length information so that
| free works. This has nothing to do with pointers, it has
| to do with the implementation of malloc and friends. It's
| only a promise of a successful malloc that you can free,
| nothing to do with the pointer other than it was returned
| by malloc. Pointers can point to all sorts of things, the
| only information they intrinsically have are the type of
| the object they point to and its address.
|
| Two posts claim a function can return an array of bytes.
| This is impossible in C. You can't return an array of
| bytes. You can return a pointer that might point into a
| continuous sequence of bytes. You could also return a
| struct whose member is an array, but that's rarely done.
| When you return (or pass) what looks like an array
| syntactically, it is converted to a pointer to its first
| element.
|
| Arrays, on the other hand, always carry length
| information via the sizeof operator. A special hand
| waving case would be you could define a pointer to an
| array (not a pointer to the first element of an array),
| so in effect the length is contained within the pointer
| type. E.g. char (*foo)[42] declared foo as a pointer to
| an array of char with length 42.
| pjmlp wrote:
| Pity that they decay into pointers all the time.
|
| So that is pretty much worthless outside the current
| scope where they were declared.
| jakubtomsu wrote:
| I switched from raylib to Sokol some time ago and it's the
| best. Super simple and single header C code, no dependencies,
| cross platform code and shaders, etc etc. I've shipped a steam
| game and I plan to continue using Sokol in the future.
| user432678 wrote:
| Do you mind sharing a link or game name? Despite all the
| advice out there picking up a game engine, I too am pursuing
| a goal of making a game from scratch using simple parts of
| C++ and SFML for now, but was also looking at SDL and Sokol.
| What was your experience? Are you a solo dev? Was it worth
| it?
| wilberton wrote:
| Not the parent, but I also use sokol as the base for my
| engine. I've shipped 3 3d web games with it, and honestly
| it was the best technical decision I ever made! There's
| just so much to be said for owning all your dependencies
| (as far as possible, sokol is still a dependency but it's
| way more manageable than a 3rd party game engine)
| user432678 wrote:
| Do you mind to share your games details? No judging, I
| promise :) I just need examples from people like me and
| not AAA studios for motivation sake. I literally was
| called an idiot for not choosing Unity or Unreal, and was
| turned down for collaboration with non-tech people just
| for that. Game dev landscape is crazy these days.
| wilberton wrote:
| It totally depends on the type of game you want to make,
| whether using an existing engine or rolling your own is
| the best option. This is one of the games I've made with
| my engine: https://poki.com/en/g/super-tunnel-rush My one
| tip is only make enough of the engine to support the game
| you're writing, and write the game at the same time as
| the engine (don't think you need to finish the engine
| before you can start writing the game, that route doesn't
| work out well :)
| user432678 wrote:
| This looks amazing and I was surprised it worked really
| good on mobile too!
| parasti wrote:
| There's something really powerful about taking the tools that you
| know very well and just making something cool with them. Really
| enjoyed this writeup, thanks.
| xixixao wrote:
| Super impresssive for getting this done in a week. Being able to
| make pretty demo models definitely helps too! :)
| sandwichukulele wrote:
| is the source code available? I looked through the blog post and
| linked videos but could not find a github repo or anything
| similar
| TruthWillHurt wrote:
| Or just being able to save/load creations would be nice :)
| dhooper wrote:
| yeah I never implemented saving/loading for the web. Thats
| one example of how raylib doesn't totally abstract the
| underlying platform for you.
| dhooper wrote:
| I just made it public:
| https://github.com/danielchasehooper/ShapeUp-public
| jbritton wrote:
| How did you create / obtain the example shapes? Is there a
| standard format your code parses?
| dhooper wrote:
| the example files in the repo were made using the macos
| build of shapeUp and saved (the web build doesn't have
| saving)
| SoKamil wrote:
| > The Shapes are kept in a statically allocated array [...] Can't
| fail to allocate, can't be leaked, no fluff. Lovely. The 100
| shape limit wasn't limiting in practice. With very little time to
| optimize the renderer, the framerate would drop before you even
| got to 100 shapes.
|
| That's the best example of avoiding premature optimization I've
| seen in a while.
| Narishma wrote:
| I think this is the opposite. It's avoiding premature
| abstraction/generalization.
| bruce343434 wrote:
| But finding abstractions and generalizations optimizes
| scratching that itch inside our heads
| HumblyTossed wrote:
| Best example of those who do vs. those who sit around bickering
| over HOW to do.
| ffitch wrote:
| > The project is 2024 lines of C
|
| got to appreciate the effort to make the irony possible : )
| poopicus wrote:
| As someone who has difficulty in detecting irony, could you
| explain the irony in this statement?
| booleandilemma wrote:
| 2024 is the current year and it's the same as the number of
| lines of code. I don't think describing it as ironic is
| correct though.
| vsuperpower2020 wrote:
| That certainly is gregarious!
| ngcc_hk wrote:
| Never get that. Bad in literature. Thanks.
| roland35 wrote:
| It's about ironic as rain on your wedding day.
| lelanthran wrote:
| > It's about ironic as rain on your wedding day.
|
| Ah!!! It's the Alanis Morrisette meaning of irony, not
| the dictionary one!
| enumjorge wrote:
| The other response is correct that this is not ironic.
| Roughly speaking, irony is when something happens that is the
| opposite of what you'd expect. A firefighter's home burning
| down is ironic. Sometimes irony is related to unfortunate or
| funny coincidences/timing, and it's easy to confuse the two.
| Alanis's song Ironic famously has a lot of examples of this.
| Rain on your wedding day--is that ironic? Maybe? You
| certainly hope there is no rain on your wedding day, but I
| don't think there's an expectation that there won't be rain.
| Now if your parents decided to get a divorce on your wedding
| day, I think that's ironic.
|
| But the parent commenter dilutes the definition further. A
| project with 2024 lines of code in 2024 is just an amusing
| coincidence. There's no reason why you'd expect a project in
| 2024 to not have 2024 lines of code.
| runevault wrote:
| Super interesting post, and appreciate him talking about the
| various decisions like his handling of memory (and the issues he
| ran into with raylib). As someone who's finally diving into part
| 2 of crafting interpreters (and using it to refresh myself on C)
| being reminded of what C does well is great.
| fallingsquirrel wrote:
| I really love the live demonstrations in the video. Forget
| building the app, I couldn't even produce that video in a week if
| I tried.
| dhooper wrote:
| The video took me longer to make than the app! I don't know how
| youtubers do it so regularly.
| an_aparallel wrote:
| They have a team :)
| movedx wrote:
| Not all of us do. If you can get to an average of 300k+
| view per video then you can hire an editor and maybe
| someone else on a contract basis to assist. Must of don't
| have a team though.
| djmips wrote:
| Yeah sometimes they eventually hire an editor but I think
| channels like Cutting Edge Engineering it's a fulltime
| job for one of the two people to do the filming and
| editing.
| swiftcoder wrote:
| That's some impressive development speed. Really enjoyed the
| explainer video too!
| emmanueloga_ wrote:
| What is a stablished 3d modeler that uses the same kind of
| modeling as this one?
| Lichtso wrote:
| Many 3D content creation tools such as Blender [0] have SDF [1]
| (e.g. metaballs in Blender) and CSG [2] (e.g. boolean modifier
| in Blender) features. But these are rarely used as they can
| only define volumes, not surfaces. And we are usually
| interested in surfaces for assigning textures and materials.
| Thus, polygons / meshes and curves / splines dominate the
| industry.
|
| [0]: https://www.blender.org/ [1]:
| https://en.wikipedia.org/wiki/Signed_distance_function [2]:
| https://en.wikipedia.org/wiki/Constructive_solid_geometry
| antirez wrote:
| TinkerCAD.
| starmole wrote:
| Adobe/Substance3D Modeler
| dantondwa wrote:
| The two best SDF modelers in existence are MagicaCSG[1] and
| Adobe Substance Modeler[2]. There are also a few others, like
| Womp, but those two are the most feature-complete. Blender is
| also adding them as part of geometry nodes, and there is also
| an add-on that is working on adding SDF for hard-surface.
|
| [1] https://ephtracy.github.io/index.html?page=magicacsg &
| https://www.patreon.com/magicavoxel
|
| [2]
| https://www.adobe.com/products/substance3d/apps/modeler.html
| joeld42 wrote:
| Blender Geometry nodes supports SDF modelling. It's just not a
| widely known or used technique. But it's super powerful.
| tcfunk wrote:
| Plasticity (https://www.plasticity.xyz/) is a new-ish one that
| looks neat, but I wish it offered a lower-price entry point.
| RamiAwar wrote:
| Amazing write up, thanks! Really enjoyed it, miss working on
| C/C++ apps from scratch and having full control
| jasonjmcghee wrote:
| This looks like such a fun jam - wish I'd have known about it!
|
| When's the next one?
| bvisness wrote:
| The next Wheel Reinvention Jam will be in September! We're just
| finalizing our plans for that jam and our smaller Visibility
| Jam in July. If you're interested in participating, then join
| the Handmade Network Discord server (link on our home page at
| https://handmade.network/).
| antirez wrote:
| I hope somebody will continue this project. It's a few months
| away to be a serious alternative to Blender / FreeCAD for certain
| use cases, with a much softer learning curve.
| turtledragonfly wrote:
| _EDIT_ aha, the program already supports exporting to a mesh
| via marching cubes; see the youtube video on the site. I hadn
| 't realized that (:
|
| ----
|
| Be aware that since it fundamentally works with SDFs, it is a
| somewhat different modeling experience (and stores different
| data) than traditional meshes with triangles, verts, etc.
|
| Transforming it from SDFs into meshes could be done with
| marching cubes or similar, but you'd likely need to "clean up"
| such data afterwards in a Blender-style app anyway.
|
| SDFs are great though, if your renderer is SDF-based, too (most
| are not).
|
| [sorry if you knew this already, wasn't sure]
| antirez wrote:
| Yep the export is already done! I used TinkerCAD a ton for
| things ways more complex than it should be used to, so even
| when I use more advanced CADs at this point I tend to think
| in SDF terms. For many things it's faster and more natural
| than extruding, rotating, ... But the fact is, the engine
| behind TinkerCAD is quite good, but there is little interest
| for AutoDesk to compete with its own Fusion360, so TinkerCAD
| is left forever as a children / beginners tool, without the
| more advanced stuff that could implement.
| johnnyanmac wrote:
| >SDFs are great though, if your renderer is SDF-based, too
| (most are not).
|
| Thanks for reminding me that one of the best SDF renderers in
| the industry is stuck behind Sony, deemed a failure because
| Sony didn't want to publish it to PC (where all the dev scene
| is).
| adastra22 wrote:
| Blender maybe, but not CAD work unfortunately.
| nineteen999 wrote:
| Not even Blender. Not even close.
|
| No disrespect to the author, it's impressive, but Blender
| gives you extreme control over mesh topology and this
| doesn't.
| adastra22 wrote:
| Sometimes that's what you want though. This is good for
| "digital clay modeling."
| nineteen999 wrote:
| So is ZBrush, which is why its the industry standard for
| sculpting for VFX and games.
|
| You still have to get decent topology out of the
| modelling package, and marching cubes aren't going to
| give you that. If you have to retopologize your sculpted
| model by hand to make it viable for use in a rendering
| pipeline you might as well have just started with good
| topology in the first place and save yourself the time.
| naasking wrote:
| Meshes in Blender have finite resolution, SDFs do not. They
| can scale to an extent that simply isn't possible with
| meshes.
| nineteen999 wrote:
| Wake me up when the deformable assets in VFX and video
| games etc are represented by SDF's instead of meshes.
|
| How do you rig an SDF for animation (eg. skeletal, for a
| humanoid figure)?
| naasking wrote:
| The signed distance function defining a solid can be
| parameterized by anything. Common ones are results of a
| finite element analysis, thereby allowing you to make the
| structure thinner where it doesn't need strength.
|
| In the case animation, parameterize it by a global clock,
| and each frame the objects are in slightly different
| positions dictated by a rough physics model (like a
| person's skeleton).
| nineteen999 wrote:
| Bad topology generated by marching cubes from an SDF is
| not going to replace hand tuned topology for animated
| meshes in VFX and video games in the near future. Even
| highly dense Nanite meshes in UE5 don't support skeletal
| deformation yet.
| johnnyanmac wrote:
| To be fair, I don't exactly think the mesh system was
| made with deformation in mind either. We kind of just
| hammered on rigs/skinning on top of it, then learned all
| the ways _not_ to model for that workflow.
|
| Shame that NURBS never really took off in the gaming
| scene. I get it from a hardware standpoint (GPUs like
| triangles, and we can cut quads into triangles), but
| NURBs solve so many problems that trianglular meshes just
| hack their way around.
|
| >How do you rig an SDF for animation
|
| I imagine with the most unholy mathematical models
| imaginable. Dreams did it, so it's not impossible. But
| the results seen definitely don't measure up to a AAA
| standard (at least in Dreams).
| nineteen999 wrote:
| Right, but the skeletal mesh workflow has been in
| production use and being developed since the late 1990's.
| It's extremely mature and a mind boggling amount of $$$
| have been spent on optimizing it and designing hardware
| around it since that time.
|
| I appreciate all the tangential discussions, but the two
| key points im trying to make are:
|
| 1) SDF's are not likely to supplant detailed hand
| modelled/cleaned up meshes any time soon, but will
| continue to be used alongside and in conjunction for all
| kinds of other cool stuff (soft shadows, ambient
| occlusion, fonts etc as seen in UE4/UE5)
|
| 2) ergo, a modeller based around SDF's is not going to
| replace mesh based modellers like Blender, Maya etc
| anytime soon, even to a small degree.
| johnnyanmac wrote:
| So, sunk cost fallacy? I suppose.
|
| I don't think anyone fundamentally disagrees with you,
| but an author making a toy 3d modeler in a week usually
| doesn't have the goal to disrupt an entire industry. It's
| a nice place to consider on a fundamental level what
| tools like these could and couldn't do that current work
| flows cannot.
| dahart wrote:
| I'm not sure that resolution helps with topology control
| at all. If true, more resolution doesn't make SDFs more
| controllable.
|
| But I don't think it's true. Why do you say SDFs don't
| have finite resolution? There are no infinite precision
| SDF implementations. Meshes as a concept have no
| resolution limits either, you could in theory store verts
| in infinite precision, but in practice people usually use
| floats. It is the same with SDFs. In practice, the
| resolution limits are identical - it's whatever you can
| store in a 32 bit float. It's extremely common with SDF
| ray marchers to have a _much_ higher threshold than the
| smallest fp32 delta, so I would say in practice, meshes
| probably have higher resolution than SDFs most of the
| time. And whatever, because it _never_ matters. Nobody is
| pushing either SDFs or meshes to their resolution limits,
| and nobody wants that because you get visible
| quantization artifacts with both meshes and SDFs when you
| come anywhere close to the resolution limits.
| naasking wrote:
| > There are no infinite precision SDF implementations.
|
| But it's relatively trivial to make one. SDFs are
| technically polymorphic over the concrete number type
| used. They are intrinsically infinitely scalable and of
| infinite resolution, and you then compute an
| approximation that can be rendered according to the
| output constraints/requirements.
|
| Meshes on the other hand are intrinsically finite. You've
| already baked in a finite precision at design time. If
| you're outputting a mesh, you're _throwing away_
| information.
|
| It's like the difference between vector and raster
| graphics. Vector graphics clearly have superior
| properties when it comes to scaling and other
| transformations. Raster images still find more use, but
| vector graphics are starting to see more use for good
| reasons.
|
| > whatever, because it never matters.
|
| It's starting to matter more, particularly in CAD
| modelling where model reuse, parameterization by finite
| element analysis and other physics models, etc. are
| starting to align better with SDF.
|
| I won't pretend to know as much about games or CGI in
| film, but I expect as the tools mature, it will just make
| sense to start adopting them there too.
| moarinfoszszz wrote:
| Check out Dune3D and Salome-Platform
| OskarS wrote:
| You should check out MagicaCSG, which is a more sophisticated
| version (though still free!) of this:
| https://ephtracy.github.io/index.html?page=magicacsg#ss-caro...
| captainhorst wrote:
| There's also https://womp.com as an SDF modeler
| fsloth wrote:
| If you like SDF:s Womp is pretty nice for starting out.
| Tinkercad is another pretty good beginner "cad".
| rationalfaith wrote:
| Good stuff! As a c/c++ coder maintaining his game engine (for
| commercial and hobby purposes), this is always good to see!
| freecodyx wrote:
| I sometimes think, that c is all we need
| yazzku wrote:
| I write C all day and enjoy every second of it. I assume there
| are many like myself. There's just nothing new to make noise
| about, and that's a good thing, other than small quality-of-
| life improvements in the standard.
| lionkor wrote:
| you dont need that comma fyi
|
| While I fully support liking one language, it wouldnt feel
| right for me to not mention the benefits other languages bring,
| such as GC for large dev teams of lower skilled devs, languages
| with builtin unit tests, languages with templating or less bad
| macros, etc.
| ngcc_hk wrote:
| Really agreed with his assertion of c. More to his " Its syntax
| doesn't hide complex operations. It's simple enough that I don't
| have to constantly look things up", and further if you need to
| look up something about c, it is very easy and very informative.
| Simple and old lang has its benefits.
| syphiant wrote:
| Impossible! Wow! This is absolutely mind blowing.
| ederamen wrote:
| Just started using Raylib, bummed to hear about the limitations!
|
| As a novice C programmer, the simplicity and immediacy of results
| opened my eyes to how C can feel as productive as higher level
| languages with robust standard libs.
| lelanthran wrote:
| > As a novice C programmer, the simplicity and immediacy of
| results opened my eyes to how C can feel as productive as
| higher level languages with robust standard libs.
|
| TBH, once you have halfway-good libraries for dealing with
| `char *` strings as-is, dynamic arrays and hashmaps, you are
| not going to be much slowed-down using C than using a higher-
| level language.
|
| You even get much stronger isolation guarantees than most other
| high-level languages, while getting _much more_
| compatibility[1] with any other language you may wish to
| interface to: https://www.lelanthran.com/chap9/content.html
|
| [1] I did a little Go project, and it annoyed me slightly when
| I wanted to do performant FFI. For Go, I think the situation
| has improved since I last checked, though.
| neonsunset wrote:
| You can trivially replace Go with C# in order to get almost
| zero-cost FFI (you can make it fully zero-cost with
| additional effort but even the baseline is better than the
| alternatives, hell you can statically link other .lib/.a's
| into AOT compiled .NET binaries).
| naasking wrote:
| > TBH, once you have halfway-good libraries for dealing with
| `char *` strings as-is, dynamic arrays and hashmaps, you are
| not going to be much slowed-down using C than using a higher-
| level language.
|
| That can't possibly be true. Not having to even think about
| object lifecycles and ownership because all memory is GC'd
| saves _a lot_ of time all by itself, not even getting into
| debugging issues when you get it wrong.
| jesse__ wrote:
| It's definitely true.
|
| Memory allocation takes a very small percentage of my time.
| I'd guess < 1%. Debugging memory issues used to take me
| more time, but these days it's basically inconsequential,
| too.
|
| Having written interpreted languages previously to jumping
| to C & C++ (>10y programming exp), there's a massive cost
| to using interpreted and/or GCd languages that comments
| like this one never seem to acknowledge. Random package
| bit-rot, high-difficulty memory leaks, high-difficulty AND
| high consequence manual memory management (to avoid the
| GC), poor performance tooling, nearly completely opaque
| performance characteristics, inability to optimize
| performance past a surface level... etc.
|
| If you're building anything more complex than simple web
| apps, this shit all adds up to a lot. I've worked at a
| couple shops that these issues hit like a ton of bricks.
| neonsunset wrote:
| What kind of GC-based languages were the source of issues
| for these use cases? Was C# among them (in any recent
| time)?
| lelanthran wrote:
| I've not used C# in recent years.
|
| While I actually liked the language, it's complexity is
| increasing with diminishing returns.
|
| There's no point in getting to a complexity level of, for
| example, C++ for any language - people who want such
| levels of complexity will be happy to use C++.
| neonsunset wrote:
| While it certainly will eventually die C++'s death (can't
| remove language features, only add), it's luckily far
| from that predicament today.
|
| I don't think you could reasonably compare the two in
| amount of tacit knowledge one has to posses to avoid all
| kinds of footguns and get best results. The rule of thumb
| today for C# is to go with simplest way to do something
| and don't ignore IDE/analyzers' suggestions or warnings.
| A lot of focus has been put on terseness and simplicity.
| jesse__ wrote:
| The experience I was referring to was JS, Python and Ruby
| naasking wrote:
| Literally all of the costs you list apply to C/C++ as
| well, except you have the _additional_ hazards of having
| to worry about memory safety and leaks all of the time
| rather than only once every 5 years. Sorry, I don 't find
| your claims plausible at all. It's just too easy to
| forget what you actually spend your time on.
|
| Edit: and the most significant evidence for this is in
| comparing all the CVEs for C/C++ vs. memory safe
| languages like C#/Java.
|
| > I've worked at a couple shops that these issues hit
| like a ton of bricks.
|
| What you're missing is that 99% those shops wouldn't have
| existed at all if they had tried to go the C/C++ route
| because their products just wouldn't have gotten to a
| viable state. What your experience shows is that working
| in memory safe languages is _so_ much easier that even
| average or mediocre programmers can get a viable product.
| lelanthran wrote:
| > Literally all of the costs you list apply to C/C++ as
| well,
|
| But we aren't talking about C/C++.
|
| At least, _we_ weren 't, but your comments make a lot
| more sense in the context of C++.
|
| > Edit: and the most significant evidence for this is in
| comparing all the CVEs for C/C++ vs. memory safe
| languages like C#/Java.
|
| Wasn't the most expensive RCE the world has ever seen
| written in Java?
| jesse__ wrote:
| In my experience, GC'd languages leak much more
| frequently because people figure 'oh, the GC will take
| care of it for me.'
|
| There are excellent tools for detecting memory
| leaks/safety issues in C, and you can even write all your
| own allocators for your own edification / amusement /
| sanity, but in a GC'd languages, you're pretty much
| fucked across the board. There's some tooling, but it
| pales in comparison to the tools available for C.
|
| I would also like to acknowledge the topic of CVEs you
| brought up. Yes, mistakes in mission critical systems
| happen. And for those systems, maybe something with
| better memory safety features is more productive in the
| long run. The original comment I replied to suggested C
| can be surprisingly productive with just a few tools,
| which I stand by supporting.
|
| > What you're missing is that 99% those shops wouldn't
| have existed at all if they had tried to go the C/C++
| route [...] average or mediocre programmers can get a
| viable product
|
| Hard disagree. The two places I have in mind hired
| average/mediocre people to do somewhat challenging
| graphics work. Both had interesting products that may
| have actually been viable (think matterport, figma) but
| both failed because the UX sucked .. due to what can only
| be described as UI jank.
|
| Lastly, it is easy to forget what you spend time on. I ve
| been tracking all my bugs that took more than 30 minutes
| for the last 10 years. The vast majority are graphics
| bugs due to API misuse. Very few are memory safety bugs,
| especially recently.
|
| EDIT: also, half the costs I listed were related to
| performance. How the fuck do you justify the statement
| that those apply to C? What language would you pick to
| have more control over the assembly the machine is
| running.. other than assembly I guess..
| naasking wrote:
| > In my experience, GC'd languages leak much more
| frequently because people figure 'oh, the GC will take
| care of it for me.'
|
| "Frequent memory leaks" has never happened to me in 20
| years of programming in GC'd languages.
|
| > There are excellent tools for detecting memory
| leaks/safety issues in C
|
| A process you don't even need in GC'd languages. I think
| I've had maybe a couple of non-critical leaks in those 20
| years due to finalizer bugs.
|
| > also, half the costs I listed were related to
| performance. How the fuck do you justify the statement
| that those apply to C?
|
| The vast majority of performance issues are related to
| algorithmic choices. With the right choice of algorithms
| and data structures, any language will likely get within
| a constant factor of C.
|
| Sometimes that constant factor matters, most often it
| does not given the added costs of eliminating that
| constant factor, eg. in dev time and risk of introducing
| bugs or security vulnerabilities. And even where it does
| matter, you're almost certainly better off writing the
| performance critical kernel in C and then calling into it
| from a higher level language, as is common in machine
| learning.
| pjmlp wrote:
| The joy of debugging memory corruption issues on
| production, while helpdesk keeps pinging dev team several
| times a day.
|
| Yep, I have multiple scars and gray hairs due to them.
| lelanthran wrote:
| > That can't possibly be true. Not having to even think
| about object lifecycles and ownership because all memory is
| GC'd saves a lot of time all by itself, not even getting
| into debugging issues when you get it wrong.
|
| I think perhaps the context may make it clearer: it was
| about simplicity.
|
| >>> the simplicity and immediacy of results opened my eyes
| to how C can feel as productive as higher level languages
| with robust standard libs.
|
| So, sure, no one is saying that you'll be _faster_ in C,
| but with such a small cognitive footprint, you can be
| faster than you 'd think.
|
| When programming in C, I don't spend much time thinking
| about the language, I think about the problem more than the
| language. I don't think about complex relationships between
| language features; about what might happen if I use a
| reference in a lambda. I don't need to remember what the
| `this` keyword refers to depending on how the function was
| created. I don't need to puzzle my way out of a painted
| corner due to colored functions.
|
| It's the simplicity that I was responding to. You go faster
| than you would expect.
|
| As far as object lifecycles go, there's a small number of
| idiomatic ways to mitigate the problems. Not foolproof, but
| with such a simple language, whatever valgrind reports can
| be quickly fixed.
|
| Regarding ownership: I'm not really aware of how GC
| languages, by way of being GC, helps there. I'm pretty
| certain it doesn't. If you pass an object to a method in
| Java, C#, whatever, and that method starts a new thread
| with it, you're still going to be boned if the callee
| starts modifying it at the same time.
|
| Whatever ownership issues you have in C, you'll have in
| most other GC languages as well.
| naasking wrote:
| > So, sure, no one is saying that you'll be faster in C,
| but with such a small cognitive footprint, you can be
| faster than you'd think.
|
| I would agree that you can be faster than you'd think _on
| problems that C is reasonably good for_. This is a fairly
| small subset of problems though, where your original
| comment was phrased like a general statement for any sort
| of problem / general purpose programming. That's what I
| take issue with.
|
| If you're going to do any kind of programming that
| depends on interfacing with the world, UTF, protobufs,
| even rendering to a screen as with this article, you're
| going to be pulling in those same sorts of dependencies
| that you denounce from all of those other languages.
|
| > Whatever ownership issues you have in C, you'll have in
| most other GC languages as well.
|
| I agree you have similar thread safety issues, the
| ownership issues I was referring to was for managing
| lifetimes leading to double-frees or leaks. Yes there are
| some idioms that almost work, but "almost work" is
| exactly the point, in GC'd languages they actually do
| just work.
|
| I understand the appeal behind the economy of C but we
| just shouldn't pretend it's something that it's not.
| neonsunset wrote:
| > If you pass an object to a method in Java, C#,
| whatever, and that method starts a new thread with it,
| you're still going to be boned if the callee starts
| modifying it at the same time.
|
| Which is why the concept of thread-safe types exists. The
| documentation usually explicitly states if a particular
| container/service/anything else is safe to call from
| multiple threads concurrently or not, and the standard
| library goes to great lengths to either make the types
| that are expected to be used in multi-threaded scenarios
| thread-safe or to offer thread-safe alternatives (like
| ConcurrentDictionary<K, V>).
|
| Worst case, most types are engineered in such a way that
| should thread-safety be violated, it would either lead to
| an exception or an invalid state but not to memory safety
| issues.
| Jach wrote:
| Really cool and the video was great too. Indie devs should
| probably consider doing this sort of thing more often, building
| these simple tools in service of a game rather than just using
| the industry standard tool. It can be a great way to add artistic
| character as well as rigorously enforce some limitations if
| that's what you're after.
| koushik wrote:
| This looks cool, after 3 years in financial technology industry
| working on c/c++ projects I'm in process of revisiting textbooks
| and relearning computer science fundamentals! Added raylib to my
| 'explore' list
|
| I love this idea of reinventing wheel with such explicit goal
| (even if it sounds counterintuitive to some), we can rethink
| initial assumptions, best case scenario we come out with better
| implementations and paradigms than existing standards, worst case
| scenario you learn internals of tools and techniques you use
| daily!
| gorkermann wrote:
| To get a look at SDF rendering in a game, check out the blue
| clouds on the ground in Solar Ash:
|
| https://youtu.be/HqQpYSQDIZQ?si=vMKplmGJIGvUn_LT
| drtgh wrote:
| Off-Topic:
|
| Glad to see for the first time a WebAssembly interface where the
| text does not look blurry. I repeat, it is the first time.
|
| Extending this to programs and some operating systems (such as
| Windows), in the past few years, there has been a pervasive issue
| with the text rasterization methods that have become a common
| trend and default setting.
|
| Unfortunately, users often do not have the option of turning off
| anti-aliasing to get sharp text, and in the rare cases where this
| option is available, the interface (menus, etc.) still uses anti-
| aliasing.
| themerone wrote:
| The crisp text is unimpressive. The typeface has no curves and
| there is no smoothing. That text will be crisp and blocky at
| any resolution.
| drtgh wrote:
| The crisp text maybe it is unimpressive in the sense that is
| being used an graphic library targeted to games, so is using
| an homologous to pixel fonts. But it is not the norm.
|
| I'm simply increasing awareness among the development
| community about the problems with text rasterization in
| applications and OS interfaces. I'm glad not to see blurry
| text.
| flohofwoe wrote:
| > The crisp text is unimpressive.
|
| Not if you actually tried to achieve that in practice across
| all browsers and display configurations ;)
|
| For instance Safari had for the longest time a hardwired
| (e.g. not fixable via CSS) linear filter applied when a WebGL
| canvas had to be upscaled. It's only been fixed last year or
| so.
|
| Also unfiltered upscaling done breaks down when fractional
| scaling outside the browser happens, the result will
| generally look horrible and there is no good way to fix it.
| The only workaround is to make hide the scaling artifacts
| behind a filter, which then makes everything look blurry.
|
| Browsers running on top of Wayland most likely still have all
| those issues.
| TachyonicBytes wrote:
| Why is there a link between WebAssembly and rasterization?
| Genuinely curious, it seems interesting
| kewp wrote:
| I wish he had tried instead to do the faster subset of
| typescript, that is a pet peeve of mine and I've love to see how
| it would be done!
| cnity wrote:
| AssemblyScript?
| rkagerer wrote:
| _You could certainly make it harder on yourself by malloc-ing
| each Shape individually and storing those pointers in a dynamic
| array. Using a language like C# ... would force that allocation
| structure._
|
| What's stopping you from using a fixed array of structs in C#,
| just as the author has done in C?
| kronovecta wrote:
| Nothing. In C# it's not unusual to use struct arrays in this
| way.
| OskarS wrote:
| Probably confusing it with Java, where the only value types
| are the basic ones (unless you store each individual coord in
| a different array).
| icoder wrote:
| Still you could in Java avoid the (under the hood) memory
| allocation and garbage collection by reusing the same
| objects. If you wanted to, of course, it probably takes a
| bit more effort / caution at the developer's side but may
| provide some improvements in performance in very specific
| cases/situations.
| OskarS wrote:
| The primary concern with this isn't necessarily the extra
| allocation and GC (though that plays a part too), it's
| the fact that you're chasing a pointer for every object.
| That's murder for the cache. MUCH faster to just have the
| data in-line in hot loops like this.
| pjmlp wrote:
| If Valhala ever lands, you will be able to do as in C#,
| D,...
|
| Until then, the best way currently, is to make use of
| Panama to create a C struct like memory layout, and have
| accessor methods for the low level details.
| neonsunset wrote:
| Trivially solved by C# - you can write an algorithm
| implementation with the same data structures that would
| perform the same as in C, C++ or Rust but often with more
| convenience.
| neonsunset wrote:
| "Using a language like C#, Javascript, or Python would force that
| allocation structure."
|
| No. C# structs are C structs. Shape[], Span<Shape> or Shape*
| would not be an array of pointers. Any of the following would
| work: var fromHeap = new Shape[100];
| var fromStack = (stackalloc Shape[100]); var fromPool =
| ArrayPool<Shape>.Shared.Rent(100); var fromMalloc =
| (Shape*)NativeMemory.Alloc(sizeof(Shape) * 100);
| kuon wrote:
| I really like this kind of projects. I still like the low level
| of C. Now I work with rust a lot and elixir/erlang but I often
| miss the simplicity and explicitness of C. For this, I use zig a
| lot too. It is a very nice improvement over C while keeping a lot
| of its philosophy.
| nesarkvechnep wrote:
| Erlang is a pretty simple language too.
| anthk wrote:
| Can I compile it with GNUStep?
| naasking wrote:
| Nice, I was considering a project like this myself. Signed
| distance fields are awesome. Everyone into modelling should check
| out ImplicitCAD based on SDFs.
| JabavuAdams wrote:
| This is really great! Nice work, and thanks for sharing.
| gromneer wrote:
| getting tired of the underhanded shilling for c and procedural
| style programming. the people doing this still pretend they are
| the underdogs but their point of view is over saturated.
| TacticalCoder wrote:
| I don't know why you got that feeling, TFA says this:
|
| > Some view C as a language so simple and raw that you'll spend
| all your time working around the language's lack of built in
| data structures, and fixing pointer bugs. The truth is that C's
| simplicity is a strength. It compiles quickly. Its syntax
| doesn't hide complex operations. It's simple enough that I
| don't have to constantly look things up. And I can easily
| compile it to both native and web assembly. While C has its
| share of quirks, I avoid them by habits developed over 22 years
| of use.
|
| Which is nothing unreasonable.
|
| I code mostly in a Lisp dialect but I don't take offense at,
| say, the Linux kernel being mostly C.
| gromneer wrote:
| i am not assessing the truthfulness, the reasonableness, the
| correctness, or the veracity of the claims made in the
| article in any way. i simply do not care because the claims
| are purely subjective, untestable, unmeasurable. it is an
| opinion piece and one that is dulled out ad nauseam in the
| programming world today. enough to be annoying now. one
| opinion for another.
| layer8 wrote:
| I'm getting tired of people not using the Shift key.
| CamperBob2 wrote:
| Other sites beckon.
| ttul wrote:
| Long ago, I worked on the operating system for a desk phone. With
| only 64K of RAM, there was no dynamic memory management
| whatsoever. We made heavy use of static variables and let the
| compiler figure out how to allocate everything at compile time.
|
| It's easy to forget that many applications probably don't need
| dynamic memory management at all. You can often get away with
| allocating a few fixed size buffers and just handling the edge
| cases nicely when those buffers are full.
|
| And in such a context, C is indeed a whole lot safer. No memory
| leaks. Your only concern is buffer overflows, which can be
| managed through careful use of sizeof when all of your variables
| are statically allocated. I'm not saying Rust and Go aren't great
| options these days, but humble old C still works and doesn't have
| to be nightmarishly complex.
___________________________________________________________________
(page generated 2024-05-04 23:00 UTC)