なんちゃって半透明


OpenGL 初心者の脇田が半透明に挑戦しようと思ったのですが、面倒そうだったのでひよって「なんちゃって」バージョンを作りました。

ちょっといいかげんですけれど、それらしく見えるでしょ?しめしめ。

以下のプログラムを動かすとまずは不透明に表示されます。次にキーボードで ‘t’ を打つと半透明になります。

let initialize () =
ignore (Glut.init [| |]);
Glut.initDisplayMode ~alpha:true ~depth:true ();
Glut.initWindowSize 800 600;
ignore (Glut.createWindow “Transparent object sample”);

GlDraw.shade_model `smooth;

GlClear.color (0., 0., 0.);
GlClear.depth 1.0;
GlFunc.depth_func `lequal;

List.iter (GlLight.light ~num: 1)
[ `position (1000., 1000., 1000., 0.); `diffuse (1.0, 1.0, 1.0, 1.0) ];
List.iter Gl.enable [ `lighting; `light1; `depth_test ];;

let transparent = ref false;;

let display () =
GlClear.clear [`color; `depth];

GlFunc.depth_mask true;
if !transparent then begin
Gl.enable `blend;
GlFunc.blend_func `one `zero;
end else Gl.disable `blend;

let red = 1.0, 0.0, 0.0, 1.0 in
let blue = 0.0, 0.0, 1.0, if !transparent then 0.5 else 1.0 in

GlMat.load_identity ();
GlMat.translate3(30.0, 30.0, -200.0);
List.iter (GlLight.material ~face:`front) [ `ambient red; `diffuse red ];
Glut.solidCube ~size:30.0;

if !transparent then begin
GlFunc.depth_mask false;
GlFunc.blend_func `src_alpha `one_minus_src_alpha;
end;

GlMat.load_identity ();
GlMat.translate3(0.0, 0.0, -200.0);
List.iter (GlLight.material ~face:`front) [ `ambient blue; `diffuse blue ];
Glut.solidCube ~size:60.0;
Gl.flush ();;

let reshape ~w ~h =
let ratio = (float w) /. (float h) in
GlDraw.viewport 0 0 w h;
GlMat.mode `projection;
GlMat.load_identity ();
GluMat.perspective 45.0 ratio (0.1, 500.);
GlMat.mode `modelview;;

let keyboard ~key ~x ~y =
if key = int_of_char ‘q’ then exit 0
else if key = int_of_char ‘t’ then transparent := not (!transparent);
display ();;

let _ =
initialize ();
Glut.displayFunc ~cb: display;
Glut.reshapeFunc reshape;
Glut.keyboardFunc keyboard;
Glut.mainLoop ()