1/*
2 * Test the GL_NV_texture_rectangle and GL_MESA_ycrcb_texture extensions.
3 *
4 * Brian Paul   13 September 2002
5 */
6
7#include <assert.h>
8#include <math.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <GL/glew.h>
13#include "glut_wrap.h"
14
15#include "../util/readtex.c"   /* I know, this is a hack. */
16
17#define TEXTURE_FILE DEMOS_DATA_DIR "girl.rgb"
18
19static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
20static GLint ImgWidth, ImgHeight;
21static GLushort *ImageYUV = NULL;
22
23
24static void DrawObject(void)
25{
26   glBegin(GL_QUADS);
27
28   glTexCoord2f(0, 0);
29   glVertex2f(-1.0, -1.0);
30
31   glTexCoord2f(ImgWidth, 0);
32   glVertex2f(1.0, -1.0);
33
34   glTexCoord2f(ImgWidth, ImgHeight);
35   glVertex2f(1.0, 1.0);
36
37   glTexCoord2f(0, ImgHeight);
38   glVertex2f(-1.0, 1.0);
39
40   glEnd();
41}
42
43
44static void Display( void )
45{
46   glClear( GL_COLOR_BUFFER_BIT );
47
48   glPushMatrix();
49      glRotatef(Xrot, 1.0, 0.0, 0.0);
50      glRotatef(Yrot, 0.0, 1.0, 0.0);
51      glRotatef(Zrot, 0.0, 0.0, 1.0);
52      DrawObject();
53   glPopMatrix();
54
55   glutSwapBuffers();
56}
57
58
59static void Reshape( int width, int height )
60{
61   glViewport( 0, 0, width, height );
62   glMatrixMode( GL_PROJECTION );
63   glLoadIdentity();
64   glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
65   glMatrixMode( GL_MODELVIEW );
66   glLoadIdentity();
67   glTranslatef( 0.0, 0.0, -15.0 );
68}
69
70
71static void Key( unsigned char key, int x, int y )
72{
73   (void) x;
74   (void) y;
75   switch (key) {
76      case 27:
77         exit(0);
78         break;
79   }
80   glutPostRedisplay();
81}
82
83
84static void SpecialKey( int key, int x, int y )
85{
86   float step = 3.0;
87   (void) x;
88   (void) y;
89
90   switch (key) {
91      case GLUT_KEY_UP:
92         Xrot += step;
93         break;
94      case GLUT_KEY_DOWN:
95         Xrot -= step;
96         break;
97      case GLUT_KEY_LEFT:
98         Yrot += step;
99         break;
100      case GLUT_KEY_RIGHT:
101         Yrot -= step;
102         break;
103   }
104   glutPostRedisplay();
105}
106
107
108
109static void Init( int argc, char *argv[] )
110{
111   GLuint texObj = 100;
112   const char *file;
113
114   if (!glutExtensionSupported("GL_NV_texture_rectangle")) {
115      printf("Sorry, GL_NV_texture_rectangle is required\n");
116      exit(0);
117   }
118
119   if (!glutExtensionSupported("GL_MESA_ycbcr_texture")) {
120      printf("Sorry, GL_MESA_ycbcr_texture is required\n");
121      exit(0);
122   }
123
124   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
125
126   glBindTexture(GL_TEXTURE_RECTANGLE_NV, texObj);
127#ifdef LINEAR_FILTER
128   /* linear filtering looks much nicer but is much slower for Mesa */
129   glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
130   glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
131#else
132   glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
133   glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
134#endif
135
136   if (argc > 1)
137      file = argv[1];
138   else
139      file = TEXTURE_FILE;
140
141   ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight);
142   if (!ImageYUV) {
143      printf("Couldn't read %s\n", TEXTURE_FILE);
144      exit(0);
145   }
146
147   printf("Image: %dx%d\n", ImgWidth, ImgHeight);
148
149   glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0,
150                GL_YCBCR_MESA, ImgWidth, ImgHeight, 0,
151                GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV);
152
153   assert(glGetError() == GL_NO_ERROR);
154   glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0,
155                   0, 0, ImgWidth, ImgHeight,
156                   GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV);
157
158   assert(glGetError() == GL_NO_ERROR);
159
160   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
161
162   glEnable(GL_TEXTURE_RECTANGLE_NV);
163
164   glShadeModel(GL_FLAT);
165   glClearColor(0.3, 0.3, 0.4, 1.0);
166
167   if (argc > 1 && strcmp(argv[1], "-info")==0) {
168      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
169      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
170      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
171      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
172   }
173}
174
175
176int main( int argc, char *argv[] )
177{
178   glutInit( &argc, argv );
179   glutInitWindowSize( 300, 300 );
180   glutInitWindowPosition( 0, 0 );
181   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
182   glutCreateWindow(argv[0] );
183   glewInit();
184
185   Init( argc, argv );
186
187   glutReshapeFunc( Reshape );
188   glutKeyboardFunc( Key );
189   glutSpecialFunc( SpecialKey );
190   glutDisplayFunc( Display );
191
192   glutMainLoop();
193   return 0;
194}
195