Clone of mesa.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

fbotexture.c 9.8KB

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