source: trunk/src/gtkvideo.cpp @ 96

Last change on this file since 96 was 96, checked in by sam, 10 years ago

Implement lazy initialisation of TileSet objects.

  • Property svn:keywords set to Id
File size: 4.3 KB
Line 
1
2#include <gtk/gtk.h>
3#include <gtkgl/gtkglarea.h>
4
5#ifdef WIN32
6#   define WIN32_LEAN_AND_MEAN
7#   include <windows.h>
8#endif
9#if defined __APPLE__ && defined __MACH__
10#   include <OpenGL/gl.h>
11#else
12#   define GL_GLEXT_PROTOTYPES
13#   include <GL/gl.h>
14#endif
15
16#include <stdlib.h>
17
18#include "gtkvideo.h"
19
20/*
21 * Gtk Video implementation class
22 */
23
24class GtkVideoData
25{
26    friend class GtkVideo;
27
28private:
29    void SetupView()
30    {
31        glViewport(0, 0, widget->allocation.width,
32                         widget->allocation.height);
33
34        glMatrixMode(GL_PROJECTION);
35        glLoadIdentity();
36        glOrtho(0, widget->allocation.width,
37                   widget->allocation.height, 0, -1, 10);
38        glMatrixMode(GL_MODELVIEW);
39        glLoadIdentity();
40
41        glEnable(GL_TEXTURE_2D);
42        glShadeModel(GL_SMOOTH);
43        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
44        glClearDepth(1.0);
45        glEnable(GL_DEPTH_TEST);
46        glDepthFunc(GL_LEQUAL);
47        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
48
49        glEnable(GL_BLEND);
50        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
51    }
52
53    static gint init(GtkWidget *widget)
54    {
55        GtkVideoData *data = (GtkVideoData *)
56            gtk_object_get_data(GTK_OBJECT(widget), "data");
57
58        /* OpenGL functions can be called only if make_current returns true */
59        if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
60        {
61            data->SetupView();
62        }
63        return TRUE;
64    }
65
66    static gint draw(GtkWidget *widget, GdkEventExpose *event)
67    {
68        GtkVideoData *data = (GtkVideoData *)
69            gtk_object_get_data(GTK_OBJECT(widget), "data");
70
71        if (event->count == 0 && data->drawing == 2
72             && gtk_gl_area_make_current(GTK_GL_AREA(widget)))
73        {
74            data->drawing = 0;
75
76            /* Swap backbuffer to front */
77            gtk_gl_area_swapbuffers(GTK_GL_AREA(widget));
78        }
79
80        return TRUE;
81    }
82
83    static gint reshape(GtkWidget *widget, GdkEventConfigure *event)
84    {
85        GtkVideoData *data = (GtkVideoData *)
86            gtk_object_get_data(GTK_OBJECT(widget), "data");
87
88        if (gtk_gl_area_make_current(GTK_GL_AREA(widget)))
89        {
90            data->SetupView();
91        }
92        return TRUE;
93    }
94
95    GtkWidget *widget;
96    int drawing;
97};
98
99/*
100 * Public GtkVideo class
101 */
102
103GtkVideo::GtkVideo(char const *title, int width, int height)
104{
105    data = new GtkVideoData();
106
107    int attrlist[] =
108    {
109        GDK_GL_RGBA,
110        GDK_GL_RED_SIZE, 1,
111        GDK_GL_GREEN_SIZE, 1,
112        GDK_GL_BLUE_SIZE, 1,
113        GDK_GL_DOUBLEBUFFER,
114        GDK_GL_NONE
115    };
116
117    if (gdk_gl_query() == FALSE)
118    {
119        // FIXME: implement a panic() mode
120        g_print("OpenGL not supported\n");
121        exit(1);
122    }
123
124    data->widget = gtk_gl_area_new(attrlist);
125    data->drawing = 0;
126
127    gtk_object_set_data(GTK_OBJECT(data->widget), "data", data);
128    gtk_widget_set_events(GTK_WIDGET(data->widget),
129                          GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
130
131    gtk_signal_connect(GTK_OBJECT(data->widget), "expose_event",
132                       GTK_SIGNAL_FUNC(GtkVideoData::draw), NULL);
133    gtk_signal_connect(GTK_OBJECT(data->widget), "configure_event",
134                       GTK_SIGNAL_FUNC(GtkVideoData::reshape), NULL);
135    gtk_signal_connect(GTK_OBJECT(data->widget), "realize",
136                       GTK_SIGNAL_FUNC(GtkVideoData::init), NULL);
137
138    // FIXME: is this needed?
139    gtk_widget_set_usize(GTK_WIDGET(data->widget), 400, 300);
140}
141
142void *GtkVideo::GetWidget()
143{
144    return data->widget;
145}
146
147int GtkVideo::GetWidth() const
148{
149    return data->widget->allocation.width;
150}
151
152int GtkVideo::GetHeight() const
153{
154    return data->widget->allocation.height;
155}
156
157void GtkVideo::PreRender()
158{
159    /// XXX: is this right?
160    gtk_gl_area_make_current(GTK_GL_AREA(data->widget));
161
162    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
163    glLoadIdentity();
164
165    data->drawing = 1;
166}
167
168void GtkVideo::PostRender(float milliseconds)
169{
170    data->drawing = 2;
171
172    gtk_widget_draw(GTK_WIDGET(data->widget), NULL);
173#if 0
174    if (milliseconds > 0.0f)
175        while (SDL_GetTicks() < data->ticks + (milliseconds - 0.5f))
176            SDL_Delay(1);
177    data->ticks = SDL_GetTicks();
178    data->frames++;
179
180    SDL_GL_SwapBuffers();
181#endif
182}
183
184void GtkVideo::FullScreen()
185{
186    // FIXME
187}
188
189GtkVideo::~GtkVideo()
190{
191    // FIXME
192}
193
Note: See TracBrowser for help on using the repository browser.