* Tasks ** TODO [#A] Improve error messages in sprite-batch-add! =sprite-batch-add!= throws an error if it is called before =sprite-batch-clear!= maps the GPU memory, but the error message doesn't mean anything to users. Also, make sure the docs explain why you need to clear first. Consider renaming =sprite-batch-clear!= to =sprite-batch-begin!= while you're at it. Explain the difference between capacity and size. ** TODO [#A] Remove allocations in hot code paths - [ ] hash-for-each causes closure allocation in at least the shader, text, and audio modules - [ ] call-with-error-handling in (chickadee game-loop) allocates closures and is called twice per loop iteration. ** TODO [#A] Bug: Vertical line rendering not working Vertical lines are invisible. Not great! ** TODO [#A] Scheme -> GLSL compiler Like CL's varjo but for Guile. Start with a simple sexp -> GLSL serializer. Goals: - Scheme-like syntax - Embeddable within Scheme source files - Compiles to GLSL during regular Guile compilation - Clean interface for passing data from Scheme to shaders - Implicit returns in tail position (no 'return' keyword) - Everything is an expression - Type inference - Understands built-in shader stage variables - See: https://www.khronos.org/opengl/wiki/Built-in_Variable_(GLSL) - Macros - Nested functions if they are hoistable (no free variables aka not closures) - Shader libraries for reusing and composing code #+BEGIN_SRC scheme ;; Input vertices are positional arguments, uniforms are keyword ;; arguments. (define (sprite-vertex (vec2 position) (vec2 tex) #:key (mat4 mvp)) ;; First argument returned is the vertex position, all others get ;; mapped to fragment shader inputs. (values (* mvp (vec4 (-> position x) (-> position y) 0.0 1.0)) tex)) (define (sprite-fragment (vec2 ))) #+END_SRC ** TODO [#A] Ditch the readline dependency Figure out how to get back to using Guile's built-in REPL for =chickadee play= so the custom can go away. Readline is hard to make work in an async manner. ** TODO [#B] Bundled games don't close properly? The window goes black but doesn't close. Closing the window again actually closes it. ** TODO [#B] REPL meta-command for rendering to an image file =,render-image= or something. Use a throwaway framebuffer to render arbitrary stuff to a texture and then save it as a PNG. ** TODO [#B] Bug: Framebuffer stencil issues Render a vector path to a framebuffer and you'll notice that the first filled path doesn't show up. Why is this?? ** TODO [#B] Framebuffer multisampling Requires creating multisampled texture. ** TODO [#B] Multiple threads SDL2 operates on the main thread, so that will control the game loop and rendering. OpenAL is already using its own thread for audio. So, what's needed is another thread for managing game state and some number of generic worker threads to offload things like loading data from the file system. Of course, this complicates things significantly, so the API will have to be carefully designed to do all the thread synchronization right so the user doesn't have to think about it. Should I add a dependency on guile-fibers?? ** TODO [#B] Texture fills for vector paths ** TODO [#B] Even-odd rule fills for vector paths Right now only the non-zero rule is supported. ** TODO [#B] Add shear transformations to vector paths ** TODO [#B] Dashed lines for stroked vector paths ** TODO [#B] Mitered corners for stroked vector paths ** TODO [#B] Text rendering for vector paths ** TODO [#B] Add screenshots to manual ** TODO [#B] Improve particle system Allow more settings to be modified. Add angular velocity. Auto-expand to hold all particles rather than setting a hard cap upfront. ** TODO [#B] Support loading fonts from system font cache ** TODO [#C] Rename array-list-size to array-list-length ** TODO [#C] Bug: Bounding boxes for stroked paths are too small Not sure how to fix right now but the bounding boxes are too small because they only account for the points within a path, not the thickness of the line, the length of the miters in a polyline, or the end caps. ** TODO [#C] Shader cache in ~/.cache/chickadee? ** TODO [#C] Switch from OpenAL to custom Scheme mixer I've decided that OpenAL is too high level to be a library that Chickadee should rely upon, since part of the goal of Chickadee is to implement as much as possible in Scheme and only resort to C if absolutely necessary. Instead, we can use SDL2's cross-platform audio API and implement all the audio mixing directly in Scheme. ** TODO [#C] Binary bundles for MacOS ** TODO [#C] GPU pipeline data structure Like this: https://reader.tymoon.eu/article/363 ** TODO [#C] 2D physics simulation Add bindings for the chipmunk library or implement a rigid body simulator in Scheme. ** TODO [#C] Multiplayer networking Take a look at Xelf's UDP networking code and https://gafferongames.com/categories/building-a-game-network-protocol/ ** TODO [#C] Render command queue processing To replace existing immediate mode rendering ** TODO [#C] Uniform buffers Need some way to support these while falling back to the current, slow way that is compatible with OpenGL 2.1. ** TODO [#C] Signed distance field font rendering ** TODO [#C] Physically-based ambient lighting The PBR shader currently does image based ambient lighting in a very naive way that does not use physically-based equations. ** TODO [#C] Right-to-left text rendering ** TODO [#C] Top-to-bottom text rendering ** TODO [#C] Octree spatial partitioning ** DONE [#A] Mention (chickadee-user) module in 'chickadee play' docs When you connect to the REPL server, it's in (guile-user) but there's nothing telling the user to switch to the right default place. Can we make the REPL automatically go to the right module? ** DONE [#A] Improve window resizing support For example, there's no user hook to handle a resize event. ** DONE [#A] Images that can be rendered in Geiser REPL Make == type that prints as =#= ** DONE [#A] CPU-side pixel buffer manipulation Make == type and use it for all image loading/manipulation, such as texture creation. ** DONE [#A] Fix 9-patch rendering not working with texture regions ** DONE [#A] Add #:clear-color argument to run-game ** DONE [#A] Tests for (chickadee math rect) ** DONE [#A] Add matrix{3,4}-copy! procedures ** DONE [#A] Load palleted PNGs ** DONE [#A] Remove SDL2-image dependency Directly link against libpng and libjpeg-turbo, for starters. Support for other formats can be added later. This will give us more flexibility since we won't be tied to SDL surfaces and thus a single thread for image loading. ** DONE [#A] Fix keyboard layout bug For example, someone with a QWERTZ keyboard layout, when they press their Z key, will invoke the key-press handler with the Z key, but (key-pressed? 'z) will be false and (key-pressed? 'y) will be true. ** DONE [#B] Quadtree spatial partitioning ** DONE [#B] Add arc-to procedure for vector paths ** DONE [#A] Tests for (chickadee data array-list) ** DONE [#A] Tests for (chickadee data heap) ** DONE [#A] Tests for (chickadee data queue) ** DONE [#A] Update rendering engine docs ** DONE [#A] Update live coding section of manual ** DONE [#A] Document polygon, cull face, depth test, stencil modes ** DONE [#A] Document cube map texture procedures ** DONE [#A] Document materials, lights, and meshes ** DONE [#A] Add intensity field to lights ** DONE [#A] Test suite ** DONE [#A] Binary bundles for Linux For easy distribution of builds so players don't have to build anything from source. ** DONE [#A] Mipmapping ** DONE [#A] Skyboxes ** DONE [#A] Basic 3D shape primitives Plane, tesselated plane, sphere, cube ** DONE [#A] Image based lighting for 3D models Cube maps and such. See: https://learnopengl.com/PBR/IBL/Diffuse-irradiance ** DONE [#A] Reimplement 9-patches ** DONE [#A] Chunk-based tile map rendering ** DONE [#A] Render rotated tiles in Tiled maps correctly See STIB library for love2d for implementation details. ** DONE [#A] Render animations in Tiled maps ** DONE [#A] Support modifications to Tiled maps ** DONE [#A] Handle window resizing gracefully ** DONE [#A] Display clear error when using OpenGL before game loop has been started ** DONE [#A] Macro for looping over number ranges Get rid of all the dang named lets for looping over x and y values in a grid. ** DONE [#A] High-level vertex buffer packing API Filling vertex buffers by hand sucks and leads to lots of redundant, brittle code all over the place. Especially so for anything that does vertex buffer streaming like sprite batches and vector paths. Maybe copy something like guile-opengl's packed structs. ** DONE [#A] Front/back face culling support ** DONE [#A] Vector graphics rendering Like NanoVG. ** DONE [#A] Feature request: Support color keyed tilesets in Tiled maps ** DONE [#A] Bug fix: Clear screen even when nothing is being drawn ** DONE [#A] Allow user to manipulate the current window ** DONE [#A] OBJ model loader and renderer ** DONE [#A] Fix bugs/missing features in particle renderer ** DONE [#A] Document how to hook up cooperative REPL server ** DONE [#A] Document (chickadee graphics tiled) module ** DONE [#A] Add pixel x,y to tile x,y procedure for Tiled maps ** DONE [#A] TrueType font rendering Like love2d or NanoVG ** DONE [#A] Chickadee executable Like love2d's =love= executable. For getting new users up and running quickly. ** DONE [#B] Linear/radial gradient fills for vector paths ** DONE [#B] Improved blending API Rather than using symbols to represent some predefined blending modes, create an api that supports the full range of options that OpenGL provides for defining the blending function. ** DONE [#B] Tile map scrolling ** DONE [#B] OpenAL sound Better than SDL_mixer. For love2d parity. ** DONE [#B] glTF 2.0 asset loading Partially implemented but most example models don't render correctly. ** DONE [#C] Rewrite GPU state and render context code Adding a new piece of state requires too much work, much of which feels redundant. ** DONE [#C] Improve technique-specific state handling Right now everything (shaders, buffers, etc.) is wrapped in 'delay' forms and then 'force'd when rendering. It would be better if we could somehow register this stuff with the gpu object. A plugin system, maybe. The plugins would be initialized when the gpu object is created and all the state would live there instead of at the top-level of various modules. ** DONE [#C] Physically based rendering Needed for full glTF rendering support but just good in general for 3D.