diff --git a/src/gtkvideo.cpp b/src/gtkvideo.cpp new file mode 100644 index 00000000..9419d50e --- /dev/null +++ b/src/gtkvideo.cpp @@ -0,0 +1,183 @@ + +#include +#include + +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +# include +#endif +#if defined __APPLE__ && defined __MACH__ +# include +#else +# define GL_GLEXT_PROTOTYPES +# include +#endif + +#include + +#include "gtkvideo.h" + +/* + * Gtk Video implementation class + */ + +class GtkVideoData +{ + friend class GtkVideo; + +private: + static gint init(GtkWidget *widget) + { + /* OpenGL functions can be called only if make_current returns true */ + if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) + { + glViewport(0, 0, widget->allocation.width, + widget->allocation.height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0,100, 100,0, -1,1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + } + return TRUE; + } + + static gint draw(GtkWidget *widget, GdkEventExpose *event) + { + if (event->count == 0 && gtk_gl_area_make_current(GTK_GL_AREA(widget))) + { + /* Draw simple triangle */ + glClearColor(0,0,0,1); + glClear(GL_COLOR_BUFFER_BIT); + glColor3f(1,1,1); + glBegin(GL_TRIANGLES); + glVertex2f(10,10); + glVertex2f(10,90); + glVertex2f(90,90); + glEnd(); + + /* Swap backbuffer to front */ + gtk_gl_area_swapbuffers(GTK_GL_AREA(widget)); + } + + return TRUE; + } + + static gint reshape(GtkWidget *widget, GdkEventConfigure *event) + { + if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) + { + glViewport(0,0, widget->allocation.width, + widget->allocation.height); + } + return TRUE; + } + + GtkWidget *widget; +}; + +/* + * Public GtkVideo class + */ + +GtkVideo::GtkVideo(char const *title, int width, int height) +{ + data = new GtkVideoData(); + + int attrlist[] = + { + GDK_GL_RGBA, + GDK_GL_RED_SIZE, 1, + GDK_GL_GREEN_SIZE, 1, + GDK_GL_BLUE_SIZE, 1, + GDK_GL_DOUBLEBUFFER, + GDK_GL_NONE + }; + + if (gdk_gl_query() == FALSE) + { + // FIXME: implement a panic() mode + g_print("OpenGL not supported\n"); + exit(1); + } + + data->widget = gtk_gl_area_new(attrlist); + gtk_widget_set_events(GTK_WIDGET(data->widget), + GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); + + gtk_signal_connect(GTK_OBJECT(data->widget), "expose_event", + GTK_SIGNAL_FUNC(GtkVideoData::draw), NULL); + gtk_signal_connect(GTK_OBJECT(data->widget), "configure_event", + GTK_SIGNAL_FUNC(GtkVideoData::reshape), NULL); + gtk_signal_connect(GTK_OBJECT(data->widget), "realize", + GTK_SIGNAL_FUNC(GtkVideoData::init), NULL); + + // FIXME: is this needed? + gtk_widget_set_usize(GTK_WIDGET(data->widget), 100, 100); + + /* Initialise OpenGL */ + glViewport(0, 0, data->widget->allocation.width, + data->widget->allocation.height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, data->widget->allocation.width, + data->widget->allocation.height, 0, -1, 10); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_TEXTURE_2D); + glShadeModel(GL_SMOOTH); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(1.0); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +void *GtkVideo::GetWidget() +{ + return data->widget; +} + +int GtkVideo::GetWidth() const +{ + return data->widget->allocation.width; +} + +int GtkVideo::GetHeight() const +{ + return data->widget->allocation.height; +} + +void GtkVideo::Clear() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); +} + +void GtkVideo::Refresh(float milliseconds) +{ +#if 0 + if (milliseconds > 0.0f) + while (SDL_GetTicks() < data->ticks + (milliseconds - 0.5f)) + SDL_Delay(1); + data->ticks = SDL_GetTicks(); + data->frames++; + + SDL_GL_SwapBuffers(); +#endif +} + +void GtkVideo::FullScreen() +{ + // FIXME +} + +GtkVideo::~GtkVideo() +{ + // FIXME +} + diff --git a/src/gtkvideo.h b/src/gtkvideo.h new file mode 100644 index 00000000..ad0b7dc4 --- /dev/null +++ b/src/gtkvideo.h @@ -0,0 +1,34 @@ + +/* + * The video driver + */ + +#if !defined __DH_GTKVIDEO_H__ +#define __DH_GTKVIDEO_H__ + +#include "video.h" + +class GtkVideoData; + +class GtkVideo : public Video +{ +public: + GtkVideo(char const *title, int width, int height); + virtual ~GtkVideo(); + + // New + void *GetWidget(); + + // Inherited + virtual int GetWidth() const; + virtual int GetHeight() const; + virtual void Clear(); + virtual void Refresh(float milliseconds); + virtual void FullScreen(); + +private: + GtkVideoData *data; +}; + +#endif // __DH_GTKVIDEO_H__ +