diff options
-rw-r--r-- | cylindermod.ml | 91 |
1 files changed, 50 insertions, 41 deletions
diff --git a/cylindermod.ml b/cylindermod.ml index f93ae78..d65361f 100644 --- a/cylindermod.ml +++ b/cylindermod.ml @@ -5,52 +5,61 @@ let pi2 = 6.2831853 (* draws the specified cylinder along the z axis. * explanation of how this works can be found at the bottom of this file *) let cylinder ~numl ~numa ~length ~rmod ~rmodd ~xmod ~xmodd ~ymod ~ymodd = - (* the formula for the normal and the vertex *) - let point a r dr x dx y dy o = - let nx = sin a *. r in - let ny = cos a *. r in - let nz = (sin a *. dr +. dx) *. -1.0 *. sin a *. r - -. cos a *. r *. (cos a *. dr +. dy) in - let len = sqrt (nx*.nx +. ny*.ny +. nz*.nz) in - GlDraw.normal3 (nx/.len, ny/.len, nz/.len); - GlDraw.vertex3 ( - sin a *. r +. x, - cos a *. r +. y, - o - ) - in - - (* cache previous values *) - let pl = ref 0.0 and - pr = ref (rmod 0.0) and - prd = ref (rmodd 0.0) and - px = ref (xmod 0.0) and - pxd = ref (xmodd 0.0) and - py = ref (ymod 0.0) and - pyd = ref (ymodd 0.0) in - - (* generate stuff *) + + (* create static C arrays for the normals and vertices + * (I would have used an interleaved array if lablgl had supported that) *) + let normals = Raw.create_static `float ((numl+1) * (numa+1) * 3) in + let vertices = Raw.create_static `float ((numl+1) * (numa+1) * 3) in + let idx l a = l*numa + a in + + (* calculate and fill the arrays *) + for li = 0 to numl do + let l = (float li) /. (float numl) *. length in + let r = rmod l and rd = rmodd l in + let x = xmod l and xd = xmodd l in + let y = ymod l and yd = ymodd l in + for ai = 0 to numa do + let a = pi2 *. (float (ai mod numa)) /. (float numa) in + (* normal *) + let nx = sin a *. r in + let ny = cos a *. r in + let nz = (sin a *. rd +. xd) *. -1.0 *. sin a *. r + -. cos a *. r *. (cos a *. rd +. yd) in + let len = sqrt (nx*.nx +. ny*.ny +. nz*.nz) in + Raw.sets_float normals ~pos:(3*idx li ai) [| nx/.len; ny/.len; nz/.len |]; + (* vertex *) + Raw.sets_float vertices ~pos:(3*idx li ai) [| + sin a *. r +. x; + cos a *. r +. y; + l + |]; + done; + done; + + GlArray.enable `normal; + GlArray.normal normals; + GlArray.enable `vertex; + GlArray.vertex `three vertices; + + (* draw the array *) GlDraw.begins `quads; for li = 1 to numl do - let l = (float li) /. (float numl) *. length in - let cr = rmod l and crd = rmodd l in - let cx = xmod l and cxd = xmodd l in - let cy = ymod l and cyd = ymodd l in - let p = ref 0.0 in for ai = 1 to numa do - let a = pi2 *. (float (ai mod numa)) /. (float numa) in - point a cr crd cx cxd cy cyd l; - point a !pr !prd !px !pxd !py !pyd !pl; - point !p !pr !prd !px !pxd !py !pyd !pl; - point !p cr crd cx cxd cy cyd l; - p := a; + GlArray.element (idx (li-1) ai); + GlArray.element (idx (li-1) (ai-1)); + GlArray.element (idx li (ai-1)); + GlArray.element (idx li ai); done; - pl := l; - pr := cr; prd := crd; - px := cx; pxd := cxd; - py := cy; pyd := cyd; done; - GlDraw.ends () + GlDraw.ends (); + + (* I'd love to use gl[Push|pop]ClientAttrib(), but lablgl doesn't have that + * function *) + GlArray.disable `vertex; + GlArray.disable `normal; + + Raw.free_static normals; + Raw.free_static vertices |