]> Pileus Git - grits/blob - examples/shader/shader.c
3d6d3d42942af6c3eca3f0ba0732f5acbabd761b
[grits] / examples / shader / shader.c
1 #define GL_GLEXT_PROTOTYPES
2 #include <gtk/gtk.h>
3 #include <gtk/gtkgl.h>
4 #include <gdk/gdkkeysyms.h>
5 #include <GL/gl.h>
6 #include <GL/glext.h>
7
8 gchar *gl_program_log(guint program, int *_len)
9 {
10         gchar *buf = NULL;
11         int len = 0;
12         glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
13         if (len > 0) {
14                 buf = g_malloc(len);
15                 glGetProgramInfoLog(program, len, &len, buf);
16         }
17         if (_len)
18                 *_len = len;
19         return buf;
20 }
21
22 void on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
23 {
24         g_message("key-press");
25         if (event->keyval == GDK_q)
26                 gtk_main_quit();
27 }
28
29 gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _)
30 {
31         glClearColor(0.5, 0.5, 1.0, 1.0);
32         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
33
34         glMatrixMode(GL_PROJECTION);
35         glLoadIdentity();
36         glOrtho(-1,1, -1,1, 10,-10);
37         glMatrixMode(GL_MODELVIEW);
38         glLoadIdentity();
39         glTranslatef(0, 0, -5);
40
41         glEnable(GL_COLOR_MATERIAL);
42         glDisable(GL_TEXTURE_2D);
43         glColor3f(1.0, 1.0, 1.0);
44         glBegin(GL_QUADS);
45         glVertex3f(-0.25, -0.75, 0.0);
46         glVertex3f(-0.25,  0.75, 0.0);
47         glVertex3f( 0.25,  0.75, 0.0);
48         glVertex3f( 0.25, -0.75, 0.0);
49         glEnd();
50
51         /* Test projection */
52         gdouble model[16], proj[16];
53         gint view[4];
54         glGetDoublev (GL_MODELVIEW_MATRIX,  model);
55         glGetDoublev (GL_PROJECTION_MATRIX, proj);
56         glGetIntegerv(GL_VIEWPORT,          view);
57         gdouble x=0.25, y=-0.75, z=0.0;
58         gdouble px, py, pz;
59         gluProject(x, y, z, model, proj, view, &px, &py, &pz);
60         g_message("%f,%f,%f -> %f,%f,%f", x, y, z, px, py, pz);
61
62         /* Textures */
63         glDisable(GL_COLOR_MATERIAL);
64         glEnable(GL_TEXTURE_2D);
65         glEnable(GL_BLEND);
66
67         /* Flush */
68         GdkGLDrawable *gldrawable = gdk_gl_drawable_get_current();
69         if (gdk_gl_drawable_is_double_buffered(gldrawable))
70                 gdk_gl_drawable_swap_buffers(gldrawable);
71         else
72                 glFlush();
73         return FALSE;
74 }
75
76 gboolean on_configure(GtkWidget *drawing, GdkEventConfigure *event, gpointer _)
77 {
78         glViewport(0, 0,
79                 drawing->allocation.width,
80                 drawing->allocation.height);
81         return FALSE;
82 }
83
84 int main(int argc, char **argv)
85 {
86         gtk_init(&argc, &argv);
87
88         GtkWidget   *window   = gtk_window_new(GTK_WINDOW_TOPLEVEL);
89         GtkWidget   *drawing  = gtk_drawing_area_new();
90         GdkGLConfig *glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(
91                         GDK_GL_MODE_RGBA   | GDK_GL_MODE_DEPTH |
92                         GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA));
93         g_signal_connect(window,  "destroy",         G_CALLBACK(gtk_main_quit), NULL);
94         g_signal_connect(window,  "key-press-event", G_CALLBACK(on_key_press),  NULL);
95         g_signal_connect(drawing, "expose-event",    G_CALLBACK(on_expose),     NULL);
96         g_signal_connect(drawing, "configure-event", G_CALLBACK(on_configure),  NULL);
97         gtk_widget_set_gl_capability(drawing, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
98         gtk_container_add(GTK_CONTAINER(window), drawing);
99         gtk_widget_show_all(window);
100
101         /* OpenGL setup */
102         GdkGLContext  *glcontext  = gtk_widget_get_gl_context(GTK_WIDGET(drawing));
103         GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(drawing));
104
105         /* Setup shader */
106         gdk_gl_drawable_gl_begin(gldrawable, glcontext);
107
108         gchar *source;
109         gboolean status = g_file_get_contents("shader.glsl", &source, NULL, NULL);
110         if (!status)
111                 g_error("Failed to load shader");
112
113         guint program = glCreateProgram();
114         if (!program)
115                 g_error("Error creating program");
116
117         guint shader = glCreateShader(GL_VERTEX_SHADER_ARB);
118         if (!shader)
119                 g_error("Error creating shader");
120
121         glShaderSource(shader, 1, (const gchar**)&source, NULL);
122         if (glGetError())
123                 g_error("Error setting shader source");
124
125         glCompileShader(shader);
126         if (glGetError())
127                 g_error("Error compiling shader");
128
129         glAttachShader(program, shader);
130         if (glGetError())
131                 g_error("Error attaching shader");
132
133         glLinkProgram(program);
134         if (glGetError())
135                 g_error("Error linking program");
136
137         glUseProgram(program);
138         if (glGetError())
139                 g_error("Error using program:\n%s", gl_program_log(program, NULL));
140
141         /* Run */
142         gtk_main();
143
144         /* Clean up */
145         glDetachShader(program, shader);
146         glDeleteShader(shader);
147         glDeleteProgram(program);
148
149         gdk_gl_drawable_gl_end(gldrawable);
150         return 0;
151 }