/* * Copyright (C) 2009-2010 Andy Spencer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #define GL_GLEXT_PROTOTYPES #include #include #include #include #include gchar *gl_program_log(guint program, int *_len) { gchar *buf = NULL; int len = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len); if (len > 0) { buf = g_malloc(len); glGetProgramInfoLog(program, len, &len, buf); } if (_len) *_len = len; return buf; } void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { g_message("key-press"); if (event->keyval == GDK_q) gtk_main_quit(); } gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _) { glClearColor(0.5, 0.5, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1,1, -1,1, 10,-10); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0, 0, -5); glEnable(GL_COLOR_MATERIAL); glDisable(GL_TEXTURE_2D); glColor3f(1.0, 1.0, 1.0); glBegin(GL_QUADS); glVertex3f(-0.25, -0.75, 0.0); glVertex3f(-0.25, 0.75, 0.0); glVertex3f( 0.25, 0.75, 0.0); glVertex3f( 0.25, -0.75, 0.0); glEnd(); /* Test projection */ gdouble model[16], proj[16]; gint view[4]; glGetDoublev (GL_MODELVIEW_MATRIX, model); glGetDoublev (GL_PROJECTION_MATRIX, proj); glGetIntegerv(GL_VIEWPORT, view); gdouble x=0.25, y=-0.75, z=0.0; gdouble px, py, pz; gluProject(x, y, z, model, proj, view, &px, &py, &pz); g_message("%f,%f,%f -> %f,%f,%f", x, y, z, px, py, pz); /* Textures */ glDisable(GL_COLOR_MATERIAL); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); /* Flush */ GdkGLDrawable *gldrawable = gdk_gl_drawable_get_current(); if (gdk_gl_drawable_is_double_buffered(gldrawable)) gdk_gl_drawable_swap_buffers(gldrawable); else glFlush(); return FALSE; } gboolean on_configure(GtkWidget *drawing, GdkEventConfigure *event, gpointer _) { glViewport(0, 0, drawing->allocation.width, drawing->allocation.height); return FALSE; } int main(int argc, char **argv) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *drawing = gtk_drawing_area_new(); GdkGLConfig *glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)( GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA)); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL); g_signal_connect(drawing, "expose-event", G_CALLBACK(on_expose), NULL); g_signal_connect(drawing, "configure-event", G_CALLBACK(on_configure), NULL); gtk_widget_set_gl_capability(drawing, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); gtk_container_add(GTK_CONTAINER(window), drawing); gtk_widget_show_all(window); /* OpenGL setup */ GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(drawing)); GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(drawing)); /* Setup shader */ gdk_gl_drawable_gl_begin(gldrawable, glcontext); gchar *source; gboolean status = g_file_get_contents("shader.glsl", &source, NULL, NULL); if (!status) g_error("Failed to load shader"); guint program = glCreateProgram(); if (!program) g_error("Error creating program"); guint shader = glCreateShader(GL_VERTEX_SHADER_ARB); if (!shader) g_error("Error creating shader"); glShaderSource(shader, 1, (const gchar**)&source, NULL); if (glGetError()) g_error("Error setting shader source"); glCompileShader(shader); if (glGetError()) g_error("Error compiling shader"); glAttachShader(program, shader); if (glGetError()) g_error("Error attaching shader"); glLinkProgram(program); if (glGetError()) g_error("Error linking program"); glUseProgram(program); if (glGetError()) g_error("Error using program:\n%s", gl_program_log(program, NULL)); /* Run */ gtk_main(); /* Clean up */ glDetachShader(program, shader); glDeleteShader(shader); glDeleteProgram(program); gdk_gl_drawable_gl_end(gldrawable); return 0; }