Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

yuvrect_client.c 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*
  2. * Test the GL_NV_texture_rectangle and GL_MESA_ycrcb_texture extensions and GLX_MESA_allocate-memory
  3. *
  4. * Dave Airlie - Feb 2005
  5. */
  6. #include <assert.h>
  7. #include <math.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <X11/Xlib.h>
  12. #include <X11/keysym.h>
  13. #define GL_GLEXT_PROTOTYPES
  14. #include <GL/glx.h>
  15. #include "../util/readtex.c" /* I know, this is a hack. */
  16. #define TEXTURE_FILE "../images/girl2.rgb"
  17. static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
  18. static GLint ImgWidth, ImgHeight;
  19. static GLushort *ImageYUV = NULL;
  20. static void *glx_memory;
  21. static void DrawObject(void)
  22. {
  23. glBegin(GL_QUADS);
  24. glTexCoord2f(0, 0);
  25. glVertex2f(-1.0, -1.0);
  26. glTexCoord2f(ImgWidth, 0);
  27. glVertex2f(1.0, -1.0);
  28. glTexCoord2f(ImgWidth, ImgHeight);
  29. glVertex2f(1.0, 1.0);
  30. glTexCoord2f(0, ImgHeight);
  31. glVertex2f(-1.0, 1.0);
  32. glEnd();
  33. }
  34. static void scr_Display( void )
  35. {
  36. glClear( GL_COLOR_BUFFER_BIT );
  37. glPushMatrix();
  38. glRotatef(Xrot, 1.0, 0.0, 0.0);
  39. glRotatef(Yrot, 0.0, 1.0, 0.0);
  40. glRotatef(Zrot, 0.0, 0.0, 1.0);
  41. DrawObject();
  42. glPopMatrix();
  43. }
  44. static void Reshape( int width, int height )
  45. {
  46. glViewport( 0, 0, width, height );
  47. glMatrixMode( GL_PROJECTION );
  48. glLoadIdentity();
  49. glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
  50. glMatrixMode( GL_MODELVIEW );
  51. glLoadIdentity();
  52. glTranslatef( 0.0, 0.0, -15.0 );
  53. }
  54. static int queryClient(Display *dpy, int screen)
  55. {
  56. #ifdef GLX_MESA_allocate_memory
  57. char *extensions;
  58. extensions = (char *)glXQueryExtensionsString(dpy, screen);
  59. if (!extensions || !strstr(extensions,"GLX_MESA_allocate_memory")) {
  60. return 0;
  61. }
  62. return 1;
  63. #else
  64. return 0;
  65. #endif
  66. }
  67. static int
  68. query_extension(char* extName) {
  69. char *p = (char *) glGetString(GL_EXTENSIONS);
  70. char *end = p + strlen(p);
  71. while (p < end) {
  72. int n = strcspn(p, " ");
  73. if ((strlen(extName) == n) && (strncmp(extName, p, n) == 0))
  74. return GL_TRUE;
  75. p += (n + 1);
  76. }
  77. return GL_FALSE;
  78. }
  79. static void Init( int argc, char *argv[] , Display *dpy, int screen, Window win)
  80. {
  81. GLuint texObj = 100;
  82. const char *file;
  83. void *glx_memory;
  84. if (!query_extension("GL_NV_texture_rectangle")) {
  85. printf("Sorry, GL_NV_texture_rectangle is required\n");
  86. exit(0);
  87. }
  88. if (!query_extension("GL_MESA_ycbcr_texture")) {
  89. printf("Sorry, GL_MESA_ycbcr_texture is required\n");
  90. exit(0);
  91. }
  92. if (!queryClient(dpy, screen)) {
  93. printf("Sorry, GLX_MESA_allocate_memory is required\n");
  94. exit(0);
  95. }
  96. glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);
  97. glBindTexture(GL_TEXTURE_RECTANGLE_NV, texObj);
  98. #ifdef LINEAR_FILTER
  99. /* linear filtering looks much nicer but is much slower for Mesa */
  100. glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  101. glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  102. #else
  103. glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  104. glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  105. #endif
  106. if (argc > 1)
  107. file = argv[1];
  108. else
  109. file = TEXTURE_FILE;
  110. ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight);
  111. if (!ImageYUV) {
  112. printf("Couldn't read %s\n", TEXTURE_FILE);
  113. exit(0);
  114. }
  115. glx_memory = glXAllocateMemoryMESA(dpy, screen, ImgWidth * ImgHeight * 2, 0, 0 ,0);
  116. if (!glx_memory)
  117. {
  118. fprintf(stderr,"Failed to allocate MESA memory\n");
  119. exit(-1);
  120. }
  121. memcpy(glx_memory, ImageYUV, ImgWidth * ImgHeight * 2);
  122. printf("Image: %dx%d\n", ImgWidth, ImgHeight);
  123. glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0,
  124. GL_YCBCR_MESA, ImgWidth, ImgHeight, 0,
  125. GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_APPLE, glx_memory);
  126. assert(glGetError() == GL_NO_ERROR);
  127. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  128. glEnable(GL_TEXTURE_RECTANGLE_NV);
  129. glShadeModel(GL_FLAT);
  130. glClearColor(0.3, 0.3, 0.4, 1.0);
  131. }
  132. /*
  133. * Create an RGB, double-buffered window.
  134. * Return the window and context handles.
  135. */
  136. static void
  137. make_window( Display *dpy, const char *name,
  138. int x, int y, int width, int height,
  139. Window *winRet, GLXContext *ctxRet)
  140. {
  141. int attribs[] = { GLX_RGBA,
  142. GLX_RED_SIZE, 1,
  143. GLX_GREEN_SIZE, 1,
  144. GLX_BLUE_SIZE, 1,
  145. GLX_DOUBLEBUFFER,
  146. GLX_DEPTH_SIZE, 1,
  147. None };
  148. int scrnum;
  149. XSetWindowAttributes attr;
  150. unsigned long mask;
  151. Window root;
  152. Window win;
  153. GLXContext ctx;
  154. XVisualInfo *visinfo;
  155. scrnum = DefaultScreen( dpy );
  156. root = RootWindow( dpy, scrnum );
  157. visinfo = glXChooseVisual( dpy, scrnum, attribs );
  158. if (!visinfo) {
  159. printf("Error: couldn't get an RGB, Double-buffered visual\n");
  160. exit(1);
  161. }
  162. /* window attributes */
  163. attr.background_pixel = 0;
  164. attr.border_pixel = 0;
  165. attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
  166. attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
  167. attr.override_redirect = 0;
  168. mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;
  169. win = XCreateWindow( dpy, root, 0, 0, width, height,
  170. 0, visinfo->depth, InputOutput,
  171. visinfo->visual, mask, &attr );
  172. /* set hints and properties */
  173. {
  174. XSizeHints sizehints;
  175. sizehints.x = x;
  176. sizehints.y = y;
  177. sizehints.width = width;
  178. sizehints.height = height;
  179. sizehints.flags = USSize | USPosition;
  180. XSetNormalHints(dpy, win, &sizehints);
  181. XSetStandardProperties(dpy, win, name, name,
  182. None, (char **)NULL, 0, &sizehints);
  183. }
  184. ctx = glXCreateContext( dpy, visinfo, NULL, True );
  185. if (!ctx) {
  186. printf("Error: glXCreateContext failed\n");
  187. exit(1);
  188. }
  189. XFree(visinfo);
  190. *winRet = win;
  191. *ctxRet = ctx;
  192. }
  193. static void
  194. event_loop(Display *dpy, Window win)
  195. {
  196. while (1) {
  197. while (XPending(dpy) > 0) {
  198. XEvent event;
  199. XNextEvent(dpy, &event);
  200. switch (event.type) {
  201. case Expose:
  202. /* we'll redraw below */
  203. break;
  204. case ConfigureNotify:
  205. Reshape(event.xconfigure.width, event.xconfigure.height);
  206. break;
  207. case KeyPress:
  208. {
  209. char buffer[10];
  210. int r, code;
  211. code = XLookupKeysym(&event.xkey, 0);
  212. r = XLookupString(&event.xkey, buffer, sizeof(buffer),
  213. NULL, NULL);
  214. if (buffer[0] == 27) {
  215. /* escape */
  216. return;
  217. }
  218. }
  219. }
  220. }
  221. }
  222. }
  223. int
  224. main(int argc, char *argv[])
  225. {
  226. Display *dpy;
  227. Window win;
  228. GLXContext ctx;
  229. char *dpyName = NULL;
  230. GLboolean printInfo = GL_FALSE;
  231. int i;
  232. for (i = 1; i < argc; i++) {
  233. if (strcmp(argv[i], "-display") == 0) {
  234. dpyName = argv[i+1];
  235. i++;
  236. }
  237. else if (strcmp(argv[i], "-info") == 0) {
  238. printInfo = GL_TRUE;
  239. }
  240. else
  241. printf("Warrning: unknown parameter: %s\n", argv[i]);
  242. }
  243. dpy = XOpenDisplay(dpyName);
  244. if (!dpy) {
  245. printf("Error: couldn't open display %s\n",
  246. XDisplayName(dpyName));
  247. return -1;
  248. }
  249. make_window(dpy, "yuvrect_client", 0, 0, 300, 300, &win, &ctx);
  250. XMapWindow(dpy, win);
  251. glXMakeCurrent(dpy, win, ctx);
  252. if (printInfo) {
  253. printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  254. printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
  255. printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
  256. printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
  257. }
  258. Init(argc, argv, dpy, DefaultScreen(dpy), win);
  259. scr_Display();
  260. glXSwapBuffers(dpy, win);
  261. event_loop(dpy, win);
  262. glXFreeMemoryMESA(dpy, DefaultScreen(dpy), glx_memory);
  263. glXDestroyContext(dpy, ctx);
  264. XDestroyWindow(dpy, win);
  265. XCloseDisplay(dpy);
  266. return 0;
  267. }