GithubHelp home page GithubHelp logo

procdraw-old's People

Contributors

simonbates avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

kikidesign

procdraw-old's Issues

Add a void* data parameter to LispInterpreter::SetGlobalCFunction()

Store this data pointer on LispCFunction and add to lisp_CFunction.

Pass the data pointer value to the registered function when we call the function in LispInterpreter::ApplyCFunction().

Use this generic data pointer to provide callback context -- in particular to store a pointer to ProcDrawAppSdl when registering functions in procdraw_app_sdl_lisp.cpp. We can then get rid of the pd_app global variable.

Use an image file to persist interpreter state

  • make the image format as human readable as possible
  • need to handle references to shared data
  • need to handle cycles
  • partition the global environment into collections/modules and store each in a separate file
    • I'm hoping this will make it easier to extract bits of an image for sharing
    • start with 2 collections: user and system
    • by default a symbol is placed into the user collection
    • add functions for getting and setting a symbol's collection membership

Depends on:

Add a Table type

(make-table)
(get key table)
(put key val table)
  • What to use for keys?
    • symbols (will need to quote)
    • keywords [http://clojure.org/data_structures]
  • Notation for literal tables?

Implement image frame Signals

Streams of bitmap images implementing the Signal interface.

For doing real time image processing.

The rendering process could be modified to act as a signal generator so that I could do full-screen post processing on the rendered images.

Add binary file utils

  • new byte array data type
  • use a hex dump for the string representation of a byte array (what is shown in the Transcript): offset, hex values, and ASCII rendering
  • (load-file filename)
    • load a file from disk, returning a byte array
  • (strings byte-array)
    • works like Unix strings -- returns a list of (offset, string) pairs for ASCII text found in the byte array

Depends on #1

Build a richer UI

Either:

  • in a separate window from the rendered graphics; or
  • overlaid in the same window

Some implementation options:

Standardise on [0, 1] for ranged values and add (lerp) and (norm)

To make patching easier by removing the need to convert between ranges with map-range.

For cases when we need to map from [0, 1] to another range, add a lerp function. We can use lerp rather than the full map-range.

(lerp v0, v1, t)

returns an interpolation between two values (v0, v1) for a parameter t in the range [0, 1]

see https://en.wikipedia.org/wiki/Linear_interpolation

Also add a norm function which normalizes a value form some range to [0, 1], like Processing:

https://processing.org/reference/norm_.html

Add time-varying Signals and Patches

A Signal is a Table [#17] that can be stepped forward in time:

(step signal)

Patches are graphs of Signals and implement the above Signal API:

(make-patch)
(add-node patch name signal)
(=> patch source-node source-key dest-node dest-key &optional fn)

An example:

(progn
  (setq p (make-patch))
  (add-node p osc1 (sine-osc))
  (add-node p osc2 (sawtooth-osc))
  (=> p in mouse-x osc1 freq)
  (=> p osc1 val osc2 freq)
  (=> p osc1 val out velocity)
  (=> p osc2 val out rotation)
  (setq draw (lambda ()
    (progn
      (put mouse-x (mouse-x) p)
      (step p)
      (rotate-y (get rotation p))
      (color (get velocity p)))))

Alternatively, with a separate Signal namespace (and the Signals in that namespace stepped implicitly):

(progn
  (defsig osc1 (sine-osc))
  (defsig osc2 (sawtooth-osc))
  (=> (mouse-x) osc1 freq)
  (=> osc1 val osc2 freq)
  (setq draw (lambda ()
    (progn
      (rotate-y (getsig osc2 val))
      (color (getsig osc1 val)))))

In this model, I can do the stepping lazily -- we step if needed when the signal is read (and in turn step any dependencies). Keep a flag for each Signal which records if it has been stepped for this frame. And reset the flags at the start of each frame.

Another possibility -- not in a separate namespace and with a single output:

(progn
  (setq osc1 (sin-osc))
  (setq osc2 (saw))
  (=> (lambda () (lerp 0 (/ 60) (mouse-x))) osc1 'freq)
  (=> (lambda () (lerp (/ 240) (/ 60) (sigval osc1))) osc2 'freq)
  (setq draw (lambda ()
    (progn
      (rotate-y (sigval osc2))
      (color (sigval osc1)))))

The function sigval steps the Signal as needed and gets values from dependencies. To know which Signals have been stepped for each frame, I can maintain a set of Signals that have been stepped and clear it out at the start of each frame. This way, I don't need to be able to enumerate all the Signals.

Use Hz for oscillator frequencies

Use Hz for oscillator frequencies rather than cycles per frame.

Mapping Hz to cycles per frame will depend on exactly how I proceed with updating the signals vs rendering ('game loop'). But if I continue with vsync, then:

  • for windowed mode, I can get the refresh rate from DwmGetCompositionTimingInfo
  • for full-screen, IDXGIOutput::GetDisplayModeList and what is requested in DXGI_SWAP_CHAIN_DESC.RefreshRate
  • or empirically using my existing ProcDrawApp::FramesPerSecond

See http://stackoverflow.com/questions/18844654/how-to-find-out-real-screen-refresh-rate-not-the-rounded-number

Efficient symbol referencing from C++

Options:

  • Keep the existing SymbolRef(std::string name) API but use a hashtable
    • std::unordered_map<std::string, LispObjectPtr>
  • String interning with a hashtable
  • A global symbol table rather than per interpreter instance -- symbols can then be created and references stored once at program start
  • Use an object oriented extension API to create symbols needed by an extension at extension registration -- references to the symbols can then be stored on the extension instance and accessed through the callback data argument (similar to how the interpreter itself uses symbols -- references are stored at construction)
  • Symbol table generation at compile time
    • mark symbols in C code with a macro
    • make a tool which scans through and generates a symbol table
    • the symbol table is represented as an array on the interpreter
    • and the symbol macro expands to a lookup into the array

Add waveform generators

A waveform generator is a type of Signal [#16].

Start with sawtooth.

I can then replace:

(setq rotation-y-velocity (map-range 0 (width) (/ pi 60) (/ pi -60) (mouse-x)))
(setq rotation-y-angle (wrap-range 0 (* 2 pi) (+ rotation-y-angle rotation-y-velocity)))
(rotate-y rotation-y-angle)

in animating.lisp with something more like:

(setq rotation-y-osc (make-sawtooth))
...
(put freq (mouse-x) rotation-y-osc)
(step rotation-y-osc)
(rotate-y (get val rotation-y-osc))

(ignoring any mapping from value ranges)

See also Patches [#16].

Article on dependency graphs in updating game objects: http://www.gamasutra.com/view/feature/131221/dependency_graphs_in_games.php

Create an extensions API

And minimise the runtime, with as much as possible structured as extensions.

I have:

  • RegisterProcdrawAppFunctions() in procdraw_app_lisp.h
  • RegisterSignals() in signals.h

Create a standard structure for expressing extensions. Maybe an object with a Register() function. Or an Exports() function.

With the addition of the void *data parameter to LispInterpreter::SetGlobalCFunction(), I should be able to bind directly to the GLRenderer instance, rather than going through ProcdrawApp.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.