COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Anyone knows how to plot 3-D graph in openGL

• Follow

```Hi, guys,

I have to plot a 3-D curves z=f(x,y). Anyone did this before?

Thanks
Newbie of Theory

```
 0
Reply Newbie 4/11/2005 1:51:22 PM

```Newbie of Theory wrote:
>     I have to plot a 3-D curves z=f(x,y). Anyone did this before?

Yes, I just did exactly this. :-)

The following OCaml program loads a flat list representing 257x257 samples
of a height surface which is then used to compute vertices and normals
which are rendered via a display list of triangle strips, lit and rotated
in real time (on my laptop):

-----
open Printf

(* Get the time since the animation was first entered. *)
let time =
let t = ref None in
fun () -> match !t with
None -> t := Some (Unix.gettimeofday ()); 0.
| Some t -> Unix.gettimeofday () -. t

(* Hardcoded number of samples per edge in the height field. *)
let n = 257

(* Load the height field as a n x n list of floats. *)
let height =
let ch = open_in "3d.mx" in
let rec aux l =
try aux (float_of_string (input_line ch) :: l)
with End_of_file -> l in
let heights = Array.of_list (aux []) in
close_in ch;
fun i j -> heights.(i + n * j)

(* 3D vector definitions. *)
type vec3 = { x: float; y: float; z: float }

let neg r = { x = -. r.x; y = -. r.y; z = -. r.z }
let add r1 r2 = { x = r1.x +. r2.x; y = r1.y +. r2.y; z = r1.z +. r2.z }
let sub r1 r2 = add r1 (neg r2)
let dot r1 r2 = r1.x *. r2.x +. r1.y *. r2.y +. r1.z *. r2.z
let cross r1 r2 = { x = r1.y *. r2.z -. r1.z *. r2.y;
y = r1.z *. r2.x -. r1.x *. r2.z;
z = r1.x *. r2.y -. r1.y *. r2.x }
let length2 r = dot r r
let length r = sqrt (length2 r)
let scale s r = { x = s *. r.x; y = s *. r.y; z = s *. r.z }
let string_of_vec r =
"("^string_of_float r.x^", "^
string_of_float r.y^", "^
string_of_float r.z^")"
let print_vec r = print_endline (string_of_vec r)
let glVertex { x = x; y = y; z = z } = GlDraw.vertex ~x ~y ~z ()
let glNormal { x = x; y = y; z = z } = GlDraw.normal ~x ~y ~z ()

(* Compute explicit vertex coordinates. *)
let vertex =
let aux i j =
{ x = float i /. float n; z = float j /. float n; y = height i j } in
Array.init n (fun i -> Array.init n (fun j -> aux i j))

(* Numerically approximate the normal vector at each vertex. *)
let normal =
let normal = Array.make_matrix n n {x=0.; y=1.; z=0.} in
for i = 1 to n - 2 do
for j = 1 to n - 2 do
let dx = height (i-1) j -. height (i+1) j in
let dz = height i (j-1) -. height i (j+1) in
let n = { x = dx; y = 2. /. float n; z = dz } in
normal.(i).(j) <- scale (1. /. length n) n
done;
done;
normal

(* The plot is memoized in this display list. *)
let dl = ref None

(* Render a lit, 3D, spinning height field. *)
let render () =
Gl.enable `depth_test;

(* Initialise lighting. *)
Gl.enable `lighting;
GlLight.light_model (`two_side true);

Gl.enable `light0;
GlLight.light ~num:0 (`position (1., 0., 0., 0.));
GlLight.light ~num:0 (`diffuse (0.25, 0.5, 1., 1.));
GlLight.light ~num:0 (`specular (0., 0., 0., 1.));

Gl.enable `light1;
GlLight.light ~num:1 (`position (0., -1., 0., 0.));
GlLight.light ~num:1 (`diffuse (1., 0.5, 0.25, 1.));
GlLight.light ~num:1 (`specular (0., 0., 0., 1.));

GlDraw.color (1., 1., 1.);
GlLight.material `both (`ambient (0.1, 0.1, 0.1, 1.));
GlLight.material `both (`diffuse (1., 1., 1., 1.));
GlLight.material `both (`specular (1., 1., 1., 1.));
GlLight.material `both (`shininess 25.);

GlMat.rotate3 (30. *. time ()) (0., 1., 0.);
GlMat.scale ~x:1.5 ~y:0.5 ~z:1.5 ();
GlMat.translate ~x:(-0.5) ~z:(-0.5) ();

begin match !dl with
Some dl -> GlList.call dl
| None ->
let dl' = GlList.create `compile in
for i = 1 to n - 3 do
GlDraw.begins `triangle_strip;
for j = 1 to n - 2 do
glNormal (normal.(i).(j));
glVertex (vertex.(i).(j));
glNormal (normal.(i+1).(j));
glVertex (vertex.(i+1).(j));
done;
GlDraw.ends ();
done;
GlList.ends ();
GlList.call dl';
dl := Some dl';
end;

Gl.disable `lighting;
Gl.disable `cull_face;

(* Render the axes. *)
Gl.enable `blend;
GlFunc.blend_func `src_alpha `one_minus_src_alpha;
Gl.enable `line_smooth;

GlDraw.begins `line_loop;
List.iter GlDraw.vertex3 [0., 0., 0.; 1., 0., 0.; 1., 0., 1.; 0., 0., 1.];
GlDraw.ends ();
GlDraw.begins `line_loop;
List.iter GlDraw.vertex3 [0., 1., 0.; 1., 1., 0.; 1., 1., 1.; 0., 1., 1.];
GlDraw.ends ();
GlDraw.begins `lines;
List.iter GlDraw.vertex3 [0., 0., 0.; 0., 1., 0.;
1., 0., 0.; 1., 1., 0.;
1., 0., 1.; 1., 1., 1.;
0., 0., 1.; 0., 1., 1.];
GlDraw.ends ();

Gl.disable `line_smooth;
Gl.disable `blend;

Gl.disable `depth_test

(* Display the scene using a 3D perspective projection. *)
let display data =
GlMat.mode `projection;
let sqr x = x *. x in
let fov = 45. +. (179. -. 45.) /. (1. +. sqr (time ())) in
GluMat.perspective fov (float data#width /. float data#height) (0.1,
100.);
GluMat.look_at (0., 2.4, 3.) (-0.7, 0.5, 0.) (0., 1., 0.);
GlMat.mode `modelview;

GlClear.clear [`depth];

render ()
-----

You could rewrite this program in C or C++ easily enough, it would just be
quite a bit more tedious.

HTH.

--
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
```
 0
Reply Jon 4/11/2005 2:53:02 PM

```Newbie of Theory wrote:
> Hi, guys,
>
>     I have to plot a 3-D curves z=f(x,y). Anyone did this before?
>

glBegin(GL_LINE_STRIP);
for (...) {
glVertex3d(x, y, f(x,y));
}
glEnd();

--
<\___/>
/ O O \
\_____/  FTB.    For email, remove my socks.
```
 0
Reply fungus 4/11/2005 4:00:37 PM

```"Newbie of Theory" <wangchao@singnet.com.sg> schrieb im Newsbeitrag
news:d3dtln\$p7u\$2@mawar.singnet.com.sg...
> Hi, guys,
>
>    I have to plot a 3-D curves z=f(x,y). Anyone did this before?
>
> Thanks
> Newbie of Theory
>
>

for(x = 0; x<maxx; ++x)
{
glBegin(GL_TIRANGLE_STRIP);
for(y=0; y<maxy; ++y)
{
glVertex3f(x+1, Values[x+1][y], y  );
glVertex3f(x,   values[x][y+1], y+1);
}
glVertex3f(x+1, values[x+1][y], y);
glEnd();
}

HTH,
Gernot

```
 0
Reply Gernot 4/11/2005 7:48:14 PM

3 Replies
254 Views

(page loaded in 0.085 seconds)

Similiar Articles:

7/29/2012 9:32:44 AM