From cbf59a78d1a85cfc92644615a56a18cf6b054604 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Mon, 10 Sep 2018 17:42:10 -0400 Subject: render: Change texture origin to top-left. This is a pretty big change, but hopefully for the best as this aligns with graphics programs and the glTF standard that uses a top-left origin. We can keep using a lower-left origin for vertices, though. * chickadee/render/texture.scm (surface->texture): Stop flipping pixel rows. * chickadee/render/sprites.scm (draw-sprite-unbatched, sprite-batch-add!, draw-nine-patch*): Adjust texture y-coordinates. * chickadee/render/font.scm (parse-fnt): Stop inverting y coordinates. * chickadee/render/tiled.scm (load-tile-map): Stop inverting tile ids. --- chickadee/render/font.scm | 5 +--- chickadee/render/sprite.scm | 64 +++++++++++++++++++++++--------------------- chickadee/render/texture.scm | 7 +---- chickadee/render/tiled.scm | 10 ++----- 4 files changed, 37 insertions(+), 49 deletions(-) diff --git a/chickadee/render/font.scm b/chickadee/render/font.scm index d5995a2..e1958a2 100644 --- a/chickadee/render/font.scm +++ b/chickadee/render/font.scm @@ -255,10 +255,7 @@ extension must be either .xml or .fnt." (width (attr node 'width string->number)) (height (attr node 'height string->number)) (x (attr node 'x string->number)) - ;; Invert the y axis. Our origin is the - ;; bottom-left corner, not top-left. - (y (- image-height height - (attr node 'y string->number))) + (y (attr node 'y string->number)) (x-offset (attr node 'xoffset string->number)) (y-offset (- line-height height (attr node 'yoffset string->number))) diff --git a/chickadee/render/sprite.scm b/chickadee/render/sprite.scm index 067384b..d8ef363 100644 --- a/chickadee/render/sprite.scm +++ b/chickadee/render/sprite.scm @@ -99,19 +99,21 @@ void main (void) { (f32vector-set! bv 6 x1) (f32vector-set! bv 7 y2))) (with-mapped-typed-buffer (force texcoord-buffer) - (let ((s1 (rect-left texture-region)) - (t1 (rect-bottom texture-region)) - (s2 (rect-right texture-region)) - (t2 (rect-top texture-region)) + ;; Texture origin is at the top-left, so we need to flip the Y + ;; coordinate relative to the vertices. + (let ((s1 (rect-x texture-region)) + (t1 (rect-y texture-region)) + (s2 (+ (rect-x texture-region) (rect-width texture-region))) + (t2 (+ (rect-y texture-region) (rect-height texture-region))) (bv (typed-buffer-data (force texcoord-buffer)))) (f32vector-set! bv 0 s1) - (f32vector-set! bv 1 t1) + (f32vector-set! bv 1 t2) (f32vector-set! bv 2 s2) - (f32vector-set! bv 3 t1) + (f32vector-set! bv 3 t2) (f32vector-set! bv 4 s2) - (f32vector-set! bv 5 t2) + (f32vector-set! bv 5 t1) (f32vector-set! bv 6 s1) - (f32vector-set! bv 7 t2))) + (f32vector-set! bv 7 t1))) (with-blend-mode blend-mode (with-texture 0 texture (gpu-apply shader (force vertex-array) @@ -248,10 +250,10 @@ void main (void) { (local-y1 (rect-y region)) (local-x2 (+ local-x1 (rect-width region))) (local-y2 (+ local-y1 (rect-height region))) - (s1 (rect-left texture-region)) - (t1 (rect-bottom texture-region)) - (s2 (rect-right texture-region)) - (t2 (rect-top texture-region))) + (s1 (rect-x texture-region)) + (t1 (rect-y texture-region)) + (s2 (+ (rect-x texture-region) (rect-width texture-region))) + (t2 (+ (rect-y texture-region) (rect-height texture-region)))) (set-vec2-x! world1 local-x1) (set-vec2-y! world1 local-y1) (set-vec2-x! world2 local-x2) @@ -293,16 +295,16 @@ void main (void) { (set-offset (* size 8)) ;; Bottom-left (f32vector-set! texcoords (offset) s1) - (f32vector-set! texcoords (+ (offset) 1) t1) + (f32vector-set! texcoords (+ (offset) 1) t2) ;; Bottom-right (f32vector-set! texcoords (+ (offset) 2) s2) - (f32vector-set! texcoords (+ (offset) 3) t1) + (f32vector-set! texcoords (+ (offset) 3) t2) ;; Top-right (f32vector-set! texcoords (+ (offset) 4) s2) - (f32vector-set! texcoords (+ (offset) 5) t2) + (f32vector-set! texcoords (+ (offset) 5) t1) ;; Top-left (f32vector-set! texcoords (+ (offset) 6) s1) - (f32vector-set! texcoords (+ (offset) 7) t2) + (f32vector-set! texcoords (+ (offset) 7) t1) (set-sprite-batch-size! batch (1+ size))))))) (define *batch?* #f) @@ -407,14 +409,14 @@ rendered entirely." (trect (texture-gl-tex-rect texture)) (tw (rect-width prect)) (th (rect-height prect)) - (border-s1 (rect-left trect)) - (border-t1 (rect-bottom trect)) - (border-s2 (rect-right trect)) - (border-t2 (rect-top trect)) + (border-s1 (rect-x trect)) + (border-t1 (rect-y trect)) + (border-s2 (+ (rect-x trect) (rect-width trect))) + (border-t2 (+ (rect-y trect) (rect-height trect))) (fill-s1 (+ border-s1 (/ left-margin tw))) - (fill-t1 (+ border-t1 (/ bottom-margin th))) + (fill-t1 (+ border-t1 (/ top-margin th))) (fill-s2 (- border-s2 (/ right-margin tw))) - (fill-t2 (- border-t2 (/ top-margin th)))) + (fill-t2 (- border-t2 (/ bottom-margin th)))) (define (draw-piece x1 y1 x2 y2 s1 t1 s2 t2) (set-rect-x! %rect x1) (set-rect-y! %rect y1) @@ -431,31 +433,31 @@ rendered entirely." (with-batched-sprites ;; bottom-left (draw-piece border-x1 border-y1 fill-x1 fill-y1 - border-s1 border-t1 fill-s1 fill-t1) + border-s1 fill-t2 fill-s1 border-t2) ;; bottom-center (draw-piece fill-x1 border-y1 fill-x2 fill-y1 - fill-s1 border-t1 fill-s2 fill-t1) + fill-s1 fill-t2 fill-s2 border-t2) ;; bottom-right (draw-piece fill-x2 border-y1 border-x2 fill-y1 - fill-s2 border-t1 border-s2 fill-t1) + fill-s2 fill-t2 border-s2 border-t2) ;; center-left (draw-piece border-x1 fill-y1 fill-x1 fill-y2 - border-s1 fill-t1 fill-s1 fill-t2) + border-s1 fill-t2 fill-s1 fill-t1) ;; center (draw-piece fill-x1 fill-y1 fill-x2 fill-y2 - fill-s1 fill-t1 fill-s2 fill-t2) + fill-s1 fill-t2 fill-s2 fill-t1) ;; center-right (draw-piece fill-x2 fill-y1 border-x2 fill-y2 - fill-s2 fill-t1 border-s2 fill-t2) + fill-s2 fill-t2 border-s2 fill-t1) ;; top-left (draw-piece border-x1 fill-y2 fill-x1 border-y2 - border-s1 fill-t2 fill-s1 border-t2) + border-s1 border-t1 fill-s1 fill-t1) ;; top-center (draw-piece fill-x1 fill-y2 fill-x2 border-y2 - fill-s1 fill-t2 fill-s2 border-t2) + fill-s1 border-t1 fill-s2 fill-t1) ;; top-right (draw-piece fill-x2 fill-y2 border-x2 border-y2 - fill-s2 fill-t2 border-s2 border-t2)))))) + fill-s2 border-t1 border-s2 fill-t1)))))) (define draw-nine-patch (let ((position (vec2 0.0 0.0)) diff --git a/chickadee/render/texture.scm b/chickadee/render/texture.scm index 960b7d0..4214c70 100644 --- a/chickadee/render/texture.scm +++ b/chickadee/render/texture.scm @@ -233,12 +233,7 @@ the given MIN-FILTER and MAG-FILTER." (lambda (surface) (let* ((width (surface-width surface)) (height (surface-height surface)) - ;; OpenGL textures use the bottom-left corner as the - ;; origin, whereas SDL uses the top-left, so the rows - ;; of pixels must be reversed before creating a - ;; texture from them. - (pixels (flip-pixels-vertically (surface-pixels surface) - width height))) + (pixels (surface-pixels surface))) (make-texture pixels width height #:min-filter min-filter #:mag-filter mag-filter diff --git a/chickadee/render/tiled.scm b/chickadee/render/tiled.scm index 42b6793..51f2cb9 100644 --- a/chickadee/render/tiled.scm +++ b/chickadee/render/tiled.scm @@ -230,17 +230,12 @@ (duration (attr node 'duration string->number))) ;; TODO: lookup actual tile in tileset (%make-animation-frame tile-id duration))) - (define (invert-tile-id id rows columns) - (let* ((x (modulo id columns)) - (y (- rows (floor (/ id columns)) 1)) - (t (+ (* y columns) x))) - (+ (* y columns) x))) (define (parse-tile node rows columns atlas) (let ((id (attr node 'id string->number)) (animation (map parse-frame ((sxpath '(animation frame)) node))) (properties (map parse-property ((sxpath '(properties property)) node)))) - (%make-tile id (texture-atlas-ref atlas (invert-tile-id id rows columns)) + (%make-tile id (texture-atlas-ref atlas id) animation properties))) (define (parse-tiles nodes size columns atlas) (let ((table (make-hash-table)) @@ -254,8 +249,7 @@ (when (< i size) (let ((tile (or (hash-ref table i) - (let* ((t (invert-tile-id i rows columns))) - (%make-tile i (texture-atlas-ref atlas t) #f '()))))) + (%make-tile i (texture-atlas-ref atlas i) #f '())))) (vector-set! tiles i tile)) (loop (+ i 1)))) tiles)) -- cgit v1.2.3