progs/tests: also test stencil INCR_WRAP mode if supported
[mesa.git] / progs / tests / ext422square.c
1 /*
2 * Exercise the EXT_422_pixels extension, a less convenient
3 * alternative to MESA_ycbcr_texture. Requires ARB_fragment_program
4 * to perform the final YUV->RGB conversion.
5 *
6 * Brian Paul 13 September 2002
7 * Keith Whitwell 30 November 2004
8 */
9
10
11 #include <math.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <GL/glew.h>
16 #include <GL/glut.h>
17 #include <assert.h>
18
19 #include "../util/readtex.c" /* I know, this is a hack. */
20
21 #define TEXTURE_FILE "../images/tile.rgb"
22
23 static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
24 static GLint ImgWidth, ImgHeight;
25 static GLushort *ImageYUV = NULL;
26 static const GLuint yuvObj = 100;
27 static const GLuint rgbObj = 101;
28
29 static void Init( int argc, char *argv[] );
30
31 static void DrawObject(void)
32 {
33 glBegin(GL_QUADS);
34
35 glTexCoord2f(0, 0);
36 glVertex2f(-1.0, -1.0);
37
38 glTexCoord2f(1, 0);
39 glVertex2f(1.0, -1.0);
40
41 glTexCoord2f(1, 1);
42 glVertex2f(1.0, 1.0);
43
44 glTexCoord2f(0, 1);
45 glVertex2f(-1.0, 1.0);
46
47 glEnd();
48 }
49
50 static void Display( void )
51 {
52 static int firsttime = 1;
53
54 if (firsttime) {
55 firsttime = 0;
56 Init( 0, 0 ); /* don't ask */
57 }
58
59 glClear( GL_COLOR_BUFFER_BIT );
60 glBindTexture(GL_TEXTURE_2D, yuvObj);
61
62 glPushMatrix();
63 glEnable(GL_FRAGMENT_PROGRAM_ARB);
64 glTranslatef( -1.1, 0.0, -15.0 );
65 glRotatef(Xrot, 1.0, 0.0, 0.0);
66 glRotatef(Yrot, 0.0, 1.0, 0.0);
67 glRotatef(Zrot, 0.0, 0.0, 1.0);
68 glBindTexture(GL_TEXTURE_2D, yuvObj);
69 DrawObject();
70 glPopMatrix();
71
72 glPushMatrix();
73 glDisable(GL_FRAGMENT_PROGRAM_ARB);
74 glTranslatef( 1.1, 0.0, -15.0 );
75 glRotatef(Xrot, 1.0, 0.0, 0.0);
76 glRotatef(Yrot, 0.0, 1.0, 0.0);
77 glRotatef(Zrot, 0.0, 0.0, 1.0);
78 glBindTexture(GL_TEXTURE_2D, rgbObj);
79 DrawObject();
80 glPopMatrix();
81
82 glutSwapBuffers();
83 }
84
85
86 static void Reshape( int width, int height )
87 {
88 glViewport( 0, 0, width, height );
89 glMatrixMode( GL_PROJECTION );
90 glLoadIdentity();
91 glFrustum( -1.1, 1.1, -1.1, 1.1, 10.0, 100.0 );
92 glMatrixMode( GL_MODELVIEW );
93 glLoadIdentity();
94 glTranslatef( 0.0, 0.0, -15.0 );
95 }
96
97
98 static void Key( unsigned char key, int x, int y )
99 {
100 (void) x;
101 (void) y;
102 switch (key) {
103 case 27:
104 exit(0);
105 break;
106 }
107 glutPostRedisplay();
108 }
109
110
111 static void SpecialKey( int key, int x, int y )
112 {
113 float step = 3.0;
114 (void) x;
115 (void) y;
116
117 switch (key) {
118 case GLUT_KEY_UP:
119 Xrot += step;
120 break;
121 case GLUT_KEY_DOWN:
122 Xrot -= step;
123 break;
124 case GLUT_KEY_LEFT:
125 Yrot += step;
126 break;
127 case GLUT_KEY_RIGHT:
128 Yrot -= step;
129 break;
130 }
131 glutPostRedisplay();
132 }
133
134
135
136
137 /* #define LINEAR_FILTER */
138
139 static void Init( int argc, char *argv[] )
140 {
141 const char *file;
142 const GLfloat yuvtorgb[16] = {
143 1.164, 1.164, 1.164, 0,
144 0, -.391, 2.018, 0,
145 1.596, -.813, 0.0, 0,
146 (-.0625*1.164 + -.5*1.596), (-.0625*1.164 + -.5*-.813 + -.5*-.391), (-.0625*1.164 + -.5*2.018), 1
147 };
148
149 if (!glutExtensionSupported("GL_ARB_fragment_program")) {
150 printf("Error: GL_ARB_fragment_program not supported!\n");
151 exit(1);
152 }
153
154 if (!glutExtensionSupported("GL_EXT_422_pixels")) {
155 printf("Error: GL_EXT_422_pixels not supported!\n");
156 exit(1);
157 }
158
159 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
160
161 file = TEXTURE_FILE;
162
163 /* Load the texture as YCbCr.
164 */
165 glBindTexture(GL_TEXTURE_2D, yuvObj);
166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
168
169 ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight );
170 if (!ImageYUV) {
171 printf("Couldn't read %s\n", TEXTURE_FILE);
172 exit(0);
173 }
174
175 glTexImage2D(GL_TEXTURE_2D, 0,
176 GL_RGB,
177 ImgWidth, ImgHeight, 0,
178 GL_422_EXT,
179 GL_UNSIGNED_BYTE, ImageYUV);
180
181 glEnable(GL_TEXTURE_2D);
182
183 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
184
185 {
186 static const char *modulateYUV =
187 "!!ARBfp1.0\n"
188 "TEMP R0;\n"
189 "TEX R0, fragment.texcoord[0], texture[0], 2D; \n"
190
191 "ADD R0, R0, {-0.0625, -0.5, -0.5, 0.0}; \n"
192 "DP3 result.color.x, R0, {1.164, 1.596, 0.0}; \n"
193 "DP3 result.color.y, R0, {1.164, -0.813, -0.391}; \n"
194 "DP3 result.color.z, R0, {1.164, 0.0, 2.018}; \n"
195 "MOV result.color.w, R0.w; \n"
196
197 "END"
198 ;
199
200 GLuint modulateProg;
201
202
203 /* Setup the fragment program */
204 glGenProgramsARB(1, &modulateProg);
205 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, modulateProg);
206 glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
207 strlen(modulateYUV), (const GLubyte *)modulateYUV);
208
209 printf("glGetError = 0x%x\n", (int) glGetError());
210 printf("glError(GL_PROGRAM_ERROR_STRING_ARB) = %s\n",
211 (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
212 assert(glIsProgramARB(modulateProg));
213
214 }
215
216 /* Now the same, but use a color matrix to do the conversion at
217 * upload time:
218 */
219 glBindTexture(GL_TEXTURE_2D, rgbObj);
220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
222
223 glMatrixMode( GL_COLOR_MATRIX );
224 glLoadMatrixf( yuvtorgb );
225
226 glTexImage2D(GL_TEXTURE_2D, 0,
227 GL_RGB,
228 ImgWidth, ImgHeight, 0,
229 GL_422_EXT,
230 GL_UNSIGNED_BYTE, ImageYUV);
231
232 glLoadIdentity();
233 glMatrixMode( GL_MODELVIEW );
234
235 glEnable(GL_TEXTURE_2D);
236
237 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
238
239
240 glShadeModel(GL_FLAT);
241 glClearColor(0.3, 0.3, 0.4, 1.0);
242 }
243
244
245 int main( int argc, char *argv[] )
246 {
247 glutInit( &argc, argv );
248 glutInitWindowSize( 300, 300 );
249 glutInitWindowPosition( 0, 0 );
250 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
251 glutCreateWindow(argv[0] );
252 glewInit();
253 glutReshapeFunc( Reshape );
254 glutKeyboardFunc( Key );
255 glutSpecialFunc( SpecialKey );
256 glutDisplayFunc( Display );
257 glutMainLoop();
258 return 0;
259 }