summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2010-06-05 08:15:28 +0200
committerYorhel <git@yorhel.nl>2010-06-05 08:15:28 +0200
commit5de406bdfd6eb181c111a0216d37b8b16074d854 (patch)
tree1031aedab4e45781f37dc25a64c56225b836d32e
parentc88be9405b6cab49843ee90c4fa39b2fc2a54149 (diff)
Faster generation of the cylindermod
All vertices and normals are now calculated once and stored in an array, from which the quads are drawn.
-rw-r--r--cylindermod.ml91
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