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 "../images/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
)
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 glx_memory
= glXAllocateMemoryMESA(dpy
, screen
, ImgWidth
* ImgHeight
* 2, 0, 0 ,0);
146 fprintf(stderr
,"Failed to allocate MESA memory\n");
150 memcpy(glx_memory
, ImageYUV
, ImgWidth
* ImgHeight
* 2);
152 printf("Image: %dx%d\n", ImgWidth
, ImgHeight
);
154 glTexImage2D(GL_TEXTURE_RECTANGLE_NV
, 0,
155 GL_YCBCR_MESA
, ImgWidth
, ImgHeight
, 0,
156 GL_YCBCR_MESA
, GL_UNSIGNED_SHORT_8_8_APPLE
, glx_memory
);
158 assert(glGetError() == GL_NO_ERROR
);
160 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
162 glEnable(GL_TEXTURE_RECTANGLE_NV
);
164 glShadeModel(GL_FLAT
);
165 glClearColor(0.3, 0.3, 0.4, 1.0);
170 * Create an RGB, double-buffered window.
171 * Return the window and context handles.
174 make_window( Display
*dpy
, const char *name
,
175 int x
, int y
, int width
, int height
,
176 Window
*winRet
, GLXContext
*ctxRet
)
178 int attribs
[] = { GLX_RGBA
,
186 XSetWindowAttributes attr
;
191 XVisualInfo
*visinfo
;
193 scrnum
= DefaultScreen( dpy
);
194 root
= RootWindow( dpy
, scrnum
);
196 visinfo
= glXChooseVisual( dpy
, scrnum
, attribs
);
198 printf("Error: couldn't get an RGB, Double-buffered visual\n");
202 /* window attributes */
203 attr
.background_pixel
= 0;
204 attr
.border_pixel
= 0;
205 attr
.colormap
= XCreateColormap( dpy
, root
, visinfo
->visual
, AllocNone
);
206 attr
.event_mask
= StructureNotifyMask
| ExposureMask
| KeyPressMask
;
207 attr
.override_redirect
= 0;
208 mask
= CWBackPixel
| CWBorderPixel
| CWColormap
| CWEventMask
| CWOverrideRedirect
;
210 win
= XCreateWindow( dpy
, root
, 0, 0, width
, height
,
211 0, visinfo
->depth
, InputOutput
,
212 visinfo
->visual
, mask
, &attr
);
214 /* set hints and properties */
216 XSizeHints sizehints
;
219 sizehints
.width
= width
;
220 sizehints
.height
= height
;
221 sizehints
.flags
= USSize
| USPosition
;
222 XSetNormalHints(dpy
, win
, &sizehints
);
223 XSetStandardProperties(dpy
, win
, name
, name
,
224 None
, (char **)NULL
, 0, &sizehints
);
227 ctx
= glXCreateContext( dpy
, visinfo
, NULL
, True
);
229 printf("Error: glXCreateContext failed\n");
241 event_loop(Display
*dpy
, Window win
)
244 while (XPending(dpy
) > 0) {
246 XNextEvent(dpy
, &event
);
247 switch (event
.type
) {
249 /* we'll redraw below */
251 case ConfigureNotify
:
252 Reshape(event
.xconfigure
.width
, event
.xconfigure
.height
);
258 code
= XLookupKeysym(&event
.xkey
, 0);
259 r
= XLookupString(&event
.xkey
, buffer
, sizeof(buffer
),
261 if (buffer
[0] == 27) {
275 main(int argc
, char *argv
[])
280 char *dpyName
= NULL
;
281 GLboolean printInfo
= GL_FALSE
;
284 for (i
= 1; i
< argc
; i
++) {
285 if (strcmp(argv
[i
], "-display") == 0) {
289 else if (strcmp(argv
[i
], "-info") == 0) {
293 printf("Warrning: unknown parameter: %s\n", argv
[i
]);
296 dpy
= XOpenDisplay(dpyName
);
298 printf("Error: couldn't open display %s\n",
299 XDisplayName(dpyName
));
303 make_window(dpy
, "yuvrect_client", 0, 0, 300, 300, &win
, &ctx
);
304 XMapWindow(dpy
, win
);
305 glXMakeCurrent(dpy
, win
, ctx
);
308 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
309 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
310 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
311 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
314 Init(argc
, argv
, dpy
, DefaultScreen(dpy
), win
);
317 glXSwapBuffers(dpy
, win
);
318 event_loop(dpy
, win
);
320 glXFreeMemoryMESA(dpy
, DefaultScreen(dpy
), glx_memory
);
321 glXDestroyContext(dpy
, ctx
);
322 XDestroyWindow(dpy
, win
);