Saving and loading images using regular opengl lisp

I created graphics using Common Lisp, OpenGL, and glut. In particular, I use the cl-opengl library. I want to save this graphic (which is made with gl: vertex points connected) to an external file so that I can load it and manipulate it in future programs.

  • How to save graphics drawn in a crowded window?
  • How to load a graphic file from an image file?
  • How do I manipulate a downloaded image (e.g. copy, translate and rotate)?
+7
common-lisp opengl glut
source share
1 answer
  • You can use the glReadPixels function in your OpenGL frame renderer to retrieve RGB data and then save it in image format using the feed library. For example, there is a ZPNG in the shortcut store for writing PNG: http://www.xach.com/lisp/zpng/#sect-examples

  • Use the image library to read image data from a file. To run my previous example in PNG format, you can quickly download png-read and use it to extract RGB data.

     (png-read:read-png-file #p"/tmp/1.png") (png-read:physical-dimensions p) ;returns width and height in meters (png-read:image-data p) ;returns a three-dimensional array of bytes 
  • If you are already using OpenGL, just turn on the orthogonal perspective mode, make a square face with your image as a texture and manipulate the grid. If you want to draw a 2D image buffer on the canvas, select a library, for example cairo .

in my SBCL after work:

  (ql:quickload '(:cl-opengl :cl-glu :cl-glut :zpng)) (defclass hello-window (glut:window) () (:default-initargs :pos-x 100 :pos-y 100 :width 250 :height 250 :mode '(:single :rgba) :title "hello")) (defmethod glut:display-window :before ((w hello-window)) ;; Select clearing color. (gl:clear-color 0 0 0 0) ;; Initialize viewing values. (gl:matrix-mode :projection) (gl:load-identity) (gl:ortho 0 1 0 1 -1 1)) (defmethod glut:display ((w hello-window)) (gl:clear :color-buffer) (gl:color 0.4 1 0.6) (gl:with-primitive :polygon (gl:vertex 0.25 0.25 0) (gl:vertex 0.75 0.25 0) (gl:vertex 0.25 0.55 0)) (gl:flush)) (defmethod glut:keyboard ((w hello-window) key xy) (declare (ignore xy)) (when (eql key #\Esc) (glut:destroy-current-window)) (when (eql key #\r) (let* ((mypng (make-instance 'zpng:png :width 250 :height 250)) (imagedata (zpng:data-array mypng)) (sample1 (gl:read-pixels 0 0 250 250 :bgra :unsigned-byte))) (format t "read~%") (dotimes (i (expt 250 2)) (multiple-value-bind (hw) (floor i 250) (setf (aref imagedata (- 249 h) w 0) (aref sample1 (+ 2 (* i 4)))) (setf (aref imagedata (- 249 h) w 1) (aref sample1 (+ 1 (* i 4)))) (setf (aref imagedata (- 249 h) w 2) (aref sample1 (+ 0 (* i 4)))))) (zpng:write-png mypng #p"/tmp/readpixels.png")) (format t "written~%"))) (defun rb-hello () (glut:display-window (make-instance 'hello-window))) 

Pressing "r" saves the file in /tmp/readpixels.png

+4
source share

All Articles