On this page:
14.1 Curried Projector
make-projector
14.2 On-Screen Triangle Geometry
triangle-counter-clockwise?
triangle-make-counter-clockwise
triangle-area
14.3 Renderer Camera
make-camera
camera?
move-camera*
move-camera
resize-camera
rotate-camera
rotate-camera-rel
camera-worldview
camera-projection
camera-fov/  2
camera-fov
14.4 Positional Lighting
make-lightsrc
lightsrc?
move-lightsrc
colorize-lightsrc
apply-lightsrc
apply-lightsrc*
triangle-normal
14.5 Renderer
make-renderer
renderer?
finish-renderer
render-triangle
render-quad
8.10

14 RRLL: Renderer

Dominik Pantůček <dominik.pantucek@trustica.cz>

Racket Rogue-Like Library: 3D renderer.

14.1 Curried Projector

 (require rrll/renderer/projector) package: rrll-renderer

Camera projection in a curried form.

procedure

((make-projector near    
  far    
  width    
  height    
  [pixel-aspect])    
  flv4)  
fixnum? fixnum? flonum?
  near : flonum?
  far : flonum?
  width : fixnum?
  height : fixnum?
  pixel-aspect : flonum? = 1.0
  flv4 : flvector?
Returns simple projector that can be used without camera management.

14.2 On-Screen Triangle Geometry

 (require rrll/renderer/geometry) package: rrll-renderer

This module is a helper for recognizing clockwise and counter-clockwise triangles on screen. It also allows computing the number of pixels within a given on-screen triangle.

procedure

(triangle-counter-clockwise? x1 y1 x2 y2 x3 y3)  boolean?

  x1 : fixnum?
  y1 : fixnum?
  x2 : fixnum?
  y2 : fixnum?
  x3 : fixnum?
  y3 : fixnum?
Returns #t if the vertices are ordered clockwise on screen.

procedure

(triangle-make-counter-clockwise x1    
  y1    
  x2    
  y2    
  x3    
  y3)  
fixnum?
fixnum?
fixnum?
fixnum?
fixnum?
fixnum?
  x1 : fixnum?
  y1 : fixnum?
  x2 : fixnum?
  y2 : fixnum?
  x3 : fixnum?
  y3 : fixnum?
Returns the vertices in the counter-clockwise order.

procedure

(triangle-area x1 y1 x2 y2 x3 y3)  fixnum?

  x1 : fixnum?
  y1 : fixnum?
  x2 : fixnum?
  y2 : fixnum?
  x3 : fixnum?
  y3 : fixnum?
Returns the number of pixels this triangle will cover on the screen.

14.3 Renderer Camera

 (require rrll/camera) package: rrll-renderer

This module implements a camera that is used for worldview and projection transformations upon actual rendering.

procedure

(make-camera width    
  height    
  [#:pos pos    
  #:aspect aspect    
  #:azimuth azimuth    
  #:inclination inclination    
  #:shear shear    
  #:far far])  camera?
  width : fixnum?
  height : fixnum?
  pos : flvector? = (flvec4)
  aspect : (or/c 'halves 'quads 'slc flonum?) = 1.0
  azimuth : flonum? = 0.0
  inclination : flonum? = 0.0
  shear : flonum? = 0.0
  far : flonum? = 100.0
{

Creates a new camera struct with given fields.

}

procedure

(camera? v)  boolean?

  v : any/c
Returns #t if the given values is a camera struct.

procedure

(move-camera* cam x y z)  camera?

  cam : camera?
  x : flonum?
  y : flonum?
  z : flonum?
Returns a new camera positioned at given coordinates. Other fields are kept intact.

procedure

(move-camera cam pos)  camera?

  cam : camera?
  pos : flvector?
Sets camera position to the one given.

procedure

(resize-camera cam    
  width    
  height    
  [#:aspect aspect    
  #:far far])  camera?
  cam : camera?
  width : fixnum?
  height : fixnum?
  aspect : (or/c #f 'halves 'quads 'slc flonum?) = #f
  far : (or/c #f flonum?) = #f
Changes the camera attributes. If aspect and/or far are non-#f, they are changed as well. This allows for changing rendering targets on the fly.

procedure

(rotate-camera cam    
  [#:azimuth azimuth    
  #:inclination inclination    
  #:shear shear])  camera?
  cam : camera?
  azimuth : (or/c #f flonum?) = #f
  inclination : (or/c #f flonum?) = #f
  shear : (or/c #f flonum?) = #f
Sets the camera rotation. All #f angles are left intact.

procedure

(rotate-camera-rel cam    
  [#:azimuth azimuth    
  #:inclination inclination    
  #:shear shear])  camera?
  cam : camera?
  azimuth : flonum? = 0.0
  inclination : flonum? = 0.0
  shear : flonum? = 0.0
Adjusts camera rotation by given angle delta values.

procedure

(camera-worldview cam)  flvector?

  cam : camera?
Returns the worldview matrix of this camera:

M\times Y\times X\times Z\times T

See rrll/math/transform4 for more information.

procedure

(camera-projection cam)  flvector?

  cam : camera?
Returns the projection matrix of the camera.

procedure

(camera-fov/2 cam)  flonum?

  cam : camera?
Returns half the size of the field of view in radians.

procedure

(camera-fov cam)  flonum?

  cam : camera?
Returns the field of view in radians.

14.4 Positional Lighting

 (require rrll/renderer/lighting) package: rrll-renderer

This module provides infrastructure for using positional lights with the renderer.

procedure

(make-lightsrc pos rgb)  lightsrc?

  pos : flvector?
  rgb : flvector?
Creates a new positional light source.

procedure

(lightsrc? v)  boolean?

  v : any/c
Returns #t if given value is a positional light source.

procedure

(move-lightsrc ls pos)  lightsrc?

  ls : lightsrc?
  pos : flvector?
Sets the light source position to the value provided.

procedure

(colorize-lightsrc ls rgb)  lightsrc?

  ls : lightsrc?
  rgb : flvector?
Sets light source’s color.

procedure

(apply-lightsrc l v n)  flvector?

  l : lightsrc?
  v : flvector?
  n : flvector?

Applies light source l at location of vertex v with assumed normal vector of the plane the vertex is part of to be n. Returns flrgb?/fllight? value.

procedure

(apply-lightsrc* ls v n)  flvector

  ls : (listof lightsrc?)
  v : flvector?
  n : flvector?
Applies apply-lightsrc for all light sources given, producing a single resulting light to be applied by rasterizer.

procedure

(triangle-normal A B C)  flvector?

  A : flvector?
  B : flvector?
  C : flvector?
Returns normalized normal vector of the triangle given.

\vec{n_0}=(B-A)\times(C-A) \vec{n}=\frac{\vec{n_0}}{|\vec{n_0}}

14.5 Renderer

 (require rrll/renderer) package: rrll-renderer

This is the module that should be used for rendering 3D triangles onto a 2D canvas with given camera.

procedure

(make-renderer can cam)  renderer?

  can : canvas?
  cam : camera?
Creates a new renderer targetting given can canvas using the camera cam given.

procedure

(renderer? v)  boolean?

  v : any/c
Returns #t if given value v is a renderer.

procedure

(finish-renderer rdr)  void?

  rdr : renderer?
Finishes rendering on given renderer and associated rasterizer. Waits until all rasterization has been finished.

procedure

(render-triangle rdr    
  x1    
  y1    
  z1    
  x2    
  y2    
  z2    
  x3    
  y3    
  z3    
  [#:color color    
  #:c1 c1    
  #:c2 c2    
  #:c3 c3    
  #:u1 u1    
  #:u2 u2    
  #:u3 u3    
  #:v1 v1    
  #:v2 v2    
  #:v3 v3    
  #:l1 l1    
  #:l2 l2    
  #:l3 l3    
  #:tex tex    
  #:blending blending    
  #:alpha alpha    
  #:id id    
  #:lights lights    
  #:lights1 lights1    
  #:lights2 lights2    
  #:lights3 lights3    
  #:ambient ambient    
  #:ambient1 ambient1    
  #:ambient2 ambient2    
  #:ambient3 ambient3    
  #:wire wire    
  #:cw cw    
  #:ccw ccw    
  #:setw setw])  void?
  rdr : renderer?
  x1 : fixnum?
  y1 : fixnum?
  z1 : flonum?
  x2 : fixnum?
  y2 : fixnum?
  z2 : flonum?
  x3 : fixnum?
  y3 : fixnum?
  z3 : flonum?
  color : fixnum? = 16711935
  c1 : (or/c fixnum? #f) = #f
  c2 : (or/c fixnum? #f) = #f
  c3 : (or/c fixnum? #f) = #f
  u1 : (or/c flonum? #f) = #f
  u2 : (or/c flonum? #f) = #f
  u3 : (or/c flonum? #f) = #f
  v1 : (or/c flonum? #f) = #f
  v2 : (or/c flonum? #f) = #f
  v3 : (or/c flonum? #f) = #f
  l1 : (or/c flvector? #f) = #f
  l2 : (or/c flvector? #f) = #f
  l3 : (or/c flvector? #f) = #f
  tex : (or/c mipmap? #f) = #f
  blending : boolean? = #f
  alpha : (or/c (integer-in 0 255) #f) = #f
  id : fixnum? = 0
  lights : (or/c #f (listof lightsrc?)) = #f
  lights1 : (or/c #f (listof lightsrc?)) = #f
  lights2 : (or/c #f (listof lightsrc?)) = #f
  lights3 : (or/c #f (listof lightsrc?)) = #f
  ambient : (or/c #f flvector?) = #f
  ambient1 : (or/c #f flvector?) = #f
  ambient2 : (or/c #f flvector?) = #f
  ambient3 : (or/c #f flvector?) = #f
  wire : boolean? = #f
  cw : boolean? = #f
  ccw : boolean? = #t
  setw : boolean = #t
Renders given triangle in world coordinates using the renderer. Clipping against near plane is performed and the results are passed down to renderer’s rasterizer.

If wire is #t then for each triangle sent to rasterizer its bounding lines are emitted as well. This is used mainly for debugging purposes.

If lights and related is provided, it overrides explicit l1 and related values.

The flags cw and ccw specify whether the clockwise or counter-clockwise oriented triangles should be rasterized.

If setw is set to #f, the w-buffer is only tested, not updated.

procedure

(render-quad rdr    
  x1    
  y1    
  z1    
  x2    
  y2    
  z2    
  x3    
  y3    
  z3    
  x4    
  y4    
  z4    
  [#:color color    
  #:c1 c1    
  #:c2 c2    
  #:c3 c3    
  #:c4 c4    
  #:u1 u1    
  #:u2 u2    
  #:u3 u3    
  #:u4 u4    
  #:v1 v1    
  #:v2 v2    
  #:v3 v3    
  #:v4 v4    
  #:l1 l1    
  #:l2 l2    
  #:l3 l3    
  #:l4 l4    
  #:tex tex    
  #:blending blending    
  #:alpha alpha    
  #:id id    
  #:lights lights    
  #:lights1 lights1    
  #:lights2 lights2    
  #:lights3 lights3    
  #:lights4 lights4    
  #:ambient ambient    
  #:ambient1 ambient1    
  #:ambient2 ambient2    
  #:ambient3 ambient3    
  #:ambient4 ambient4    
  #:wire wire    
  #:cw cw    
  #:ccw ccw    
  #:setw setw])  void?
  rdr : renderer?
  x1 : fixnum?
  y1 : fixnum?
  z1 : flonum?
  x2 : fixnum?
  y2 : fixnum?
  z2 : flonum?
  x3 : fixnum?
  y3 : fixnum?
  z3 : flonum?
  x4 : fixnum?
  y4 : fixnum?
  z4 : flonum?
  color : fixnum? = 16711935
  c1 : (or/c fixnum? #f) = #f
  c2 : (or/c fixnum? #f) = #f
  c3 : (or/c fixnum? #f) = #f
  c4 : (or/c fixnum? #f) = #f
  u1 : (or/c flonum? #f) = #f
  u2 : (or/c flonum? #f) = #f
  u3 : (or/c flonum? #f) = #f
  u4 : (or/c flonum? #f) = #f
  v1 : (or/c flonum? #f) = #f
  v2 : (or/c flonum? #f) = #f
  v3 : (or/c flonum? #f) = #f
  v4 : (or/c flonum? #f) = #f
  l1 : (or/c flvector? #f) = #f
  l2 : (or/c flvector? #f) = #f
  l3 : (or/c flvector? #f) = #f
  l4 : (or/c flvector? #f) = #f
  tex : (or/c mipmap? #f) = #f
  blending : boolean? = #f
  alpha : (or/c (integer-in 0 255) #f) = #f
  id : fixnum? = 0
  lights : (or/c #f (listof lightsrc?)) = #f
  lights1 : (or/c #f (listof lightsrc?)) = #f
  lights2 : (or/c #f (listof lightsrc?)) = #f
  lights3 : (or/c #f (listof lightsrc?)) = #f
  lights4 : (or/c #f (listof lightsrc?)) = #f
  ambient : (or/c #f flvector?) = #f
  ambient1 : (or/c #f flvector?) = #f
  ambient2 : (or/c #f flvector?) = #f
  ambient3 : (or/c #f flvector?) = #f
  ambient4 : (or/c #f flvector?) = #f
  wire : boolean? = #f
  cw : boolean? = #f
  ccw : boolean? = #t
  setw : boolean = #t
Like render-triangle but emits two triangles comprising the quad specified.

All four vertices must be coplanar or very close to being so.