在OCaml中处理带有openGL和SDL的键盘问题

时间:2011-09-28 06:26:31

标签: opengl keyboard ocaml sdl keyboard-events

我在处理使用SDL(仅用于键盘事件)和openGL(用于显示图形,我计划显示3D图形)的键盘事件时遇到问题。当我使用Sdlevent.poll时没有任何事情发生,我不能使用wait_event,因为我要实时显示。我已经尝试了几乎每一个我想的并且没有成功,你是我唯一的希望! ^^

这是我的源代码(它只是一个旋转的方块......)

let rotate = ref 1.0

let _ = Sdl.init [`VIDEO] ; at_exit Sdl.quit

 let key_handler k = match k with
   | {Sdlevent.keysym=Sdlkey.KEY_ESCAPE} ->
       print_endline "I'll miss you so much..." ;
   | {Sdlevent.keysym=Sdlkey.KEY_SPACE} ->
print_endline "UP" ;
   | {Sdlevent.keysym=Sdlkey.KEY_DOWN} ->
     print_endline "DOWN";  
   | _ -> ()

let renderScene () =
  let current_time = ref (Sdltimer.get_ticks()) in
    GlClear.clear[`color;`depth];
  GlMat.rotate3 (!rotate) (0.0,0.0,1.0);
  GlDraw.begins `quad_strip;
  GlDraw.color (1.0, 0.0, 0.0);
  GlDraw.vertex3 (-0.5, 0.5, 0.0);
  GlDraw.vertex3 (-0.5, -0.5, 0.0);
  GlDraw.color (0.0, 0.0, 1.0);
  GlDraw.vertex3 (0.5, 0.5, 0.0);
  GlDraw.vertex3 (0.5,-0.5, 0.0);
  GlDraw.ends ();
  current_time := Sdltimer.get_ticks() - !current_time;
  if(!current_time < 10) then
    Sdltimer.delay (10 - !current_time);
  Glut.swapBuffers();
  Glut.postRedisplay();
 begin
    match Sdlevent.poll () with
      | Some (Sdlevent.KEYDOWN k) ->
     print_endline "nope"; key_handler k
      | None | _ -> print_endline "nopeee";
   end;
  Gl.flush();;



let () =
   ignore(Glut.init Sys.argv);
   Glut.initDisplayMode ~alpha:true ~double_buffer:true ~depth:true ();
   Glut.initWindowPosition ~x:100 ~y:100;
   Glut.initWindowSize ~w:500 ~h:500;
   ignore(Glut.createWindow ~title:"3DMapPro - Edition Expert Business 2012");
   GlClear.color(1.,1.,1.);
   Glut.displayFunc ~cb:(renderScene);
   print_string "oui";
   Glut.keyboardFunc (fun ~key ~x ~y -> if key=27 then exit 0);
   Glut.mainLoop();;

由于我不明白如何在stackoverflow上正确发布代码,你也可以在这里找到我的源代码缩进和突出显示:Pastebin

2 个答案:

答案 0 :(得分:2)

首先要做的事情是:你将GLUT与SDL混合在一起,两者都会争先恐后地处理窗口和输入事件处理。其中一个安顿下来。 GLUT不属于OpenGL

我认为你从一些教程中得到了这个。关键是这一个,它使用GLUT:

Glut.keyboardFunc (fun ~key ~x ~y -> if key=27 then exit 0);

这里创建一个lambda(= anonymous)函数,并作为处理程序传递给Glut.keyboadFunc。如果ESC被传递,这个lambda将调用exit 0。要解决这个问题,首先需要摆脱GLUT(所有以Glut.开头的语句)并将其替换为SDL对应项。

此外,您将SDL事件轮询放在渲染功能中。这只是错!事件轮询应该发生,目前Glut.mainLoop()是。

此外,您的渲染功能缺少正确的视口,投影和模型视图设置,这也需要修复。

答案 1 :(得分:0)

在我看来,SDL和Glut都认为他们应该正在阅读密钥。也许Glut赢了,SDL也输了。如果你按ESC(代码为27),程序是否退出?