render: buffer: Add divisor field to typed buffers.
authorDavid Thompson <dthompson2@worcester.edu>
Thu, 25 Oct 2018 12:44:48 +0000 (08:44 -0400)
committerDavid Thompson <dthompson2@worcester.edu>
Thu, 25 Oct 2018 12:44:48 +0000 (08:44 -0400)
* chickadee/render/buffer.scm (<typed-buffer>)[divisor]: New field.
(typed-buffer-divisor): New procedure.
(make-typed-buffer, make-streaming-typed-buffer): Add #:divisor argument.
(apply-typed-buffer): Setup vertex attribute divisor if there is one.

chickadee/render/buffer.scm

index 686197c..83a2925 100644 (file)
@@ -66,6 +66,7 @@
             typed-buffer-min
             typed-buffer-sparse
             typed-buffer-data
+            typed-buffer-divisor
             map-typed-buffer!
             unmap-typed-buffer!
             with-mapped-typed-buffer
@@ -221,7 +222,7 @@ vertex buffer data back to the GPU."
 
 (define-record-type <typed-buffer>
   (%make-typed-buffer name buffer offset component-type
-                      normalized? length type max min sparse)
+                      normalized? length type max min sparse divisor)
   typed-buffer?
   (name typed-buffer-name)
   (buffer typed-buffer->buffer)
@@ -232,7 +233,8 @@ vertex buffer data back to the GPU."
   (type typed-buffer-type)
   (max typed-buffer-max)
   (min typed-buffer-min)
-  (sparse typed-buffer-sparse))
+  (sparse typed-buffer-sparse)
+  (divisor typed-buffer-divisor)) ; for instanced rendering
 
 (define (typed-buffer-stride typed-buffer)
   (or (buffer-stride (typed-buffer->buffer typed-buffer))
@@ -260,9 +262,10 @@ vertex buffer data back to the GPU."
                                                   component-type))
                             max
                             min
-                            sparse)
+                            sparse
+                            divisor)
   (%make-typed-buffer name buffer offset component-type
-                      normalized? length type max min sparse))
+                      normalized? length type max min sparse divisor))
 
 (define (type-size type)
   (match type
@@ -285,11 +288,14 @@ vertex buffer data back to the GPU."
 (define* (make-streaming-typed-buffer type component-type length #:key
                                       (name "anonymous")
                                       (target 'vertex)
-                                      data)
+                                      data
+                                      divisor)
   "Return a new typed buffer to hold LENGTH elements of TYPE whose
 components are comprised of COMPONENT-TYPE values.  The underlying
 untyped buffer is configured for GPU streaming.  Optonally, a NAME can
-be specified for the buffer."
+be specified for the buffer.  If the buffer will be used for instanced
+rendering, the DIVISOR argument must be used to specify the rate at
+which attributes advance when rendering multiple instances."
   (let* ((buffer-length
           (* length (type-size type) (component-type-size component-type)))
          (buffer (if data
@@ -305,7 +311,8 @@ be specified for the buffer."
                        #:buffer buffer
                        #:type type
                        #:component-type component-type
-                       #:length length)))
+                       #:length length
+                       #:divisor divisor)))
 
 (define (display-typed-buffer typed-buffer port)
   (format port "#<typed-buffer name: ~s buffer: ~a type: ~s component-type: ~s length: ~d offset: ~d>"
@@ -353,7 +360,10 @@ be specified for the buffer."
                               (typed-buffer-type-gl typed-buffer)
                               (typed-buffer-normalized? typed-buffer)
                               (typed-buffer-stride typed-buffer)
-                              (make-pointer (typed-buffer-offset typed-buffer)))))
+                              (make-pointer (typed-buffer-offset typed-buffer)))
+    (let ((divisor (typed-buffer-divisor typed-buffer)))
+      (when divisor
+        (gl-vertex-attrib-divisor attribute-index divisor)))))
 
 ;; TODO: Handle 4-byte alignment rule for the types that need it.
 (define (typed-buffer->vector typed-buffer)