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