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.

fbotexture.c 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /*
  2. * Test GL_EXT_framebuffer_object render-to-texture
  3. *
  4. * Draw a teapot into a texture image with stenciling.
  5. * Then draw a textured quad using that texture.
  6. *
  7. * Brian Paul
  8. * 18 Apr 2005
  9. */
  10. #define GL_GLEXT_PROTOTYPES
  11. #include <GL/glut.h>
  12. #include <assert.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <math.h>
  17. /* For debug */
  18. #define DEPTH 1
  19. #define STENCIL 1
  20. #define DRAW 1
  21. static int Win = 0;
  22. static int Width = 400, Height = 400;
  23. static GLenum TexTarget = GL_TEXTURE_2D; /*GL_TEXTURE_RECTANGLE_ARB;*/
  24. static int TexWidth = 512, TexHeight = 512;
  25. /*static int TexWidth = 600, TexHeight = 600;*/
  26. static GLuint MyFB;
  27. static GLuint TexObj;
  28. static GLuint DepthRB, StencilRB;
  29. static GLboolean Anim = GL_FALSE;
  30. static GLfloat Rot = 0.0;
  31. static GLboolean UsePackedDepthStencil = GL_FALSE;
  32. static GLuint TextureLevel = 1; /* which texture level to render to */
  33. static GLenum TexIntFormat = GL_RGB; /* either GL_RGB or GL_RGBA */
  34. static GLboolean Cull = GL_FALSE;
  35. static GLboolean Wireframe = GL_FALSE;
  36. static void
  37. CheckError(int line)
  38. {
  39. GLenum err = glGetError();
  40. if (err) {
  41. printf("GL Error 0x%x at line %d\n", (int) err, line);
  42. }
  43. }
  44. static void
  45. Idle(void)
  46. {
  47. Rot = glutGet(GLUT_ELAPSED_TIME) * 0.1;
  48. glutPostRedisplay();
  49. }
  50. static void
  51. RenderTexture(void)
  52. {
  53. GLenum status;
  54. glMatrixMode(GL_PROJECTION);
  55. glLoadIdentity();
  56. glOrtho(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
  57. glMatrixMode(GL_MODELVIEW);
  58. glLoadIdentity();
  59. glTranslatef(0.0, 0.0, -15.0);
  60. /* draw to texture image */
  61. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
  62. status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  63. if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  64. printf("Framebuffer incomplete!!!\n");
  65. }
  66. glViewport(0, 0, TexWidth, TexHeight);
  67. glClearColor(0.5, 0.5, 1.0, 0.0);
  68. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  69. CheckError(__LINE__);
  70. #if DEPTH
  71. glEnable(GL_DEPTH_TEST);
  72. #endif
  73. #if STENCIL
  74. glEnable(GL_STENCIL_TEST);
  75. glStencilFunc(GL_NEVER, 1, ~0);
  76. glStencilOp(GL_REPLACE, GL_KEEP, GL_REPLACE);
  77. #endif
  78. CheckError(__LINE__);
  79. #if DEPTH || STENCIL
  80. /* draw diamond-shaped stencil pattern */
  81. glColor3f(0, 1, 0);
  82. glBegin(GL_POLYGON);
  83. glVertex2f(-0.2, 0.0);
  84. glVertex2f( 0.0, -0.2);
  85. glVertex2f( 0.2, 0.0);
  86. glVertex2f( 0.0, 0.2);
  87. glEnd();
  88. #endif
  89. /* draw teapot where stencil != 1 */
  90. #if STENCIL
  91. glStencilFunc(GL_NOTEQUAL, 1, ~0);
  92. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  93. #endif
  94. CheckError(__LINE__);
  95. if (Wireframe) {
  96. glPolygonMode(GL_FRONT, GL_LINE);
  97. }
  98. else {
  99. glPolygonMode(GL_FRONT, GL_FILL);
  100. }
  101. if (Cull) {
  102. /* cull back */
  103. glCullFace(GL_BACK);
  104. glEnable(GL_CULL_FACE);
  105. }
  106. else {
  107. glDisable(GL_CULL_FACE);
  108. }
  109. #if 0
  110. glBegin(GL_POLYGON);
  111. glColor3f(1, 0, 0);
  112. glVertex2f(-1, -1);
  113. glColor3f(0, 1, 0);
  114. glVertex2f(1, -1);
  115. glColor3f(0, 0, 1);
  116. glVertex2f(0, 1);
  117. glEnd();
  118. #else
  119. glEnable(GL_LIGHTING);
  120. glEnable(GL_LIGHT0);
  121. glPushMatrix();
  122. glRotatef(0.5 * Rot, 1.0, 0.0, 0.0);
  123. glFrontFace(GL_CW); /* Teapot patches backward */
  124. glutSolidTeapot(0.5);
  125. glFrontFace(GL_CCW);
  126. glPopMatrix();
  127. glDisable(GL_LIGHTING);
  128. /*
  129. PrintStencilHistogram(TexWidth, TexHeight);
  130. */
  131. #endif
  132. glDisable(GL_DEPTH_TEST);
  133. glDisable(GL_STENCIL_TEST);
  134. glDisable(GL_CULL_FACE);
  135. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  136. #if DRAW
  137. /* Bind normal framebuffer */
  138. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  139. #endif
  140. CheckError(__LINE__);
  141. }
  142. static void
  143. Display(void)
  144. {
  145. float ar = (float) Width / (float) Height;
  146. RenderTexture();
  147. /* draw textured quad in the window */
  148. #if DRAW
  149. glMatrixMode(GL_PROJECTION);
  150. glLoadIdentity();
  151. glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
  152. glMatrixMode(GL_MODELVIEW);
  153. glLoadIdentity();
  154. glTranslatef(0.0, 0.0, -7.0);
  155. glViewport(0, 0, Width, Height);
  156. glClearColor(0.25, 0.25, 0.25, 0);
  157. glClear(GL_COLOR_BUFFER_BIT);
  158. glPushMatrix();
  159. glRotatef(Rot, 0, 1, 0);
  160. glEnable(TexTarget);
  161. glBindTexture(TexTarget, TexObj);
  162. glBegin(GL_POLYGON);
  163. glColor3f(0.25, 0.25, 0.25);
  164. if (TexTarget == GL_TEXTURE_2D) {
  165. glTexCoord2f(0, 0);
  166. glVertex2f(-1, -1);
  167. glTexCoord2f(1, 0);
  168. glVertex2f(1, -1);
  169. glColor3f(1.0, 1.0, 1.0);
  170. glTexCoord2f(1, 1);
  171. glVertex2f(1, 1);
  172. glTexCoord2f(0, 1);
  173. glVertex2f(-1, 1);
  174. }
  175. else {
  176. assert(TexTarget == GL_TEXTURE_RECTANGLE_ARB);
  177. glTexCoord2f(0, 0);
  178. glVertex2f(-1, -1);
  179. glTexCoord2f(TexWidth, 0);
  180. glVertex2f(1, -1);
  181. glColor3f(1.0, 1.0, 1.0);
  182. glTexCoord2f(TexWidth, TexHeight);
  183. glVertex2f(1, 1);
  184. glTexCoord2f(0, TexHeight);
  185. glVertex2f(-1, 1);
  186. }
  187. glEnd();
  188. glPopMatrix();
  189. glDisable(TexTarget);
  190. #endif
  191. glutSwapBuffers();
  192. CheckError(__LINE__);
  193. }
  194. static void
  195. Reshape(int width, int height)
  196. {
  197. glViewport(0, 0, width, height);
  198. Width = width;
  199. Height = height;
  200. }
  201. static void
  202. CleanUp(void)
  203. {
  204. #if DEPTH
  205. glDeleteRenderbuffersEXT(1, &DepthRB);
  206. #endif
  207. #if STENCIL
  208. if (!UsePackedDepthStencil)
  209. glDeleteRenderbuffersEXT(1, &StencilRB);
  210. #endif
  211. glDeleteFramebuffersEXT(1, &MyFB);
  212. glDeleteTextures(1, &TexObj);
  213. glutDestroyWindow(Win);
  214. exit(0);
  215. }
  216. static void
  217. Key(unsigned char key, int x, int y)
  218. {
  219. (void) x;
  220. (void) y;
  221. switch (key) {
  222. case 'a':
  223. Anim = !Anim;
  224. if (Anim)
  225. glutIdleFunc(Idle);
  226. else
  227. glutIdleFunc(NULL);
  228. break;
  229. case 'c':
  230. Cull = !Cull;
  231. break;
  232. case 'w':
  233. Wireframe = !Wireframe;
  234. break;
  235. case 's':
  236. Rot += 2.0;
  237. break;
  238. case 'S':
  239. Rot -= 2.0;
  240. break;
  241. case 27:
  242. CleanUp();
  243. break;
  244. }
  245. glutPostRedisplay();
  246. }
  247. static void
  248. Usage(void)
  249. {
  250. printf("Usage:\n");
  251. printf(" a Toggle animation\n");
  252. printf(" s/s Step/rotate\n");
  253. printf(" c Toggle back-face culling\n");
  254. printf(" w Toggle wireframe mode (front-face only)\n");
  255. printf(" Esc Exit\n");
  256. }
  257. static void
  258. Init(int argc, char *argv[])
  259. {
  260. static const GLfloat mat[4] = { 1.0, 0.5, 0.5, 1.0 };
  261. GLint i;
  262. if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
  263. printf("GL_EXT_framebuffer_object not found!\n");
  264. exit(0);
  265. }
  266. if (argc > 1 && strcmp(argv[1], "-ds") == 0) {
  267. if (!glutExtensionSupported("GL_EXT_packed_depth_stencil")) {
  268. printf("GL_EXT_packed_depth_stencil not found!\n");
  269. exit(0);
  270. }
  271. UsePackedDepthStencil = GL_TRUE;
  272. printf("Using GL_EXT_packed_depth_stencil\n");
  273. }
  274. printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  275. /* gen framebuffer id, delete it, do some assertions, just for testing */
  276. glGenFramebuffersEXT(1, &MyFB);
  277. assert(MyFB);
  278. assert(!glIsFramebufferEXT(MyFB));
  279. glDeleteFramebuffersEXT(1, &MyFB);
  280. assert(!glIsFramebufferEXT(MyFB));
  281. /* Note, continue to use MyFB below */
  282. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFB);
  283. assert(glIsFramebufferEXT(MyFB));
  284. glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &i);
  285. assert(i == MyFB);
  286. /* Make texture object/image */
  287. glGenTextures(1, &TexObj);
  288. glBindTexture(TexTarget, TexObj);
  289. /* make two image levels */
  290. glTexImage2D(TexTarget, 0, TexIntFormat, TexWidth, TexHeight, 0,
  291. GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  292. glTexImage2D(TexTarget, 1, TexIntFormat, TexWidth/2, TexHeight/2, 0,
  293. GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  294. TexWidth = TexWidth >> TextureLevel;
  295. TexHeight = TexHeight >> TextureLevel;
  296. glTexParameteri(TexTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  297. glTexParameteri(TexTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  298. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  299. glTexParameteri(TexTarget, GL_TEXTURE_BASE_LEVEL, TextureLevel);
  300. glTexParameteri(TexTarget, GL_TEXTURE_MAX_LEVEL, TextureLevel);
  301. CheckError(__LINE__);
  302. /* Render color to texture */
  303. glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
  304. TexTarget, TexObj, TextureLevel);
  305. #if DEPTH
  306. /* make depth renderbuffer */
  307. glGenRenderbuffersEXT(1, &DepthRB);
  308. assert(DepthRB);
  309. assert(!glIsRenderbufferEXT(DepthRB));
  310. glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthRB);
  311. assert(glIsRenderbufferEXT(DepthRB));
  312. if (UsePackedDepthStencil)
  313. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
  314. TexWidth, TexHeight);
  315. else
  316. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
  317. TexWidth, TexHeight);
  318. CheckError(__LINE__);
  319. glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
  320. GL_RENDERBUFFER_DEPTH_SIZE_EXT, &i);
  321. CheckError(__LINE__);
  322. printf("Depth renderbuffer size = %d bits\n", i);
  323. assert(i > 0);
  324. /* attach DepthRB to MyFB */
  325. glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
  326. GL_RENDERBUFFER_EXT, DepthRB);
  327. #endif
  328. CheckError(__LINE__);
  329. #if STENCIL
  330. if (UsePackedDepthStencil) {
  331. /* DepthRb is a combined depth/stencil renderbuffer */
  332. glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
  333. GL_STENCIL_ATTACHMENT_EXT,
  334. GL_RENDERBUFFER_EXT, DepthRB);
  335. }
  336. else {
  337. /* make stencil renderbuffer */
  338. glGenRenderbuffersEXT(1, &StencilRB);
  339. assert(StencilRB);
  340. assert(!glIsRenderbufferEXT(StencilRB));
  341. glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilRB);
  342. assert(glIsRenderbufferEXT(StencilRB));
  343. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
  344. TexWidth, TexHeight);
  345. /* attach StencilRB to MyFB */
  346. glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
  347. GL_STENCIL_ATTACHMENT_EXT,
  348. GL_RENDERBUFFER_EXT, StencilRB);
  349. }
  350. glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT,
  351. GL_RENDERBUFFER_STENCIL_SIZE_EXT, &i);
  352. CheckError(__LINE__);
  353. printf("Stencil renderbuffer size = %d bits\n", i);
  354. assert(i > 0);
  355. #endif
  356. CheckError(__LINE__);
  357. /* bind regular framebuffer */
  358. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  359. /* lighting */
  360. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat);
  361. }
  362. int
  363. main(int argc, char *argv[])
  364. {
  365. glutInit(&argc, argv);
  366. glutInitWindowPosition(0, 0);
  367. glutInitWindowSize(Width, Height);
  368. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  369. Win = glutCreateWindow(argv[0]);
  370. glutReshapeFunc(Reshape);
  371. glutKeyboardFunc(Key);
  372. glutDisplayFunc(Display);
  373. if (Anim)
  374. glutIdleFunc(Idle);
  375. Init(argc, argv);
  376. Usage();
  377. glutMainLoop();
  378. return 0;
  379. }