You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

149 lines
3.4 KiB

  1. //
  2. // Deus Hax (working title)
  3. // Copyright (c) 2010 Sam Hocevar <sam@hocevar.net>
  4. //
  5. #if defined HAVE_CONFIG_H
  6. # include "config.h"
  7. #endif
  8. #include <cstdlib>
  9. #include <gtk/gtk.h>
  10. #include <gtkgl/gtkglarea.h>
  11. #include "gtkvideo.h"
  12. #include "video.h"
  13. /*
  14. * Gtk Video implementation class
  15. */
  16. class GtkVideoData
  17. {
  18. friend class GtkVideo;
  19. private:
  20. static gint init(GtkWidget *widget)
  21. {
  22. GtkVideoData *data = (GtkVideoData *)
  23. gtk_object_get_data(GTK_OBJECT(widget), "data");
  24. /* OpenGL functions can be called only if make_current returns true */
  25. if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
  26. {
  27. Video::Setup(widget->allocation.width,
  28. widget->allocation.height);
  29. }
  30. return TRUE;
  31. }
  32. static gint draw(GtkWidget *widget, GdkEventExpose *event)
  33. {
  34. GtkVideoData *data = (GtkVideoData *)
  35. gtk_object_get_data(GTK_OBJECT(widget), "data");
  36. if (event->count == 0 && data->drawing == 2
  37. && gtk_gl_area_make_current(GTK_GL_AREA(widget)))
  38. {
  39. data->drawing = 0;
  40. /* Swap backbuffer to front */
  41. gtk_gl_area_swapbuffers(GTK_GL_AREA(widget));
  42. }
  43. return TRUE;
  44. }
  45. static gint reshape(GtkWidget *widget, GdkEventConfigure *event)
  46. {
  47. GtkVideoData *data = (GtkVideoData *)
  48. gtk_object_get_data(GTK_OBJECT(widget), "data");
  49. if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
  50. {
  51. Video::Setup(widget->allocation.width,
  52. widget->allocation.height);
  53. }
  54. return TRUE;
  55. }
  56. GtkWidget *widget;
  57. int drawing;
  58. };
  59. /*
  60. * Public GtkVideo class
  61. */
  62. GtkVideo::GtkVideo(char const *title, int width, int height)
  63. {
  64. data = new GtkVideoData();
  65. int attrlist[] =
  66. {
  67. GDK_GL_RGBA,
  68. GDK_GL_RED_SIZE, 1,
  69. GDK_GL_GREEN_SIZE, 1,
  70. GDK_GL_BLUE_SIZE, 1,
  71. GDK_GL_DOUBLEBUFFER,
  72. GDK_GL_NONE
  73. };
  74. if (gdk_gl_query() == FALSE)
  75. {
  76. // FIXME: implement a panic() mode
  77. g_print("OpenGL not supported\n");
  78. exit(1);
  79. }
  80. data->widget = gtk_gl_area_new(attrlist);
  81. data->drawing = 0;
  82. gtk_object_set_data(GTK_OBJECT(data->widget), "data", data);
  83. gtk_widget_set_events(GTK_WIDGET(data->widget),
  84. GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
  85. gtk_signal_connect(GTK_OBJECT(data->widget), "expose_event",
  86. GTK_SIGNAL_FUNC(GtkVideoData::draw), NULL);
  87. gtk_signal_connect(GTK_OBJECT(data->widget), "configure_event",
  88. GTK_SIGNAL_FUNC(GtkVideoData::reshape), NULL);
  89. gtk_signal_connect(GTK_OBJECT(data->widget), "realize",
  90. GTK_SIGNAL_FUNC(GtkVideoData::init), NULL);
  91. // FIXME: is this needed?
  92. gtk_widget_set_usize(GTK_WIDGET(data->widget), 400, 300);
  93. }
  94. void *GtkVideo::GetWidget()
  95. {
  96. return data->widget;
  97. }
  98. void GtkVideo::PreRender()
  99. {
  100. /// XXX: is this right?
  101. gtk_gl_area_make_current(GTK_GL_AREA(data->widget));
  102. Video::Clear();
  103. data->drawing = 1;
  104. }
  105. void GtkVideo::PostRender(float milliseconds)
  106. {
  107. data->drawing = 2;
  108. gtk_widget_draw(GTK_WIDGET(data->widget), NULL);
  109. #if 0
  110. if (milliseconds > 0.0f)
  111. while (SDL_GetTicks() < data->ticks + (milliseconds - 0.5f))
  112. SDL_Delay(1);
  113. data->ticks = SDL_GetTicks();
  114. data->frames++;
  115. SDL_GL_SwapBuffers();
  116. #endif
  117. }