]> Pileus Git - grits/blob - examples/tex/tex.c
cdd03228591875fb122a661a3be478c5e16f152b
[grits] / examples / tex / tex.c
1 /*
2  * Copyright (C) 2009-2010 Andy Spencer <andy753421@gmail.com>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <gtk/gtk.h>
19 #include <gtk/gtkgl.h>
20 #include <gdk/gdkkeysyms.h>
21 #include <GL/gl.h>
22 #include <GL/glu.h>
23
24 guint tex, texl, texr, mask;
25
26 gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer _)
27 {
28         if (event->keyval == GDK_q)
29                 gtk_main_quit();
30         return FALSE;
31 }
32
33 gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _)
34 {
35         gdouble y = 0;
36
37         /* Setup view */
38         glMatrixMode(GL_PROJECTION);
39         glLoadIdentity();
40         glOrtho(-1,1, -1,1, 10,-10);
41         glMatrixMode(GL_MODELVIEW);
42         glLoadIdentity();
43         glTranslatef(0, 0, -5);
44         glClearColor(0.5, 0.5, 1.0, 1.0);
45         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
46
47         /* Draw white background rectangle */
48         glEnable(GL_COLOR_MATERIAL);
49         glDisable(GL_TEXTURE_2D);
50         glColor3f(1.0, 1.0, 1.0);
51         glBegin(GL_QUADS);
52         glVertex3f(-0.25, -0.75, 0.0);
53         glVertex3f(-0.25,  0.75, 0.0);
54         glVertex3f( 0.25,  0.75, 0.0);
55         glVertex3f( 0.25, -0.75, 0.0);
56         glEnd();
57
58         /* Setup for textures */
59         glEnable(GL_TEXTURE_2D);
60         glEnable(GL_BLEND);
61         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
62         glDisable(GL_COLOR_MATERIAL);
63
64         /* Setup mask */
65         glActiveTexture(GL_TEXTURE1);
66         glEnable(GL_TEXTURE_2D);
67         glBindTexture(GL_TEXTURE_2D, mask);
68         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
69
70         glActiveTexture(GL_TEXTURE0);
71         glEnable(GL_TEXTURE_2D);
72         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
73
74         /* Left */
75         glBindTexture(GL_TEXTURE_2D, texl);
76         glBegin(GL_QUADS);
77         glMultiTexCoord2f(GL_TEXTURE0,  0.0, y);     glMultiTexCoord2f(GL_TEXTURE1,  0.0, y);     glVertex3f(-0.75,  0.0, 0.0);
78         glMultiTexCoord2f(GL_TEXTURE0,  0.0, 1.0);   glMultiTexCoord2f(GL_TEXTURE1,  0.0, 1.0);   glVertex3f(-0.75,  0.5, 0.0);
79         glMultiTexCoord2f(GL_TEXTURE0,  2.0, 1.0);   glMultiTexCoord2f(GL_TEXTURE1,  2.0, 1.0);   glVertex3f( 0.75,  0.5, 0.0);
80         glMultiTexCoord2f(GL_TEXTURE0,  2.0, y);     glMultiTexCoord2f(GL_TEXTURE1,  2.0, y);     glVertex3f( 0.75,  0.0, 0.0);
81         glEnd();
82
83         /* Right */
84         glBindTexture(GL_TEXTURE_2D, texr);
85         glBegin(GL_QUADS);
86         glMultiTexCoord2f(GL_TEXTURE0, -1.0, y);     glMultiTexCoord2f(GL_TEXTURE1, -1.0, y);     glVertex3f(-0.75, 0.0, 0.0);
87         glMultiTexCoord2f(GL_TEXTURE0, -1.0, 1.0);   glMultiTexCoord2f(GL_TEXTURE1, -1.0, 1.0);   glVertex3f(-0.75, 0.5, 0.0);
88         glMultiTexCoord2f(GL_TEXTURE0,  1.0, 1.0);   glMultiTexCoord2f(GL_TEXTURE1,  1.0, 1.0);   glVertex3f( 0.75, 0.5, 0.0);
89         glMultiTexCoord2f(GL_TEXTURE0,  1.0, y);     glMultiTexCoord2f(GL_TEXTURE1,  1.0, y);     glVertex3f( 0.75, 0.0, 0.0);
90         glEnd();
91
92         glActiveTexture(GL_TEXTURE1);
93         glDisable(GL_TEXTURE_2D);
94         glActiveTexture(GL_TEXTURE0);
95
96         /* Bottom */
97         glBindTexture(GL_TEXTURE_2D, tex);
98         glBegin(GL_QUADS);
99         glTexCoord2f( 0.0, 0.0);   glVertex3f(-0.75, -0.5, 0.0);
100         glTexCoord2f( 0.0, 1.0-y); glVertex3f(-0.75, -0.0, 0.0);
101         glTexCoord2f( 1.0, 1.0-y); glVertex3f( 0.75, -0.0, 0.0);
102         glTexCoord2f( 1.0, 0.0);   glVertex3f( 0.75, -0.5, 0.0);
103         glEnd();
104
105         /* Flush */
106         GdkGLDrawable *gldrawable = gdk_gl_drawable_get_current();
107         if (gdk_gl_drawable_is_double_buffered(gldrawable))
108                 gdk_gl_drawable_swap_buffers(gldrawable);
109         else
110                 glFlush();
111         return FALSE;
112 }
113 gboolean on_configure(GtkWidget *drawing, GdkEventConfigure *event, gpointer _)
114 {
115         glViewport(0, 0,
116                 drawing->allocation.width,
117                 drawing->allocation.height);
118         return FALSE;
119 }
120
121 guint load_mask(void)
122 {
123         guint  tex  = 0;
124         guint8 byte = 0xff;
125
126         glGenTextures(1, &tex);
127         glBindTexture(GL_TEXTURE_2D, tex);
128
129         glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0,
130                         GL_ALPHA, GL_UNSIGNED_BYTE, &byte);
131
132         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
133         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
134
135         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
136         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
137
138         return tex;
139 }
140
141 guint load_tex(gchar *filename)
142 {
143         GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
144         guchar    *pixels = gdk_pixbuf_get_pixels(pixbuf);
145         int        width  = gdk_pixbuf_get_width(pixbuf);
146         int        height = gdk_pixbuf_get_height(pixbuf);
147         int        alpha  = gdk_pixbuf_get_has_alpha(pixbuf);
148         guint      tex;
149
150         glGenTextures(1, &tex);
151         glBindTexture(GL_TEXTURE_2D, tex);
152         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
153                         (alpha ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, pixels);
154
155         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
156         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
157
158         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
159         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
160
161         g_object_unref(pixbuf);
162         return tex;
163 }
164
165 int main(int argc, char **argv)
166 {
167         gtk_init(&argc, &argv);
168
169         GtkWidget   *window   = gtk_window_new(GTK_WINDOW_TOPLEVEL);
170         GtkWidget   *drawing  = gtk_drawing_area_new();
171         GdkGLConfig *glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(
172                         GDK_GL_MODE_RGBA   | GDK_GL_MODE_DEPTH |
173                         GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA));
174         g_signal_connect(window,  "destroy",         G_CALLBACK(gtk_main_quit), NULL);
175         g_signal_connect(window,  "key-press-event", G_CALLBACK(on_key_press),  NULL);
176         g_signal_connect(drawing, "expose-event",    G_CALLBACK(on_expose),     NULL);
177         g_signal_connect(drawing, "configure-event", G_CALLBACK(on_configure),  NULL);
178         gtk_widget_set_gl_capability(drawing, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
179         gtk_container_add(GTK_CONTAINER(window), drawing);
180         gtk_widget_show_all(window);
181
182         /* OpenGL setup */
183         GdkGLContext  *glcontext  = gtk_widget_get_gl_context(GTK_WIDGET(drawing));
184         GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(drawing));
185         gdk_gl_drawable_gl_begin(gldrawable, glcontext);
186
187         /* Load texture */
188         mask = load_mask();
189         texl = load_tex("texls.png");
190         texr = load_tex("texrs.png");
191         tex  = load_tex("tex.png");
192
193         gtk_main();
194
195         gdk_gl_drawable_gl_end(gldrawable);
196 }