Skip to content

Instantly share code, notes, and snippets.

@lamberta
Created October 24, 2009 23:34
Show Gist options
  • Save lamberta/217800 to your computer and use it in GitHub Desktop.
Save lamberta/217800 to your computer and use it in GitHub Desktop.
cl-opengl, load toon shader
;;cl-opengl, load toon shader
(require :asdf)
(asdf:load-system :cl-opengl)
(asdf:load-system :cl-glu)
(asdf:load-system :cl-glut)
(defun file->string (path)
"Sucks up an entire file from PATH into a freshly-allocated string,
returning two values: the string and the number of bytes read."
(with-open-file (s path)
(let* ((len (file-length s))
(data (make-string len)))
(values data (read-sequence data s)))))
(defparameter *my-shader* nil)
(defparameter *angle* 0)
(defclass shader-window (glut:window)
()
(:default-initargs :width 500 :height 500 :title "toon shader test"
:mode '(:single :rgb :depth)))
(cffi:defcallback update :void ((value :int))
(declare (ignore value))
;;update rotation
(incf *angle* 2)
(if (> *angle* 360) (decf *angle* 360))
;;redraw and loop
(glut:post-redisplay)
(glut:timer-func 30 (cffi:callback update) 0))
(defmethod glut:display-window :before ((w shader-window))
(gl:clear-color 0 0 0 0)
(gl:cull-face :back)
(gl:depth-func :less)
(gl:disable :dither)
(gl:shade-model :smooth)
(gl:light-model :light-model-local-viewer 1)
(gl:color-material :front :ambient-and-diffuse)
(gl:enable :light0 :lighting :cull-face :depth-test)
;;load shader if not already
(unless *my-shader*
(let ((vs (gl:create-shader :vertex-shader))
(fs (gl:create-shader :fragment-shader)))
(gl:shader-source vs (file->string "toon_shade.vert"))
(gl:compile-shader vs)
(gl:shader-source fs (file->string "toon_shade.frag"))
(gl:compile-shader fs)
(setf *my-shader* (gl:create-program))
(gl:attach-shader *my-shader* vs)
(gl:attach-shader *my-shader* fs)
(gl:link-program *my-shader*)
(gl:use-program *my-shader*)))
(glut:timer-func 30 (cffi:callback update) 0))
(defmethod glut:display ((w shader-window))
(gl:clear :color-buffer :depth-buffer)
(gl:matrix-mode :modelview)
(gl:load-identity)
(gl:translate 0 0 -5) ;move back
(gl:light :light0 :position '(0 1 1 0))
(gl:light :light0 :diffuse '(0.2 0.4 0.6 0))
(gl:color 1 1 1)
(gl:with-pushed-matrix
(gl:rotate *angle* 0.5 1 0)
(gl:front-face :cw)
(glut:solid-teapot 1)
(gl:front-face :ccw))
(glut:swap-buffers))
(defmethod glut:reshape ((w shader-window) width height)
(gl:viewport 0 0 width height)
(gl:matrix-mode :projection)
(gl:load-identity)
(glu:perspective 45 (/ width height) 1 200))
(defmethod glut:keyboard ((w shader-window) key x y)
(declare (ignore x y))
(case key
(#\ESC
(glut:destroy-current-window)
(quit))))
(defun toon-shader ()
(glut:display-window (make-instance 'shader-window)))
(toon-shader)
/* fragment shader */
varying vec3 normal;
void main () {
float intensity;
vec4 color;
vec3 n = normalize(normal);
intensity = dot(vec3(gl_LightSource[0].position), n);
if (intensity > 0.95)
color = vec4(1.0,0.5,0.5,1.0);
else if (intensity > 0.5)
color = vec4(0.6,0.3,0.3,1.0);
else if (intensity > 0.25)
color = vec4(0.4,0.2,0.2,1.0);
else
color = vec4(0.2,0.1,0.1,1.0);
gl_FragColor = color;
}
/* vertex shader */
varying vec3 normal;
void main (void) {
//only need to write to varying var for frag shader access
normal = gl_NormalMatrix * gl_Normal;
gl_Position = ftransform();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment