diff options
Diffstat (limited to 'progs/tests/ext422square.c')
-rw-r--r-- | progs/tests/ext422square.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/progs/tests/ext422square.c b/progs/tests/ext422square.c new file mode 100644 index 000000000..6533514d6 --- /dev/null +++ b/progs/tests/ext422square.c @@ -0,0 +1,258 @@ +/* + * Exercise the EXT_422_pixels extension, a less convenient + * alternative to MESA_ycbcr_texture. Requires ARB_fragment_program + * to perform the final YUV->RGB conversion. + * + * Brian Paul 13 September 2002 + * Keith Whitwell 30 November 2004 + */ + + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#define GL_GLEXT_PROTOTYPES +#include <GL/glut.h> +#include <assert.h> + +#include "../util/readtex.c" /* I know, this is a hack. */ + +#define TEXTURE_FILE "../images/tile.rgb" + +static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; +static GLint ImgWidth, ImgHeight; +static GLushort *ImageYUV = NULL; +static const GLuint yuvObj = 100; +static const GLuint rgbObj = 101; + +static void Init( int argc, char *argv[] ); + +static void DrawObject(void) +{ + glBegin(GL_QUADS); + + glTexCoord2f(0, 0); + glVertex2f(-1.0, -1.0); + + glTexCoord2f(1, 0); + glVertex2f(1.0, -1.0); + + glTexCoord2f(1, 1); + glVertex2f(1.0, 1.0); + + glTexCoord2f(0, 1); + glVertex2f(-1.0, 1.0); + + glEnd(); +} + +static void Display( void ) +{ + static int firsttime = 1; + + if (firsttime) { + firsttime = 0; + Init( 0, 0 ); /* don't ask */ + } + + glClear( GL_COLOR_BUFFER_BIT ); + glBindTexture(GL_TEXTURE_2D, yuvObj); + + glPushMatrix(); + glEnable(GL_FRAGMENT_PROGRAM_ARB); + glTranslatef( -1.1, 0.0, -15.0 ); + glRotatef(Xrot, 1.0, 0.0, 0.0); + glRotatef(Yrot, 0.0, 1.0, 0.0); + glRotatef(Zrot, 0.0, 0.0, 1.0); + glBindTexture(GL_TEXTURE_2D, yuvObj); + DrawObject(); + glPopMatrix(); + + glPushMatrix(); + glDisable(GL_FRAGMENT_PROGRAM_ARB); + glTranslatef( 1.1, 0.0, -15.0 ); + glRotatef(Xrot, 1.0, 0.0, 0.0); + glRotatef(Yrot, 0.0, 1.0, 0.0); + glRotatef(Zrot, 0.0, 0.0, 1.0); + glBindTexture(GL_TEXTURE_2D, rgbObj); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -1.1, 1.1, -1.1, 1.1, 10.0, 100.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -15.0 ); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + float step = 3.0; + (void) x; + (void) y; + + switch (key) { + case GLUT_KEY_UP: + Xrot += step; + break; + case GLUT_KEY_DOWN: + Xrot -= step; + break; + case GLUT_KEY_LEFT: + Yrot += step; + break; + case GLUT_KEY_RIGHT: + Yrot -= step; + break; + } + glutPostRedisplay(); +} + + + + +/* #define LINEAR_FILTER */ + +static void Init( int argc, char *argv[] ) +{ + const char *file; + const GLfloat yuvtorgb[16] = { + 1.164, 1.164, 1.164, 0, + 0, -.391, 2.018, 0, + 1.596, -.813, 0.0, 0, + (-.0625*1.164 + -.5*1.596), (-.0625*1.164 + -.5*-.813 + -.5*-.391), (-.0625*1.164 + -.5*2.018), 1 + }; + + if (!glutExtensionSupported("GL_ARB_fragment_program")) { + printf("Error: GL_ARB_fragment_program not supported!\n"); + exit(1); + } + + if (!glutExtensionSupported("GL_EXT_422_pixels")) { + printf("Error: GL_EXT_422_pixels not supported!\n"); + exit(1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + file = TEXTURE_FILE; + + /* Load the texture as YCbCr. + */ + glBindTexture(GL_TEXTURE_2D, yuvObj); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight ); + if (!ImageYUV) { + printf("Couldn't read %s\n", TEXTURE_FILE); + exit(0); + } + + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGB, + ImgWidth, ImgHeight, 0, + GL_422_EXT, + GL_UNSIGNED_BYTE, ImageYUV); + + glEnable(GL_TEXTURE_2D); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + { + static const char *modulateYUV = + "!!ARBfp1.0\n" + "TEMP R0;\n" + "TEX R0, fragment.texcoord[0], texture[0], 2D; \n" + + "ADD R0, R0, {-0.0625, -0.5, -0.5, 0.0}; \n" + "DP3 result.color.x, R0, {1.164, 1.596, 0.0}; \n" + "DP3 result.color.y, R0, {1.164, -0.813, -0.391}; \n" + "DP3 result.color.z, R0, {1.164, 0.0, 2.018}; \n" + "MOV result.color.w, R0.w; \n" + + "END" + ; + + GLuint modulateProg; + + + /* Setup the fragment program */ + glGenProgramsARB(1, &modulateProg); + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, modulateProg); + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(modulateYUV), (const GLubyte *)modulateYUV); + + printf("glGetError = 0x%x\n", (int) glGetError()); + printf("glError(GL_PROGRAM_ERROR_STRING_ARB) = %s\n", + (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB)); + assert(glIsProgramARB(modulateProg)); + + } + + /* Now the same, but use a color matrix to do the conversion at + * upload time: + */ + glBindTexture(GL_TEXTURE_2D, rgbObj); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glMatrixMode( GL_COLOR_MATRIX ); + glLoadMatrixf( yuvtorgb ); + + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGB, + ImgWidth, ImgHeight, 0, + GL_422_EXT, + GL_UNSIGNED_BYTE, ImageYUV); + + glLoadIdentity(); + glMatrixMode( GL_MODELVIEW ); + + glEnable(GL_TEXTURE_2D); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + + glShadeModel(GL_FLAT); + glClearColor(0.3, 0.3, 0.4, 1.0); +} + + +int main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowSize( 300, 300 ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + glutMainLoop(); + return 0; +} |