`(kakko ,man)

Find a guide into tomorrow by taking lessons from the past

cl-glut pre-study <page 5>

レッスン13.2次元と3次元
y軸を中心に25°回転してみた。
f:id:tomekame0126:20151108163333p:plain

;;
;; lesson13 <2D & 3D>
;; -----------------------------------------------------------------------------------------------
;; Set window class
(defclass Window (glut:window) 
  ()
  (:default-initargs
   :mode '(:rgba)))

;; Init
(defmethod glut:display-window :before ((window Window))
  (gl:clear-color 1 1 1 1))                  ; set white

;; Display
(defmethod glut:display ((window Window))
  (gl:clear :color-buffer-bit)               ; clear buffer 
  ;       degreee  x   y   z
  (gl:rotate 25.0 0.0 1.0 0.0)               ; y-axis rotate 25 degrees
  ; draw a square
  (gl:begin :polygon)
    ; set red color 
    (%gl:color-3d 1 0 0)
    (%gl:vertex-2d -0.9 -0.9)
    ; set green color 
    (%gl:color-3d 0 1 0)
    (%gl:vertex-2d 0.9 -0.9)
    ; set blue color 
    (%gl:color-3d 0 0 1)
    (%gl:vertex-2d 0.9 0.9)
    ; set yellow color 
    (%gl:color-3d 1 1 0)
    (%gl:vertex-2d -0.9 0.9)
  (gl:end)
  (gl:flush))                                ; show window

;; Main
(defun lesson13 ()
  (glut:display-window (make-instance 'Window)))  ; create window

(lesson13)

レッスン14.線画(3D)を表示する
vertex-3dの使い方がわからなかったため、wire-cubeで試してみた。
これも、そのうち考えてみることとする。
加えて、ダブルバッファも試してみた。
f:id:tomekame0126:20151108163655p:plain

;;
;; lesson14 <Line drawing>
;; -----------------------------------------------------------------------------------------------
;; Set window class
(defclass Window (glut:window)
  ()
 (:default-initargs
   :pos-x 100 :pos-y 100 :width 500 :height 500
   :mode '(:double :rgb) :title "cube-test"))

;; Init
(defmethod glut:display-window :before ((window Window))
  (gl:clear-color 0 0 0 1))                  ; set black

;; View port
(defmethod glut:reshape ((window Window) width height)
  (gl:viewport 0 0 width height)
  (gl:load-identity)
  (gl:ortho -2.0 2.0 -2.0 2.0 -2.0 2.0))

;; Display
(defmethod glut:display ((window Window))
  (gl:clear :color-buffer-bit)               ; clear buffer 
    ;; cube
    (gl:with-pushed-matrix
      (gl:scale 1 1 1)
      (glut:wire-cube 1))
  (glut:swap-buffers))
  
;; Main
(defun lesson14 ()
  (glut:display-window (make-instance 'Window)))  ; create window

(lesson14)

レッスン15.透視投影する
f:id:tomekame0126:20151108163920p:plain

;;
;; lesson15 <Perspective>
;; -----------------------------------------------------------------------------------------------
;; Set window class
(defclass Window (glut:window)
  ()
 (:default-initargs
   :pos-x 100 :pos-y 100 :width 500 :height 500
   :mode '(:double :rgb) :title "cube-test"))

;; Init
(defmethod glut:display-window :before ((window Window))
  (gl:clear-color 0 0 0 1))                  ; set black

;; View port
(defmethod glut:reshape ((window Window) width height)
  (gl:viewport 0 0 width height)
  (gl:load-identity)
  (glu:perspective 30.0 (/ width height) 1.0 100.0)
  (gl:translate 0.0 0.0 -5.0))

;; Display
(defmethod glut:display ((window Window))
  (gl:clear :color-buffer-bit)               ; clear buffer 
    ;; cube
    (gl:with-pushed-matrix
      (gl:scale 1 1 1)
      (glut:wire-cube 1))
  (glut:swap-buffers))
  
;; Main
(defun lesson15 ()
  (glut:display-window (make-instance 'Window)))  ; create window

(lesson15)

レッスン16.視点の位置を変更する
f:id:tomekame0126:20151108164103p:plain

;;
;; lesson16 <Look at>
;; -----------------------------------------------------------------------------------------------
;; Set window class
(defclass Window (glut:window)
  ()
 (:default-initargs
   :pos-x 100 :pos-y 100 :width 500 :height 500
   :mode '(:double :rgb) :title "cube-test"))

;; Init
(defmethod glut:display-window :before ((window Window))
  (gl:clear-color 0 0 0 1))                  ; set black

;; View port
(defmethod glut:reshape ((window Window) width height)
  (gl:viewport 0 0 width height)
  (gl:load-identity)
  (glu:perspective 30.0 (/ width height) 1.0 100.0)
  (glu:look-at 3.0 4.0 5.0 0.0 0.0 0.0 0.0 1.0 0.0))

;; Display
(defmethod glut:display ((window Window))
  (gl:clear :color-buffer-bit)               ; clear buffer 
    ;; cube
    (gl:with-pushed-matrix
      (gl:scale 1 1 1)
      (glut:wire-cube 1))
  (glut:swap-buffers))
  
;; Main
(defun lesson16 ()
  (glut:display-window (make-instance 'Window)))  ; create window

(lesson16)

レッスン17.図形を動かす
マウスの右ボタンを押しっぱなしで右回転、左ボタンは左回転し、ホイールボタンを押すと1ステップずつ直前に回転していた方向に動く。
ついでだから、マウスのホイールを回すことで視点の位置を動かすようにしてみた。
但し、これはfreeglutの機能を利用して提供されているとの記載が以下にある。
https://github.com/3b/cl-opengl/blob/master/glut/package.lisp
#:mouse-wheel-func ; freeglut ext
また、fやFを押すとフルスクリーンになったり元に戻ったりするようにしてみた。終了はqやQを押すことでウィンドウが消滅する。
f:id:tomekame0126:20151108164418p:plain

;;
;; lesson17 <animation>
;; -----------------------------------------------------------------------------------------------
(defvar *r* 0)  ; angle
(defvar *p* 5.0) ; lookat
(defvar *flag* t) ; rotation flag
(defvar *toggle* t) ;toggle switch

;; Set window class
(defclass Window (glut:window)
  ((fullscreen :initarg :fullscreen :reader fullscreen-p)) 
  (:default-initargs
   :pos-x 100 :pos-y 100 :width 500 :height 500
   :fullscreen nil
   :mode '(:double :rgb) :title "cube-test"))

;; Init
(defmethod glut:display-window :before ((window Window))
  (gl:clear-color 0 0 0 1)        ; set black
  (when (fullscreen-p window)     ; check to see if fullscreen needed
    (glut:full-screen)))          ; if so, then tell GLUT

;; View port
(defmethod glut:reshape ((window Window) width height)
  (gl:viewport 0 0 width height)
  (gl:matrix-mode :projection)
  (gl:load-identity)
  (glu:perspective 30.0 (/ width height) 1.0 100.0) 
  (gl:matrix-mode :modelview))

;; idle
(defmethod glut:idle ((window Window))
    ;; user idling process
    (sleep (/ 1.0 60.0))
    (glut:post-redisplay))

;; mouse
(defmethod glut:mouse ((window Window) button state x y)
  (declare (ignore x y))
  (case button 
    (:RIGHT-BUTTON
      (if (eql state :DOWN)
        (progn
          (setf *flag* t)
          (glut:enable-event window :idle))
        (glut:disable-event window :idle)))
    (:MIDDLE-BUTTON
      (if (eql state :DOWN)
	(glut:post-redisplay)))
    (:LEFT-BUTTON
      (if (eql state :DOWN)
        (progn
	  (setf *flag* nil)
          (glut:enable-event window :idle))
        (glut:disable-event window :idle)))))

;; mouse-wheel
(defmethod glut:mouse-wheel ((window Window) wheel direction x y)
 (declare (ignore x y))
 (case direction
   (:wheel-down
     (progn
       (incf *p* 0.2) 
       (when (>= *p* 9.8)
	 (setf *p* 9.8))
       (glut:post-redisplay)))       
   (otherwise
     (progn 
       (decf *p* 0.2)
       (when (<= *p* 0.2)
         (setf *p* 0.2))
       (glut:post-redisplay)))))

;; Keyboard
(defmethod glut:keyboard ((window Window) key x y)
  (declare (ignore x y))
    (case key
      ((#\q #\Q)                              ; q, Q --> exit
        (glut:destroy-current-window))
      ((#\f #\F)                              ; f, F --> full or windowed
        (if (eql *toggle* t)
	    (progn
	      (setf *toggle* nil)
	      (glut:full-screen))
	    (progn
	      (setf *toggle* t)
	      (glut:position-window 100 100)       ; initial position
              (glut:reshape-window 500 500))))))   ; initial width height

;; Display
(defmethod glut:display ((window Window))
  (gl:clear :color-buffer-bit)                ; clear buffer
  (gl:load-identity)
  (glu:look-at 3.0 4.0 *p* 0.0 0.0 0.0 0.0 1.0 0.0)
  (gl:rotate *r* 0.0 1.0 0.0)
    ;; cube
    (gl:with-pushed-matrix
      (gl:scale 1 1 1)
      (glut:wire-cube 1))
  (glut:swap-buffers)
  (if (eql *flag* t)
    (incf *r*)                                ; right rotation
    (decf *r*))                               ; left  rotation
  (cond ((>= *r* 360)
          (setf *r* 0))
        ((<= *r* 0)
          (setf *r* 360))))  
 
;; Main
(defun lesson17 ()
  (glut:display-window (make-instance 'Window)))  ; create window

(lesson17)

Cで書かれたサンプルは結構な数が見つかるけど、cl-glutのサンプルは少ないなぁ。
マウスのホイールを利用するサンプルは探しきれなかった。
暗雲だだよう、pre-study編。