]> Pileus Git - grits/blob - examples/tex/tex.c
bef3a340c309b29124f0606fa2cd1920680446dc
[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;
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.875;
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         /* Clear background for GL_ONE */
59         glEnable(GL_COLOR_MATERIAL);
60         glDisable(GL_TEXTURE_2D);
61         glColor4f(0.0, 0.0, 0.0, 0.0);
62         glBegin(GL_QUADS);
63         glVertex3f(-0.75,  0.0, 0.0);
64         glVertex3f(-0.75,  0.5, 0.0);
65         glVertex3f( 0.75,  0.5, 0.0);
66         glVertex3f( 0.75,  0.0, 0.0);
67         glEnd();
68
69         /* Setup for textures */
70         glEnable(GL_TEXTURE_2D);
71         glEnable(GL_BLEND);
72         glColor4f(1.0, 1.0, 1.0, 1.0);
73         glDisable(GL_COLOR_MATERIAL);
74         glBlendFunc(GL_ONE, GL_ONE);
75
76         /* Left */
77         glBindTexture(GL_TEXTURE_2D, texl);
78         glBegin(GL_QUADS);
79         glTexCoord2f( 0.0, y);     glVertex3f(-0.75,  0.0, 0.0);
80         glTexCoord2f( 0.0, 1.0);   glVertex3f(-0.75,  0.5, 0.0);
81         glTexCoord2f( 2.0, 1.0);   glVertex3f( 0.75,  0.5, 0.0);
82         glTexCoord2f( 2.0, y);     glVertex3f( 0.75,  0.0, 0.0);
83         glEnd();
84
85         /* Right */
86         glBindTexture(GL_TEXTURE_2D, texr);
87         glBegin(GL_QUADS);
88         glTexCoord2f(-1.0, y);     glVertex3f(-0.75, 0.0, 0.0);
89         glTexCoord2f(-1.0, 1.0);   glVertex3f(-0.75, 0.5, 0.0);
90         glTexCoord2f( 1.0, 1.0);   glVertex3f( 0.75, 0.5, 0.0);
91         glTexCoord2f( 1.0, y);     glVertex3f( 0.75, 0.0, 0.0);
92         glEnd();
93
94         /* Bottom */
95         glBlendFunc(GL_ONE, GL_ZERO);
96         glBindTexture(GL_TEXTURE_2D, tex);
97         glBegin(GL_QUADS);
98         glTexCoord2f( 0.0, 0.0);   glVertex3f(-0.75, -0.5, 0.0);
99         glTexCoord2f( 0.0, 1.0-y); glVertex3f(-0.75, -0.0, 0.0);
100         glTexCoord2f( 1.0, 1.0-y); glVertex3f( 0.75, -0.0, 0.0);
101         glTexCoord2f( 1.0, 0.0);   glVertex3f( 0.75, -0.5, 0.0);
102         glEnd();
103
104         /* Flush */
105         GdkGLDrawable *gldrawable = gdk_gl_drawable_get_current();
106         if (gdk_gl_drawable_is_double_buffered(gldrawable))
107                 gdk_gl_drawable_swap_buffers(gldrawable);
108         else
109                 glFlush();
110         return FALSE;
111 }
112 gboolean on_configure(GtkWidget *drawing, GdkEventConfigure *event, gpointer _)
113 {
114         glViewport(0, 0,
115                 drawing->allocation.width,
116                 drawing->allocation.height);
117         return FALSE;
118 }
119
120 guint load_tex(gchar *filename)
121 {
122         GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
123         guchar    *pixels = gdk_pixbuf_get_pixels(pixbuf);
124         int        width  = gdk_pixbuf_get_width(pixbuf);
125         int        height = gdk_pixbuf_get_height(pixbuf);
126         int        alpha  = gdk_pixbuf_get_has_alpha(pixbuf);
127         guint      tex;
128         glGenTextures(1, &tex);
129         glBindTexture(GL_TEXTURE_2D, tex);
130         glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0,
131                         (alpha ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, pixels);
132         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
133         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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         g_object_unref(pixbuf);
138         return tex;
139 }
140
141 int main(int argc, char **argv)
142 {
143         gtk_init(&argc, &argv);
144
145         GtkWidget   *window   = gtk_window_new(GTK_WINDOW_TOPLEVEL);
146         GtkWidget   *drawing  = gtk_drawing_area_new();
147         GdkGLConfig *glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(
148                         GDK_GL_MODE_RGBA   | GDK_GL_MODE_DEPTH |
149                         GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA));
150         g_signal_connect(window,  "destroy",         G_CALLBACK(gtk_main_quit), NULL);
151         g_signal_connect(window,  "key-press-event", G_CALLBACK(on_key_press),  NULL);
152         g_signal_connect(drawing, "expose-event",    G_CALLBACK(on_expose),     NULL);
153         g_signal_connect(drawing, "configure-event", G_CALLBACK(on_configure),  NULL);
154         gtk_widget_set_gl_capability(drawing, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
155         gtk_container_add(GTK_CONTAINER(window), drawing);
156         gtk_widget_show_all(window);
157
158         /* OpenGL setup */
159         GdkGLContext  *glcontext  = gtk_widget_get_gl_context(GTK_WIDGET(drawing));
160         GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(drawing));
161         gdk_gl_drawable_gl_begin(gldrawable, glcontext);
162
163         /* Load texture */
164         texl = load_tex("texls.png");
165         texr = load_tex("texrs.png");
166         tex  = load_tex("tex.png");
167
168         gtk_main();
169
170         gdk_gl_drawable_gl_end(gldrawable);
171 }