From 1054cbd906ced5cb38476b00700aa8c279f6e1c8 Mon Sep 17 00:00:00 2001 From: Leo Prikler Date: Tue, 29 Sep 2020 11:10:32 +0200 Subject: Add blend mode bindings. --- Makefile.am | 1 + doc/api.texi | 100 +++++++++++++++++++++++++++++++++++++ sdl2/bindings.scm | 35 +++++++++++++ sdl2/blend-mode.scm | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sdl2/render.scm | 7 +++ 5 files changed, 282 insertions(+) create mode 100644 sdl2/blend-mode.scm diff --git a/Makefile.am b/Makefile.am index ecf18a2..287a19c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,6 +44,7 @@ SOURCES = \ sdl2.scm \ sdl2/config.scm \ sdl2/bindings.scm \ + sdl2/blend-mode.scm \ sdl2/clipboard.scm \ sdl2/rect.scm \ sdl2/surface.scm \ diff --git a/doc/api.texi b/doc/api.texi index 6ee2187..20c7e20 100644 --- a/doc/api.texi +++ b/doc/api.texi @@ -6,6 +6,7 @@ * Rects:: 2D rectangles. * Surfaces:: Software rendering. * Rendering:: Hardware accelerated rendering. +* Blend Modes:: Color blending. * Images:: Loading and saving images. * Sound:: Sound effects and music. * Fonts:: Truetype and bitmap font rendering. @@ -1062,6 +1063,11 @@ color channels @var{r}, @var{g}, @var{b}, @var{a}. Each color channel value is in the range [0, 255]. @end deffn +@deffn {Procedure} set-render-draw-blend-mode renderer blend-mode +Set blend mode of @var{renderer} to @var{blend-mode}. @xref{Blend +Modes} for more information. +@end deffn + @deffn {Procedure} render-draw-line renderer x1 y1 x2 y2 Draw a line from (@var{x1}, @var{y1}) to (@var{x2}, @var{y2}) on the current rendering target of @var{renderer}. @@ -1146,6 +1152,100 @@ Set the color mod of @var{texture}. Set the alpha mod of @var{texture}. @end deffn +@node Blend Modes +@section Blend Modes + +@example +(use-modules (sdl2 blend-mode)) +@end example + +SDL2 provides several of the most commonly used blend modes: + +@defvar none +No blending. +@end defvar + +@defvar blend +Alpha blending. +@end defvar + +@defvar add +Additive blending. +@end defvar + +@defvar mul +Multiplicative blending. +@end defvar + +@defvar mod +Color modulation. +@end defvar + +Custom blend modes can be created using the @code{make-blend-mode} +procedure. + +@deffn {Procedure} make-blend-mode src-color-factor dst-color-factor color-operation src-alpha-factor dst-alpha-factor alpha-operation +Return a new custom blend mode for renderers. + +@var{src-color-factor} applies to the red, green, and blue components +of the source pixels. + +@var{dst-color-factor} applies to the red, green, and blue components of the +destination pixels. + +@var{color-operation} specifies how to combine the red, green, and blue +components of the source and destination pixels. + +@var{src-alpha-factor} applies to the alpha component of the source pixels. + +@var{dst-alpha-factor} applies to the alpha component of the destination +pixels. + +@var{alpha-operation} specifies how to combine the alpha component of the +source and destination pixels. + +Possible values for factors are @code{zero}, @code{one}, +@code{src-color}, @code{one-minus-src-color}, @code{src-alpha}, +@code{one-minus-src-alpha}, @code{dst-color}, +@code{one-minus-dst-color}, @code{dst-alpha}, and @code{one-minus-dst +alpha}. + +Possible values for operations are @code{add}, @code{subtract}, +@code{rev-subtract}, @code{minimum}, and @code{maximum}. +@end deffn + +@deffn {Procedure} blend-mode? obj +Return @code{#t} if @var{obj} is a blend mode object. +@end deffn + +@deffn {Procedure} blend-mode-src-color-factor blend-mode +Return the source red, green, and blue channel blend factor for +@var{blend-mode}. +@end deffn + +@deffn {Procedure} blend-mode-dst-color-factor blend-mode +Return the destination red, green, and blue channel blend factor for +@var{blend-mode}. +@end deffn + +@deffn {Procedure} blend-mode-color-operation blend-mode +Return the red, green, and blue channel blend operation for +@var{blend-mode}. +@end deffn + +@deffn {Procedure} blend-mode-src-alpha-factor blend-mode +Return the source alpha channel blend factor for @var{blend-mode}. +@end deffn + +@deffn {Procedure} blend-mode-dst-alpha-factor blend-mode +Return the destination alpha channel blend factor for +@var{blend-mode}. +@end deffn + +@deffn {Procedure} blend-mode-alpha-operation blend-mode +Return the alpha channel blend operation for @var{blend-mode}. +@end deffn + @node Images @section Images diff --git a/sdl2/bindings.scm b/sdl2/bindings.scm index 238320c..d2f3bbe 100644 --- a/sdl2/bindings.scm +++ b/sdl2/bindings.scm @@ -98,6 +98,38 @@ RETURN-TYPE and accept arguments of ARG-TYPES." (define-foreign sdl-get-version void "SDL_GetVersion" '(*)) + +;;; +;;; Blend Mode +;;; + +(define-public SDL_BLENDMODE_NONE #x00000000) +(define-public SDL_BLENDMODE_BLEND #x00000001) +(define-public SDL_BLENDMODE_ADD #x00000002) +(define-public SDL_BLENDMODE_MOD #x00000004) +(define-public SDL_BLENDMODE_MUL #x00000008) +(define-public SDL_BLENDMODE_INVALID #x7fffffff) + +(define-public SDL_BLENDOPERATION_ADD #x1) +(define-public SDL_BLENDOPERATION_SUBTRACT #x2) +(define-public SDL_BLENDOPERATION_REV_SUBTRACT #x3) +(define-public SDL_BLENDOPERATION_MINIMUM #x4) +(define-public SDL_BLENDOPERATION_MAXIMUM #x5) + +(define-public SDL_BLENDFACTOR_ZERO #x1) +(define-public SDL_BLENDFACTOR_ONE #x2) +(define-public SDL_BLENDFACTOR_SRC_COLOR #x3) +(define-public SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR #x4) +(define-public SDL_BLENDFACTOR_SRC_ALPHA #x5) +(define-public SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA #x6) +(define-public SDL_BLENDFACTOR_DST_COLOR #x7) +(define-public SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR #x8) +(define-public SDL_BLENDFACTOR_DST_ALPHA #x9) +(define-public SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA #xa) + +(define-foreign sdl-compose-custom-blend-mode + int "SDL_ComposeCustomBlendMode" (list int int int int int int)) + ;;; ;;; Video @@ -271,6 +303,9 @@ RETURN-TYPE and accept arguments of ARG-TYPES." (define-foreign sdl-get-texture-alpha-mod int "SDL_GetTextureAlphaMod" '(* *)) +(define-foreign sdl-set-render-draw-blend-mode + int "SDL_SetRenderDrawBlendMode" (list '* int)) + (define-foreign sdl-set-render-draw-color int "SDL_SetRenderDrawColor" (list '* uint8 uint8 uint8 uint8)) diff --git a/sdl2/blend-mode.scm b/sdl2/blend-mode.scm new file mode 100644 index 0000000..d73c999 --- /dev/null +++ b/sdl2/blend-mode.scm @@ -0,0 +1,139 @@ +;;; guile-sdl2 --- FFI bindings for SDL2 +;;; Copyright © 2020 Leo Prikler +;;; Copyright © 2020 David Thompson +;;; +;;; This file is part of guile-sdl2. +;;; +;;; Guile-sdl2 is free software; you can redistribute it and/or modify +;;; it under the terms of the GNU Lesser General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; Guile-sdl2 is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU Lesser General Public +;;; License along with guile-sdl2. If not, see +;;; . + +(define-module (sdl2 blend-mode) + #:use-module (ice-9 match) + #:use-module (srfi srfi-9) + #:use-module (sdl2) + #:use-module ((sdl2 bindings) #:prefix ffi:) + #:export (make-blend-mode + blend-mode? + blend-mode-src-color-factor + blend-mode-dst-color-factor + blend-mode-color-operation + blend-mode-src-alpha-factor + blend-mode-dst-alpha-factor + blend-mode-alpha-operation + none + blend + add + mod + mul)) + +(define-record-type + (%make-blend-mode src-color-factor dst-color-factor color-operation + src-alpha-factor dst-alpha-factor alpha-operation + bitmask) + blend-mode? + (src-color-factor blend-mode-src-color-factor) + (dst-color-factor blend-mode-dst-color-factor) + (color-operation blend-mode-color-operation) + (src-alpha-factor blend-mode-src-alpha-factor) + (dst-alpha-factor blend-mode-dst-alpha-factor) + (alpha-operation blend-mode-alpha-operation) + (bitmask blend-mode-bitmask)) + +(define none + (%make-blend-mode 'one 'zero 'add 'one 'zero 'add + ffi:SDL_BLENDMODE_NONE)) + +(define blend + (%make-blend-mode 'src-alpha 'one-minus-src-alpha 'add + 'one 'one-minus-src-alpha 'add + ffi:SDL_BLENDMODE_BLEND)) + +(define add + (%make-blend-mode 'src-alpha 'one 'add + 'zero 'one 'add + ffi:SDL_BLENDMODE_ADD)) + +(define mod + (%make-blend-mode 'zero 'src-color 'add + 'zero 'one 'add + ffi:SDL_BLENDMODE_MOD)) + +(define mul + (%make-blend-mode 'dst-color 'one-minus-src-alpha 'add + 'dst-alpha 'one-minus-src-alpha 'add + ffi:SDL_BLENDMODE_MUL)) + +(define (make-blend-mode src-color-factor dst-color-factor color-operation + src-alpha-factor dst-alpha-factor alpha-operation) + "Return a new custom blend mode for renderers. + +SRC-COLOR-FACTOR applies to the red, green, and blue components of the +source pixels. + +DST-COLOR-FACTOR applies to the red, green, and blue components of the +destination pixels. + +COLOR-OPERATION specifies how to combine the red, green, and blue +components of the source and destination pixels. + +SRC-ALPHA-FACTOR applies to the alpha component of the source pixels. + +DST-ALPHA-FACTOR applies to the alpha component of the destination +pixels. + +ALPHA-OPERATION specifies how to combine the alpha component of the +source and destination pixels. + +Possible values for factors are zero, one, src-color, +one-minus-src-color, src-alpha, one-minus-src-alpha, dst-color, +one-minus-dst-color, dst-alpha, and one-minus-dst alpha. + +Possible values for operations are add, subtract, rev-subtract, +minimum, and maximum." + (define symbol->blend-operation + (match-lambda + ('add ffi:SDL_BLENDOPERATION_ADD) + ('subtract ffi:SDL_BLENDOPERATION_SUBTRACT) + ('rev-subtract ffi:SDL_BLENDOPERATION_REV_SUBTRACT) + ('minimum ffi:SDL_BLENDOPERATION_MINIMUM) + ('maximum ffi:SDL_BLENDOPERATION_MAXIMUM))) + (define symbol->blend-factor + (match-lambda + ('zero ffi:SDL_BLENDFACTOR_ZERO) + ('one ffi:SDL_BLENDFACTOR_ONE) + ('src-color ffi:SDL_BLENDFACTOR_SRC_COLOR) + ('one-minus-src-color ffi:SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR) + ('src-alpha ffi:SDL_BLENDFACTOR_SRC_ALPHA) + ('one-minus-src-alpha ffi:SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA) + ('dst-color ffi:SDL_BLENDFACTOR_DST_COLOR) + ('one-minus-dst-color ffi:SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR) + ('dst-alpha ffi:SDL_BLENDFACTOR_DST_ALPHA) + ('one-minus-dst-alpha ffi:SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA))) + (let ((bitmask (ffi:sdl-compose-custom-blend-mode + (symbol->blend-factor src-color-factor) + (symbol->blend-factor dst-color-factor) + (symbol->blend-operation color-operation) + (symbol->blend-factor src-alpha-factor) + (symbol->blend-factor dst-alpha-factor) + (symbol->blend-operation alpha-operation)))) + (if (eq? bitmask ffi:SDL_BLENDMODE_INVALID) + (sdl-error "make-blend-mode" + "invalid custom blend mode") + (%make-blend-mode src-color-factor + dst-color-factor + color-operation + src-alpha-factor + dst-alpha-factor + alpha-operation + bitmask)))) diff --git a/sdl2/render.scm b/sdl2/render.scm index f937eca..6a9c0b2 100644 --- a/sdl2/render.scm +++ b/sdl2/render.scm @@ -41,6 +41,7 @@ set-render-target! get-render-target set-render-draw-color + set-render-draw-blend-mode render-draw-line render-draw-lines render-draw-point @@ -121,6 +122,12 @@ color." "Display RENDERER." (ffi:sdl-render-present (unwrap-renderer renderer))) +(define (set-render-draw-blend-mode renderer blend-mode) + "Set blend mode of RENDERER to BLEND-MODE." + (ffi:sdl-set-render-draw-blend-mode + (unwrap-renderer renderer) + ((@@ (sdl2 blend-mode) blend-mode-bitmask) blend-mode))) + (define (set-render-draw-color renderer r g b a) "Set draw color of RENDERER." (ffi:sdl-set-render-draw-color (unwrap-renderer renderer) r g b a)) -- cgit v1.2.3