-
-
Notifications
You must be signed in to change notification settings - Fork 30
/
palette.lisp
59 lines (52 loc) · 2.52 KB
/
palette.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
(in-package #:org.shirakumo.fraf.kandria)
(define-shader-entity paletted-entity ()
((palette :initarg :palette :initform (// 'kandria 'placeholder) :accessor palette
:type resource :documentation "The texture to use for palette lookups")
(palette-index :initarg :palette-index :initform 0 :accessor palette-index
:type integer :documentation "Which palette to use")))
;; FIXME: auto-fill palette...
#++
(defmethod observe-generation :after ((sprite paletted-entity) (data sprite-data) result)
(when (palette sprite)
()))
(defmethod stage :after ((entity paletted-entity) (area staging-area))
(stage (palette entity) area))
(defmethod render :before ((entity paletted-entity) (program shader-program))
(gl:active-texture :texture4)
(gl:bind-texture :texture-2D (gl-name (palette entity)))
(setf (uniform program "palette") 4)
(setf (uniform program "palette_index") (palette-index entity)))
(define-class-shader (paletted-entity :fragment-shader -1)
"uniform sampler2D palette;
uniform int palette_index = 0;
void main(){
maybe_call_next_method();
if(color.r*color.b == 1 && color.g < 0.1){
color = texelFetch(palette, ivec2(color.g*255, palette_index), 0);
}
}")
(defun convert-palette (file palette)
(let* ((palette (pngload:data (pngload:load-file palette)))
(input (pngload:load-file file :flatten T))
(data (pngload:data input))
(y (1- (array-dimension palette 0))))
(flet ((find-color (r g b)
(loop for x from 0 below (array-dimension palette 1)
do (when (and (= r (aref palette y x 0))
(= g (aref palette y x 1))
(= b (aref palette y x 2)))
(return x)))))
(loop for i from 0 below (length data) by 4
for index = (when (< 0 (aref data (+ i 3)))
(find-color (aref data (+ i 0))
(aref data (+ i 1))
(aref data (+ i 2))))
do (when index
(setf (aref data (+ i 0)) 255)
(setf (aref data (+ i 1)) index)
(setf (aref data (+ i 2)) 255))))
(zpng:write-png (make-instance 'zpng:png :color-type :truecolor-alpha
:width (pngload:width input)
:height (pngload:height input)
:image-data data)
file :if-exists :supersede)))