From http://www.jwz.org/xscreensaver/xscreensaver-5.16.tar.gz
[xscreensaver] / hacks / glx / dropshadow.c
1 /* dropshadow.c, Copyright (c) 2009 Jens Kilian <jjk@acm.org>
2  *
3  * Permission to use, copy, modify, distribute, and sell this software and its
4  * documentation for any purpose is hereby granted without fee, provided that
5  * the above copyright notice appear in all copies and that both that
6  * copyright notice and this permission notice appear in supporting
7  * documentation.  No representations are made about the suitability of this
8  * software for any purpose.  It is provided "as is" without express or
9  * implied warranty.
10  */
11
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif /* HAVE_CONFIG_H */
15
16 #include <stdlib.h>
17
18 #include "dropshadow.h"
19
20 /* (Alpha) texture data for drop shadow.
21  */
22 static int drop_shadow_width = 32;
23 static int drop_shadow_height = 32;
24 static unsigned char drop_shadow_data[] =
25 {
26   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28   0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
29   0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
30   0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
31   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
32   0, 0, 0, 0, 0, 1, 1, 1, 3, 3, 4, 4, 4, 4, 4, 4,
33   4, 4, 4, 4, 4, 4, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0,
34   0, 0, 0, 0, 1, 1, 3, 4, 6, 7, 9, 10, 10, 10, 10, 10,
35   10, 10, 10, 10, 10, 9, 7, 6, 4, 3, 1, 1, 0, 0, 0, 0,
36   0, 0, 0, 1, 1, 3, 5, 9, 13, 16, 19, 19, 21, 21, 22, 22,
37   22, 22, 21, 21, 19, 19, 16, 13, 9, 5, 3, 1, 1, 0, 0, 0,
38   0, 0, 1, 1, 3, 5, 10, 16, 22, 28, 32, 35, 37, 37, 38, 38,
39   38, 38, 37, 37, 35, 32, 28, 22, 16, 10, 5, 3, 1, 1, 0, 0,
40   0, 0, 1, 1, 4, 9, 16, 25, 34, 43, 50, 55, 58, 59, 60, 60,
41   60, 60, 59, 58, 55, 50, 43, 34, 25, 16, 9, 4, 1, 1, 0, 0,
42   0, 0, 1, 3, 6, 13, 22, 34, 48, 61, 70, 77, 80, 82, 83, 84,
43   84, 83, 82, 80, 77, 70, 61, 48, 34, 22, 13, 6, 3, 1, 0, 0,
44   0, 0, 1, 3, 7, 16, 28, 43, 61, 76, 88, 97, 102, 103, 104, 104,
45   104, 104, 103, 102, 97, 88, 76, 61, 43, 28, 16, 7, 3, 1, 0, 0,
46   0, 1, 1, 4, 9, 19, 32, 51, 70, 88, 103, 112, 117, 120, 121, 121,
47   121, 121, 120, 117, 112, 103, 88, 70, 51, 32, 19, 9, 4, 1, 1, 0,
48   0, 1, 1, 4, 10, 20, 35, 55, 77, 97, 112, 122, 128, 130, 132, 133,
49   133, 132, 130, 128, 122, 112, 97, 77, 55, 35, 20, 10, 4, 1, 1, 0,
50   0, 1, 1, 4, 10, 21, 37, 58, 80, 101, 117, 128, 134, 137, 138, 139,
51   139, 138, 137, 134, 128, 117, 101, 80, 58, 37, 21, 10, 4, 1, 0, 0,
52   0, 0, 1, 4, 10, 21, 38, 59, 82, 103, 119, 130, 137, 139, 141, 142,
53   142, 141, 139, 137, 130, 119, 103, 82, 59, 38, 21, 10, 4, 1, 0, 0,
54   0, 0, 1, 4, 10, 22, 38, 59, 83, 104, 121, 132, 139, 141, 142, 142,
55   142, 142, 141, 139, 132, 121, 104, 83, 59, 38, 22, 10, 4, 1, 0, 0,
56   0, 0, 1, 4, 10, 22, 38, 60, 84, 104, 121, 133, 139, 142, 142, 142,
57   142, 142, 142, 139, 133, 121, 104, 84, 60, 38, 22, 10, 4, 1, 0, 0,
58   0, 0, 1, 4, 10, 22, 38, 60, 84, 104, 121, 133, 139, 142, 142, 142,
59   142, 142, 142, 139, 133, 121, 104, 84, 60, 38, 22, 10, 4, 1, 0, 0,
60   0, 0, 1, 4, 10, 22, 38, 59, 83, 104, 121, 132, 139, 141, 142, 142,
61   142, 142, 141, 139, 132, 121, 104, 83, 59, 38, 22, 10, 4, 1, 0, 0,
62   0, 0, 1, 4, 10, 21, 38, 59, 82, 103, 119, 130, 137, 139, 141, 142,
63   142, 141, 139, 137, 130, 119, 103, 82, 59, 38, 21, 10, 4, 1, 0, 0,
64   0, 1, 1, 4, 10, 21, 37, 58, 80, 101, 118, 128, 134, 137, 139, 139,
65   139, 139, 137, 134, 128, 117, 102, 80, 58, 37, 21, 10, 4, 1, 0, 0,
66   0, 1, 1, 4, 10, 20, 35, 55, 77, 97, 112, 122, 128, 130, 132, 133,
67   133, 132, 130, 128, 122, 112, 97, 77, 55, 35, 20, 10, 4, 1, 1, 0,
68   0, 1, 1, 4, 9, 19, 32, 51, 70, 88, 103, 112, 117, 120, 121, 121,
69   121, 121, 120, 117, 112, 103, 88, 70, 51, 32, 19, 9, 4, 1, 1, 0,
70   0, 0, 1, 3, 7, 16, 28, 43, 61, 76, 88, 97, 102, 103, 104, 104,
71   104, 104, 103, 102, 97, 88, 76, 61, 43, 28, 16, 7, 3, 1, 0, 0,
72   0, 0, 1, 3, 6, 13, 22, 34, 48, 61, 70, 77, 80, 82, 83, 84,
73   84, 83, 82, 80, 77, 70, 61, 48, 34, 22, 13, 6, 3, 1, 0, 0,
74   0, 0, 1, 1, 4, 9, 16, 25, 34, 43, 50, 55, 58, 59, 60, 60,
75   60, 60, 59, 58, 55, 50, 43, 34, 25, 16, 9, 4, 1, 1, 0, 0,
76   0, 0, 1, 1, 3, 5, 10, 16, 22, 28, 32, 35, 37, 37, 38, 38,
77   38, 38, 37, 37, 35, 32, 28, 22, 16, 10, 5, 3, 1, 1, 0, 0,
78   0, 0, 0, 1, 1, 3, 5, 9, 13, 16, 19, 19, 21, 21, 22, 22,
79   22, 22, 21, 21, 19, 19, 16, 13, 9, 5, 3, 1, 1, 0, 0, 0,
80   0, 0, 0, 0, 1, 1, 3, 4, 6, 7, 9, 10, 10, 10, 10, 10,
81   10, 10, 10, 10, 10, 9, 7, 6, 4, 3, 1, 1, 0, 0, 0, 0,
82   0, 0, 0, 0, 0, 1, 1, 1, 3, 3, 4, 4, 4, 4, 4, 4,
83   4, 4, 4, 4, 4, 4, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0,
84   0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
85   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
86   0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
87   0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
88   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
90 };
91
92 GLuint
93 init_drop_shadow(void)
94 {
95     GLuint t;
96
97     glGenTextures (1, &t);
98     if (t <= 0) abort();
99
100     glBindTexture (GL_TEXTURE_2D, t);
101 #if 0
102     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
103     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
104     gluBuild2DMipmaps (GL_TEXTURE_2D, GL_ALPHA,
105                        drop_shadow_width, drop_shadow_height,
106                        GL_ALPHA, GL_UNSIGNED_BYTE,
107                        drop_shadow_data);
108 #else
109     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
110     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
111     glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, 
112                   drop_shadow_width, drop_shadow_height, 0,
113                   GL_ALPHA, GL_UNSIGNED_BYTE,
114                   drop_shadow_data);
115 #endif
116
117     return t;
118 }
119
120 void
121 draw_drop_shadow (GLuint t,
122                   GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h,
123                   GLfloat r)
124 {
125   /* Inner and outer boundaries of shadow. */
126   const GLfloat li = x,     lo = li - r;
127   const GLfloat ri = x + w, ro = ri + r;
128   const GLfloat bi = y,     bo = bi - r;
129   const GLfloat ti = y + h, to = ti + r;
130
131   glEnable (GL_BLEND);
132   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
133
134   glEnable (GL_TEXTURE_2D);
135   glBindTexture (GL_TEXTURE_2D, t);
136
137   glBegin (GL_QUADS);
138
139   /* There's likely a better way to do this... */
140   glTexCoord2f (0.0, 0.0); glVertex3f (lo, bo, z);
141   glTexCoord2f (0.5, 0.0); glVertex3f (li, bo, z);
142   glTexCoord2f (0.5, 0.5); glVertex3f (li, bi, z);
143   glTexCoord2f (0.0, 0.5); glVertex3f (lo, bi, z);
144
145   glTexCoord2f (0.5, 0.0); glVertex3f (li, bo, z);
146   glTexCoord2f (0.5, 0.0); glVertex3f (ri, bo, z);
147   glTexCoord2f (0.5, 0.5); glVertex3f (ri, bi, z);
148   glTexCoord2f (0.5, 0.5); glVertex3f (li, bi, z);
149
150   glTexCoord2f (0.5, 0.0); glVertex3f (ri, bo, z);
151   glTexCoord2f (1.0, 0.0); glVertex3f (ro, bo, z);
152   glTexCoord2f (1.0, 0.5); glVertex3f (ro, bi, z);
153   glTexCoord2f (0.5, 0.5); glVertex3f (ri, bi, z);
154
155   glTexCoord2f (0.5, 0.5); glVertex3f (ri, bi, z);
156   glTexCoord2f (1.0, 0.5); glVertex3f (ro, bi, z);
157   glTexCoord2f (1.0, 0.5); glVertex3f (ro, ti, z);
158   glTexCoord2f (0.5, 0.5); glVertex3f (ri, ti, z);
159
160   glTexCoord2f (0.5, 0.5); glVertex3f (ri, ti, z);
161   glTexCoord2f (1.0, 0.5); glVertex3f (ro, ti, z);
162   glTexCoord2f (1.0, 1.0); glVertex3f (ro, to, z);
163   glTexCoord2f (0.5, 1.0); glVertex3f (ri, to, z);
164
165   glTexCoord2f (0.5, 0.5); glVertex3f (li, ti, z);
166   glTexCoord2f (0.5, 0.5); glVertex3f (ri, ti, z);
167   glTexCoord2f (0.5, 1.0); glVertex3f (ri, to, z);
168   glTexCoord2f (0.5, 1.0); glVertex3f (li, to, z);
169
170   glTexCoord2f (0.0, 0.5); glVertex3f (lo, ti, z);
171   glTexCoord2f (0.5, 0.5); glVertex3f (li, ti, z);
172   glTexCoord2f (0.5, 1.0); glVertex3f (li, to, z);
173   glTexCoord2f (0.0, 1.0); glVertex3f (lo, to, z);
174
175   glTexCoord2f (0.0, 0.5); glVertex3f (lo, bi, z);
176   glTexCoord2f (0.5, 0.5); glVertex3f (li, bi, z);
177   glTexCoord2f (0.5, 0.5); glVertex3f (li, ti, z);
178   glTexCoord2f (0.0, 0.5); glVertex3f (lo, ti, z);
179
180   glEnd();
181 }