ob-glsl
ob-glsl copied to clipboard
glsl code blocks for org-mode
#+TITLE: GLSL code blocks for Emacs Org-mode
This org-mode extension adds the capability to run GLSL code blocks directly from inside Emacs and immediately displays the rendering results inline in your org-mode buffers.
-
Requirements
- SDL2 (for creating OpenGL context)
- SDL2_image (for saving PNG files)
- glbinding (for OpenGL SDK)
The rendering is done with OpenGL 3.3 so should work on any graphcs card.
-
Building
-
Generate project with CMake: #+begin_src sh cmake -G "Ninja" . #+end_src
-
Build the code: #+begin_src sh ninja #+end_src
This will create the Emacs dynamic module ~ob-glsl-module.so~ (Linux) or ~ob-glsl-module.dll~ (Windows) or ~ob-glsl-module.dylib~ (MacOS).
-
-
Installing
- Put both ~ob-glsl.el~ and the dynamic module under your elisp load path.
- Add ~(glsl . t)~ to ~org-babel-load-languages~. You can either customize the variable or add it manually in lisp code.
-
Supported parameters
- ~:file~ The output file path (required)
- ~:width~ The render width in pixels
- ~:height~ The render height in pixels
You can omit either ~:width~ or ~:height~ and the omitted one will be calculated based on the other parameter. If you omit both, then the default output size is 400x300.
-
A simple pixel shader example #+BEGIN_SRC glsl :file img/mandel.png :width 600 :height 450 vec3 mandel(vec2 z0) { float k = 0.0; vec2 z = vec2(0.0); for(int i = 0; i < 420; ++i) { z = vec2(z.xz.x-z.yz.y, z.xz.y2.0) + z0; if (length(z) > 20.0) break; k += 1.0; } float mu = k + 1.0 - log2(log(length(z))); return sin(mu0.1 + vec3(0.0,0.5,1.0)); } void main() { float ar = iResolution.x / iResolution.y; vec2 uv = gl_FragCoord.xy / iResolution.yy - vec2(0.66 * ar, 0.5); // uv = uv * 2.0 + vec2(-0.3, 0.0); float p = 30.0; float t = mod(13.0, p); if (t > p/2.0) t = p - t; float scale = 0.5 + pow(2.0, t); vec2 offset = vec2(-1.36799, .01); uv += offsetscale; uv /= scale; fragColor = vec4(mandel(uv), 1.0); } #+END_SRC
[[img/mandel.png]]