exercise glDeleteProgramsARB
[mesa.git] / progs / demos / pixeltex.c
1 /*
2 * GL_SGIS_pixel_texture demo
3 *
4 * Brian Paul
5 * 6 Apr 2000
6 *
7 * Copyright (C) 2000 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 /*
29 * How this works:
30 * 1. We load the image into a 2D texture.
31 * 2. We generate a sequence of RGB images in which the R component
32 * is really the S texture coordinate and the G component is really
33 * the T texture coordinate.
34 * By warping the mapping from R to S and G to T we can get non-linear
35 * distortions.
36 * 3. Draw the warped image (a 2-D warping function) with pixel texgen
37 * enabled.
38 * 4. Loop over the warped images to animate.
39 *
40 * The pixel texgen extension can also be used to do color-space
41 * conversions. For example, we could convert YCR to RGB with a
42 * 3D texture map which takes YCR as the S,T,R texture coordinate and
43 * returns RGB texel values.
44 *
45 * You can use this extension in (at least) two ways:
46 * 1. glDrawPixels w/ color space conversion/warping
47 * 2. glDrawPixels to spatially warp another image in texture memory
48 *
49 * We're basically using glDrawPixels to draw a texture coordinate image.
50 */
51
52
53 #include <math.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <GL/glut.h>
58 #include <GL/glext.h>
59 #include "readtex.c" /* I know, this is a hack. */
60
61 #define TEXTURE_FILE "../images/girl.rgb"
62
63 static int ImgWidth = 300, ImgHeight = 300;
64 #define FRAMES 20
65 static GLubyte *ImgData[FRAMES];
66 static GLint Frame = 0;
67
68 static GLboolean TextureFlag = GL_TRUE;
69
70
71 static void Display( void )
72 {
73 glClear( GL_COLOR_BUFFER_BIT );
74
75 if (TextureFlag) {
76 glEnable(GL_PIXEL_TEXTURE_SGIS);
77 glEnable(GL_TEXTURE_2D);
78 }
79 else {
80 glDisable(GL_PIXEL_TEXTURE_SGIS);
81 glDisable(GL_TEXTURE_2D);
82 }
83
84 glColor3f(1, 1, 1);
85 glRasterPos2f(10, 10);
86 glDrawPixels(ImgWidth, ImgHeight, GL_RGB, GL_UNSIGNED_BYTE, ImgData[Frame]);
87
88 glutSwapBuffers();
89 }
90
91
92 static void Reshape( int width, int height )
93 {
94 glViewport( 0, 0, width, height );
95 glMatrixMode( GL_PROJECTION );
96 glLoadIdentity();
97 glOrtho(0, width, 0, height, -1, 1);
98 glMatrixMode( GL_MODELVIEW );
99 glLoadIdentity();
100 }
101
102
103 static void Key( unsigned char key, int x, int y )
104 {
105 (void) x;
106 (void) y;
107 switch (key) {
108 case ' ':
109 TextureFlag = !TextureFlag;
110 break;
111 case 27:
112 exit(0);
113 break;
114 }
115 glutPostRedisplay();
116 }
117
118
119 static void Idle(void)
120 {
121 Frame++;
122 if (Frame >= FRAMES)
123 Frame = 0;
124 glutPostRedisplay();
125 }
126
127
128 static GLubyte warp(GLfloat s, int frame)
129 {
130 static const GLfloat pi = 3.14159265;
131 static int halfFrame = FRAMES / 2;
132 GLfloat y, weight, v;
133 if (frame >= halfFrame)
134 frame = halfFrame - (frame - halfFrame);
135 y = sin(s * pi);
136 weight = (float) frame / (FRAMES-1);
137 v = y * (0.8 * weight + 0.2);
138 return (GLint) (v * 255.0F);
139 }
140
141
142 static void InitImage(void)
143 {
144 int i, j, frame;
145 for (frame = 0; frame < FRAMES; frame++) {
146 ImgData[frame] = (GLubyte *) malloc(ImgWidth * ImgHeight * 3);
147 for (i = 0; i < ImgHeight; i++) {
148 for (j = 0; j < ImgWidth; j++) {
149 GLubyte *pixel = ImgData[frame] + (i * ImgWidth + j) * 3;
150 pixel[0] = warp((float) j / (ImgWidth - 0), frame);
151 pixel[1] = warp((float) i / (ImgHeight - 0), frame);
152 pixel[2] = 0.0;
153 }
154 }
155 }
156 }
157
158
159 static void Init( int argc, char *argv[] )
160 {
161 const char *exten = (const char *) glGetString(GL_EXTENSIONS);
162 if (!strstr(exten, "GL_SGIS_pixel_texture")) {
163 printf("Sorry, GL_SGIS_pixel_texture not supported by this renderer.\n");
164 exit(1);
165 }
166
167 /* linear filtering looks nicer, but it's slower, since it's in software */
168 #if 1
169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
171 #else
172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
174 #endif
175
176 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
177
178 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
179
180 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
181 printf("Error: couldn't load texture image\n");
182 exit(1);
183 }
184
185 glClearColor(0.3, 0.3, 0.4, 1.0);
186
187 InitImage();
188
189 printf("Hit SPACE to toggle pixel texgen\n");
190 }
191
192
193 int main( int argc, char *argv[] )
194 {
195 glutInit( &argc, argv );
196 glutInitWindowSize( 330, 330 );
197 glutInitWindowPosition( 0, 0 );
198 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
199 glutCreateWindow(argv[0] );
200
201 Init( argc, argv );
202
203 glutKeyboardFunc( Key );
204 glutReshapeFunc( Reshape );
205 glutDisplayFunc( Display );
206 glutIdleFunc( Idle );
207
208 glutMainLoop();
209 return 0;
210 }