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