Проблема обработки клавиатуры с openGL и SDL в OCaml - PullRequest
1 голос
/ 28 сентября 2011

У меня проблема с обработкой событий клавиатуры с использованием 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 ]

2 голосов
/ 28 сентября 2011

Перво-наперво: вы смешиваете GLUT с SDL, оба будут бороться за управление окнами и обработку входных событий.Согласитесь на один из тех. GLUT не является частью OpenGL

Я полагаю, у вас есть это из какого-то учебника.Эта ключевая строка использует GLUT:

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

Здесь лямбда (= анонимная) функция создается на месте и передается Glut.keyboadFunc в качестве обработчика.Эта лямбда будет вызывать exit 0, если ESC пройден.Чтобы это исправить, сначала нужно избавиться от GLUT (все операторы начинаются с Glut.) и заменить его аналогами SDL.

Кроме того, вы поместили опрос событий SDL в функцию рендеринга.Это просто НЕПРАВИЛЬНО!Опрос событий должен происходить там, где на данный момент Glut.mainLoop() есть.

Также вашей функции рендеринга не хватает правильной настройки области просмотра, проекции и просмотра модели, это также необходимо исправить.

0 голосов
/ 28 сентября 2011

Мне кажется, что и SDL, и Glut думают, что они должны читать ключи. Так что, возможно, Glut выигрывает, а SDL проигрывает. Программа завершается, если вы нажмете ESC (код 27)?

...