我使用Common Lisp,OpenGL和过剩创建了一个图形。具体来说,我正在使用库cl-opengl。我希望将这个图形(使用gl:vertex points连接)保存到外部文件中,以便我可以加载它并在将来的程序中对其进行操作。
答案 0 :(得分:4)
您可以在OpenGL帧渲染例程中使用glReadPixels函数来获取RGB数据,然后使用拟合库将其保存为图片格式。例如,quicklisp存储库中有ZPNG来编写PNG: http://www.xach.com/lisp/zpng/#sect-examples
使用图像库从文件中读取图像数据。要使用PNG格式关注我之前的示例,您可以快速加载png-read
并使用它来提取RGB数据。
(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
如果您已经使用OpenGL,只需启用正交透视模式,将图像作为纹理制作四边形并操纵网格。如果要在2D图像缓冲画布上绘画,请选择cairo
之类的库。
在我的SBCL下面的作品中:
(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 x y)
(declare (ignore x y))
(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 (h w) (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)))
按“r”将文件保存在/tmp/readpixels.png