/emacs-gl

OpenGL bindings for Emacs Lisp

Primary LanguageCGNU General Public License v3.0GPL-3.0

Emacs-gl

OpenGL bindings for Emacs Lisp. It enables drawing to Emacs buffers with OpenGL through a GLArea xwidget embedded in the buffers.

screenshot

Features

  • Raw bindings for OpenGL commands up to version 3.3
  • Helper functions for loading images into textures (gl-helper-load-texture and gl-helper-bind-texture)
  • ImGui-based GUI rendering

Installation

Requirements

  1. GNU Emacs with the GLArea xwidget feature and module support.

You can build the feature from the feature/glarea branch of this repo using the following commands:

git clone -b feature/glarea https://github.com/Jimx-/emacs.git
cd emacs
./autogen.sh
./configure --with-xwidgets --with-x-toolkit=gtk --with-modules 
make
  1. CMake (>= 3.11)
  2. Conan
  3. Python 3.8

Building the module

To build the module itself, first clone this repo:

git clone https://github.com/Jimx-/emacs-gl.git
cd emacs-gl

Build the module with:

python generate.py
mkdir build
cd build
conan install ..
cmake ..
make

After that, you should see a gl-module.so under the root directory of the repo. To load the module:

(add-to-list 'load-path "path/to/emacs-gl")
(require 'gl)

Usage

Before using any command provided by the module, you should make sure that a GL context is properly set up. This can be done by creating a GLArea xwidget. This xwidget also provides an area for these commands to draw to.

(glarea-new :init init-cb :render render-cb)

You also need to provide two callback functions to this xwidget. They are called by the xwidget to initialize the context and render the frames, respectively. The init callback will be invoked before the first frame is rendered with an active GL context so it’s the ideal place to load the GL function pointers:

(defun init-cb (width height)
  (gl-load))

You can also initialize some global resources in this callback:

(defun init-cb (width height)
  ...
  (setq texture (gl-helper-load-texture "foo.png")))

The render callback is invoked when the xwidget needs to be redrawed. You can use the GL commands provided by the module to draw to the framebuffer:

(defun render-cb ()
  (gl-clear-color 1.0 1.0 1.0 1.0)
  (gl-clear GL-COLOR-BUFFER-BIT)

  (gl-begin GL-TRIANGLES)
  (gl-color3f 1.0 0.0 0.0)
  (gl-vertex3f -0.4 -0.7 0.5)
  (gl-color3f 0.0 1.0 0.0)
  (gl-vertex3f 0.8 -0.7 0.5)
  (gl-color3f 0.0 0.0 1.0)
  (gl-vertex3f 0.2 0.5 0.5)
  (gl-end))

More examples can be found here.