blob: 08fac15c89d71b75e154152cf3584f7f21ee9dbe [file] [log] [blame]
Brianaa71b882007-07-29 18:04:23 -06001/**
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>
Keith Whitwellb799af92009-06-29 14:13:58 +010012#include <GL/glew.h>
Brianaa71b882007-07-29 18:04:23 -060013#include <GL/gl.h>
14#include <GL/glut.h>
15#include <GL/glext.h>
16#include "extfuncs.h"
Brian2dca3372008-04-09 22:28:23 -060017#include "shaderutil.h"
Brianaa71b882007-07-29 18:04:23 -060018
19
20static GLuint FragShader;
21static GLuint VertShader;
22static GLuint Program;
23
24static GLint Win = 0;
25static GLint WinWidth = 500, WinHeight = 500;
26static GLboolean Anim = GL_TRUE;
27static GLboolean Bitmap = GL_FALSE;
28static GLfloat Xrot = 20.0f, Yrot = 70.0f;
29static GLint uTex, uScale;
30static GLuint Textures[2];
31
32#define TEX_WIDTH 16
33#define TEX_HEIGHT 8
34
35
36static void
37BitmapText(const char *s)
38{
39 while (*s) {
40 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
41 s++;
42 }
43}
44
45
46static void
47Redisplay(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
118static void
119Idle(void)
120{
121 Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.01;
122 glutPostRedisplay();
123}
124
125
126static void
127Reshape(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
141static void
142Key(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
174static void
175SpecialKey(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
197static void
198MakeTexImage(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
224static void
225MakeBitmapTextures(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
251static void
Brianaa71b882007-07-29 18:04:23 -0600252Init(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";
Brianaa71b882007-07-29 18:04:23 -0600277
Brian2dca3372008-04-09 22:28:23 -0600278 if (!ShadersSupported())
Brianaa71b882007-07-29 18:04:23 -0600279 exit(1);
Brianaa71b882007-07-29 18:04:23 -0600280
281 GetExtensionFuncs();
282
Brian2dca3372008-04-09 22:28:23 -0600283 VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
284 FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
285 Program = LinkShaders(VertShader, FragShader);
Brianaa71b882007-07-29 18:04:23 -0600286
Brianaa71b882007-07-29 18:04:23 -0600287 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
306int
307main(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]);
Keith Whitwellb799af92009-06-29 14:13:58 +0100313 glewInit();
Brianaa71b882007-07-29 18:04:23 -0600314 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