progs/glsl: compile with scons and glew
[mesa.git] / progs / glsl / bitmap.c
1 /**
2 * Implement glRasterPos + glBitmap with textures + shaders.
3 * Brian Paul
4 * 14 May 2007
5 */
6
7 #include <assert.h>
8 #include <string.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <math.h>
12 #include <GL/glew.h>
13 #include <GL/gl.h>
14 #include <GL/glut.h>
15 #include <GL/glext.h>
16 #include "extfuncs.h"
17 #include "shaderutil.h"
18
19
20 static GLuint FragShader;
21 static GLuint VertShader;
22 static GLuint Program;
23
24 static GLint Win = 0;
25 static GLint WinWidth = 500, WinHeight = 500;
26 static GLboolean Anim = GL_TRUE;
27 static GLboolean Bitmap = GL_FALSE;
28 static GLfloat Xrot = 20.0f, Yrot = 70.0f;
29 static GLint uTex, uScale;
30 static GLuint Textures[2];
31
32 #define TEX_WIDTH 16
33 #define TEX_HEIGHT 8
34
35
36 static void
37 BitmapText(const char *s)
38 {
39 while (*s) {
40 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
41 s++;
42 }
43 }
44
45
46 static void
47 Redisplay(void)
48 {
49 static const GLfloat px[3] = { 1.2, 0, 0};
50 static const GLfloat nx[3] = {-1.2, 0, 0};
51
52 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
53
54 glPushMatrix();
55 glRotatef(Xrot, 1.0f, 0.0f, 0.0f);
56 glRotatef(Yrot, 0.0f, 1.0f, 0.0f);
57
58 glEnable(GL_LIGHTING);
59
60 glPushMatrix();
61 glScalef(0.5, 0.5, 0.5);
62 glutSolidDodecahedron();
63 glPopMatrix();
64
65 glDisable(GL_LIGHTING);
66
67 glColor3f(0, 1, 0);
68 glBegin(GL_LINES);
69 glVertex3f(-1, 0, 0);
70 glVertex3f( 1, 0, 0);
71 glEnd();
72
73 glColor3f(1, 1, 0);
74
75 if (Bitmap) {
76 glRasterPos3fv(px);
77 BitmapText("+X");
78 glRasterPos3fv(nx);
79 BitmapText("-X");
80 }
81 else {
82 glUseProgram_func(Program);
83
84 /* vertex positions (deltas) depend on texture size and window size */
85 if (uScale != -1) {
86 glUniform2f_func(uScale,
87 2.0 * TEX_WIDTH / WinWidth,
88 2.0 * TEX_HEIGHT / WinHeight);
89 }
90
91 /* draw +X */
92 glBindTexture(GL_TEXTURE_2D, Textures[0]);
93 glBegin(GL_QUADS);
94 glTexCoord2f(0, 0); glVertex3fv(px);
95 glTexCoord2f(1, 0); glVertex3fv(px);
96 glTexCoord2f(1, 1); glVertex3fv(px);
97 glTexCoord2f(0, 1); glVertex3fv(px);
98 glEnd();
99
100 /* draw -X */
101 glBindTexture(GL_TEXTURE_2D, Textures[1]);
102 glBegin(GL_QUADS);
103 glTexCoord2f(0, 0); glVertex3fv(nx);
104 glTexCoord2f(1, 0); glVertex3fv(nx);
105 glTexCoord2f(1, 1); glVertex3fv(nx);
106 glTexCoord2f(0, 1); glVertex3fv(nx);
107 glEnd();
108
109 glUseProgram_func(0);
110 }
111
112 glPopMatrix();
113
114 glutSwapBuffers();
115 }
116
117
118 static void
119 Idle(void)
120 {
121 Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.01;
122 glutPostRedisplay();
123 }
124
125
126 static void
127 Reshape(int width, int height)
128 {
129 WinWidth = width;
130 WinHeight = height;
131 glViewport(0, 0, width, height);
132 glMatrixMode(GL_PROJECTION);
133 glLoadIdentity();
134 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
135 glMatrixMode(GL_MODELVIEW);
136 glLoadIdentity();
137 glTranslatef(0.0f, 0.0f, -10.0f);
138 }
139
140
141 static void
142 Key(unsigned char key, int x, int y)
143 {
144 (void) x;
145 (void) y;
146
147 switch(key) {
148 case ' ':
149 case 'a':
150 Anim = !Anim;
151 if (Anim)
152 glutIdleFunc(Idle);
153 else
154 glutIdleFunc(NULL);
155 break;
156 case 'b':
157 Bitmap = !Bitmap;
158 if (Bitmap)
159 printf("Using glBitmap\n");
160 else
161 printf("Using billboard texture\n");
162 break;
163 case 27:
164 glDeleteShader_func(FragShader);
165 glDeleteShader_func(VertShader);
166 glDeleteProgram_func(Program);
167 glutDestroyWindow(Win);
168 exit(0);
169 }
170 glutPostRedisplay();
171 }
172
173
174 static void
175 SpecialKey(int key, int x, int y)
176 {
177 const GLfloat step = 0.125f;
178 switch(key) {
179 case GLUT_KEY_UP:
180 Xrot -= step;
181 break;
182 case GLUT_KEY_DOWN:
183 Xrot += step;
184 break;
185 case GLUT_KEY_LEFT:
186 Yrot -= step;
187 break;
188 case GLUT_KEY_RIGHT:
189 Yrot += step;
190 break;
191 }
192 /*printf("Xrot: %f Yrot: %f\n", Xrot, Yrot);*/
193 glutPostRedisplay();
194 }
195
196
197 static void
198 MakeTexImage(const char *p, GLuint texobj)
199 {
200 GLubyte image[TEX_HEIGHT][TEX_WIDTH];
201 GLuint i, j, k;
202
203 for (i = 0; i < TEX_HEIGHT; i++) {
204 for (j = 0; j < TEX_WIDTH; j++) {
205 k = i * TEX_WIDTH + j;
206 if (p[k] == ' ') {
207 image[i][j] = 0;
208 }
209 else {
210 image[i][j] = 255;
211 }
212 }
213 }
214
215 glBindTexture(GL_TEXTURE_2D, texobj);
216 glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, TEX_WIDTH, TEX_HEIGHT, 0,
217 GL_RED, GL_UNSIGNED_BYTE, image);
218 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
221 }
222
223
224 static void
225 MakeBitmapTextures(void)
226 {
227 const char *px =
228 " X X "
229 " X X X "
230 " X X X "
231 " XXXXX X "
232 " X X X "
233 " X X X "
234 " X X "
235 " X X ";
236 const char *nx =
237 " X X "
238 " X X "
239 " X X "
240 " XXXXX X "
241 " X X "
242 " X X "
243 " X X "
244 " X X ";
245 glGenTextures(2, Textures);
246 MakeTexImage(px, Textures[0]);
247 MakeTexImage(nx, Textures[1]);
248 }
249
250
251 static void
252 Init(void)
253 {
254 /* Fragment shader: modulate raster color by texture, discard fragments
255 * with alpha < 1.0
256 */
257 static const char *fragShaderText =
258 "uniform sampler2D tex2d; \n"
259 "void main() {\n"
260 " vec4 c = texture2D(tex2d, gl_TexCoord[0].xy); \n"
261 " if (c.w < 1.0) \n"
262 " discard; \n"
263 " gl_FragColor = c * gl_Color; \n"
264 "}\n";
265 /* Vertex shader: compute new vertex position based on incoming vertex pos,
266 * texcoords and special scale factor.
267 */
268 static const char *vertShaderText =
269 "uniform vec2 scale; \n"
270 "void main() {\n"
271 " vec4 p = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
272 " gl_Position.xy = p.xy + gl_MultiTexCoord0.xy * scale * p.w; \n"
273 " gl_Position.zw = p.zw; \n"
274 " gl_TexCoord[0] = gl_MultiTexCoord0; \n"
275 " gl_FrontColor = gl_Color; \n"
276 "}\n";
277
278 if (!ShadersSupported())
279 exit(1);
280
281 GetExtensionFuncs();
282
283 VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
284 FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
285 Program = LinkShaders(VertShader, FragShader);
286
287 glUseProgram_func(Program);
288
289 uScale = glGetUniformLocation_func(Program, "scale");
290 uTex = glGetUniformLocation_func(Program, "tex2d");
291 if (uTex != -1) {
292 glUniform1i_func(uTex, 0); /* tex unit 0 */
293 }
294
295 glUseProgram_func(0);
296
297 glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
298 glEnable(GL_DEPTH_TEST);
299 glEnable(GL_NORMALIZE);
300 glEnable(GL_LIGHT0);
301
302 MakeBitmapTextures();
303 }
304
305
306 int
307 main(int argc, char *argv[])
308 {
309 glutInit(&argc, argv);
310 glutInitWindowSize(WinWidth, WinHeight);
311 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
312 Win = glutCreateWindow(argv[0]);
313 glewInit();
314 glutReshapeFunc(Reshape);
315 glutKeyboardFunc(Key);
316 glutSpecialFunc(SpecialKey);
317 glutDisplayFunc(Redisplay);
318 if (Anim)
319 glutIdleFunc(Idle);
320 Init();
321 glutMainLoop();
322 return 0;
323 }
324
325