mirror of
https://github.com/rabbibotton/clog.git
synced 2025-12-06 02:30:42 -08:00
first web gl tutorial
This commit is contained in:
parent
47b869f80a
commit
91b229133d
5 changed files with 370 additions and 20 deletions
|
|
@ -1,7 +1,3 @@
|
|||
(in-package :asdf)
|
||||
|
||||
(defclass clog-file (asdf:doc-file) ((type :initform "clog")))
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -57,10 +57,9 @@
|
|||
|
||||
(defmethod create-context2d ((obj clog-canvas))
|
||||
(let ((web-id (clog-connection:generate-id)))
|
||||
(clog-connection:execute (connection-id obj)
|
||||
(format nil "clog['~A']=clog['~A'].getContext('2d')"
|
||||
web-id
|
||||
(html-id obj)))
|
||||
(js-execute obj (format nil "clog['~A']=clog['~A'].getContext('2d')"
|
||||
web-id
|
||||
(html-id obj)))
|
||||
(make-instance 'clog-context2d
|
||||
:connection-id (connection-id obj)
|
||||
:html-id web-id)))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,59 @@
|
|||
;;;; clog-webgl.lisp ;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(cl:in-package :clog)
|
||||
(mgl-pax:define-package :clog-webgl
|
||||
(:documentation "CLOG-WEBGL bindings to WebGL")
|
||||
(:use #:cl #:parse-float #:clog #:mgl-pax))
|
||||
|
||||
(cl:in-package :clog-webgl)
|
||||
|
||||
(defsection @clog-webgl (:title "CLOG WebGL Objects")
|
||||
"CLOG-WebGL - Class for CLOG WebGL objects"
|
||||
(clog-webgl class)
|
||||
(create-webgl generic-function)
|
||||
(compile-shader-source generic-function)
|
||||
(compile-webgl-program generic-function)
|
||||
(clear-color generic-function)
|
||||
(clear-webgl generic-function)
|
||||
(viewport generic-function)
|
||||
(enable-vertex-attribute-array generic-function)
|
||||
(vertex-attribute-pointer generic-function)
|
||||
(draw-arrays generic-function)
|
||||
|
||||
"CLOG-WebGL-Shader - Class for CLOG WebGL-Shader objects"
|
||||
(clog-webgl-shader class)
|
||||
(create-shader generic-function)
|
||||
|
||||
(shader-source generic-function)
|
||||
(shader-parameter generic-function)
|
||||
(shader-info-log generic-function)
|
||||
(compile-shader generic-function)
|
||||
(delete-shader generic-function)
|
||||
|
||||
"CLOG-WebGL-Program - Class for CLOG WebGL-Program objects"
|
||||
(clog-webgl-program class)
|
||||
(create-program generic-function)
|
||||
|
||||
(attach-shader generic-function)
|
||||
(program-parameter generic-function)
|
||||
(attribute-location generic-function)
|
||||
(program-info-log generic-function)
|
||||
(link-program generic-function)
|
||||
(use-program generic-function)
|
||||
(delete-program generic-function)
|
||||
|
||||
"CLOG-WebGL-Buffer - Class for CLOG WebGL-Buffer objects"
|
||||
(clog-webgl-buffer class)
|
||||
(create-webgl-buffer generic-function)
|
||||
(bind-buffer generic-function)
|
||||
(buffer-data generic-function)
|
||||
(delete-buffer generic-function)
|
||||
|
||||
"CLOG-WebGL-Vertex-Array - Class for CLOG WebGL-Vertex-Array objects"
|
||||
(clog-vertex-array class)
|
||||
(create-vertex-array generic-function)
|
||||
(bind-vertex-array generic-function)
|
||||
(delete-vertex-array generic-function))
|
||||
|
||||
;; Use clog-canvas to create the html element and then use clog-webgl
|
||||
;; to obtain the WebGL2 context
|
||||
|
|
@ -27,11 +79,251 @@
|
|||
|
||||
(defmethod create-webgl ((obj clog-canvas))
|
||||
(let ((web-id (clog-connection:generate-id)))
|
||||
(clog-connection:execute (connection-id obj)
|
||||
(format nil "clog['~A']=clog['~A'].getContext('webgl2')"
|
||||
web-id
|
||||
(html-id obj)))
|
||||
(make-instance 'clog-context2d
|
||||
:connection-id (connection-id obj)
|
||||
(js-execute obj (format nil "clog['~A']=clog['~A'].getContext('webgl2')"
|
||||
web-id
|
||||
(html-id obj)))
|
||||
(make-instance 'clog-webgl
|
||||
:connection-id (clog::connection-id obj)
|
||||
:html-id web-id)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Implementation - clog-webgl-shader
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defclass clog-webgl-shader (clog-obj)
|
||||
((gl :accessor gl :initarg :clog-webgl)))
|
||||
|
||||
(defgeneric create-shader (clog-webgl glenum-type)
|
||||
(:documentation "Create a clog-webgl-shader for type :GLENUM.
|
||||
See https://github.com/KhronosGroup/WebGL/blob/main/specs/latest/2.0/webgl2.idl
|
||||
For :GLENUM values"))
|
||||
|
||||
(defmethod create-shader ((obj clog-webgl) glenum-type)
|
||||
(let ((web-id (clog-connection:generate-id)))
|
||||
(js-execute obj (format nil "clog['~A']=~A.createShader(~A.~A)"
|
||||
web-id
|
||||
(script-id obj) (script-id obj) glenum-type))
|
||||
(make-instance 'clog-webgl-shader
|
||||
:connection-id (clog::connection-id obj)
|
||||
:html-id web-id
|
||||
:clog-webgl obj)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Properties - clog-webgl-shader
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmethod (setf shader-source) (source (obj clog-webgl-shader))
|
||||
(execute (gl obj) (format nil "shaderSource(~A, '~A')"
|
||||
(script-id obj)
|
||||
(escape-string source)))
|
||||
source)
|
||||
|
||||
(defmethod shader-parameter ((obj clog-webgl-shader) glenum-param)
|
||||
(query (gl obj) (format nil "getShaderParameter(~A, ~A.~A)"
|
||||
(script-id obj)
|
||||
(script-id (gl obj)) glenum-param)))
|
||||
|
||||
(defmethod shader-info-log ((obj clog-webgl-shader))
|
||||
(query (gl obj) (format nil "getShaderInfoLog(~A)"
|
||||
(script-id obj))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Methods - clog-webgl-shader
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmethod compile-shader ((obj clog-webgl-shader))
|
||||
(execute (gl obj) (format nil "compileShader(~A)"
|
||||
(script-id obj))))
|
||||
|
||||
(defmethod delete-shader ((obj clog-webgl-shader))
|
||||
(execute (gl obj) (format nil "deleteShader(~A)"
|
||||
(script-id obj))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Implementation - clog-webgl-program
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defclass clog-webgl-program (clog-obj)
|
||||
((gl :accessor gl :initarg :clog-webgl)))
|
||||
|
||||
(defgeneric create-program (clog-webgl)
|
||||
(:documentation "Create a clog-webgl-program"))
|
||||
|
||||
(defmethod create-program ((obj clog-webgl))
|
||||
(let ((web-id (clog-connection:generate-id)))
|
||||
(js-execute obj (format nil "clog['~A']=~A.createProgram()"
|
||||
web-id
|
||||
(script-id obj)))
|
||||
(make-instance 'clog-webgl-program
|
||||
:connection-id (clog::connection-id obj)
|
||||
:html-id web-id
|
||||
:clog-webgl obj)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Parameters - clog-webgl-program
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmethod program-parameter ((obj clog-webgl-program) glenum-param)
|
||||
(query (gl obj) (format nil "getProgramParameter(~A, ~A.~A)"
|
||||
(script-id obj)
|
||||
(script-id (gl obj)) glenum-param)))
|
||||
|
||||
(defmethod attribute-location ((obj clog-webgl-program) name)
|
||||
(query (gl obj) (format nil "getAttribLocation(~A, '~A')"
|
||||
(script-id obj) name)))
|
||||
|
||||
(defmethod program-info-log ((obj clog-webgl-program))
|
||||
(query (gl obj) (format nil "getProgramInfoLog(~A)"
|
||||
(script-id obj))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Methods - clog-webgl-program
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmethod attach-shader ((obj clog-webgl-program) (shader clog-webgl-shader))
|
||||
(execute (gl obj) (format nil "attachShader(~A, ~A)"
|
||||
(script-id obj)
|
||||
(script-id shader))))
|
||||
|
||||
(defmethod link-program ((obj clog-webgl-program))
|
||||
(execute (gl obj) (format nil "linkProgram(~A)" (script-id obj))))
|
||||
|
||||
(defmethod use-program ((obj clog-webgl-program))
|
||||
(execute (gl obj) (format nil "useProgram(~A)" (script-id obj))))
|
||||
|
||||
(defmethod delete-program ((obj clog-webgl-program))
|
||||
(execute (gl obj) (format nil "deleteProgram(~A)"
|
||||
(script-id obj))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Methdods - clog-webgl
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmethod clear-color ((obj clog-webgl) red green blue alpha)
|
||||
(execute obj (format nil "clearColor(~A,~A,~A,~A)"
|
||||
red green blue alpha)))
|
||||
|
||||
(defmethod clear-webgl ((obj clog-webgl) glenum-mask)
|
||||
(execute obj (format nil "clear(~A.~A)"
|
||||
(script-id obj)
|
||||
glenum-mask)))
|
||||
|
||||
(defmethod viewport ((obj clog-webgl) x y width height)
|
||||
(execute obj (format nil "viewport(~A,~A,~A,~A)"
|
||||
x y width height)))
|
||||
|
||||
(defmethod draw-arrays ((obj clog-webgl) primitive-type offset count)
|
||||
(execute obj (format nil "drawArrays(~A.~A,~A,~A)"
|
||||
(script-id obj) primitive-type
|
||||
offset count)))
|
||||
|
||||
(defmethod enable-vertex-attribute-array ((obj clog-webgl) attribute-location)
|
||||
(execute obj (format nil "enableVertexAttribArray(~A)"
|
||||
attribute-location)))
|
||||
|
||||
(defmethod vertex-attribute-pointer ((obj clog-webgl) attribute-location size type normalize stride offset)
|
||||
(execute obj (format nil "vertexAttribPointer(~A,~A,~A.~A,~A,~A,~A)"
|
||||
attribute-location size (script-id obj) type
|
||||
(p-true-js normalize) stride offset)))
|
||||
|
||||
(defmethod compile-shader-source ((obj clog-webgl) glenum-type source)
|
||||
(let ((shader (create-shader obj glenum-type)))
|
||||
(setf (shader-source shader) source)
|
||||
(compile-shader shader)
|
||||
(let ((result (shader-parameter shader :COMPILE_STATUS)))
|
||||
(cond ((js-true-p result)
|
||||
shader)
|
||||
(t
|
||||
(setf result (shader-info-log shader))
|
||||
(delete-shader shader)
|
||||
(error result))))))
|
||||
|
||||
(defmethod compile-webgl-program ((obj clog-webgl) vertex-shader fragment-shader)
|
||||
(let ((program (create-program obj)))
|
||||
(attach-shader program vertex-shader)
|
||||
(attach-shader program fragment-shader)
|
||||
(link-program program)
|
||||
(let ((result (program-parameter program :LINK_STATUS)))
|
||||
(cond ((js-true-p result)
|
||||
program)
|
||||
(t
|
||||
(setf result (program-info-log program))
|
||||
(delete-program program)
|
||||
(error result))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Implementation - clog-webgl-buffer
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defclass clog-webgl-buffer (clog-obj)
|
||||
((gl :accessor gl :initarg :clog-webgl)
|
||||
(gl-type :accessor gl-type :initarg :gl-type)))
|
||||
|
||||
(defgeneric create-webgl-buffer (clog-webgl &key bind-type)
|
||||
(:documentation "Create a clog-webgl-buffer"))
|
||||
|
||||
(defmethod create-webgl-buffer ((obj clog-webgl) &key bind-type)
|
||||
(let ((web-id (clog-connection:generate-id)))
|
||||
(js-execute obj (format nil "clog['~A']=~A.createBuffer()"
|
||||
web-id
|
||||
(script-id obj)))
|
||||
(let ((new-obj (make-instance 'clog-webgl-buffer
|
||||
:connection-id (clog::connection-id obj)
|
||||
:html-id web-id
|
||||
:clog-webgl obj
|
||||
:gl-type bind-type)))
|
||||
(when bind-type
|
||||
(bind-buffer new-obj bind-type))
|
||||
new-obj)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Methods - clog-webgl-buffer
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmethod bind-buffer ((obj clog-webgl-buffer) glenum-target)
|
||||
(execute (gl obj) (format nil "bindBuffer(~A.~A,~A)"
|
||||
(script-id (gl obj)) glenum-target
|
||||
(script-id obj)))
|
||||
(setf (gl-type obj) glenum-target))
|
||||
|
||||
(defmethod buffer-data ((obj clog-webgl-buffer) data-list data-type hint)
|
||||
(execute (gl obj) (format nil "bufferData(~A.~A, new ~A([~{~A~^,~}]), ~A.~A)"
|
||||
(script-id (gl obj)) (gl-type obj)
|
||||
data-type data-list
|
||||
(script-id (gl obj)) hint)))
|
||||
|
||||
(defmethod delete-buffer ((obj clog-webgl-buffer))
|
||||
(execute (gl obj) (format nil "deleteBuffer(~A)"
|
||||
(script-id obj))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Implementation - clog-webgl-vertex-array
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defclass clog-webgl-vertex-array (clog-obj)
|
||||
((gl :accessor gl :initarg :clog-webgl)))
|
||||
|
||||
(defgeneric create-vertex-array (clog-webgl)
|
||||
(:documentation "Create a clog-webgl-vertex-array"))
|
||||
|
||||
(defmethod create-vertex-array ((obj clog-webgl))
|
||||
(let ((web-id (clog-connection:generate-id)))
|
||||
(js-execute obj (format nil "clog['~A']=~A.createVertexArray()"
|
||||
web-id
|
||||
(script-id obj)))
|
||||
(make-instance 'clog-webgl-vertex-array
|
||||
:connection-id (clog::connection-id obj)
|
||||
:html-id web-id
|
||||
:clog-webgl obj)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Methods - clog-webgl-vertex-array
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defmethod bind-vertex-array ((obj clog-webgl-vertex-array))
|
||||
(execute (gl obj) (format nil "bindVertexArray(~A)"
|
||||
(script-id obj))))
|
||||
|
||||
(defmethod delete-vertex-array ((obj clog-webgl-vertex-array))
|
||||
(execute (gl obj) (format nil "deleteVertexArray(~A)"
|
||||
(script-id obj))))
|
||||
|
|
|
|||
|
|
@ -770,11 +770,6 @@ embedded in a native template application.)"
|
|||
(canvas-save generic-function)
|
||||
(canvas-restore generic-function))
|
||||
|
||||
(defsection @clog-webgl (:title "CLOG WebGL Objects")
|
||||
"CLOG-WebGL - Class for CLOG WebGL objects"
|
||||
(clog-webgl class)
|
||||
(create-webgl generic-function))
|
||||
|
||||
(defsection @clog-multimedia (:title "CLOG Multimedia Objects")
|
||||
"CLOG-Multimedia - Base Class for CLOG multimedia objects"
|
||||
(clog-multimedia class)
|
||||
|
|
|
|||
68
tutorial/34-tutorial.lisp
Normal file
68
tutorial/34-tutorial.lisp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
(defpackage #:clog-tut-34
|
||||
(:use #:cl #:clog #:clog-webgl)
|
||||
(:export start-tutorial))
|
||||
|
||||
(in-package :clog-tut-34)
|
||||
|
||||
;; example based on - https://webgl2fundamentals.org/webgl/lessons/webgl-fundamentals.html
|
||||
|
||||
;; "#version 300 es" MUST BE THE VERY FIRST LINE OF YOUR SHADER.
|
||||
;; No comments or blank lines are allowed before it
|
||||
(defparameter *vertex-shader-source* "#version 300 es
|
||||
|
||||
// an attribute is an input (in) to a vertex shader.
|
||||
// It will receive data from a buffer
|
||||
in vec4 a_position;
|
||||
|
||||
// all shaders have a main function
|
||||
void main() {
|
||||
|
||||
// gl_Position is a special variable a vertex shader
|
||||
// is responsible for setting
|
||||
gl_Position = a_position;
|
||||
}")
|
||||
|
||||
(defparameter *fragment-shader-source* "#version 300 es
|
||||
|
||||
// fragment shaders don't have a default precision so we need
|
||||
// to pick one. highp is a good default. It means \"high precision\"
|
||||
precision highp float;
|
||||
|
||||
// we need to declare an output for the fragment shader
|
||||
out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
// Just set the output to a constant reddish-purple
|
||||
outColor = vec4(1, 0, 0.5, 1);
|
||||
}")
|
||||
|
||||
(defun on-new-window (body)
|
||||
(debug-mode body)
|
||||
(setf (title (html-document body)) "Tutorial 34")
|
||||
(let* ((canvas (create-canvas body :width 1000 :height 500))
|
||||
(gl (create-webgl canvas))
|
||||
(vertex-shader (compile-shader-source gl :VERTEX_SHADER *vertex-shader-source*))
|
||||
(fragment-shader (compile-shader-source gl :FRAGMENT_SHADER *fragment-shader-source*))
|
||||
(program (compile-webgl-program gl vertex-shader fragment-shader))
|
||||
(pos (attribute-location program "a_position"))
|
||||
(pos-buffer (create-webgl-buffer gl))
|
||||
(vao (create-vertex-array gl)))
|
||||
(bind-buffer pos-buffer :ARRAY_BUFFER)
|
||||
(buffer-data pos-buffer `(0 0
|
||||
0 0.5
|
||||
0.7 0)
|
||||
"Float32Array" :STATIC_DRAW)
|
||||
(bind-vertex-array vao)
|
||||
(enable-vertex-attribute-array gl pos)
|
||||
(vertex-attribute-pointer gl pos 2 :FLOAT nil 0 0)
|
||||
(viewport gl 0 0 (width canvas) (height canvas))
|
||||
(clear-color gl 0.0 0.0 0.0 1.0)
|
||||
(clear-webgl gl :COLOR_BUFFER_BIT)
|
||||
(use-program program)
|
||||
(bind-vertex-array vao)
|
||||
(draw-arrays gl :TRIANGLES 0 3)))
|
||||
|
||||
(defun start-tutorial ()
|
||||
"Start turtorial."
|
||||
(initialize 'on-new-window)
|
||||
(open-browser))
|
||||
Loading…
Add table
Add a link
Reference in a new issue