Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;;; Tutorial 01: Hello OpenGL from - https://learnopengl.com/Getting-started/Hello-Triangle
- ;;;; Original C source: https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/2.1.hello_triangle/hello_triangle.cpp
- ;;;; Usage; Recommend using quicklisp and create an ASD file that loads this.
- ;;;; Dependencies: #:CL-opengl #:bt-semaphore #:Lispbuilder-sdl
- (defpackage #:hello-triangle
- (:use #:cl)
- (:export :main))
- (in-package #:hello-triangle)
- (defparameter *fps* 60)
- (defparameter *Width* 640)
- (defparameter *height* 480)
- (defparameter *vertex-shader-source* "
- #version 330 core
- layout (location = 0) in vec3 position;
- void main(){
- gl_Position = vec4(position.x, position.y, position.z, 1.0);
- }")
- (defparameter *fragment-shader-source* "
- #version 330 core
- out vec4 color;
- void main(){
- color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
- }")
- ;x ;y ;z
- (defparameter *verticies-data* #(-0.5 -0.5 0.0 ; Bottom Left
- 0.5 -0.5 0.0 ; Bottom Right
- 0.0 0.5 0.0)) ; Top
- (defparameter *verticies* nil)
- (defparameter *VBO* nil)
- (defparameter *VAO* nil)
- (defparameter *shader-program* nil)
- (defun check-shader-error (shader)
- "Check for shader compilation errors"
- (let ((success (cffi:foreign-alloc :int :initial-element 0)))
- (unwind-protect
- (progn
- (%gl:get-shader-iv shader :compile-status success)
- (unless (= (cffi:mem-aref success :int) 1)
- (error "OpenGL Shader Error:~%~a~%" (gl:get-shader-info-log shader)))
- (cffi:foreign-free success)))))
- (defun check-program-error (program)
- "Check for linking errors"
- (let ((success (cffi:foreign-alloc :int :initial-element 0)))
- (unwind-protect
- (progn
- (%gl:get-program-iv program :link-status success)
- (unless (= (cffi:mem-aref success :int) 1)
- (error "OpenGL Program Error:~%~a~%" (gl:get-program-info-log program))))
- (cffi:foreign-free success))))
- (defun setup-program (vertex-Shader Fragment-Shader)
- "link and attach the shader programs"
- (let ((program (gl:create-program)))
- (gl:attach-shader program vertex-shader)
- (gl:attach-shader program fragment-shader)
- (gl:link-program program)
- (check-program-error program)
- (setf *shader-program* program)))
- (defun setup-shaders ()
- "Build and compile the actual shaders"
- (let ((vertex-shader (gl:create-shader :vertex-shader))
- (fragment-shader (gl:create-shader :fragment-shader)))
- ;; Vertex shader
- (gl:shader-source vertex-shader *vertex-shader-source*)
- (gl:compile-shader vertex-shader)
- (check-shader-error vertex-shader)
- ;; Fragment shader
- (gl:shader-source fragment-shader *fragment-shader-source*)
- (gl:compile-shader fragment-shader)
- (check-shader-error fragment-shader)
- (setup-program vertex-shader fragment-shader)
- (gl:delete-shader vertex-shader)
- (gl:delete-shader fragment-shader)))
- (defun setup-vertex-attributes ()
- "Set up vertex data (and buffer(s)) and configure vertex attributes"
- ;; Bind the vertex array object first, then bind and set vertex buffer(s), and then configure vertex attribute(s).
- (setf *VBO* (gl:gen-buffer))
- (setf *vao* (gl:gen-vertex-array))
- (gl:bind-vertex-array *vao*)
- (gl:bind-buffer :array-buffer *vbo*)
- ;; Convert CL array into an C array
- (setf *verticies*
- (loop :with gl-array = (gl:alloc-gl-array :float (length *verticies-data*))
- :for i :below (length *verticies-data*)
- :do (setf (gl:glaref gl-array i) (aref *verticies-data* i))
- :finally (return gl-array)))
- (gl:buffer-data :array-buffer :static-draw *verticies*)
- (gl:vertex-attrib-pointer 0 3 :float 0 (* 3 (cffi:foreign-type-size :float)) 0)
- (gl:enable-vertex-attrib-array 0))
- (defun init-openGL ()
- "Gets openGL ready"
- (gl:clear-color .2 .3 .3 1.0)
- ;;(gl:polygon-mode :front-and-back :line)
- (setup-shaders)
- (setup-vertex-attributes)
- )
- (defun rendering ()
- "Displays the actual triangle"
- (gl:clear :color-buffer-bit)
- (gl:use-program *shader-program*)
- (gl:bind-vertex-array *vao*)
- (gl:draw-arrays :triangles 0 3)
- (sdl:update-display))
- ;;; Since OpenGL doesn't have an garbage collector, have to manually do it.
- (defun freeing-memory ()
- "Clear allocated memory"
- (gl:free-gl-array *verticies*)
- (gl:delete-vertex-arrays '(*vao*))
- (gl:delete-buffers '(*vbo*))
- (gl:delete-program *shader-program*))
- (defun main (&aux (title "Hello Triangle"))
- (bt:make-thread
- (lambda ()
- (sdl:with-init ()
- (unwind-protect ; ensures proper error handling in-case of crash
- (sdl:window *width* *height* :title-caption title :flags '(sdl:sdl-opengl)) ; Window creation with opengl rendering
- (setf (sdl:frame-rate) *fps*)
- (sdl:enable-key-repeat 100 1)
- (setf cl-opengl-bindings:*gl-get-proc-address* #'sdl-cffi::sdl-gl-get-proc-address) ; overwrite SDL's rendering with CL-opengl's.
- (init-openGL)
- (sdl:with-events ()
- (:quit-event () t)
- (:idle ()
- (rendering)))
- (freeing-memory)))) ;; Freeing the memory after program terminates
- :name title))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement