1 #define GL_GLEXT_PROTOTYPES
4 #include <gdk/gdkkeysyms.h>
17 } __attribute__ ((packed)) vert_t;
19 static int sort_cmp(const void *a, const void *b)
21 vert_t *a_verts = (vert_t*)(((gfloat*)a)+2);
22 vert_t *b_verts = (vert_t*)(((gfloat*)b)+2);
23 gfloat a_sum = a_verts[0].xyz[2] + a_verts[1].xyz[2] + a_verts[2].xyz[2];
24 gfloat b_sum = b_verts[0].xyz[2] + b_verts[1].xyz[2] + b_verts[2].xyz[2];
25 return a_sum == b_sum ? 0 :
26 a_sum < b_sum ? 1 : -1;
29 static gfloat *sort_start()
32 gfloat *data = g_new0(gfloat, size);
33 glFeedbackBuffer(size, GL_4D_COLOR_TEXTURE, data);
34 glRenderMode(GL_FEEDBACK);
35 g_print("1st = %f\n", data[0]);
39 static void sort_end(gfloat *data)
41 int vertsize = sizeof(vert_t)/sizeof(gfloat);
42 int nvals = glRenderMode(GL_RENDER);
44 /* Set up screen coords */
46 glGetIntegerv(GL_VIEWPORT, view);
48 glMatrixMode(GL_PROJECTION);
51 glOrtho(view[0],view[2], view[1],view[3], -100,100);
53 glMatrixMode(GL_MODELVIEW);
56 glDisable(GL_LIGHTING);
58 glMatrixMode(GL_TEXTURE);
62 //glTranslatef(pos[0], pos[1], pos[2]);
63 //glTranslatef(0.05, 0.1, -2);
64 //glRotatef(0.03, 1, 1, 0);
66 //gluPerspective(90, 0.8, 0.1, 10);
69 /* Sort the vertexes (this only works with all-triangles */
70 int trisize = 2*sizeof(gfloat) + 3*sizeof(vert_t);
71 int ntris = nvals*sizeof(gfloat) / trisize;
72 g_print("%d, %d, %d\n", sizeof(gfloat), trisize, ntris);
73 qsort(data, ntris, trisize, sort_cmp);
76 for (int i = 0; i < nvals;) {
77 gfloat token = data[i++];
78 if (token == GL_POLYGON_TOKEN) {
80 vert_t *verts = (vert_t*)&data[i];
82 //g_print("GL_POLYGON_TOKEN: %f\n", n);
85 glBegin(GL_TRIANGLES);
86 for (int j = 0; j < n; j++) {
87 g_print("\t%7.2f, %6.2f, %6.2f %6.2f - "
88 "%5.2f, %5.2f, %5.2f, %5.2f\n",
101 verts[j].texture[3]);
108 verts[j].xyz[2] = -100;
117 //glDisable(GL_TEXTURE_2D);
118 //glBegin(GL_LINE_LOOP);
119 //glColor4f(1,1,1,1);
120 //for (int j = 0; j < n; j++)
121 // glVertex3fv(verts[j].xyz);
124 g_error("Unknown token: %f\n", token);
127 glMatrixMode(GL_PROJECTION);
129 glMatrixMode(GL_MODELVIEW);
131 glMatrixMode(GL_TEXTURE);
136 static gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _)
138 //glClearColor(0.5, 0.5, 1.0, 1.0);
139 glClearColor(0.0, 0.0, 0.0, 0.0);
140 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
144 /* Blend, but broken sorting */
145 //glEnable(GL_DEPTH_TEST);
146 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
148 /* No sorting, just add */
149 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
150 //glBlendFunc(GL_ONE, GL_ONE);
153 float light_ambient[] = {0.1f, 0.1f, 0.0f, 1.0f};
154 float light_diffuse[] = {0.9f, 0.9f, 0.9f, 1.0f};
155 float light_position[] = {-30.0f, 50.0f, 40.0f, 1.0f};
156 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
157 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
158 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
159 glEnable(GL_COLOR_MATERIAL);
160 glEnable(GL_LIGHTING);
163 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
166 g_print("%f,%f,%f\n", pos[0], pos[1], pos[2]);
167 g_print("%f,%f,%f\n", rot[0], rot[1], rot[2]);
169 glMatrixMode(GL_MODELVIEW);
171 gfloat *data = sort_start();
173 glTranslatef(pos[0], pos[1], pos[2]);
174 glTranslatef(0.05, 0.1, -2);
175 glRotatef(60, 1, -1, -0.2);
177 glDisable(GL_COLOR_MATERIAL);
178 glEnable(GL_TEXTURE_2D);
179 glBindTexture(GL_TEXTURE_2D, tex);
181 glTexCoord2f(0, 0); glVertex3f(-0.8, 0.5, 0.0);
182 glTexCoord2f(0, 1); glVertex3f(-0.8, -0.5, 0.0);
183 glTexCoord2f(1, 1); glVertex3f( 0.8, -0.5, 0.0);
184 glTexCoord2f(1, 0); glVertex3f( 0.8, 0.5, 0.0);
188 //glTranslatef(pos[0], pos[1], pos[2]);
189 //glTranslatef(0.05, 0.1, -2);
190 //glRotatef(30, 1, -1, -0.2);
191 //glColor4f(1.0, 0.2, 0.2, 0.5);
192 ////gdk_gl_draw_teapot(TRUE, 0.5);
193 //gdk_gl_draw_cube(TRUE, 0.5);
196 //glTranslatef(pos[0], pos[1], pos[2]);
197 //glTranslatef(-0.2, 0, -2);
198 //glRotatef(30, 1, -1, -0.2);
199 //glColor4f(0.2, 0.2, 1.0, 0.5);
200 ////gdk_gl_draw_teapot(TRUE, 0.5);
201 //gdk_gl_draw_cube(TRUE, 0.5);
205 GdkGLDrawable *gldrawable = gdk_gl_drawable_get_current();
206 if (gdk_gl_drawable_is_double_buffered(gldrawable))
207 gdk_gl_drawable_swap_buffers(gldrawable);
213 static gboolean on_configure(GtkWidget *drawing, GdkEventConfigure *event, gpointer _)
215 gdouble width = drawing->allocation.width;
216 gdouble height = drawing->allocation.height;
217 glViewport(0, 0, width, height);
219 /* Set up projection */
220 glMatrixMode(GL_PROJECTION);
222 //gluPerspective(90, width/height, 0.1, 10);
223 gluPerspective(90, 0.8, 0.1, 10);
224 //glOrtho(1,-1, -0.7,0.7, -10,10);
228 static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer _)
230 guint kv = event->keyval;
231 if (kv == GDK_q) gtk_main_quit();
232 else if (kv == GDK_h) pos[0] -= 0.02;
233 else if (kv == GDK_j) pos[1] += 0.02;
234 else if (kv == GDK_k) pos[1] -= 0.02;
235 else if (kv == GDK_l) pos[0] += 0.02;
236 else if (kv == GDK_o) pos[2] -= 0.02;
237 else if (kv == GDK_i) pos[2] += 0.02;
238 else if (kv == GDK_H) rot[2] -= 2.0;
239 else if (kv == GDK_J) rot[0] += 2.0;
240 else if (kv == GDK_K) rot[0] -= 2.0;
241 else if (kv == GDK_L) rot[2] += 2.0;
242 gtk_widget_queue_draw(widget);
246 static guint load_tex(gchar *filename)
248 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
249 guchar *pixels = gdk_pixbuf_get_pixels(pixbuf);
250 int width = gdk_pixbuf_get_width(pixbuf);
251 int height = gdk_pixbuf_get_height(pixbuf);
252 int alpha = gdk_pixbuf_get_has_alpha(pixbuf);
254 glGenTextures(1, &tex);
255 glBindTexture(GL_TEXTURE_2D, tex);
256 glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0,
257 (alpha ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, pixels);
258 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
259 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
261 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
262 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
263 g_object_unref(pixbuf);
267 int main(int argc, char **argv)
269 gtk_init(&argc, &argv);
271 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
272 GtkWidget *drawing = gtk_drawing_area_new();
273 GdkGLConfig *glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(
274 GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH |
275 GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA));
276 g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
277 g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL);
278 g_signal_connect(drawing, "expose-event", G_CALLBACK(on_expose), NULL);
279 g_signal_connect(drawing, "configure-event", G_CALLBACK(on_configure), NULL);
280 gtk_widget_set_gl_capability(drawing, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
281 gtk_container_add(GTK_CONTAINER(window), drawing);
282 gtk_widget_show_all(window);
285 GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(drawing));
286 GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(drawing));
287 gdk_gl_drawable_gl_begin(gldrawable, glcontext);
290 tex = load_tex("flag.png");
294 gdk_gl_drawable_gl_end(gldrawable);