ext422square.c revision 32001f49
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 "glut_wrap.h" 17#include <assert.h> 18 19#include "../util/readtex.c" /* I know, this is a hack. */ 20 21#define TEXTURE_FILE DEMOS_DATA_DIR "tile.rgb" 22 23static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; 24static GLint ImgWidth, ImgHeight; 25static GLushort *ImageYUV = NULL; 26static const GLuint yuvObj = 100; 27static const GLuint rgbObj = 101; 28 29static void Init( int argc, char *argv[] ); 30 31static 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 50static 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 86static 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 98static 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 111static 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 139static 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 245int 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} 260