adamdruppe / arsd

This is a collection of modules that I've released over the years. Most of them stand alone, or have just one or two dependencies in here, so you don't have to download this whole repo.
http://arsd-official.dpldocs.info/arsd.html
529 stars 128 forks source link

Add Pixmap Recorder module #449

Closed 0xEAB closed 3 months ago

0xEAB commented 3 months ago

I’m positively surprised how simple it is to create actual video files from frame data. Let’s make it easy as well.

0xEAB commented 3 months ago

I’ve also ported over the “stars” demo from This Week in D issue 2023-12-25.

Code here. ```d import arsd.pixmaprecorder; import arsd.pixmappaint; int main() { // Instantiate a recorder. auto recorder = new PixmapRecorder( 120, "stars.mkv", ); // We will use this framebuffer later on to provide image data // to the encoder. auto frame = Pixmap(640, 400); Color emptyColor = Color.black; frame.data[] = emptyColor; static struct Star { float x; float y; float z; void reset() { import std.random; this.x = uniform(-1.0, 1.0); this.y = uniform(-1.0, 1.0); this.z = uniform(0.1, 1.0); if (this.x == 0) this.x = 0.1; if (this.y == 0) this.y = 0.1; } } Star[] stars; stars.length = 164; // pick a number! foreach (ref star; stars) { star.reset(); } enum max_distance = 0.5; // anything > 0 and <= 1.0 foreach (_foo; 0 .. 6000) { foreach (ref star; stars) { auto drawX = cast(int)((star.x * (1.0 - star.z * max_distance) + 1.0) / 2 * frame.width); auto drawY = cast(int)((star.y * (1.0 - star.z * max_distance) + 1.0) / 2 * frame.height); // erase the old position... unless you're accumulating snow frame.data[drawY * frame.width + drawX] = emptyColor; // for flying through space, adjust z star.z -= 0.005; if (star.z <= 0) star.reset(); if (star.y >= 1 || star.z < 0) star.reset(); drawX = cast(int)((star.x * (1.0 - star.z * max_distance) + 1.0) / 2 * frame.width); drawY = cast(int)((star.y * (1.0 - star.z * max_distance) + 1.0) / 2 * frame.height); // draw the new position frame.data[drawY * frame.width + drawX] = rgb(0xFF, 0xFF, 0xFF); } recorder.put(frame); } // End and finalize the recording process. return recorder.stopRecording(); } ```
adamdruppe commented 3 months ago

nice, yeah, ive been thinking about adding some kind of ffmpeg module eventually