blob: d1c168773091f0adefc2f28398763c7153a17707 [file] [log] [blame]
Keith Whitwell4f144b62004-11-30 19:15:06 +00001/*
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#define GL_GLEXT_PROTOTYPES
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
23static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
24static GLint ImgWidth, ImgHeight;
25static GLushort *ImageYUV = NULL;
26static const GLuint yuvObj = 100;
27
28static void Init( int argc, char *argv[] );
29
30static void DrawObject(void)
31{
32 glBegin(GL_QUADS);
33
34 glTexCoord2f(0, 0);
35 glVertex2f(-1.0, -1.0);
36
37 glTexCoord2f(1, 0);
38 glVertex2f(1.0, -1.0);
39
40 glTexCoord2f(1, 1);
41 glVertex2f(1.0, 1.0);
42
43 glTexCoord2f(0, 1);
44 glVertex2f(-1.0, 1.0);
45
46 glEnd();
47}
48
49static void Display( void )
50{
51 static int firsttime = 1;
52
53 if (firsttime) {
54 firsttime = 0;
55 Init( 0, 0 ); /* don't ask */
56 }
57
58 glClear( GL_COLOR_BUFFER_BIT );
59 glBindTexture(GL_TEXTURE_2D, yuvObj);
60
61 glPushMatrix();
62 glEnable(GL_FRAGMENT_PROGRAM_ARB);
63 glTranslatef( -1.1, 0.0, -15.0 );
64 glRotatef(Xrot, 1.0, 0.0, 0.0);
65 glRotatef(Yrot, 0.0, 1.0, 0.0);
66 glRotatef(Zrot, 0.0, 0.0, 1.0);
67 DrawObject();
68 glPopMatrix();
69
70 glPushMatrix();
71 glDisable(GL_FRAGMENT_PROGRAM_ARB);
72 glTranslatef( 1.1, 0.0, -15.0 );
73 glRotatef(Xrot, 1.0, 0.0, 0.0);
74 glRotatef(Yrot, 0.0, 1.0, 0.0);
75 glRotatef(Zrot, 0.0, 0.0, 1.0);
76 DrawObject();
77 glPopMatrix();
78
79 glutSwapBuffers();
80}
81
82
83static void Reshape( int width, int height )
84{
85 glViewport( 0, 0, width, height );
86 glMatrixMode( GL_PROJECTION );
87 glLoadIdentity();
88 glFrustum( -1.1, 1.1, -1.1, 1.1, 10.0, 100.0 );
89 glMatrixMode( GL_MODELVIEW );
90 glLoadIdentity();
91 glTranslatef( 0.0, 0.0, -15.0 );
92}
93
94
95static void Key( unsigned char key, int x, int y )
96{
97 (void) x;
98 (void) y;
99 switch (key) {
100 case 27:
101 exit(0);
102 break;
103 }
104 glutPostRedisplay();
105}
106
107
108static void SpecialKey( int key, int x, int y )
109{
110 float step = 3.0;
111 (void) x;
112 (void) y;
113
114 switch (key) {
115 case GLUT_KEY_UP:
116 Xrot += step;
117 break;
118 case GLUT_KEY_DOWN:
119 Xrot -= step;
120 break;
121 case GLUT_KEY_LEFT:
122 Yrot += step;
123 break;
124 case GLUT_KEY_RIGHT:
125 Yrot -= step;
126 break;
127 }
128 glutPostRedisplay();
129}
130
131
132
133
134/* #define LINEAR_FILTER */
135
136static void Init( int argc, char *argv[] )
137{
138 const char *file;
139
140 if (!glutExtensionSupported("GL_ARB_fragment_program")) {
141 printf("Error: GL_ARB_fragment_program not supported!\n");
142 exit(1);
143 }
144
145 if (!glutExtensionSupported("GL_EXT_422_pixels")) {
146 printf("Error: GL_EXT_422_pixels not supported!\n");
147 exit(1);
148 }
149
150 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
151
152 file = TEXTURE_FILE;
153
154 /* Load the texture as YCbCr.
155 */
156 glBindTexture(GL_TEXTURE_2D, yuvObj);
157 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
158 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
159
160 ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight );
161 if (!ImageYUV) {
162 printf("Couldn't read %s\n", TEXTURE_FILE);
163 exit(0);
164 }
165
166 glTexImage2D(GL_TEXTURE_2D, 0,
167 GL_RGB,
168 ImgWidth, ImgHeight, 0,
169 GL_422_EXT,
170 GL_UNSIGNED_BYTE, ImageYUV);
171
172 glEnable(GL_TEXTURE_2D);
173
174 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
175
176 {
177 static const char *modulateYUV =
178 "!!ARBfp1.0\n"
179 "TEMP R0;\n"
180 "TEX R0, fragment.texcoord[0], texture[0], 2D; \n"
181
182 "ADD R0, R0, {-0.0625, -0.5, -0.5, 0.0}; \n"
183 "DP3 result.color.x, R0, {1.164, 1.596, 0.0}; \n"
184 "DP3 result.color.y, R0, {1.164, -0.813, -0.391}; \n"
185 "DP3 result.color.z, R0, {1.164, 0.0, 2.018}; \n"
186 "MOV result.color.w, R0.w; \n"
187
188 "END"
189 ;
190
191 GLuint modulateProg;
192
193
194 /* Setup the fragment program */
195 glGenProgramsARB(1, &modulateProg);
196 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, modulateProg);
197 glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
198 strlen(modulateYUV), (const GLubyte *)modulateYUV);
199
200 printf("glGetError = 0x%x\n", (int) glGetError());
201 printf("glError(GL_PROGRAM_ERROR_STRING_ARB) = %s\n",
202 (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
203 assert(glIsProgramARB(modulateProg));
204
205 }
206
207 glShadeModel(GL_FLAT);
208 glClearColor(0.3, 0.3, 0.4, 1.0);
209}
210
211
212int main( int argc, char *argv[] )
213{
214 glutInit( &argc, argv );
215 glutInitWindowSize( 300, 300 );
216 glutInitWindowPosition( 0, 0 );
217 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
218 glutCreateWindow(argv[0] );
219 glutReshapeFunc( Reshape );
220 glutKeyboardFunc( Key );
221 glutSpecialFunc( SpecialKey );
222 glutDisplayFunc( Display );
223 glutMainLoop();
224 return 0;
225}