Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

184 rader
4.2 KiB

  1. #include <gtk/gtk.h>
  2. #include <gtkgl/gtkglarea.h>
  3. #ifdef WIN32
  4. # define WIN32_LEAN_AND_MEAN
  5. # include <windows.h>
  6. #endif
  7. #if defined __APPLE__ && defined __MACH__
  8. # include <OpenGL/gl.h>
  9. #else
  10. # define GL_GLEXT_PROTOTYPES
  11. # include <GL/gl.h>
  12. #endif
  13. #include <stdlib.h>
  14. #include "gtkvideo.h"
  15. /*
  16. * Gtk Video implementation class
  17. */
  18. class GtkVideoData
  19. {
  20. friend class GtkVideo;
  21. private:
  22. static gint init(GtkWidget *widget)
  23. {
  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. glViewport(0, 0, widget->allocation.width,
  28. widget->allocation.height);
  29. glMatrixMode(GL_PROJECTION);
  30. glLoadIdentity();
  31. glOrtho(0,100, 100,0, -1,1);
  32. glMatrixMode(GL_MODELVIEW);
  33. glLoadIdentity();
  34. }
  35. return TRUE;
  36. }
  37. static gint draw(GtkWidget *widget, GdkEventExpose *event)
  38. {
  39. if (event->count == 0 && gtk_gl_area_make_current(GTK_GL_AREA(widget)))
  40. {
  41. /* Draw simple triangle */
  42. glClearColor(0,0,0,1);
  43. glClear(GL_COLOR_BUFFER_BIT);
  44. glColor3f(1,1,1);
  45. glBegin(GL_TRIANGLES);
  46. glVertex2f(10,10);
  47. glVertex2f(10,90);
  48. glVertex2f(90,90);
  49. glEnd();
  50. /* Swap backbuffer to front */
  51. gtk_gl_area_swapbuffers(GTK_GL_AREA(widget));
  52. }
  53. return TRUE;
  54. }
  55. static gint reshape(GtkWidget *widget, GdkEventConfigure *event)
  56. {
  57. if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
  58. {
  59. glViewport(0,0, widget->allocation.width,
  60. widget->allocation.height);
  61. }
  62. return TRUE;
  63. }
  64. GtkWidget *widget;
  65. };
  66. /*
  67. * Public GtkVideo class
  68. */
  69. GtkVideo::GtkVideo(char const *title, int width, int height)
  70. {
  71. data = new GtkVideoData();
  72. int attrlist[] =
  73. {
  74. GDK_GL_RGBA,
  75. GDK_GL_RED_SIZE, 1,
  76. GDK_GL_GREEN_SIZE, 1,
  77. GDK_GL_BLUE_SIZE, 1,
  78. GDK_GL_DOUBLEBUFFER,
  79. GDK_GL_NONE
  80. };
  81. if (gdk_gl_query() == FALSE)
  82. {
  83. // FIXME: implement a panic() mode
  84. g_print("OpenGL not supported\n");
  85. exit(1);
  86. }
  87. data->widget = gtk_gl_area_new(attrlist);
  88. gtk_widget_set_events(GTK_WIDGET(data->widget),
  89. GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
  90. gtk_signal_connect(GTK_OBJECT(data->widget), "expose_event",
  91. GTK_SIGNAL_FUNC(GtkVideoData::draw), NULL);
  92. gtk_signal_connect(GTK_OBJECT(data->widget), "configure_event",
  93. GTK_SIGNAL_FUNC(GtkVideoData::reshape), NULL);
  94. gtk_signal_connect(GTK_OBJECT(data->widget), "realize",
  95. GTK_SIGNAL_FUNC(GtkVideoData::init), NULL);
  96. // FIXME: is this needed?
  97. gtk_widget_set_usize(GTK_WIDGET(data->widget), 100, 100);
  98. /* Initialise OpenGL */
  99. glViewport(0, 0, data->widget->allocation.width,
  100. data->widget->allocation.height);
  101. glMatrixMode(GL_PROJECTION);
  102. glLoadIdentity();
  103. glOrtho(0, data->widget->allocation.width,
  104. data->widget->allocation.height, 0, -1, 10);
  105. glMatrixMode(GL_MODELVIEW);
  106. glLoadIdentity();
  107. glEnable(GL_TEXTURE_2D);
  108. glShadeModel(GL_SMOOTH);
  109. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  110. glClearDepth(1.0);
  111. glEnable(GL_DEPTH_TEST);
  112. glDepthFunc(GL_LEQUAL);
  113. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  114. glEnable(GL_BLEND);
  115. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  116. }
  117. void *GtkVideo::GetWidget()
  118. {
  119. return data->widget;
  120. }
  121. int GtkVideo::GetWidth() const
  122. {
  123. return data->widget->allocation.width;
  124. }
  125. int GtkVideo::GetHeight() const
  126. {
  127. return data->widget->allocation.height;
  128. }
  129. void GtkVideo::Clear()
  130. {
  131. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  132. glLoadIdentity();
  133. }
  134. void GtkVideo::Refresh(float milliseconds)
  135. {
  136. #if 0
  137. if (milliseconds > 0.0f)
  138. while (SDL_GetTicks() < data->ticks + (milliseconds - 0.5f))
  139. SDL_Delay(1);
  140. data->ticks = SDL_GetTicks();
  141. data->frames++;
  142. SDL_GL_SwapBuffers();
  143. #endif
  144. }
  145. void GtkVideo::FullScreen()
  146. {
  147. // FIXME
  148. }
  149. GtkVideo::~GtkVideo()
  150. {
  151. // FIXME
  152. }