GithubHelp home page GithubHelp logo

vydd / sketch Goto Github PK

View Code? Open in Web Editor NEW
1.4K 1.4K 67.0 1.48 MB

A Common Lisp framework for the creation of electronic art, visual design, game prototyping, game making, computer graphics, exploration of human-computer interaction, and more.

License: MIT License

Common Lisp 100.00%
2d art common-lisp games graphics hci sketch visual

sketch's Introduction

Sketch

http://quickdocs.org/badge/sketch.svg

Sketch is a Common Lisp environment for the creation of electronic art, visual design, game prototyping, game making, computer graphics, exploration of human-computer interaction and more. It is inspired by Processing Language and shares some of the API.

http://i.imgur.com/MNZUwz8.png

Installation

Sketch is available through Quicklisp, Common Lisp’s de facto package manager. From your REPL, run:

(ql:quickload :sketch)

To make Sketch run correctly, however, a few requirements must be met.

Requirements

Common Lisp Implementation

Sketch should be compatible with all major Common Lisp implementations and all major operating systems - more specifically, all CL implementations and operating systems that cl-sdl2 runs on. Incompatibility with any of these is considered a bug.

Sketch is known to work with:

  • CCL 1.11 on Mac OS X El Capitan
  • CCL 1.12.1 on MacOS 13.1 (steps)
  • CCL SVN 1.12.dev.r16617 on Arch Linux
  • CCL 1.11 on Windows 10 64bit
  • SBCL on Debian Unstable
  • SBCL 1.2.16 on Arch Linux
  • SBCL 1.3.1 on Linux Mint 17
  • SBCL 1.3.6 on Windows 10 64bit

Workarounds, or extra steps, may be required on some systems:

  • Arch Linux, issue.
  • OpenSuse, issue.
  • CCL on OSX: Make sure to use the 64-bit version of CCL (issue).
  • Quickload fails with libffi error, issue.

Sketch is known to not work with:

  • SBCL 1.2.15 on Mac OS X

Sketch can’t handle input and the window’s titlebar is black. These kinds of issues are a known problem with Mac OS X, because it needs its GUI threads to be main, and CCL is the only lisp that accounts for that out of the box. There are ways to counter this, but until a solution finds its way into this repository, SBCL on Mac OS X will stay on this list. In the meantime, use CCL.

If you test Sketch on other systems, please send a pull request to include your results.

Foreign dependencies

SDL2

SDL2 is currently Sketch’s only backend. It is a C library which you will need to download manually from libsdl webpage. Select the release compatible with your operating system, or compile from the source code.

SDL2 Image & SDL2 TTF

For loading image and font files, Sketch relies on SDL2 Image and SDL2 TTF, respectively, both part of the SDL project.

libffi

Some users have reported that libffi needed to be installed to make Sketch work.

OpenGL

Sketch requires graphics hardware and drivers with support for GL version 3.3.

Installing and running Sketch on Windows

Sketch works on both CCL and SBCL, but installing all prerequisites might not be as straightforward as it is on the other platforms.

Libraries

Download SDL2, SDL2_IMAGE and SDL2_TTF dlls from libsdl webpage and copy them somewhere Windows can find them - \Windows\System32 will work. When copying SDL2_TTF, make sure to copy all of the dlls provided in the archive, and not just the TTF one.

Now you will need to get a libffi dll. One of the ways of doing this is compiling from the source, but for a quick and easy solution, you can just find a trusted source and use their version. For example, if you are using Emacs on Windows, you can find libffi-6.dll in emacs\bin. Copy it to the same directory you copied sdl2 dlls to earlier.

GCC

To bootstrap cffi-libffi, you are going to need a C compiler, more specifically the one from the GNU Compiler Collection. Also, libffi headers and pkg-config are needed. Luckily, you can get all these things (and more) with MSYS2. Go to https://msys2.github.io and follow the instructions for installing the 64bit version.

From its console, install gcc, libffi headers and pkg-config by running pacman -S gcc libffi libffi-devel pkg-config.

Environment variables

From the Control Panel, open System properties, go to the Advanced tab, and click “Environment Variables…” - or click the Start button, start typing “environment” and select “Edit the system environment variables”.

Double click “Path” from the list of System variables and make sure that both your lisp implementation’s path (something like C:\Program Files\Steel Bank Common Lisp\1.3.6\) and MSYS path (probably C:\msys64\usr\bin) are listed. If not, click “New” and add them now.

If you needed to change anything here, restart the computer now.

SLIME

If you are using SLIME, you won’t be able to load or run Sketch if you start SWANK from emacs (by running M-x slime). Instead, you should open the Command Prompt (the regular one, not MSYS), start your lisp and eval (ql:quickload :swank) (swank:create-server). From Emacs, type M-x slime-connect, and finally, press enter twice (for localhost and port 4005).

If you did everything correctly, you should be able to (ql:quickload :sketch) and move on to the tutorial.

Running provided examples

To get a feel for what Sketch can do, and also to make sure that everything has been installed correctly, run the examples as follows.

CL-USER> (ql:quickload :sketch-examples)
CL-USER> (make-instance 'sketch-examples:hello-world)
CL-USER> (make-instance 'sketch-examples:sinewave)
CL-USER> (make-instance 'sketch-examples:brownian)
CL-USER> (make-instance 'sketch-examples:life) ; Click to toggle cells,
                                               ; any key to toggle iteration
CL-USER> (make-instance 'sketch-examples:input)
CL-USER> (make-instance 'sketch-examples:stars)

Running example code from this page

In all the following examples, we’re going to assume that Sketch is loaded with (ql:quickload :sketch), and that we’re in package :TUTORIAL, which is set to use :SKETCH.

CL-USER> (ql:quickload :sketch)
CL-USER> (defpackage :tutorial (:use :cl :sketch))
CL-USER> (in-package :tutorial)
TUTORIAL> ;; ready

Tutorial

Defining sketches is done with the defsketch macro, which is essentially a wrapper for defclass.

(defsketch tutorial ())
(make-instance 'tutorial)

If all goes well, this should give you an unremarkable gray window. From now on, assuming you’re using Emacs + SLIME, or a similarly capable environment, you can just re-evaluate (defsketch tutorial () <insert drawing code here>) and the sketch will be restarted without you having to close the window or make another instance of the class.

Shapes

Let’s draw something! Drawing code goes inside the body of defsketch.

(rect x y w h) draws a rectangle where x and y specify the top-left corner of the rectangle, and w and h are the width and height. By default, the origin (0, 0) is at the top-left corner of the drawing area, and the positive y direction is facing down.

(defsketch tutorial ()
  (rect 100 100 200 200))
(defsketch tutorial ()
  (dotimes (i 10)
    (rect 0 (* i 40) (* (+ i 1) 40) 40)))

Something to note: drawing code doesn’t need to go into a special function or method, or be explicitly binded to a sketch. defsketch is defined as (defsketch sketch-name bindings &body body): that body, and any functions it calls to, is your drawing code. We will get to bindings later.

Circles and ellipses are drawn with (circle x y r) and (ellipse cx cy rx ry):

(defsketch tutorial ()
  (circle 300 100 50)
  (ellipse 200 200 100 50))

Lines with (line x1 y1 x2 y2):

(defsketch tutorial ()
  (line 0 0 400 400)
  (line 400 0 0 400))

Lines with an arbitrary number of segments with polyline:

(defsketch tutorial ()
  (polyline 100 100 200 150 300 100
            200 200 100 100))

Arbitrary polygons can be drawn using (polygon x1 y1 x2 y2 ...), the winding rule (how the “inside parts” and “outside parts” are determined) is specified as a pen property (pens will be described in more detail later) and can be one of (:odd :nonzero :positive :negative :abs-geq-two). By default, it’s :nonzero.

(defsketch tutorial ()
  (with-pen (make-pen :fill +blue+ :winding-rule :odd)
    (polygon 100 100 200 150 300 100 200 200)))

To draw a regular polygon with n sides, call (ngon n cx cy rx ry &optional (angle 0)); cx and cy are the coordinates of the center of the shape, while rx and ry are height of an ellipse that the shape is inscribed inside.

(defsketch tutorial ()
  (dotimes (i 4)
    (ngon (+ i 3) (+ 50 (* i 100)) 200 20 20 (* i 20))))

Bezier curves with 4 control points are drawn with (bezier x1 y1 bx1 by1 bx2 by2 x2 y2); x1, y1, x2 and y2 determine the start and end points.

(defsketch tutorial ()
  (bezier 0 400 100 100 300 100 400 400))

The resolution of a curve can be controlled with the pen property :curve-steps, for example:

(defsketch tutorial ()
  (with-pen (make-pen :curve-steps 4 :stroke +white+)
    (bezier 0 400 100 100 300 100 400 400)))

Configuring your sketch

The first form in defsketch after the name of your sketch, and before the body, is a list of bindings that will be available in the sketch body. This is also where a number of configuration options can be set:

  • title (string): window title.
  • width and height (in pixels): window dimensions, 400 x 400 by default.
  • fullscreen (t or nil): whether window is fullscreen.
  • resizable (t or nil): whether window is resizable.
  • copy-pixels (t or nil): if true, the screen is not cleared before each drawing loop.
  • y-axis (:down or :up): :down by default. Determines both the location of the origin and the positive direction of the y-axis. :down means (0,0) is in the top-left corner and greater values of y move down the screen. :up means (0,0) is in the bottom-left corner and greater y values go up.
  • close-on (a keyword symbol denoting a key, or nil to disable): a shortcut for closing the sketch window, :escape by default. Set to nil to disable. The key names (e.g. :space, :g) are based on SDL2 scancodes, see here.
(defsketch tutorial
    ((radius 10)
     (resizable t)
     (width 200))
  (circle (/ width 2) (/ radius 2) radius))

Colors

In the previous examples, you may have noticed how to draw a shape with a fill color. Let’s now explore the color capabilities of Sketch in more detail. To draw a yellow background:

(defsketch tutorial ()
  (background +yellow+))

Predefined colors

There are constants for commonly used colors: +RED+, +GREEN+, +BLUE+, +YELLOW+, +MAGENTA+, +CYAN+, +ORANGE+ +WHITE+, and +BLACK+.

RGB, HSB, GRAY

You can create other colors using (rgb red green blue &optional (alpha 1.0)), (hsb hue saturation brightness &optional (alpha 1.0)) or (gray amount &optional (alpha 1.0)). The arguments to these functions are values from 0 to 1. (gray amount &optional (alpha 1.0)) is really just a convenient alias for (rgb amount amount amount &optional (alpha 1.0)).

More information:

This might be a good place to note that function names in Sketch use the American English spellings, like “gray” and “color”. It’s just a choice that needed to be made, in pursuit of uniformity and good style.

For a lighter yellow:

(defsketch tutorial ()
  (background (rgb 1 1 0.5)))

All color functions have an additional ALPHA parameter that determines the transparency.

RGB-255, HSB-360, GRAY-255

Sometimes it’s easier to think about color values in non-normalized ranges. That’s why Sketch offers RGB-255, HSB-360, and GRAY-255.

This is how these functions map to their normalized variants.

(rgb-255 r g b a)(rgb (/ r 255) (/ g 255) (/ b 255) (/ a 255))
(hsb-360 h s b a)(hsb (/ h 360) (/ s 100) (/ b 100) (/ a 255))
(gray-255 g a)(gray (/ g 255) (/ a 255))

HSB-360 uses different ranges, because hue is represented in degrees (0-360), and saturation and brightness are represented as percentages (0-100).

HEX-TO-COLOR

If you are used to working with colors in hex, like in CSS, you can use (hex-to-color string), where STRING is the color in one of the following formats: “4bc”, “#4bc”, “4bcdef”, or “#4bcdef”.

Generating colors

If you don’t care about fiddling with the exact values, but still need different colors, you can use one of the following functions.

(lerp-color (start-color end-color amount &key (mode :hsb)))

Lerp is a shorthand for linear interpolation. This function takes the starting color and the ending color, and returns the color between them, which is an AMOUNT away from the starting color. When AMOUNT equals zero, the returned color equals the starting color, and when AMOUNT equals one, the ending color is returned. Amounts between zero and one give colors that are “in-between”. These colors are calculated according to the specified MODE, which is :HSB by default, meaning that the resulting color’s hue is between the starting and ending hue, as is the case with its saturation and brightness.

(defsketch lerp-test ((title "lerp-color") (width 400) (height 100))
  (dotimes (i 4)
    (with-pen (make-pen :fill (lerp-color +red+ +yellow+ (/ i 4)))
      (rect (* i 100) 0 100 100))))
(random-color (&optional (alpha 1.0)))

Returns a random color. You probably don’t want to use this, because many of the returned colors will be either too dark, or too light. You do get to choose the ALPHA value, though.

(defparameter *colors* (loop for i below 16 collect (random-color)))

(defsketch random-color-test ((title "random-color") (width 400) (height 100))
  (dotimes (x 8)
    (dotimes (y 2)
      (with-pen (make-pen :fill (elt *colors* (+ x (* y 8))))
        (rect (* x 50) (* y 50) 50 50)))))
(hash-color (n &optional (alpha 1.0)))

This is probably the function you’re looking for, if you just want to create a non-repeating set of colors quickly. It maps all numbers to “interesting” (not too dark, not too light) colors. You can use this for coloring procedurally generated objects, when prototyping and just trying to make things look different quickly, when making palettes, looking for “the right” color, and many other things.

(defsketch hash-color-test ((title "hash-color") (width 400) (height 100))
  (dotimes (i 128)
    (with-pen (make-pen :fill (hash-color i))
      (rect (* i (/ 400 128)) 0 (/ 400 128) 100))))

Color filters

Sometimes you have a color, and would like to transform it in some way. That’s what color filters are for.

Grayscale

To convert colors to grayscale, you can use color-filter-grayscale. Two modes of grayscale conversion are implemented:

  • :luminosity, the default, which is luminance-preserving
  • :average, which sets all color channels to their average
(defsketch grayscale-test ((title "grayscale") (width 400) (height 300))
  (dotimes (i 10)
    (let ((color (hash-color i)))
      (with-pen (make-pen :fill (color-filter-grayscale color))
        (rect (* i 40) 0 40 100))
      (with-pen (make-pen :fill color)
        (rect (* i 40) 100 40 100))
      (with-pen (make-pen :fill (color-filter-grayscale color :average))
        (rect (* i 40) 200 40 100)))))
Invert

To invert a color, use color-filter-invert:

(defsketch invert-test
    ((title "invert") (width 300) (height 300) (i 0))
  (background +white+)
  (incf i 0.01)
  (let ((color (rgb (abs (sin i)) (abs (cos i)) 0)))
    (with-pen (make-pen :fill color)
      (circle 100 150 50))
    (with-pen (make-pen :fill (color-filter-invert color))
      (circle 200 150 50))))
Rotate

Rotating a color in Sketch using color-filter-rotate sets the value of its red channel to the previous value of the green channel; green to blue, and blue to red. The operation is intended to be used in palette generation, because the rotated colors usually work pretty well together.

(defsketch rotate-test
    ((title "rotate") (width 300) (height 300)
     (i 0) (color (rgb 0.2 0.8 1.0)))
  (background +white+)
  (incf i 1)
  (when (zerop (mod i 60))
    (setf color (color-filter-rotate color)))
  (with-pen (make-pen :fill color)
    (rect 100 100 100 100)))
HSB

HSB stands for Hue/Saturation/Brightness. You can use color-filter-hsb to adjust hue, saturation and brightness of an existing color.

(defsketch hsb-test
    ((title "hsb") (width 400) (height 300) (color (rgb 0.2 0.5 0.6)))
  (dotimes (i 4)
    (with-pen (make-pen :fill (color-filter-hsb color :hue (* 0.1 (+ i 1))))
      (rect (* i 100) 0 100 100))
    (with-pen (make-pen :fill (color-filter-hsb color :saturation (* 0.1 (+ i 1))))
      (rect (* i 100) 100 100 100))
    (with-pen (make-pen :fill (color-filter-hsb color :brightness (* 0.1 (+ i 1))))
      (rect (* i 100) 200 100 100))))

Pens

Pens are used to draw shapes. If no pen is specified, the default pen sets :fill to white, :stroke to black, and weight to 1.

Creating and Using Pens

Say you want to draw a red square and a blue circle. You would need to use two different pens.

(defsketch pen-test
    ((title "pens"))
  (with-pen (make-pen :fill +red+)
    (rect 100 100 100 100)) ; this rect will be red
  (with-pen (make-pen :fill +blue+)
    (circle 315 315 50))) ; this rect will be blue
Fill/Stroke

The squares in the previous example were filled because we specified the :fill property in make-pen. If we wanted to just draw the outline of the square, we would use :stroke like this:

(defsketch outline-square
    ((title "Outline Square"))
  (with-pen (make-pen :stroke +red+)
    (rect 100 100 100 100)))
(defsketch fill-stroke
    ((title "Fill and Stroke"))
  (background +white+)
  (with-pen (make-pen :stroke (rgb .5 0 .6) :fill (rgb 0 .8 .8))
    (rect 50 50 100 75)
    (circle 300 220 100)))
Weight

We can also change the thickness of the lines and shapes that we draw by changing the pen :weight.

(defsketch weight-test
    ((title "Weight Test"))
  (dotimes (i 10)
    (with-pen (make-pen :stroke +white+ :weight (+ i 1)) ; pen weight can't be zero
      (line 50 (* i 20) 350 (* i 20)))))

Curve-steps

:curve-steps is used to change the smoothness (resolution) of curves like #'bezier.

(defsketch curve-test
   ((title "Curve-steps"))
  (dotimes (i 99)
    (with-pen (make-pen :stroke +red+ :curve-steps (+ i 1)) ; as curve-step increases, curve becomes "smoother"
      (bezier 0 400 100 100 300 100 400 400))))

Transforms

The transforms (translate dx dy), (rotate angle &optional (cx 0) (cy 0)) and (scale sx &optional sy (cx 0) (cy 0)) are available to change the view matrix that is applied to coordinates.

Macros (with-translate (dx dy) &body body), (with-rotate (angle &optional (cx 0) (cy 0)) &body body) and (with-scale (sx &optional sy (cx 0) (cy 0)) &body body) can be used to restore the view matrix after executing the body.

The current view can also be saved on a stack and restored with (push-matrix) and (pop-matrix), which are analogous to push() and pop() in p5.js. The macro (with-identity-matrix &body body) pushes the current view matrix onto the stack, sets the view matrix to the identity matrix, executes body, and then pops the view matrix. (with-current-matrix &body body) is the same, except it doesn’t change the view matrix after pushing it.

In this example, translation and rotation are used to draw a triangle in the centre of the screen, without explicitly defining the coordinates of the vertices.

(defsketch transform-test
    ((title "Transform test")
     (width 500)
     (height 500)
     (side 100)
     (y-offset (/ side (* 2 (tan (radians 60))))))
  (with-translate (250 250)
    (loop repeat 3
          do (line (- (* 1/2 side)) y-offset  (* 1/2 side) y-offset)
          do (rotate 120))))

This example draws a sequence of increasingly shrinking squares using scaling.

(defsketch transform-test
    ((width 400)
     (height 400)
     (title "Scale test"))
 (translate 100 100)
 (dotimes (x 5)
   (rect 0 0 100 100)
   (translate 150 0)
   (scale 1/2)))

Text

Use (text text-string x y &optional width height) to draw text, where x and y specify the top-left corner of the rectangle containing the text. width and height control the shape of the text box. There is support for changing the font.

(defsketch text-test
   ((title "Hello, world!"))
 (text title 0 0 100))

The font can be specified using (make-font &key face color size line-height align) and the with-font macro.

(defsketch text-test
   ((title (format nil "Hello, world!~%Next line"))
 (with-font (make-font :color +white+
                       :face (load-resource "/path/to/font.ttf")
                       :size 12
                       :line-height 1
                       :align :left)
   (text title 0 0 100)))

align can be :left, :centre or :right, and determines whether the x & y coordinates correspond to the left end, centre, or right end of the text box. line-height determines the vertical space given to a line of text, scaled according to the font size, i.e. :line-height 1 leaves just enough space so that the text on two lines won’t overlap.

Images

First (load-resource filename ...) to load the image from a given file, then (draw image &key x y width height) to draw the image with its top-left corner at (x, y) and with the given width and height. If not provided, default (x,y) is (0,0) and width & height are taken from the image.

(defsketch image-test
   ((title "Hello, image!")
    (pic (load-resource "/path/to/img.png")))
  (draw pic :x 10 :y 10 :width 200 :height 200))

Note that load-resource automatically caches the resource when it is called inside a valid sketch environment (i.e. inside the defsketch’s body), so it is not inefficient to call it in every loop. It is important to release resources using sketch::free-resource; this is done automatically for resources in the sketch environment when the sketch window is closed. Finally, to avoid caching and to reload the resource every time, the parameter :force-reload-p can be passed to load-resource.

Images can be cropped using (crop image x y w h), where x and y indicate the top-left corner of the cropping rectangle (relative to the top-left corner of the image) and w and h indicate the width & height. Image flipping can be accomplished by using negative w and h values.

Input

Input is handled by defining implementations of the methods listed below. Currently, it is not possible to call drawing functions from these methods, though this can be worked around by saving the input somewhere and then doing the drawing from the sketch body, as demonstrated in the examples to follow.

  • (on-click instance x y), (on-middle-click x y) and (on-right-click x y) are called when there’s a left, middle or right click. x and y give the coordinates of the click.
  • (on-mouse-button button state x y) is called for left, middle and right mousebutton interactions. button can be one of :left, :middle and :right. state can be either :up or :down.
  • Depending on the value of button, this propagates to one of: (on-mouse-left state x y), (on-mouse-middle state x y), or (on-mouse-right state x y).
  • These methods, in turn, propagate to (on-mouse-left-up x y), (on-mouse-right-down x y), (on-mouse-right-down x y), …
  • (on-hover instance x y) is called when the mouse moves, x and y give its coordinates.
  • (on-text instance text) is called when a single character is entered, text is a string consisting of just this character.
  • (on-key instance key state) is called when a key is pressed. key is a keyword symbol denoting which key was pressed/released (like :space or :left; for now, the names are based on SDL2 scancodes, see here for the full list), and state is a keyword symbol denoting whether the key was pressed (:up) or released (:down).

In this example, we draw a new rectangle every time there is a click.

(defsketch input-test
   ((title "Hello, input")
    (rectangles nil))
 (loop for (x y) in rectangles
       do (rect x y 50 50)))
(defmethod on-click ((window input-test) x y)
  (with-slots (rectangles) window
    (push (list x y) rectangles)))

In this example, all keyboard text input is echoed to the screen.

(defsketch text-test
   ((title "Hello, input")
    (text-to-write nil))
  (loop for s in text-to-write
        do (text s 0 0 20 20)
        do (translate 20 0)))
(defmethod on-text ((window text-test) text)
  (with-slots (text-to-write) window
    (setf text-to-write (nconc text-to-write (list text)))))

Finally, here is an example where a pair of eyes follow the mouse (the pupils are restricted to a rectangle, it would look better if they were restricted to a circle).

(defsketch hover-test
   ((looking-at (list 0 0))
    (cx (/ width 2))
    (cy (/ height 2)))
  (let ((cx-1 (- cx 50))
        (cx-2 (+ cx 50))
        (mx (car looking-at))
        (my (cadr looking-at)))
    (with-pen (make-pen :fill +white+)
      (ellipse cx-1 cy 40 80)
      (ellipse cx-2 cy 40 80))
    (with-pen (make-pen :fill +black+)
      (flet ((move-towards (x1 x2)
               (let ((diff (- x2 x1)))
                 (+ x1 (if (< (abs diff) 10)
                           diff
                           (* (signum diff) 10))))))
        (circle (move-towards cx-1 mx) (move-towards cy my) 10)
        (circle (move-towards cx-2 mx) (move-towards cy my) 10)))))
(defmethod on-hover ((window hover-test) x y)
  (with-slots (looking-at) window
    (setf (car looking-at) x
          (cadr looking-at) y)))

See also: life.lisp.

Setup

The generic function (setup instance &key &allow-other-keys) is a hook that gets called once on every “restart” of the sketch. That is:

  • before the drawing code in the sketch body is called for the first time.
  • whenever the sketch is redefined.
  • every time an error occurs.

Note that any drawing that takes place within setup will be immediately covered by a gray background, unless (copy-pixels t) is added to defsketch.

Here is an example usage of setup from brownian.lisp.

(defmethod setup ((instance brownian) &key &allow-other-keys)
  (background (gray 1)))

Saving a picture

(save-png pathname) can be called within the body of defsketch to save a PNG of the currently running sketch. A keyboard shortcut could be set up to take screenshots, as follows.

(defsketch save-test
   ((should-save nil)
    (copy-pixels t))
  (rect (random width) (random height) 10 10)
  (when should-save
    (setf should-save nil)
    (save-png "/tmp/my-sketch.png")))
(defmethod on-text ((window save-test) text)
  (when (string= text "s")
    (setf (slot-value window 'should-save) t)))

Drawing with a canvas

(make-canvas width height) can be used to create a rectangular grid of pixels. The shape of the grid is defined by width and height.

(canvas-paint canvas color x y) sets the color of a pixel within the grid.

(canvas-lock canvas) freezes the appearance of the canvas. Any calls to (canvas-image canvas) will show an image of the canvas when canvas-lock was last called.

(canvas-unlock canvas) allows the image of the canvas to be modified again.

(draw canvas &key (x 0) (y 0) (width nil) (height nil) draws the canvas; by default, the original width and height of the canvas are used, but these can be overridden.

Example: stars.lisp.

Control flow

(stop-loop) from within a sketch body or within an event handler to disable the drawing loop.

(start-loop) to start the drawing loop again.

This can be used, for example, to draw a static sketch and then disable the drawing loop so as to not burn up your CPU. It can also be used to regenerate the sketch with each mouseclick.

Example: control-flow.lisp.

Made with Sketch

Outro

For everything else, read the code or ask vydd at #lispgames. Go make something pretty!

sketch's People

Contributors

austinsmith29 avatar cbaggers avatar gavinok avatar gleefre avatar iamfirecracker avatar kevinpgalligan avatar tatrix avatar vitovan avatar vydd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sketch's Issues

Delivering application based on sketch

Hello,
I'm trying to make a standalone executable of an app made with sketch. I tried to look at qelt, since it has binaries here (itch.io), but I haven't been able to find a solution.

How can I define a main function? Just doing (make-instance 'app) doesn't work - main thread is closed immediately and the application is close just after starting up.

initialising interdependent variables inside the defsketch macro

Hi

I have a problem when it comes to creating objects with their own state when using the defsketch macro.

Here is simple (and quite pointless) example:

#!/usr/bin/sbcl --script

(load "~/quicklisp/setup.lisp")
(ql:quickload "sketch")

(in-package :sketch)

(defun change-state (a)
  (setf (gethash 'v a) 1)
  a)

(defsketch nier ((title "weir")
                 (width 1000)
                 (a (make-hash-table :test #'equal))
                 (b (change-state a))
                 (height 1000))

  ; expect this to print (:A 1 :B 1)
  ; but it prints (:A NIL :B 1), so a has not been altered.
  (print (list :a (gethash 'v a) :b (gethash 'v b)))

  (background (gray 0.1)))

(defun main ()
  ; can i pass variables here somehow instead?
  ; i've tried eg. (make-instance 'nier :a 3), but this does not 
  ; affect the value of a inside defsketch
  (make-instance 'nier)
  (sleep 100))

(main)

So I'm wondering if this is expected behaviour? (I sort of assume it is.) And what is the preferred way of initialising multiple interdependent things inside defsketch, where those things have an internal state?

As a sidenote, evaluating the following code has the behaviour i'm expecting

(let* ((a (make-hash-table :test #'equal))
       (b (change-state a)))
 (print (list :a (gethash 'v a) :b (gethash 'v b))))

Setup

I see that there is a setup method in sketch, but i haven't found any documentation or examples anywhere. Perhaps this is the correct approach? If so, could someone provide an example, please?

Thank you for this library either way, it is precisely what i need!
Best
Anders

Cant run examples, blank screen with SDL Error

Hello

I wanted to check out this project, installed the dependencies and i got this:

(ql:quickload :sketch-examples)
To load "sketch-examples":
  Load 1 ASDF system:
    sketch-examples
; Loading "sketch-examples"

(:SKETCH-EXAMPLES)
(make-instance 'sketch-examples:sinewave)

debugger invoked on a SDL2::SDL-RC-ERROR in thread
#<THREAD "SDL2 Main Thread" RUNNING {1001CA72C3}>:
  SDL Error (-1): That operation is not supported

The current thread is not at the foreground,
SB-THREAD:RELEASE-FOREGROUND has to be called in #<SB-THREAD:THREAD "main thread" RUNNING {1004DE01F3}>

I don't know what to do from here :(

Can not make tutorial working

Hi I load sketch and sketch-example,
first my machine OSX EL Capitan description, slime and roswell:

CL-USER> (lisp-implementation-type)
"Clozure Common Lisp"
CL-USER> (lisp-implementation-version)
"Version 1.11-r16635 (DarwinX8664)"

when I load sketch it works and also when samples are working


CL-USER> (ql:quickload :sketch-examples)
To load "sketch-examples":
  Load 1 ASDF system:
    sketch-examples
; Loading "sketch-examples"

(:SKETCH-EXAMPLES)
CL-USER> (make-instance 'sketch-examples:hello-world)
#<SKETCH-EXAMPLES:HELLO-WORLD #x30200289FC0D>

screen shot 2016-05-17 at 17 01 10

also the other examples work well

but when I try teh sample tutorial in the readme:

CL-USER> (ql:quickload :sketch)
To load "sketch":
  Load 1 ASDF system:
    sketch
; Loading "sketch"

(:SKETCH)
CL-USER> (in-package :sketch)
#<Package "SKETCH">
SKETCH> (defsketch tutorial ())

gives the sldb output:

(TUTORIAL
 NIL) can't be destructured against the lambda list (SKETCH-NAME
                                                     WINDOW-OPTIONS
                                                     SLOT-BINDINGS
                                                     &BODY
                                                     BODY), because it does not contain at least 3 elements.
   [Condition of type CCL::SIMPLE-PROGRAM-ERROR]

Restarts:
 0: [*ABORT] Return to SLIME's top level.
 1: [ABORT-BREAK] Reset this thread
 2: [ABORT] Kill this thread

Backtrace:
  0: (CCL::PREPARE-TO-DESTRUCTURE (TUTORIAL NIL) (SKETCH-NAME WINDOW-OPTIONS SLOT-BINDINGS &BODY BODY) 3 NIL)
  1: (DEFSKETCH (DEFSKETCH TUTORIAL NIL) NIL)
  2: (FUNCALL #<Compiled-function DEFSKETCH Macroexpander #x30200255E35F> (DEFSKETCH TUTORIAL NIL) NIL)
  3: (MACROEXPAND-1 (DEFSKETCH TUTORIAL NIL) NIL)
  4: (CCL::CHEAP-EVAL-MACROEXPAND-1 (DEFSKETCH TUTORIAL NIL) NIL)
  5: (CCL::CHEAP-EVAL-IN-ENVIRONMENT (DEFSKETCH TUTORIAL NIL) NIL)
  6: (CCL::CHEAP-EVAL (DEFSKETCH TUTORIAL NIL))
  7: (SWANK::%EVAL-REGION "(defsketch tutorial ())\n")
  8: ((:INTERNAL SWANK::%LISTENER-EVAL))
  9: (SWANK-REPL::TRACK-PACKAGE #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::%LISTENER-EVAL) #x3020027C54EF>)
 10: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::%LISTENER-EVAL) #x3020027C552F>)
 11: (SWANK::%LISTENER-EVAL "(defsketch tutorial ())\n")
 12: (CCL::CALL-CHECK-REGS SWANK-REPL:LISTENER-EVAL "(defsketch tutorial ())\n")
 13: (CCL::CHEAP-EVAL (SWANK-REPL:LISTENER-EVAL "(defsketch tutorial ())\n"))
 14: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(defsketch tutorial ())\n") "SKETCH" 84)
 15: (SWANK::PROCESS-REQUESTS NIL)
 16: ((:INTERNAL SWANK::HANDLE-REQUESTS))
 17: ((:INTERNAL SWANK::HANDLE-REQUESTS))
 18: (SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK #<Compiled-function SWANK:SWANK-DEBUGGER-HOOK #x302000A1F26F> #<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::HANDLE-REQUESTS) #x302000BFD3BF>)
 19: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #<SWANK/GRAY::SLIME-INPUT-STREAM #x302000BFC58D>) (*STANDARD-OUTPUT* . #<SWANK/GRAY::SLIME-OUTPUT-STREAM #x302000BFC21D>) ..))) #<CCL:COMPILED-LEXICAL-C..
 20: (SWANK::HANDLE-REQUESTS #<MULTITHREADED-CONNECTION #x302000AA3DFD> NIL)
 21: (CCL::RUN-PROCESS-INITIAL-FORM #<PROCESS repl-thread(13) [Active] #x302000BEB46D> (#<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL CCL::%PROCESS-RUN-FUNCTION) #x302000BEB1FF>))
 22: ((:INTERNAL (CCL::%PROCESS-PRESET-INTERNAL (CCL:PROCESS))) #<PROCESS repl-thread(13) [Active] #x302000BEB46D> (#<CCL:COMPILED-LEXICAL-CLOSURE (:INTERNAL CCL::%PROCESS-RUN-FUNCTION) #x302000BEB1FF>))
 23: ((:INTERNAL CCL::THREAD-MAKE-STARTUP-FUNCTION))

So I d not know if this is an error in the tutorial, of course the main problem is that I do not know enouch common lisp and sketch particullary

Thanks in advance

Error while Compiling

Hello,
I am trying to get sketch working on Artix Linux (Arch Linux without systemd) with sbcl 2.1.1-1. I am having an issue while loading sketch with quicklisp. Here is what the error looks like:

compile-file-error while compiling
   #<cl-source-file "cl-opengl" "gl" "funcs-gl-glcore-gles2">
   [Condition of type uiop/lisp-build:compile-file-error]

Restarts:
 0: [retry] Retry compiling #<cl-source-file "cl-opengl" "gl" "funcs-gl-glcore-gles2">.
 1: [accept] Continue, treating compiling #<cl-source-file "cl-opengl" "gl" "funcs-gl-glcore-gles2"> as having been successful.
 2: [retry] Retry ASDF operation.
 3: [clear-configuration-and-retry] Retry ASDF operation after resetting the configuration.
 4: [retry] Retry ASDF operation.
 5: [clear-configuration-and-retry] Retry ASDF operation after resetting the configuration.
 --more--

Backtrace:
  0: (uiop/lisp-build:check-lisp-compile-results nil t t "~/asdf-action::format-action/" ((#<asdf/lisp-action:compile-op > . #<asdf/lisp-action:cl-source-file "cl-opengl" "gl" "funcs-gl-glcore-gles2">)))
  1: ((sb-pcl::emf asdf/action:perform) #<unused argument> #<unused argument> #<asdf/lisp-action:compile-op > #<asdf/lisp-action:cl-source-file "cl-opengl" "gl" "funcs-gl-glcore-gles2">)
  2: ((lambda nil :in asdf/action:call-while-visiting-action))
  3: ((:method asdf/action:perform-with-restarts :around (t t)) #<asdf/lisp-action:compile-op > #<asdf/lisp-action:cl-source-file "cl-opengl" "gl" "funcs-gl-glcore-gles2">) [fast-method]
  4: ((:method asdf/plan:perform-plan (t)) #<asdf/plan:sequential-plan {10147ADC63}>) [fast-method]
  5: ((flet sb-c::with-it :in sb-c::%with-compilation-unit))
  6: ((:method asdf/plan:perform-plan :around (t)) #<asdf/plan:sequential-plan {10147ADC63}>) [fast-method]
  7: ((:method asdf/operate:operate (asdf/operation:operation asdf/component:component)) #<asdf/lisp-action:load-op > #<asdf/system:system "sketch"> :plan-class nil :plan-options nil) [fast-method]
  8: ((sb-pcl::emf asdf/operate:operate) #<unused argument> #<unused argument> #<asdf/lisp-action:load-op > #<asdf/system:system "sketch"> :verbose nil)
  9: ((lambda nil :in asdf/operate:operate))
 10: ((:method asdf/operate:operate :around (t t)) #<asdf/lisp-action:load-op > #<asdf/system:system "sketch"> :verbose nil) [fast-method]
 11: ((sb-pcl::emf asdf/operate:operate) #<unused argument> #<unused argument> asdf/lisp-action:load-op "sketch" :verbose nil)
 12: ((lambda nil :in asdf/operate:operate))
 13: ((:method asdf/operate:operate :around (t t)) asdf/lisp-action:load-op "sketch" :verbose nil) [fast-method]
 14: (asdf/session:call-with-asdf-session #<function (lambda nil :in asdf/operate:operate) {10147A8F7B}> :override t :key nil :override-cache t :override-forcing nil)
 15: ((lambda nil :in asdf/operate:operate))
 16: (asdf/session:call-with-asdf-session #<function (lambda nil :in asdf/operate:operate) {101479DF6B}> :override nil :key nil :override-cache nil :override-forcing nil)
 17: ((:method asdf/operate:operate :around (t t)) asdf/lisp-action:load-op "sketch" :verbose nil) [fast-method]
 18: (asdf/operate:load-system "sketch" :verbose nil)
 19: (quicklisp-client::call-with-macroexpand-progress #<function (lambda nil :in quicklisp-client::apply-load-strategy) {101479DD3B}>)
 --more--

I think I have all of the dependencies installed needed (I went through 1-by-1 to make sure i have them installed). Is my problem a dependency problem?

Thank you for any help you are able to offer!

Not reinitializing vao

In the guide here http://onrendering.blogspot.no/2011/10/buffer-object-streaming-in-opengl.html it shows that after orphaning the buffer you need to reset your vao. In sketch currently it is only rebound.

instead something like this should be added to glkit

(defun reinit-vao (vao)
  (with-slots ((vao-type type) id vbos vertex-count) vao
    (with-slots (groups) vao-type
      (loop for group across groups
         as vbo-offset = 0 then (+ vbo-offset vbo-count)
         as vbo-count = (vao-vbo-count group)
         as vbo-subset = (make-array vbo-count :displaced-to vbos
                                     :displaced-index-offset vbo-offset)
         as attr-offset = 0 then (+ attr-offset attr-count)
         as attr-count = (vao-attr-count group)
         do (loop for i from 0 below (vao-attr-count group)
               do (%gl:enable-vertex-attrib-array (+ i attr-offset)))
           (vao-set-pointers group attr-offset vertex-count vbo-subset)))))

and this be called from start-draw, as in:

(defun start-draw ()
  (%gl:bind-buffer :array-buffer 1)
  (%gl:buffer-data :array-buffer *buffer-size* (cffi:null-pointer) :stream-draw)
  (setf (env-buffer-position *env*) 0)
  (kit.gl.vao:vao-bind (env-vao *env*))
  (kit.gl.vao::reinit-vao (env-vao *env*)))

This has been working but I think only because there is only one vao.

Working on macOS 13.1 using Clozure CL

Using MacPorts and ccl64

Not a bug, but and update too anyone interested Sketch seems run fine on macOS 13.1 using Clozure CL.

Steps I took, to the best of my recollection. Install Clozure CL 1.12.1 from MacPorts. (I haven't tested with SBCL, yet).

sudi port install ccl

Install Quicklisp, enter the ccl64 REPL run the setup.

curl -O https://beta.quicklisp.org/quicklisp.lisp

ccl64 --load quicklisp.lisp

(quicklisp-quickstart:install)

# If you are using Emacs and SLIME
(ql:quickload "quicklisp-slime-helper")

# Add this to your init.el
(load (expand-file-name "~/quicklisp/slime-helper.el"))
(setq inferior-lisp-program "ccl64")

Open a REPL in Emacs M-x slime and load Sketch.

CL-USER> (ql:quickload :sketch)

Now install the SDL2 external/foreign dependencies.

sudo port install libsdl2
sudo port install libsdl2_image
sudo port install libsdl2_ttfd

Now it should be possible to load the examples.

CL-USER> (ql:quickload :sketch-examples)
CL-USER> (make-instance 'sketch-examples:hello-world)
CL-USER> (make-instance 'sketch-examples:sinewave)
CL-USER> (make-instance 'sketch-examples:brownian)
CL-USER> (make-instance 'sketch-examples:life)

Versions

| macOS | 13.1 (Intel 64) |
| GNU Emacs | 30.0.50 |
| SLIME | 2.27 |
| Sketch | 20221106 |
| ccl | 1.12.1 |
| libsdl2 | 2.26.2 |
| libsdl2image | 2.6.2 |
| libsdl2ttf | 2.20.1 |

Screenshots

sketch-macOS

The appropriate way to set a custom font

Currently, I use the following code to achieve the custom font:

(set-font
 (make-font
  :face (make-instance 'sketch::typeface :filename "/tmp/my-stupid-font.ttf")))

I basically know nothing about SDL, and know very little about Common Lisp.

And the code above used something like sketch::typeface, which makes me feel inelegant. Since the double colons (::) tell me that you do not want me to use it.

So I am wondering:

Is this the proper way to set a custom font?

If not, what should I do?

Thank you very much for creating sketch, I enjoyed it very much.

Double evaluation in defsketch custom bindings

Intro

Hi!
As mentioned before in this issue(#33), initforms of custom bindings in defsketch macro are evaluated twice. (@inconvergent wrote that it seemed to be fixed. Unfortunately, I still observe this issue using both quicklisp version and this repo version.)

Examples

Here is my simple example:

(ql:quickload :sketch)
(use-package :sketch)

(defparameter *result* ())

(defsketch double-evaluation ((hi (push "world" *result*)))
  (text (format nil "~a" *result*) 100 100))

(make-instance 'double-evaluation)

This will display a text (world world) instead of just (world).

As a more complicated example - it seems that Qelt doesn't run properly with current version of sketch because of that.

Solution?

I think that I have found when this issue was introduced - 19fe205:
implementation of make-custom-slots-setf function changed from

(defun make-custom-slots-setf (sketch bindings)
  `(setf ,@(mapcan (lambda (binding)
                     `((,(binding-accessor sketch binding) instance) ,(car binding)))
                   bindings)))

to

(defun make-custom-slots-setf (sketch bindings)
  `(setf ,@(mapcan (lambda (binding)
                     `((slot-value instance ',(car binding)) ,(cadr binding)))
                   bindings)))

Notice that second argument changed from (car binding), which refers to the binding name, to (cadr binding), which refers to the binding initform.

So, the patch proposed in this comment (#33 (comment)) should be the solution to this issue.

Sketch doesn't resize properly after class redefinition

Hello,

If you try to redefine sketch which was either created with different from default size, or if you redefine size itself, it will stop rendering properly.

(Example: redefined from (width 400) to (width 800))
before-redefine
after-redefine

Adding method for window-event :resize as in #59 fixes this problem.

sineweave example drops into ldb on SBCL/ubuntu/x86_64

The sineweave example starts but dies after a second or so with the following error if I run it from SLIME. If I run it from the SBCL command prompt directly, everything works.

free(): invalid pointer
fatal error encountered in SBCL pid 19874(tid 0x7f16ba2af700):
SIGABRT received.

Error opening /dev/tty: No such device or address
Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb> backtrace
Backtrace:
   0: Foreign function gsignal, pc = 0x7f16e018fed7, fp = 0x7f16ba2ae5f0
ldb> 

Attempting to render images results in a garbled mess.

When trying to load and render any PNG image, the image comes out as a garbled mess. I have, quite literally, 1 week of experience with common lisp, so my understanding of why this is happening is a bit limited.

Minimal-ish example:

(asdf:load-system :cffi)

(cffi:define-foreign-library libffi  ; Required for loading sketch.
  (t (:default "libffi-7")))

(cffi:use-foreign-library libffi)

(ql:quickload :sketch)

(defpackage :stickies (:use :cl :sketch))
(in-package :stickies)

...

(defsketch app 
    ((title "Stickies") (width 600) (height 400)
    (save-icon (load-resource "..\\assets\\StickiesSaveIcon.png")))
  (image save-icon 0 0))

(defun main ()
  (make-instance 'app))

(main)

The image I'm trying to draw to the screen:
saveIconTemp
What I'm getting:
saveIconRenderResult
My operating system is Windows 10, and I've been using SBCL 2.2.10.

:y-axis :up flips text vertically

Setting :y-axis :up works properly, except that when you draw text with (text ... everything is flipped vertically, which can be kind of hard to read. This also includes the text on the debug screen. :)

Text rendering problem with hello-world example

Hi maintainers, thank you very much for this project! I'm having one issue on my machines with the hello-world example, specifically with the text rendering. This is what I'm seeing on my arch linux machine and also on another 2019 MacBook Pro machine.

Screenshot_20220626_205029

If I try rendering some text other than "Hello, world!". This is what I see:

  • 5 a's (i.e. "aaaaa"):
    Screenshot_20220626_205540

  • 6 a/s (i.e. "aaaaaa"):
    Screenshot_20220626_204957

  • 7 a's (i.e. "aaaaaaa"):
    Screenshot_20220626_210621

I'm still learning more about computer graphics and the GPU so I don't quite know how to troubleshoot this issue. It'll be really appreciated if you can help me to troubleshoot this.
I have the lastest master of lispgames/cl-sdl2 and lispgames/sdl2kit in my local-projects directory. Here's my opengl version information:

$ glxinfo | grep OpenGL
OpenGL vendor string: Intel
OpenGL renderer string: Mesa Intel(R) HD Graphics 520 (SKL GT2)
OpenGL core profile version string: 3.3 (Core Profile) Mesa 22.1.2
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.3 (Compatibility Profile) Mesa 22.1.2
OpenGL shading language version string: 3.30
OpenGL context flags: (none)
OpenGL profile mask: compatibility profile
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.2 Mesa 22.1.2
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
OpenGL ES profile extensions:

Make resizable sketchs

Hello,

Is there any way to make a sketch resizable?
I tried to use sdl2:sdl-set-window-resizable, but the app wasn't able to adapt to resize properly.

Error when loading on MacOS 11

All dependencies installed. This issue affects cl-sdl2 as well. Any clue how to get around this?

% sbcl
This is SBCL 2.1.3, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (ql:quickload 'sketch)
To load "sketch":
  Load 1 ASDF system:
    sketch
; Loading "sketch"
...
debugger invoked on a LOAD-FOREIGN-LIBRARY-ERROR in thread
#<THREAD "main thread" RUNNING {1004AE81C3}>:
  Unable to find framework OpenGL

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETRY                        ] Try loading the foreign library again.
  1: [USE-VALUE                    ] Use another library instead.
  2: [TRY-RECOMPILING              ] Recompile library and try loading it again
  3: [RETRY                        ] Retry
                                     loading FASL for #<CL-SOURCE-FILE "cl-opengl" "gl" "library">.
  4: [ACCEPT                       ] Continue, treating
                                     loading FASL for #<CL-SOURCE-FILE "cl-opengl" "gl" "library">
                                     as having been successful.
  5:                                 Retry ASDF operation.
  6: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the
                                     configuration.
  7:                                 Retry ASDF operation.
  8:                                 Retry ASDF operation after resetting the
                                     configuration.
  9: [ABORT                        ] Give up on "sketch"
 10: [REGISTER-LOCAL-PROJECTS      ] Register local projects and try again.
 11:                                 Exit debugger, returning to top level.

(CFFI::FL-ERROR "Unable to find framework ~A" "OpenGL")
   source: (ERROR 'LOAD-FOREIGN-LIBRARY-ERROR :FORMAT-CONTROL CONTROL
                  :FORMAT-ARGUMENTS ARGUMENTS)
0]

defsketch compiler warnings

It seems defsketch is doing a bunch of wrong stuff. If I define a window width/height, it will emit warnings for unused variables. This is because the code expands to a LET* with 2 width and 2 height bindings, as well as a needless WITH-SLOTS form binding them, when WITH-ACCESSORS does the same thing prior. This is madness ha

Evaluation order in DEFSKETCH

I tried this:

(DEFSKETCH xxx (...)
    ((x-left 1.0d0)
     (x-right 1.0d0)
     (x-step (/ (- x-right x-left) width))
...))

but that fails with "unbound variable". Can/should that be similar to LET*, perhaps?

Drawing thicker points

POINT seems to be always drawing a 1x1 rectangle:

(defun point (x y)
  (declare (type real x y))
  (with-pen (make-pen :fill (pen-stroke (env-pen *env*)))
    (rect x y 1 1)))

What if I wanted to increase the thickness of my points instead? I know I can replace all my calls to POINT with RECT, but what if POINT used the current PEN's weight to figure out how big the rectangle should be?

(defun point (x y)
  (declare (type real x y))
  (let ((weight (or (pen-weight (env-pen *env*)) 1)))
    (with-pen (make-pen :fill (pen-stroke (env-pen *env*)))
      (rect (- x (floor weight 2))
            (- y (floor weight 2))
            weight
            weight))))

I am happy to open an PR if there is interest in this.

Save sketches as static images

Dear Dev,
first, let me thank you for this fantastic library. At the risk of asking something potentially trivial, I would like to know whether it is possible to save sketches as static images e.g. png. I am a researcher and I am very interested in using Sketch to programatically generate diagrams and graphics to (i) share my research results; and (ii) teach some Computer Science modules. I am new to Lisp, and so, again, I might be asking something very basic. Unfortunately, I could not find an answer to my question by looking at Sketch's source code. Or maybe this is not a correct use case for Sketch?
I will be very happy if you could give me some pointers.

Thanks for your efforts.

Nery

ql:quickload :sketch fails with libffi error

cffi does not admit the possibility of libffi.so.8

One fix is to add to line 34 ~quicklisp/dists/quicklisp/software/cffi_0.24.1/libffi/libffi.lisp

  (:unix (:or "libffi.so.8" "libffi.so.7" "libffi32.so.7" "libffi.so.6" "libffi32.so.6" "libffi.so.5" "libffi32.so.5"))

Reporting it here as I discovered it trying to get sketch to run on ArchLinux where the libffi is installed via pacman.

I am a lisp noob. Appreciate comments on a better fix than editing the source code of some quicklisp installed package.

Should be fixed once this this pull request to cffi makes into the quicklisp version cffi/cffi#191

Weird geometry error when using transform matrices and line/polyline

Test program:

(defsketch test
    ((title "test") (width 640) (height 640))
  (let ((size 48))
    (scale (/ size 2))
    (translate 4 4)
    (with-pen (make-pen :stroke +white+ :weight (/ 2 size))
      #+nil (line 0.4 0.4 1 1)
      #+nil (line 1 1 0.4 0.4)
      (polyline 0.8 0.8 -1 -1 -0.8 -0.8))))

Problem:

  1. the output from the polyline is wrong, it flies outside the screen.

Screen Shot 2022-08-22 at 3 57 56 PM

  1. The output of the two (commented out in the snippet) line has different position. When composing larger algorithms I find geometry gets put in wrong positions everywhere.

polygon is sometimes broken

Sometimes the polygon function seems to break and spew lots of strange output.

If you clone down http://github.com/sjl/coding-math and check out commit 3d6ba7a35004215b185674032cbba9b2d4a2e452 you can see an example. Run with:

(ql:quickload 'coding-math)
(in-package #:coding-math.2d.demo)
(defparameter *demo* (make-instance 'cm))

I'm drawing a couple of stars onto the screen. Each star has a list of points, which I draw the circles at. I also draw lines between the points:

(defun draw-star (star)
  (draw-particle (getf star :center))
  ; (draw-polygon (getf star :points))
  (iterate
    (with points = (getf star :points))
    (for (p1 . p2) :pairs-of-list points)
    (draw-circle p1 3)
    (draw-line p1 p2)))

If you uncomment the draw-polygon call there it should fail with something like this:

screenshot

Sdl2-image and sdl2-ttf not found

Hi,

I would love to give sketch a try, but I can't seem to get it to load. When I call (ql:quickload "sketch") quicklisp complains that it cannot find system "sdl2-image". Any idea of why that happens?
I'm using CCL 1.11 on OS X.

Thanks a lot!

Error in Brownian example

When I try to run the Brownian example, I get the following error:

* (make-instance 'sketch-examples:brownian)

debugger invoked on a SDL2::SDL-RC-ERROR in thread
#<THREAD "SDL2 Main Thread" RUNNING {1004CF4B43}>:
  SDL Error (#<SDL-WINDOW {#X00000000}>): Couldn't find matching GLX visual

I am running SBCL 1.2.14 on Ubuntu 15.10, with Intel HD Graphics 5500. I guess there's a good chance this is something to do with the Intel graphics drivers.

Commenting out these lines seems to solve the problem, but I cannot say I know why.

Changed colors with load image

If I load a PNG-file, instead of red the color blue is rendered.

(defsketch image ((title "image") (width 500) (height 600)) (image (load-resource "png/my-image.png") 100 50)

Graph

Any idea about how hard it can be to construct graph functions on top of that to draw graphs

Tutorial Sketch Broken

After running the tutorial sketch, it opened blank windows until my computer froze (On a related note how do I kill something like this quickly?). The windows had two different titles, "Sketch", and "SDL2 Window". I'm not sure if this is relevant, but I installed cl-sdl2 manually from git, because the quicklisp version didn't have the sdl2-ffi:sdl-point.

Shader Error when trying to run examples

Not sure if this is more glkit related but anyway, here we go:

Link Log:
WARNING: Output of vertex shader 'f_pos' not read by fragment shader
   [Condition of type SIMPLE-ERROR]

Restarts:
 0: [*CONTINUE] Return to the SDL2 main loop.
 1: [ABORT] Abort, quitting SDL2 entirely.
 2: [ABORT] abort thread (#<THREAD "SDL2 Main Thread" RUNNING {1006331B33}>)

Backtrace:
  0: (KIT.GL.SHADER:COMPILE-AND-LINK-PROGRAM NIL :VERTEX-SHADER " ..)
  1: (KIT.GL.SHADER::PROCESS-SOURCE #<KIT.GL.SHADER::SHADER-DICTIONARY-DEFINITION {1005D5A683}> #<KIT.GL.SHADER::PROGRAM-SOURCE :FILL-SHADER> #<KIT.GL.SHADER:PROGRAM {10063419B3}>)
  2: ((:METHOD KIT.GL.SHADER:COMPILE-SHADER-DICTIONARY (KIT.GL.SHADER::SHADER-DICTIONARY-DEFINITION)) #<KIT.GL.SHADER::SHADER-DICTIONARY-DEFINITION {1005D5A683}>) [fast-method]
  3: (SKETCH::INITIALIZE-ENVIRONMENT #<SKETCH-EXAMPLES:HELLO-WORLD {10063319B3}>)
  4: ((:METHOD INITIALIZE-INSTANCE :AFTER (SKETCH:SKETCH)) #<SKETCH-EXAMPLES:HELLO-WORLD {10063319B3}>) [fast-method]
  5: ((SB-PCL::EMF INITIALIZE-INSTANCE) #<unused argument> #<unused argument> #<SKETCH-EXAMPLES:HELLO-WORLD {10063319B3}>)
  6: ((LAMBDA NIL :IN INITIALIZE-INSTANCE))
  7: (SDL2::HANDLE-MESSAGE (#<CLOSURE (LAMBDA NIL :IN INITIALIZE-INSTANCE) {1006331D2B}> . #S(TRIVIAL-CHANNELS:CHANNEL :QUEUE #S(TRIVIAL-CHANNELS.QUEUE:QUEUE :HEAD NIL :TAIL NIL) :Q-CONDITION #<SB-THREAD:W..
  8: (SDL2::GET-AND-HANDLE-MESSAGES)
  9: (KIT.SDL2::MAIN-LOOP-FUNCTION #<SDL2-FFI:SDL-EVENT {#X0062CA90}> NIL)
 10: (KIT.SDL2::MAIN-LOOP)
 11: ((LAMBDA NIL :IN KIT.SDL2:START))
 12: (SDL2::HANDLE-MESSAGE (#<FUNCTION (LAMBDA NIL :IN KIT.SDL2:START) {1005B3C73B}>))
 13: (SDL2::SDL-MAIN-THREAD)
 14: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS) #<unavailable lambda list>)
 15: ((FLET #:WITHOUT-INTERRUPTS-BODY-1002 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 16: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
 17: ((FLET #:WITHOUT-INTERRUPTS-BODY-335 :IN SB-THREAD::CALL-WITH-MUTEX))
 18: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {B24DCFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
 19: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "SDL2 Main Thread" RUNNING {1006331B33}> NIL #<CLOSURE (LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS) {1006331ADB}> (#<SB..
 --more--

This happens under OSX El Capitain with SBCL 1.3 or CCL 1.11 and an Intel Iris Pro GPU for all examples. If you need any more information, or feel that this should be reported to glkit, please let me know.

copy-pixels overrides background colour depending on window size

This works, draws random black circles on a white background:

 (defsketch bug
          ((width 800)
           (height 600)
           (copy-pixels t)
           (pen (make-pen :fill +black+)))
        (with-pen pen
          (circle (random width) (random height) (random 10))))
  (defmethod setup ((instance bug) &key &allow-other-keys)
              (background +white+))

But if you change both the width & height to 400, for example, then the background goes black. It also seems like an initial window comes up, then gets closed and a new one opens up with the desired dimensions. I'm on Linux and have Intel graphics hardware, if that makes a difference.

edit: My guess is that sketch restarts the window in order to initialise it with the proper dimensions, but then doesn't call setup afterwards. I'm not sure why this behaviour is dependent on the width and height, though.

OSX Can't run hello world example

I've just installed sbcl via brew and installed quicklisp package manager. I load the library and load the example, but when the window is drawn the program crashes.

SDL2 ttf is version 2.0.14, image is 2.0.3, and SDL2 is 2.0.8.

: [~] > sbcl
This is SBCL 1.4.11, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (ql:quickload :sketch)
To load "sketch":
  Load 1 ASDF system:
    sketch
; Loading "sketch"
..........
(:SKETCH)
* (ql:quickload :sketch-examples)
To load "sketch-examples":
  Load 1 ASDF system:
    sketch-examples
; Loading "sketch-examples"

(:SKETCH-EXAMPLES)
* (make-instance 'sketch-examples:hello-world)

#<SKETCH-EXAMPLES:HELLO-WORLD {1003462033}>
* 2018-09-07 19:32:44.626 sbcl[38221:6484905] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'nextEventMatchingMask should only be called from the Main Thread!'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007fffaa0522cb __exceptionPreprocess + 171
	1   libobjc.A.dylib                     0x00007fffbee6c48d objc_exception_throw + 48
	2   AppKit                              0x00007fffa823de82 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 4480
	3   SDL2                                0x0000000002a225f5 SDL2 + 140789
	4   SDL2                                0x0000000002a0c8dd SDL2 + 51421
	5   ???                                 0x0000000022a6b721 0x0 + 581351201
	6   ???                                 0x0000000022ae2d8e 0x0 + 581840270
)
libc++abi.dylib: terminating with uncaught exception of type NSException
fatal error encountered in SBCL pid 38221(tid 0xb0000000):
SIGABRT received.


Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb>

Add ability to change default window dimensions

It would be useful if you could specify the default window dimensions globally, for when you want to create windows that are not 400x400, without explicitly adding bindings to every DEFSKETCH form.

Attemps to print text cause errors

Trying the hello-world-example yields the following, while other examples seem to work just fine:

The 'ffi_prep_cif' libffi call failed for function "TTF_RenderUTF8_Blended".
   [Condition of type CFFI::SIMPLE-LIBFFI-ERROR]

Restarts:
 0: [CONTINUE] Return to the SDL2 main loop.
 1: [ABORT] Abort, quitting SDL2 entirely.
 2: [ABORT] abort thread (#<THREAD "SDL2 Main Thread" RUNNING {1006605D53}>)

Backtrace:
  0: ((FLET "H0" :IN KIT.SDL2:RENDER) #<CFFI::SIMPLE-LIBFFI-ERROR "The 'ffi_prep_cif' libffi call failed for function ~S." {1007DC13B3}>)
  1: (SB-KERNEL::%SIGNAL #<CFFI::SIMPLE-LIBFFI-ERROR "The 'ffi_prep_cif' libffi call failed for function ~S." {1007DC13B3}>)
  2: (ERROR CFFI::SIMPLE-LIBFFI-ERROR :FUNCTION-NAME "TTF_RenderUTF8_Blended" :FORMAT-CONTROL "The 'ffi_prep_cif' libffi call failed for function ~S." :FORMAT-ARGUMENTS ("TTF_RenderUTF8_Blended"))
  3: (CFFI::LIBFFI-ERROR "TTF_RenderUTF8_Blended" "The 'ffi_prep_cif' libffi call failed for function ~S." "TTF_RenderUTF8_Blended")
  4: (CFFI::MAKE-LIBFFI-CIF "TTF_RenderUTF8_Blended" :POINTER (:POINTER :POINTER (:STRUCT SDL2-TTF::SDL-COLOR)) :DEFAULT-ABI)
  5: (SDL2-TTF::%SDL-RENDER-UTF8-BLENDED #.(SB-SYS:INT-SAP #X00BA7930) "ERROR" (SDL2-TTF::R 255 SDL2-TTF::G 255 SDL2-TTF::B 255 ...))
  6: (SDL2-TTF:RENDER-UTF8-BLENDED #<SDL2-FFI:TTF-FONT {#X00BA7930}> "ERROR" 255 255 255 255)
  7: (SKETCH:TEXT-LINE-IMAGE "ERROR")
      Locals:
        LINE = "ERROR"
  8: (SKETCH:TEXT "ERROR ..)
      Locals:
        FONT = #<SKETCH::FONT {1002CBCDC3}>
        HEIGHT = NIL
        PREVIOUS-PEN = #S(SKETCH:PEN :FILL NIL :STROKE NIL :WEIGHT 1 :CURVE-STEPS 100)
        TEXT-STRING = "ERROR\n---\nThe 'ffi_prep_cif' libffi call failed for function \"TTF_RenderUTF8_Blended\".\n---\nClick for restarts."
        TOP = 0
        WIDTH = NIL
        X = 20
        Y = 20
  9: ((:METHOD KIT.SDL2:RENDER (SKETCH:SKETCH)) #<SKETCH-EXAMPLES:HELLO-WORLD {1007D90313}>) [fast-method]
 10: ((SB-PCL::EMF KIT.SDL2:RENDER) #<unused argument> #<unused argument> #<SKETCH-EXAMPLES:HELLO-WORLD {1007D90313}>)
 11: ((LAMBDA NIL :IN KIT.SDL2:RENDER))
 12: ((SB-PCL::EMF KIT.SDL2:WINDOW-EVENT) #<unused argument> #<unused argument> #<SKETCH-EXAMPLES:HELLO-WORLD {1007D90313}> :EXPOSED 156704 0 0)
 13: (KIT.SDL2::MAIN-LOOP-FUNCTION #<SDL2-FFI:SDL-EVENT {#X02D08C60}> NIL)
 14: (KIT.SDL2::MAIN-LOOP)
 15: ((LAMBDA NIL :IN KIT.SDL2:START))
 16: (SDL2::HANDLE-MESSAGE (#<CLOSURE (LAMBDA NIL :IN KIT.SDL2:START) {1002762DBB}>))
 17: (SDL2::SDL-MAIN-THREAD)
 18: ((LAMBDA NIL :IN BORDEAUX-THREADS::BINDING-DEFAULT-SPECIALS))
 19: ((FLET SB-UNIX::BODY :IN SB-TH

It seems I'm generally able to use Sketch, but any attempts at text cause the same error to appear.. I didn't know Sketch was supposed to show that nice red screen with errors because that has failed before with the above error.. :D

Running on Windows.

How to run sketch across VNC?

Hello,

I am accessing sketch from a Windows laptop via VNC to a CentOS server (no graphics card on server).

I cannot run Sketch examples from Emacs/slime, so I am trying to debug the issue by first running the examples in sbcl running from a Gnome terminal.

I was able to run CL-SDL2 example in that sbcl.

Back to Sketch. After setting the SDL_VIDEO_X11-VISUALID to 0x210, I get a black window with error SDL error: could not generate GLX context.

Two questions:

  • Does anyone know how to deal with the GLX context error (I could not follow the discussions and solutions that I found on the web)
  • Does anyone have sketch running across VNC and can share their setup?

I realize that these issues are Lisp and Sketch unrelated, but I am hoping someone has them figured out. I also understand that this topic is quite complex, and this forum may not be the right place to look for answers.

Thanks,

Mirko

Proper way to geometrically scale line sketches?

It seems that the current transform/matrix facility scales both the shape itself and the pen. Is there a nice way to scale the geometry of line sketches but maintain line thickness?

If this has to be done manually for now, would a patch that provides pen-preserving transformation be desirable? (I think to do that we need to do calculation in the drawing primitives instead of delegating to the OpenGL side).

Using images.

I am trying to use images in Sketch on Linux and the rectangle fill renders out weird. I am looking for clues as to what might be causing this issue from anyone here in the community.

Code:

(defsketch tutorial
    ((title "line")
     (width 400)
     (height 400))
     (background +orange+)
     (with-pen (make-pen :stroke +red+ :weight 1 :fill (load-resource "mia.png")) 
               (rect 50 30 200 113)))

Here is what Sketch renders:

sketch

Here is the source image:

mia

Details:

  1. I tried creating a rectangle of the same size as the image @ 200 x 113 px but the weird artifacting still happens regardless.

  2. This happens on Linux machines with AMD and Intel gpus.

  3. I am using latest Debian everything and latest Sketch pull.

Does anyone have any thought son why this might be happening? What might be the fix?

Thanks.

TEXT won't do ~%

When writing via TEXT, any newline in there will be shown as a box.

Being able to embed newlines in a text string would be nice.

Thank you for the quick response ;) !

Can't quickload on macOS 12 M1

Getting the following:

Assumption is that sdl2 lib is in /opt/homebrew/lib insteade of /usr/local/lib which might cause the issue.
Is there anyway to check closer?

COMPILE-FILE-ERROR while
compiling #<CL-SOURCE-FILE "sdl2" "autowrap">
   [Condition of type UIOP/LISP-BUILD:COMPILE-FILE-ERROR]

Restarts:
 0: [RETRY] Retry compiling #<CL-SOURCE-FILE "sdl2" "autowrap">.
 1: [ACCEPT] Continue, treating compiling #<CL-SOURCE-FILE "sdl2" "autowrap"> as having been successful.
 2: [RETRY] Retry ASDF operation.
 3: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the configuration.
 4: [RETRY] Retry ASDF operation.
 5: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the configuration.
 --more--

Backtrace:
 0: (UIOP/LISP-BUILD:CHECK-LISP-COMPILE-RESULTS NIL T T "~/asdf-action::format-action/" ((#<ASDF/LISP-ACTION:COMPILE-OP > . #<ASDF/LISP-ACTION:CL-SOURCE-FILE "sdl2" "autowrap">)))
 1: ((SB-PCL::EMF ASDF/ACTION:PERFORM) #<unused argument> #<unused argument> #<ASDF/LISP-ACTION:COMPILE-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "sdl2" "autowrap">)
 2: ((LAMBDA NIL :IN ASDF/ACTION:CALL-WHILE-VISITING-ACTION))
 3: ((:METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS :AROUND (T T)) #<ASDF/LISP-ACTION:COMPILE-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "sdl2" "autowrap">) [fast-method]
 4: ((:METHOD ASDF/PLAN:PERFORM-PLAN (T)) #<ASDF/PLAN:SEQUENTIAL-PLAN {700EF204B3}>) [fast-method]
 5: ((FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT))
 6: ((:METHOD ASDF/PLAN:PERFORM-PLAN :AROUND (T)) #<ASDF/PLAN:SEQUENTIAL-PLAN {700EF204B3}>) [fast-method]
 7: ((:METHOD ASDF/OPERATE:OPERATE (ASDF/OPERATION:OPERATION ASDF/COMPONENT:COMPONENT)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "sketch"> :PLAN-CLASS NIL :PLAN-OPTIONS NIL) [fast-method]
 8: ((SB-PCL::EMF ASDF/OPERATE:OPERATE) #<unused argument> #<unused argument> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "sketch"> :VERBOSE NIL)
 9: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
10: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/SYSTEM:SYSTEM "sketch"> :VERBOSE NIL) [fast-method]
11: ((SB-PCL::EMF ASDF/OPERATE:OPERATE) #<unused argument> #<unused argument> ASDF/LISP-ACTION:LOAD-OP "sketch" :VERBOSE NIL)
12: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
13: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) ASDF/LISP-ACTION:LOAD-OP "sketch" :VERBOSE NIL) [fast-method]
14: (ASDF/SESSION:CALL-WITH-ASDF-SESSION #<FUNCTION (LAMBDA NIL :IN ASDF/OPERATE:OPERATE) {700EF203AB}> :OVERRIDE T :KEY NIL :OVERRIDE-CACHE T :OVERRIDE-FORCING NIL)
15: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
16: (ASDF/SESSION:CALL-WITH-ASDF-SESSION #<FUNCTION (LAMBDA NIL :IN ASDF/OPERATE:OPERATE) {700EF202DB}> :OVERRIDE NIL :KEY NIL :OVERRIDE-CACHE NIL :OVERRIDE-FORCING NIL)
17: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) ASDF/LISP-ACTION:LOAD-OP "sketch" :VERBOSE NIL) [fast-method]
18: (ASDF/OPERATE:LOAD-SYSTEM "sketch" :VERBOSE NIL)
19

Request for OpenGL 2.1 support

Very interesting project, sadly I cannot make use of it because my hardware only supports OpenGL 2.1 not 3.3, and it's not something that my current situation really allows me to change anytime soon.

I don't really know how hard of an issue this would be to solve. I understand if it is unfeasible, I just figured I'd at least let you know that there are people that would appreciate wider OpenGL support.

OSX can't find SDL2_image

I have installed SDL2, SDL2_image and SDL2_ttf into /Library/Frameworks but for some reason ccl can't find it... However, SBCL can find it but of course sbcl has issues with the rendering.

Error compiling on OpenSuse

cc -m64 -o /home/silver/.cache/common-lisp/sbcl-1.3.11-1.4-suse-linux-x64/home/silver/quicklisp/dists/quicklisp/software/cffi_0.18.0/libffi/libffi-types__grovel-tmpGHU3ALSV -I/home/silver/quicklisp/dists/quicklisp/software/cffi_0.18.0/ /home/silver/.cache/common-lisp/sbcl-1.3.11-1.4-suse-linux-x64/home/silver/quicklisp/dists/quicklisp/software/cffi_0.18.0/libffi/libffi-types__grovel.c

 with command ("cc" "-m64" "-o"
               "/home/silver/.cache/common-lisp/sbcl-1.3.11-1.4-suse-linux-x64/home/silver/quicklisp/dists/quicklisp/software/cffi_0.18.0/libffi/libffi-types__grovel-tmpGHU3ALSV"
               "-I/home/silver/quicklisp/dists/quicklisp/software/cffi_0.18.0/"
               "/home/silver/.cache/common-lisp/sbcl-1.3.11-1.4-suse-linux-x64/home/silver/quicklisp/dists/quicklisp/software/cffi_0.18.0/libffi/libffi-types__grovel.c")
 exited with error code 1
   [Condition of type CFFI-GROVEL:GROVEL-ERROR]

Getting the following error when trying to ql:quickload sketch. Running openSuse Tumbleweed, tried it with sbcl 1.3.11 and CCL 1.12 and got the same error.

Tried starting swank in emacs and separately and clearing out the common lisp cache so it had a fresh try each time.

Can't get it to work on CCL 1.11.1 macOS Sierra.

I tried to run it using ccl with SDL2 installed and I recieve the following error:

 Error: Unknown field :WINDOW for foreign-record type:
>        #<FOREIGN-RECORD ANON-TYPE-7768 #x302001A7FDCD>
>        Valid fields:
>          :HDC (SDL2-FFI:HDC)
>        
> While executing: #<STANDARD-METHOD PLUS-C::BUILD-REF (SYMBOL AUTOWRAP:FOREIGN-RECORD T T)>, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.

This is on CCL64 BTW, I also tried running SDL2 to only arrive the same error.

[feature?] is it possible to prevent clear screen at each redraw

I currently in the process of learning a bit about processing.
I started with :trivial-gamekit. However, I disliked the idea of refreshing the screen at every draw.
Especially for simple programs like random walker, wouldn't be much better if the program continuously draw, instead of keeping a list of objects drawn.

So is there a way to achieve this?

Libffi error when attempting to use (text) in a defsketch

OS: Windows 10
Implementation: SBCL 2.0.0 AMD64

When trying to use a sketch with (text) such as the hello-world example, the following error is generated:
The 'ffi_prep_cif' libffi call failed for function "TTF_RenderUTF8_Blended".

I used the windows installation method outlined in the README. The other sketch-examples (sinewave, brownian, life) work correctly.

More informative errors

If any error executed (in game-logic for example), sketch becomes red and speechless about whats wrong. Maybe there is some way to debug these errors, but i'm can't get it.

It will be very handy to see what kind of error i have.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.