10 Textures
This section covers texture loading, creation, manipulation, and rendering. Textures are GPU-accelerated images that can be rendered efficiently.
10.1 Loading Textures
procedure
(load-texture renderer source [ #:type type #:custodian cust]) → texture? renderer : renderer? source : (or/c string? path? bytes? input-port?) type : (or/c symbol? string? #f) = #f cust : custodian? = (current-custodian)
A file path (string or path)
Bytes containing image data
An input port
Supported formats include PNG, JPEG, BMP, GIF, and others via SDL_image.
The #:type hint specifies the image format when loading from bytes or a port. Use symbols like 'png, 'jpg, etc.
;; Load from file (define tex (load-texture ren "sprites/player.png")) ;; Load from bytes with format hint (define tex2 (load-texture ren image-bytes #:type 'png))
procedure
(texture-ptr tex) → cpointer?
tex : texture?
procedure
(texture-destroy! tex) → void?
tex : texture?
Note: Textures are automatically destroyed when their custodian shuts down, so manual destruction is usually not necessary.
10.2 Creating Textures
procedure
(create-texture renderer width height [ #:access access #:scale scale #:format format #:custodian cust]) → texture? renderer : renderer? width : exact-nonnegative-integer? height : exact-nonnegative-integer? access : (or/c 'static 'streaming 'target) = 'target scale : (or/c 'nearest 'linear) = 'nearest format : exact-nonnegative-integer? = SDL_PIXELFORMAT_RGBA8888 cust : custodian? = (current-custodian)
'static —
Texture rarely changes, not lockable 'streaming —
Texture changes frequently, lockable for CPU access 'target —
Can be used as a render target
'nearest —
Nearest-neighbor sampling (pixelated look) 'linear —
Linear filtering (smooth scaling)
;; Create a render target texture (define target (create-texture ren 256 256 #:access 'target)) ;; Create a streaming texture for dynamic updates (define dynamic-tex (create-texture ren 64 64 #:access 'streaming))
procedure
(texture-from-pointer ptr [#:custodian cust]) → texture?
ptr : cpointer? cust : custodian? = (current-custodian)
The texture will be registered with the custodian for automatic cleanup.
10.3 Texture Properties
procedure
(texture-size tex) →
real? real? tex : texture?
10.3.1 Scale Mode
procedure
(texture-set-scale-mode! tex mode) → void?
tex : texture? mode : (or/c 'nearest 'linear)
procedure
(texture-get-scale-mode tex) → symbol?
tex : texture?
10.3.2 Blend Mode
procedure
(set-texture-blend-mode! tex mode) → void?
tex : texture? mode : (or/c symbol? exact-nonnegative-integer?)
'none —
No blending 'blend —
Alpha blending 'add —
Additive blending 'mod —
Color modulation 'mul —
Multiplicative blending
procedure
(get-texture-blend-mode tex) → symbol?
tex : texture?
10.4 Color and Alpha Modulation
Color modulation tints the texture. Alpha modulation controls transparency.
Values are 0-255. The default (255, 255, 255) means no tint.
;; Tint texture red (texture-set-color-mod! tex 255 100 100) ;; Remove tint (texture-set-color-mod! tex 255 255 255)
procedure
(texture-get-color-mod tex) →
byte? byte? byte? tex : texture?
procedure
(texture-set-alpha-mod! tex alpha) → void?
tex : texture? alpha : byte?
0 = fully transparent, 255 = fully opaque.
procedure
(texture-get-alpha-mod tex) → byte?
tex : texture?
10.4.1 Float Color/Alpha Modulation
For extended range and precision, float versions are available:
procedure
(texture-set-color-mod-float! tex r g b) → void?
tex : texture? r : real? g : real? b : real?
procedure
(texture-get-color-mod-float tex) →
real? real? real? tex : texture?
procedure
(texture-set-alpha-mod-float! tex alpha) → void?
tex : texture? alpha : real?
procedure
(texture-get-alpha-mod-float tex) → real?
tex : texture?
10.5 Rendering Textures
procedure
(render-texture! renderer texture x y [ #:width width #:height height #:src-x src-x #:src-y src-y #:src-w src-w #:src-h src-h #:angle angle #:center center #:flip flip]) → void? renderer : renderer? texture : texture? x : real? y : real? width : (or/c real? #f) = #f height : (or/c real? #f) = #f src-x : (or/c real? #f) = #f src-y : (or/c real? #f) = #f src-w : (or/c real? #f) = #f src-h : (or/c real? #f) = #f angle : (or/c real? #f) = #f center : (or/c (cons/c real? real?) #f) = #f flip : (or/c 'none 'horizontal 'vertical 'both #f) = #f
#:width, #:height —
Scale the texture to this size #:src-x, #:src-y, #:src-w, #:src-h —
Render only a portion of the texture (sprite sheet support) #:angle —
Rotation in degrees (clockwise) #:center —
Rotation center as (cons x y), defaults to texture center #:flip —
Flip the texture horizontally, vertically, or both
;; Simple render at position (render-texture! ren tex 100 100) ;; Scale to specific size (render-texture! ren tex 100 100 #:width 64 #:height 64) ;; Render a sprite from a sprite sheet (render-texture! ren sprites 100 100 #:src-x (* frame 32) #:src-y 0 #:src-w 32 #:src-h 32) ;; Rotate 45 degrees (render-texture! ren tex 100 100 #:angle 45.0) ;; Flip horizontally (for character facing) (render-texture! ren tex 100 100 #:flip 'horizontal)
procedure
(render-texture-affine! renderer texture origin right down [ #:src-x src-x #:src-y src-y #:src-w src-w #:src-h src-h]) → void? renderer : renderer? texture : texture? origin : (or/c (cons/c real? real?) #f) right : (or/c (cons/c real? real?) #f) down : (or/c (cons/c real? real?) #f) src-x : (or/c real? #f) = #f src-y : (or/c real? #f) = #f src-w : (or/c real? #f) = #f src-h : (or/c real? #f) = #f
This allows for skewing, shearing, and other 2D transformations.
origin —
Where the top-left corner appears right —
Where the top-right corner appears down —
Where the bottom-left corner appears
The bottom-right is inferred from these three points.
procedure
(render-texture-tiled! renderer texture dst-x dst-y dst-w dst-h [ #:scale scale #:src-x src-x #:src-y src-y #:src-w src-w #:src-h src-h]) → void? renderer : renderer? texture : texture? dst-x : real? dst-y : real? dst-w : real? dst-h : real? scale : real? = 1.0 src-x : (or/c real? #f) = #f src-y : (or/c real? #f) = #f src-w : (or/c real? #f) = #f src-h : (or/c real? #f) = #f
Useful for repeating patterns like backgrounds and floors.
;; Tile a grass texture across the ground (render-texture-tiled! ren grass-tex 0 400 800 200)
procedure
(render-texture-9grid! renderer texture dst-x dst-y dst-w dst-h #:left-width left-width #:right-width right-width #:top-height top-height #:bottom-height bottom-height [ #:scale scale #:src-x src-x #:src-y src-y #:src-w src-w #:src-h src-h]) → void? renderer : renderer? texture : texture? dst-x : real? dst-y : real? dst-w : real? dst-h : real? left-width : real? right-width : real? top-height : real? bottom-height : real? scale : real? = 1.0 src-x : (or/c real? #f) = #f src-y : (or/c real? #f) = #f src-w : (or/c real? #f) = #f src-h : (or/c real? #f) = #f
This is ideal for UI elements like buttons and panels that need to scale without distorting corners.
The texture is divided into 9 regions: 4 corners (which don’t scale), 4 edges (which scale in one direction), and a center (which scales in both).
10.6 Render Targets
Textures created with #:access 'target can be used as render targets, allowing you to draw onto them instead of the screen.
procedure
(set-render-target! renderer texture) → void?
renderer : renderer? texture : (or/c texture? #f)
Pass #f to restore rendering to the default target (the window).
;; Draw to an offscreen texture (define offscreen (create-texture ren 256 256 #:access 'target)) (set-render-target! ren offscreen) (set-draw-color! ren 0 0 0) (render-clear! ren) (set-draw-color! ren 255 0 0) (fill-rect! ren 10 10 50 50) ;; Restore normal rendering and use the texture (set-render-target! ren #f) (render-texture! ren offscreen 100 100)
procedure
(get-render-target renderer) → (or/c texture? #f)
renderer : renderer?
syntax
(with-render-target renderer texture body ...)
(with-render-target ren offscreen (set-draw-color! ren 0 0 0) (render-clear! ren) (draw-scene-to-texture!))
10.7 Texture Updates and Locking
For streaming textures, you can update pixel data directly.
procedure
(texture-update! texture pixels pitch [ #:rect rect]) → void? texture : texture? pixels : (or/c bytes? cpointer?) pitch : exact-nonnegative-integer? rect : (or/c (list/c real? real? real? real?) #f) = #f
pitch is the number of bytes per row in the source data. rect specifies the region to update as (list x y w h), or #f for the entire texture.
procedure
(texture-lock! texture [#:rect rect])
→
cpointer? exact-nonnegative-integer? texture : texture? rect : (or/c (list/c real? real? real? real?) #f) = #f
Returns a pointer to the pixel data and the pitch (bytes per row). Call texture-unlock! when done.
procedure
(texture-unlock! texture) → void?
texture : texture?
procedure
(call-with-locked-texture texture proc [ #:rect rect]) → any texture : texture?
proc :
(-> cpointer? exact-nonnegative-integer? exact-nonnegative-integer? exact-nonnegative-integer? any) rect : (or/c (list/c real? real? real? real?) #f) = #f
The procedure receives: pixels-pointer, width, height, pitch.
(call-with-locked-texture tex (lambda (pixels w h pitch) ;; Modify pixels directly (for ([y (in-range h)]) (for ([x (in-range w)]) (define offset (+ (* y pitch) (* x 4))) ;; Set pixel to red (RGBA) (ptr-set! pixels _uint8 offset 255) (ptr-set! pixels _uint8 (+ offset 1) 0) (ptr-set! pixels _uint8 (+ offset 2) 0) (ptr-set! pixels _uint8 (+ offset 3) 255)))))
10.8 Flip Mode Conversion
procedure
sym : symbol?
Symbols: 'none, 'horizontal (or 'h), 'vertical (or 'v), 'both (or 'hv).
procedure
(flip-mode->symbol mode) → symbol?
mode : exact-nonnegative-integer?
10.9 Access Mode Conversion
procedure
sym : symbol?
Symbols: 'static, 'streaming, 'target.
procedure
(texture-access->symbol mode) → symbol?
mode : exact-nonnegative-integer?
10.10 Scale Mode Conversion
procedure
sym : symbol?
Symbols: 'nearest, 'linear.
procedure
(scale-mode->symbol mode) → symbol?
mode : exact-nonnegative-integer?