;;; Sly ;;; Copyright (C) 2014, 2015 David Thompson ;;; ;;; Sly is free software: you can redistribute it and/or modify it ;;; under the terms of the GNU General Public License as published by ;;; the Free Software Foundation, either version 3 of the License, or ;;; (at your option) any later version. ;;; ;;; Sly 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 General Public License ;;; along with this program. If not, see ;;; . ;;; Commentary: ;; ;; Viewports. ;; ;;; Code: (define-module (sly render viewport) #:use-module (ice-9 match) #:use-module (srfi srfi-9) #:use-module (gl) #:use-module (gl low-level) #:use-module (sly wrappers gl) #:use-module (sly math rect) #:use-module (sly utils) #:use-module (sly render color) #:export (make-viewport viewport? viewport-area viewport-clear-color viewport-clear-flags null-viewport %standard-clear-flags apply-viewport clear-viewport)) ;;; ;;; Viewport ;;; (define-record-type (%make-viewport area clear-color clear-flags) viewport? (area viewport-area) (clear-color viewport-clear-color) (clear-flags viewport-clear-flags)) (define %standard-clear-flags '(color-buffer depth-buffer)) (define* (make-viewport area #:optional #:key (clear-color black) (clear-flags %standard-clear-flags)) "Create a viewport that covers the rectangle AREA of the window. Fill the viewport with CLEAR-COLOR when clearing the screen. Clear the buffers denoted by the list of symbols in CLEAR-FLAGS. Possible values for CLEAR-FLAGS are 'color-buffer', 'depth-buffer', 'accum-buffer', and 'stencil-buffer'." (%make-viewport area clear-color clear-flags)) (define null-viewport (make-viewport (make-rect 0 0 0 0))) (define clear-buffer-mask (memoize (lambda (flags) (apply logior ;; Map symbols to OpenGL constants. (map (match-lambda ('depth-buffer 256) ('accum-buffer 512) ('stencil-buffer 1024) ('color-buffer 16384)) flags))))) (define (apply-viewport viewport) "Set the OpenGL state for VIEWPORT. Clip rendering to the viewport area, set the clear color, and clear necessary buffers." (gl-enable (enable-cap scissor-test)) (let* ((rect (viewport-area viewport)) (x (inexact->exact (rect-x rect))) (y (inexact->exact (rect-y rect))) (width (inexact->exact (rect-width rect))) (height (inexact->exact (rect-height rect)))) (gl-viewport x y width height) (gl-scissor x y width height)) (match (viewport-clear-color viewport) (($ r g b a) (gl-clear-color r g b a)))) (define (clear-viewport viewport) "Clear the relevant OpenGL buffers VIEWPORT." (gl-clear (clear-buffer-mask (viewport-clear-flags viewport))))