Clone of mesa.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

ostest1.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /*
  2. * Test OSMesa interface at 8, 16 and 32 bits/channel.
  3. *
  4. * Usage: osdemo [options]
  5. *
  6. * Options:
  7. * -f generate image files
  8. * -g render gradient and print color values
  9. */
  10. #include <assert.h>
  11. #include <math.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "GL/osmesa.h"
  16. #include "GL/glu.h"
  17. #define WIDTH 600
  18. #define HEIGHT 600
  19. static GLboolean WriteFiles = GL_FALSE;
  20. static GLboolean Gradient = GL_FALSE;
  21. static void
  22. Sphere(float radius, int slices, int stacks)
  23. {
  24. GLUquadric *q = gluNewQuadric();
  25. gluQuadricNormals(q, GLU_SMOOTH);
  26. gluSphere(q, radius, slices, stacks);
  27. gluDeleteQuadric(q);
  28. }
  29. static void
  30. Cone(float base, float height, int slices, int stacks)
  31. {
  32. GLUquadric *q = gluNewQuadric();
  33. gluQuadricDrawStyle(q, GLU_FILL);
  34. gluQuadricNormals(q, GLU_SMOOTH);
  35. gluCylinder(q, base, 0.0, height, slices, stacks);
  36. gluDeleteQuadric(q);
  37. }
  38. static void
  39. Torus(float innerRadius, float outerRadius, int sides, int rings)
  40. {
  41. /* from GLUT... */
  42. int i, j;
  43. GLfloat theta, phi, theta1;
  44. GLfloat cosTheta, sinTheta;
  45. GLfloat cosTheta1, sinTheta1;
  46. const GLfloat ringDelta = 2.0 * M_PI / rings;
  47. const GLfloat sideDelta = 2.0 * M_PI / sides;
  48. theta = 0.0;
  49. cosTheta = 1.0;
  50. sinTheta = 0.0;
  51. for (i = rings - 1; i >= 0; i--) {
  52. theta1 = theta + ringDelta;
  53. cosTheta1 = cos(theta1);
  54. sinTheta1 = sin(theta1);
  55. glBegin(GL_QUAD_STRIP);
  56. phi = 0.0;
  57. for (j = sides; j >= 0; j--) {
  58. GLfloat cosPhi, sinPhi, dist;
  59. phi += sideDelta;
  60. cosPhi = cos(phi);
  61. sinPhi = sin(phi);
  62. dist = outerRadius + innerRadius * cosPhi;
  63. glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
  64. glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, innerRadius * sinPhi);
  65. glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
  66. glVertex3f(cosTheta * dist, -sinTheta * dist, innerRadius * sinPhi);
  67. }
  68. glEnd();
  69. theta = theta1;
  70. cosTheta = cosTheta1;
  71. sinTheta = sinTheta1;
  72. }
  73. }
  74. static void Cube(float size)
  75. {
  76. size = 0.5 * size;
  77. glBegin(GL_QUADS);
  78. /* +X face */
  79. glNormal3f(1, 0, 0);
  80. glVertex3f(size, -size, size);
  81. glVertex3f(size, -size, -size);
  82. glVertex3f(size, size, -size);
  83. glVertex3f(size, size, size);
  84. /* -X face */
  85. glNormal3f(-1, 0, 0);
  86. glVertex3f(-size, size, size);
  87. glVertex3f(-size, size, -size);
  88. glVertex3f(-size, -size, -size);
  89. glVertex3f(-size, -size, size);
  90. /* +Y face */
  91. glNormal3f(0, 1, 0);
  92. glVertex3f(-size, size, size);
  93. glVertex3f( size, size, size);
  94. glVertex3f( size, size, -size);
  95. glVertex3f(-size, size, -size);
  96. /* -Y face */
  97. glNormal3f(0, -1, 0);
  98. glVertex3f(-size, -size, -size);
  99. glVertex3f( size, -size, -size);
  100. glVertex3f( size, -size, size);
  101. glVertex3f(-size, -size, size);
  102. /* +Z face */
  103. glNormal3f(0, 0, 1);
  104. glVertex3f(-size, -size, size);
  105. glVertex3f( size, -size, size);
  106. glVertex3f( size, size, size);
  107. glVertex3f(-size, size, size);
  108. /* -Z face */
  109. glNormal3f(0, 0, -1);
  110. glVertex3f(-size, size, -size);
  111. glVertex3f( size, size, -size);
  112. glVertex3f( size, -size, -size);
  113. glVertex3f(-size, -size, -size);
  114. glEnd();
  115. }
  116. /**
  117. * Draw red/green gradient across bottom of image.
  118. * Read pixels to check deltas.
  119. */
  120. static void
  121. render_gradient(void)
  122. {
  123. GLfloat row[WIDTH][4];
  124. int i;
  125. glMatrixMode(GL_PROJECTION);
  126. glLoadIdentity();
  127. glOrtho(-1, 1, -1, 1, -1, 1);
  128. glMatrixMode(GL_MODELVIEW);
  129. glLoadIdentity();
  130. glBegin(GL_POLYGON);
  131. glColor3f(1, 0, 0);
  132. glVertex2f(-1, -1.0);
  133. glVertex2f(-1, -0.9);
  134. glColor3f(0, 1, 0);
  135. glVertex2f(1, -0.9);
  136. glVertex2f(1, -1.0);
  137. glEnd();
  138. glFinish();
  139. glReadPixels(0, 0, WIDTH, 1, GL_RGBA, GL_FLOAT, row);
  140. for (i = 0; i < 4; i++) {
  141. printf("row[i] = %f, %f, %f\n", row[i][0], row[i][1], row[i][2]);
  142. }
  143. }
  144. static void
  145. render_image(void)
  146. {
  147. static const GLfloat light_ambient[4] = { 0.0, 0.0, 0.0, 1.0 };
  148. static const GLfloat light_diffuse[4] = { 1.0, 1.0, 1.0, 1.0 };
  149. static const GLfloat light_specular[4] = { 1.0, 1.0, 1.0, 1.0 };
  150. static const GLfloat light_position[4] = { 1.0, 1.0, 1.0, 0.0 };
  151. static const GLfloat red_mat[4] = { 1.0, 0.2, 0.2, 1.0 };
  152. static const GLfloat green_mat[4] = { 0.2, 1.0, 0.2, 1.0 };
  153. static const GLfloat blue_mat[4] = { 0.2, 0.2, 1.0, 1.0 };
  154. #if 0
  155. static const GLfloat yellow_mat[4] = { 0.8, 0.8, 0.0, 1.0 };
  156. #endif
  157. static const GLfloat purple_mat[4] = { 0.8, 0.4, 0.8, 0.6 };
  158. glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
  159. glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  160. glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
  161. glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  162. glEnable(GL_DEPTH_TEST);
  163. glEnable(GL_LIGHT0);
  164. glMatrixMode(GL_PROJECTION);
  165. glLoadIdentity();
  166. glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 50.0);
  167. glMatrixMode(GL_MODELVIEW);
  168. glTranslatef(0, 0.5, -7);
  169. glClearColor(0.3, 0.3, 0.7, 0.0);
  170. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  171. glPushMatrix();
  172. glRotatef(20.0, 1.0, 0.0, 0.0);
  173. /* ground */
  174. glEnable(GL_TEXTURE_2D);
  175. glBegin(GL_POLYGON);
  176. glNormal3f(0, 1, 0);
  177. glTexCoord2f(0, 0); glVertex3f(-5, -1, -5);
  178. glTexCoord2f(1, 0); glVertex3f( 5, -1, -5);
  179. glTexCoord2f(1, 1); glVertex3f( 5, -1, 5);
  180. glTexCoord2f(0, 1); glVertex3f(-5, -1, 5);
  181. glEnd();
  182. glDisable(GL_TEXTURE_2D);
  183. glEnable(GL_LIGHTING);
  184. glPushMatrix();
  185. glTranslatef(-1.5, 0.5, 0.0);
  186. glRotatef(90.0, 1.0, 0.0, 0.0);
  187. glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_mat );
  188. Torus(0.275, 0.85, 20, 20);
  189. glPopMatrix();
  190. glPushMatrix();
  191. glTranslatef(-1.5, -0.5, 0.0);
  192. glRotatef(270.0, 1.0, 0.0, 0.0);
  193. glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green_mat );
  194. Cone(1.0, 2.0, 16, 1);
  195. glPopMatrix();
  196. glPushMatrix();
  197. glTranslatef(0.95, 0.0, -0.8);
  198. glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
  199. glLineWidth(2.0);
  200. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  201. Sphere(1.2, 20, 20);
  202. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  203. glPopMatrix();
  204. #if 0
  205. glPushMatrix();
  206. glTranslatef(0.75, 0.0, 1.3);
  207. glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow_mat );
  208. glutWireTeapot(1.0);
  209. glPopMatrix();
  210. #endif
  211. glPushMatrix();
  212. glTranslatef(-0.25, 0.0, 2.5);
  213. glRotatef(40, 0, 1, 0);
  214. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  215. glEnable(GL_BLEND);
  216. glEnable(GL_CULL_FACE);
  217. glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, purple_mat );
  218. Cube(1.0);
  219. glDisable(GL_BLEND);
  220. glDisable(GL_CULL_FACE);
  221. glPopMatrix();
  222. glDisable(GL_LIGHTING);
  223. glPopMatrix();
  224. glDisable(GL_DEPTH_TEST);
  225. }
  226. static void
  227. init_context(void)
  228. {
  229. const GLint texWidth = 64, texHeight = 64;
  230. GLubyte *texImage;
  231. int i, j;
  232. /* checker image */
  233. texImage = malloc(texWidth * texHeight * 4);
  234. for (i = 0; i < texHeight; i++) {
  235. for (j = 0; j < texWidth; j++) {
  236. int k = (i * texWidth + j) * 4;
  237. if ((i % 5) == 0 || (j % 5) == 0) {
  238. texImage[k+0] = 200;
  239. texImage[k+1] = 200;
  240. texImage[k+2] = 200;
  241. texImage[k+3] = 255;
  242. }
  243. else {
  244. if ((i % 5) == 1 || (j % 5) == 1) {
  245. texImage[k+0] = 50;
  246. texImage[k+1] = 50;
  247. texImage[k+2] = 50;
  248. texImage[k+3] = 255;
  249. }
  250. else {
  251. texImage[k+0] = 100;
  252. texImage[k+1] = 100;
  253. texImage[k+2] = 100;
  254. texImage[k+3] = 255;
  255. }
  256. }
  257. }
  258. }
  259. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0,
  260. GL_RGBA, GL_UNSIGNED_BYTE, texImage);
  261. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  262. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  263. free(texImage);
  264. }
  265. static void
  266. write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
  267. {
  268. const int binary = 0;
  269. FILE *f = fopen( filename, "w" );
  270. if (f) {
  271. int i, x, y;
  272. const GLubyte *ptr = buffer;
  273. if (binary) {
  274. fprintf(f,"P6\n");
  275. fprintf(f,"# ppm-file created by osdemo.c\n");
  276. fprintf(f,"%i %i\n", width,height);
  277. fprintf(f,"255\n");
  278. fclose(f);
  279. f = fopen( filename, "ab" ); /* reopen in binary append mode */
  280. for (y=height-1; y>=0; y--) {
  281. for (x=0; x<width; x++) {
  282. i = (y*width + x) * 4;
  283. fputc(ptr[i], f); /* write red */
  284. fputc(ptr[i+1], f); /* write green */
  285. fputc(ptr[i+2], f); /* write blue */
  286. }
  287. }
  288. }
  289. else {
  290. /*ASCII*/
  291. int counter = 0;
  292. fprintf(f,"P3\n");
  293. fprintf(f,"# ascii ppm file created by osdemo.c\n");
  294. fprintf(f,"%i %i\n", width, height);
  295. fprintf(f,"255\n");
  296. for (y=height-1; y>=0; y--) {
  297. for (x=0; x<width; x++) {
  298. i = (y*width + x) * 4;
  299. fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]);
  300. counter++;
  301. if (counter % 5 == 0)
  302. fprintf(f, "\n");
  303. }
  304. }
  305. }
  306. fclose(f);
  307. }
  308. }
  309. static GLboolean
  310. test(GLenum type, GLint bits, const char *filename)
  311. {
  312. const GLint z = 16, stencil = 0, accum = 0;
  313. OSMesaContext ctx;
  314. void *buffer;
  315. GLint cBits;
  316. assert(bits == 8 ||
  317. bits == 16 ||
  318. bits == 32);
  319. assert(type == GL_UNSIGNED_BYTE ||
  320. type == GL_UNSIGNED_SHORT ||
  321. type == GL_FLOAT);
  322. ctx = OSMesaCreateContextExt(OSMESA_RGBA, z, stencil, accum, NULL );
  323. if (!ctx) {
  324. printf("OSMesaCreateContextExt() failed!\n");
  325. return 0;
  326. }
  327. /* Allocate the image buffer */
  328. buffer = malloc(WIDTH * HEIGHT * 4 * bits / 8);
  329. if (!buffer) {
  330. printf("Alloc image buffer failed!\n");
  331. return 0;
  332. }
  333. /* Bind the buffer to the context and make it current */
  334. if (!OSMesaMakeCurrent( ctx, buffer, type, WIDTH, HEIGHT )) {
  335. printf("OSMesaMakeCurrent (%d bits/channel) failed!\n", bits);
  336. free(buffer);
  337. OSMesaDestroyContext(ctx);
  338. return 0;
  339. }
  340. /* sanity checks */
  341. glGetIntegerv(GL_RED_BITS, &cBits);
  342. assert(cBits == bits);
  343. glGetIntegerv(GL_GREEN_BITS, &cBits);
  344. assert(cBits == bits);
  345. glGetIntegerv(GL_BLUE_BITS, &cBits);
  346. assert(cBits == bits);
  347. glGetIntegerv(GL_ALPHA_BITS, &cBits);
  348. assert(cBits == bits);
  349. printf("Rendering %d bit/channel image: %s\n", bits, filename);
  350. OSMesaColorClamp(GL_TRUE);
  351. init_context();
  352. render_image();
  353. if (Gradient)
  354. render_gradient();
  355. /* Make sure buffered commands are finished! */
  356. glFinish();
  357. if (WriteFiles && filename != NULL) {
  358. if (type == GL_UNSIGNED_SHORT) {
  359. GLushort *buffer16 = (GLushort *) buffer;
  360. GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
  361. int i;
  362. for (i = 0; i < WIDTH * HEIGHT * 4; i++)
  363. buffer8[i] = buffer16[i] >> 8;
  364. write_ppm(filename, buffer8, WIDTH, HEIGHT);
  365. free(buffer8);
  366. }
  367. else if (type == GL_FLOAT) {
  368. GLfloat *buffer32 = (GLfloat *) buffer;
  369. GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
  370. int i;
  371. /* colors may be outside [0,1] so we need to clamp */
  372. for (i = 0; i < WIDTH * HEIGHT * 4; i++)
  373. buffer8[i] = (GLubyte) (buffer32[i] * 255.0);
  374. write_ppm(filename, buffer8, WIDTH, HEIGHT);
  375. free(buffer8);
  376. }
  377. else {
  378. write_ppm(filename, buffer, WIDTH, HEIGHT);
  379. }
  380. }
  381. OSMesaDestroyContext(ctx);
  382. free(buffer);
  383. return 1;
  384. }
  385. int
  386. main( int argc, char *argv[] )
  387. {
  388. int i;
  389. for (i = 1; i < argc; i++) {
  390. if (strcmp(argv[i], "-f") == 0)
  391. WriteFiles = GL_TRUE;
  392. else if (strcmp(argv[i], "-g") == 0)
  393. Gradient = GL_TRUE;
  394. }
  395. test(GL_UNSIGNED_BYTE, 8, "image8.ppm");
  396. test(GL_UNSIGNED_SHORT, 16, "image16.ppm");
  397. test(GL_FLOAT, 32, "image32.ppm");
  398. return 0;
  399. }