2 * Test the GL_NV_texture_rectangle and GL_MESA_ycrcb_texture extensions and GLX_MESA_allocate-memory
4 * Dave Airlie - Feb 2005
13 #include <X11/keysym.h>
14 #define GL_GLEXT_PROTOTYPES
17 #include "../util/readtex.c" /* I know, this is a hack. */
19 #define TEXTURE_FILE DEMOS_DATA_DIR "girl2.rgb"
21 static GLfloat Xrot
= 0, Yrot
= 0, Zrot
= 0;
22 static GLint ImgWidth
, ImgHeight
;
23 static GLushort
*ImageYUV
= NULL
;
24 static void *glx_memory
;
26 static void DrawObject(void)
31 glVertex2f(-1.0, -1.0);
33 glTexCoord2f(ImgWidth
, 0);
34 glVertex2f(1.0, -1.0);
36 glTexCoord2f(ImgWidth
, ImgHeight
);
39 glTexCoord2f(0, ImgHeight
);
40 glVertex2f(-1.0, 1.0);
46 static void scr_Display( void )
48 glClear( GL_COLOR_BUFFER_BIT
);
51 glRotatef(Xrot
, 1.0, 0.0, 0.0);
52 glRotatef(Yrot
, 0.0, 1.0, 0.0);
53 glRotatef(Zrot
, 0.0, 0.0, 1.0);
60 static void Reshape( int width
, int height
)
62 glViewport( 0, 0, width
, height
);
63 glMatrixMode( GL_PROJECTION
);
65 glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
66 glMatrixMode( GL_MODELVIEW
);
68 glTranslatef( 0.0, 0.0, -15.0 );
71 static int queryClient(Display
*dpy
, int screen
)
73 #ifdef GLX_MESA_allocate_memory
76 extensions
= (char *)glXQueryExtensionsString(dpy
, screen
);
77 if (!extensions
|| !strstr(extensions
,"GLX_MESA_allocate_memory")) {
88 query_extension(char* extName
) {
89 char *p
= (char *) glGetString(GL_EXTENSIONS
);
90 char *end
= p
+ strlen(p
);
92 int n
= strcspn(p
, " ");
93 if ((strlen(extName
) == n
) && (strncmp(extName
, p
, n
) == 0))
100 static void Init( int argc
, char *argv
[] , Display
*dpy
, int screen
, Window win
)
104 void *glx_memory
= NULL
;
106 if (!query_extension("GL_NV_texture_rectangle")) {
107 printf("Sorry, GL_NV_texture_rectangle is required\n");
111 if (!query_extension("GL_MESA_ycbcr_texture")) {
112 printf("Sorry, GL_MESA_ycbcr_texture is required\n");
116 if (!queryClient(dpy
, screen
)) {
117 printf("Sorry, GLX_MESA_allocate_memory is required\n");
121 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE
, 1);
122 glBindTexture(GL_TEXTURE_RECTANGLE_NV
, texObj
);
124 /* linear filtering looks much nicer but is much slower for Mesa */
125 glTexParameteri(GL_TEXTURE_RECTANGLE_NV
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
126 glTexParameteri(GL_TEXTURE_RECTANGLE_NV
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
128 glTexParameteri(GL_TEXTURE_RECTANGLE_NV
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
129 glTexParameteri(GL_TEXTURE_RECTANGLE_NV
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
137 ImageYUV
= LoadYUVImage(file
, &ImgWidth
, &ImgHeight
);
139 printf("Couldn't read %s\n", TEXTURE_FILE
);
143 #ifdef GLX_MESA_allocate_memory
144 glx_memory
= glXAllocateMemoryMESA(dpy
, screen
, ImgWidth
* ImgHeight
* 2, 0, 0 ,0);
148 fprintf(stderr
,"Failed to allocate MESA memory\n");
152 memcpy(glx_memory
, ImageYUV
, ImgWidth
* ImgHeight
* 2);
154 printf("Image: %dx%d\n", ImgWidth
, ImgHeight
);
156 glTexImage2D(GL_TEXTURE_RECTANGLE_NV
, 0,
157 GL_YCBCR_MESA
, ImgWidth
, ImgHeight
, 0,
158 GL_YCBCR_MESA
, GL_UNSIGNED_SHORT_8_8_APPLE
, glx_memory
);
160 assert(glGetError() == GL_NO_ERROR
);
162 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
164 glEnable(GL_TEXTURE_RECTANGLE_NV
);
166 glShadeModel(GL_FLAT
);
167 glClearColor(0.3, 0.3, 0.4, 1.0);
172 * Create an RGB, double-buffered window.
173 * Return the window and context handles.
176 make_window( Display
*dpy
, const char *name
,
177 int x
, int y
, int width
, int height
,
178 Window
*winRet
, GLXContext
*ctxRet
)
180 int attribs
[] = { GLX_RGBA
,
188 XSetWindowAttributes attr
;
193 XVisualInfo
*visinfo
;
195 scrnum
= DefaultScreen( dpy
);
196 root
= RootWindow( dpy
, scrnum
);
198 visinfo
= glXChooseVisual( dpy
, scrnum
, attribs
);
200 printf("Error: couldn't get an RGB, Double-buffered visual\n");
204 /* window attributes */
205 attr
.background_pixel
= 0;
206 attr
.border_pixel
= 0;
207 attr
.colormap
= XCreateColormap( dpy
, root
, visinfo
->visual
, AllocNone
);
208 attr
.event_mask
= StructureNotifyMask
| ExposureMask
| KeyPressMask
;
209 attr
.override_redirect
= 0;
210 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
| CWOverrideRedirect
;
212 win
= XCreateWindow( dpy
, root
, 0, 0, width
, height
,
213 0, visinfo
->depth
, InputOutput
,
214 visinfo
->visual
, mask
, &attr
);
216 /* set hints and properties */
218 XSizeHints sizehints
;
221 sizehints
.width
= width
;
222 sizehints
.height
= height
;
223 sizehints
.flags
= USSize
| USPosition
;
224 XSetNormalHints(dpy
, win
, &sizehints
);
225 XSetStandardProperties(dpy
, win
, name
, name
,
226 None
, (char **)NULL
, 0, &sizehints
);
229 ctx
= glXCreateContext( dpy
, visinfo
, NULL
, True
);
231 printf("Error: glXCreateContext failed\n");
243 event_loop(Display
*dpy
, Window win
)
246 while (XPending(dpy
) > 0) {
248 XNextEvent(dpy
, &event
);
249 switch (event
.type
) {
251 /* we'll redraw below */
253 case ConfigureNotify
:
254 Reshape(event
.xconfigure
.width
, event
.xconfigure
.height
);
260 code
= XLookupKeysym(&event
.xkey
, 0);
261 r
= XLookupString(&event
.xkey
, buffer
, sizeof(buffer
),
263 if (buffer
[0] == 27) {
277 main(int argc
, char *argv
[])
282 char *dpyName
= NULL
;
283 GLboolean printInfo
= GL_FALSE
;
286 for (i
= 1; i
< argc
; i
++) {
287 if (strcmp(argv
[i
], "-display") == 0) {
291 else if (strcmp(argv
[i
], "-info") == 0) {
295 printf("Warrning: unknown parameter: %s\n", argv
[i
]);
298 dpy
= XOpenDisplay(dpyName
);
300 printf("Error: couldn't open display %s\n",
301 XDisplayName(dpyName
));
305 make_window(dpy
, "yuvrect_client", 0, 0, 300, 300, &win
, &ctx
);
306 XMapWindow(dpy
, win
);
307 glXMakeCurrent(dpy
, win
, ctx
);
310 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
311 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
312 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
313 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
316 Init(argc
, argv
, dpy
, DefaultScreen(dpy
), win
);
319 glXSwapBuffers(dpy
, win
);
320 event_loop(dpy
, win
);
322 #ifdef GLX_MESA_allocate_memory
323 glXFreeMemoryMESA(dpy
, DefaultScreen(dpy
), glx_memory
);
325 glXDestroyContext(dpy
, ctx
);
326 XDestroyWindow(dpy
, win
);