Qiitaの記事をはじめて書きます。
どうぞ生暖かい目で見てやってください。
common lispでグラフィックスやりましょう。
使うのはcl-openglです、QuickLispを使ってインストールします。
まずはcl-openglをインストールしましょう。
cl-openglと一緒にcl-glutとcl-glutもインストールします。
replを起動して。
(ql:quickload :cl-opengl)
(ql:quickload :cl-glu)
(ql:quickload :cl-glut)
とするとインストールされます。
画面にグラフィックを描画するための最低限のソースを書いていきます。
;; Require libralies
(require 'asdf)
(require 'cl-opengl)
(require 'cl-glut)
(require 'cl-glu)
;; Parameters
(defvar *width* 500)
(defvar *height* 500)
;; USER FUNCTIONS
(defun user-display () ())
(defun user-init () ())
(defun user-idle () ())
;; Derived window class
(defclass main-window (glut:window) ()
(:default-initargs :title "opengl test" :mode '(:double :rgb :depth) :width *width* :height *height*))
;; glut:display
;; Draw.
(defmethod glut:display ((window main-window))
;; Clear buffer
(gl:clear :color-buffer :depth-buffer)
;; Draw shape
;;(glDisable GL_CULL_FACE)
(gl:shade-model :flat)
(gl:normal 0 0 1)
;; user display process
(user-display)
;; Swap buffer
(glut:swap-buffers))
;; glut:idle
;; Application idle.
(defmethod glut:idle ((window main-window))
;; user idling process
(user-idle)
(glut:post-redisplay))
;; glut:reshape
(defmethod glut:reshape ((w main-window) width height)
(gl:viewport 0 0 width height)
(gl:load-identity)
(glu:ortho-2d 0.0 *width* *height* 0.0))
;; glut-display
;; Draw.
(defmethod glut:display-window :before ((window main-window)) )
;; main
;; Main function (Program entry point).
(defun main ()
;; user initalization process
(user-init)
;;(glut:special-func #'key-special)
(glut:display-window (make-instance 'main-window)))
(load "glib.lisp")
(defun user-init ())
(defun user-idle ()
(sleep (/ 1.0 60.0)))
(defun user-display ())
では実行してみましょう。
(load "gltest.lisp")
(main)
真っ黒な画面がでてきます。
さて、それではなにか描いてみましょう。
線分を描画する関数を定義します。
;; Draw 2D line.
(defun g2line (x y x2 y2)
(gl:with-primitives :lines
(gl:vertex x y 0.0)
(gl:vertex x2 y2 0.0)))
そしてこんな感じにしてみます。
(load "glib.lisp")
(defun user-init ()
(defparameter *theta* 0.0)
(defparameter *length* 100.0)
(defparameter *n* 500)
(defparameter *pi-part* (/ (* 2.0 PI) *n*))
)
(defun user-idle ()
(sleep (/ 1.0 60.0)))
(defun user-display ()
(setf *theta* (+ *theta* 0.01))
(mapcar
(lambda (n)
(let ((rand-len (random 100)))
(g2line (/ *width* 2.0)
(/ *height* 2.0)
(+ (/ *width* 2.0) (* (cos (+ *theta* (* n *pi-part*))) (+ *length* rand-len)))
(+ (/ *height* 2.0) (* (sin (+ *theta* (* n *pi-part*))) (+ *length* rand-len))))))
(iota *n*))
)
;; Draw 2D line.
(defun g2line (x y x2 y2)
(gl:with-primitives :lines
(gl:vertex x y 0.0)
(gl:vertex x2 y2 0.0)))
;; iota
(defun iota (m &optional (n 0) (step 1))
(if (>= n m)
nil
(cons n (iota m (+ n step) step))))
ええ、目がチカチカしますね。
線に色をつけるにはこんな感じにします。
;; Draw 2D line.
(defun g2linec (x y x2 y2 r g b)
(gl:with-primitives :lines
(gl:color r g b)
(gl:vertex x y 0.0)
(gl:vertex x2 y2 0.0))
(gl:color 1.0 1.0 1.0))
(defun user-display ()
(setf *theta* (+ *theta* 0.01))
(mapcar
(lambda (n)
(let ((rand-len (random 100)))
(g2linec (/ *width* 2.0)
(/ *height* 2.0)
(+ (/ *width* 2.0) (* (cos (+ *theta* (* n *pi-part*))) (+ *length* rand-len)))
(+ (/ *height* 2.0) (* (sin (+ *theta* (* n *pi-part*))) (+ *length* rand-len)))
(random 1.0)
(random 1.0)
(random 1.0))))
(iota *n*))
)
もう目がこわれてしまいそうです。
さあ、あなたの目にトドメを刺しましょう ( ̄ー ̄)ニヤリッ
;; draw filled rect
(defun g2fillrectc (x y x2 y2 r g b)
(gl:with-primitives :polygon
(gl:color r g b)
(gl:vertex x y 0.0)
(gl:vertex x2 y 0.0)
(gl:vertex x2 y2 0.0)
(gl:vertex x y2 0.0)
(gl:color 1.0 1.0 1.0)))
(defun user-display ()
(setf *theta* (+ *theta* 0.01))
(g2fillrectc 0.0 0.0 *width* *height*
(random 1.0)
(random 1.0)
(random 1.0))
(mapcar
(lambda (n)
(let ((rand-len (random 100)))
(g2linec (/ *width* 2.0)
(/ *height* 2.0)
(+ (/ *width* 2.0) (* (cos (+ *theta* (* n *pi-part*))) (+ *length* rand-len)))
(+ (/ *height* 2.0) (* (sin (+ *theta* (* n *pi-part*))) (+ *length* rand-len)))
(random 1.0)
(random 1.0)
(random 1.0))))
(iota *n*))
)
画像ではわかんないですが、背景がぴかぴかしています。
もう眼球が取れそうです。
さて、今日はここまで。
ここまで読んでくださった皆様、ありがとうございました。
追記1
環境を書き忘れました。
OS:Windows 7 64bit
処理系:SBCL 1.2.15 x86
追記2
cl-openglを使ったグラフィックスライブラリをつくりました。
より手軽にグラフィックスを扱うことができます。