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.

drawbuffers.c 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Test GL_ARB_draw_buffers, GL_EXT_framebuffer_object
  3. * and GLSL's gl_FragData[].
  4. *
  5. * Brian Paul
  6. * 11 March 2007
  7. */
  8. #define GL_GLEXT_PROTOTYPES
  9. #include <assert.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <GL/glut.h>
  14. #include "extfuncs.h"
  15. static int Win;
  16. static int Width = 400, Height = 400;
  17. static GLuint FBobject, RBobjects[3];
  18. static GLfloat Xrot = 0.0, Yrot = 0.0;
  19. static GLuint Program;
  20. static void
  21. CheckError(int line)
  22. {
  23. GLenum err = glGetError();
  24. if (err) {
  25. printf("GL Error 0x%x at line %d\n", (int) err, line);
  26. }
  27. }
  28. static void
  29. Display(void)
  30. {
  31. GLubyte *buffer = malloc(Width * Height * 4);
  32. static const GLenum buffers[2] = {
  33. GL_COLOR_ATTACHMENT0_EXT,
  34. GL_COLOR_ATTACHMENT1_EXT
  35. };
  36. glUseProgram_func(Program);
  37. /* draw to user framebuffer */
  38. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject);
  39. /* Clear color buffer 0 (blue) */
  40. glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
  41. glClearColor(0.5, 0.5, 1.0, 0.0);
  42. glClear(GL_COLOR_BUFFER_BIT);
  43. /* Clear color buffer 1 (1 - blue) */
  44. glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
  45. glClearColor(0.5, 0.5, 0.0, 0.0);
  46. glClear(GL_COLOR_BUFFER_BIT);
  47. glClear(GL_DEPTH_BUFFER_BIT);
  48. /* draw to two buffers w/ fragment shader */
  49. glDrawBuffersARB(2, buffers);
  50. glPushMatrix();
  51. glRotatef(Xrot, 1, 0, 0);
  52. glRotatef(Yrot, 0, 1, 0);
  53. glutSolidTorus(0.75, 2.0, 10, 20);
  54. glPopMatrix();
  55. /* read from user framebuffer */
  56. /* bottom half = colorbuffer 0 */
  57. glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
  58. glReadPixels(0, 0, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE,
  59. buffer);
  60. /* top half = colorbuffer 1 */
  61. glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
  62. glReadPixels(0, Height/2, Width, Height - Height / 2,
  63. GL_RGBA, GL_UNSIGNED_BYTE,
  64. buffer + Width * (Height / 2) * 4);
  65. /* draw to window */
  66. glUseProgram_func(0);
  67. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  68. glWindowPos2iARB(0, 0);
  69. glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  70. free(buffer);
  71. glutSwapBuffers();
  72. CheckError(__LINE__);
  73. }
  74. static void
  75. Reshape(int width, int height)
  76. {
  77. float ar = (float) width / (float) height;
  78. glViewport(0, 0, width, height);
  79. glMatrixMode(GL_PROJECTION);
  80. glLoadIdentity();
  81. glFrustum(-ar, ar, -1.0, 1.0, 5.0, 35.0);
  82. glMatrixMode(GL_MODELVIEW);
  83. glLoadIdentity();
  84. glTranslatef(0.0, 0.0, -20.0);
  85. Width = width;
  86. Height = height;
  87. glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]);
  88. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
  89. glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]);
  90. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
  91. glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]);
  92. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
  93. Width, Height);
  94. }
  95. static void
  96. CleanUp(void)
  97. {
  98. glDeleteFramebuffersEXT(1, &FBobject);
  99. glDeleteRenderbuffersEXT(3, RBobjects);
  100. glutDestroyWindow(Win);
  101. exit(0);
  102. }
  103. static void
  104. Key(unsigned char key, int x, int y)
  105. {
  106. (void) x;
  107. (void) y;
  108. switch (key) {
  109. case 'x':
  110. Xrot += 5.0;
  111. break;
  112. case 'y':
  113. Yrot += 5.0;
  114. break;
  115. case 27:
  116. CleanUp();
  117. break;
  118. }
  119. glutPostRedisplay();
  120. }
  121. static void
  122. CheckExtensions(void)
  123. {
  124. const char *version = (const char *) glGetString(GL_VERSION);
  125. GLint numBuf;
  126. if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
  127. printf("Sorry, GL_EXT_framebuffer_object is required!\n");
  128. exit(1);
  129. }
  130. if (!glutExtensionSupported("GL_ARB_draw_buffers")) {
  131. printf("Sorry, GL_ARB_draw_buffers is required!\n");
  132. exit(1);
  133. }
  134. if (version[0] != '2') {
  135. printf("Sorry, OpenGL 2.0 is required!\n");
  136. exit(1);
  137. }
  138. glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &numBuf);
  139. printf("GL_MAX_DRAW_BUFFERS_ARB = %d\n", numBuf);
  140. if (numBuf < 2) {
  141. printf("Sorry, GL_MAX_DRAW_BUFFERS_ARB needs to be >= 2\n");
  142. exit(1);
  143. }
  144. printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  145. }
  146. static void
  147. SetupRenderbuffers(void)
  148. {
  149. glGenFramebuffersEXT(1, &FBobject);
  150. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject);
  151. glGenRenderbuffersEXT(3, RBobjects);
  152. glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]);
  153. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
  154. glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]);
  155. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
  156. glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]);
  157. glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
  158. Width, Height);
  159. glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
  160. GL_RENDERBUFFER_EXT, RBobjects[0]);
  161. glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,
  162. GL_RENDERBUFFER_EXT, RBobjects[1]);
  163. glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
  164. GL_RENDERBUFFER_EXT, RBobjects[2]);
  165. CheckError(__LINE__);
  166. }
  167. static GLuint
  168. LoadAndCompileShader(GLenum target, const char *text)
  169. {
  170. GLint stat;
  171. GLuint shader = glCreateShader_func(target);
  172. glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
  173. glCompileShader_func(shader);
  174. glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
  175. if (!stat) {
  176. GLchar log[1000];
  177. GLsizei len;
  178. glGetShaderInfoLog_func(shader, 1000, &len, log);
  179. fprintf(stderr, "drawbuffers: problem compiling shader:\n%s\n", log);
  180. exit(1);
  181. }
  182. return shader;
  183. }
  184. static void
  185. CheckLink(GLuint prog)
  186. {
  187. GLint stat;
  188. glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
  189. if (!stat) {
  190. GLchar log[1000];
  191. GLsizei len;
  192. glGetProgramInfoLog_func(prog, 1000, &len, log);
  193. fprintf(stderr, "drawbuffers: shader link error:\n%s\n", log);
  194. }
  195. }
  196. static void
  197. SetupShaders(void)
  198. {
  199. /* second color output = 1 - first color */
  200. static const char *fragShaderText =
  201. "void main() {\n"
  202. " gl_FragData[0] = gl_Color; \n"
  203. " gl_FragData[1] = vec4(1.0) - gl_Color; \n"
  204. "}\n";
  205. GLuint fragShader;
  206. fragShader = LoadAndCompileShader(GL_FRAGMENT_SHADER, fragShaderText);
  207. Program = glCreateProgram_func();
  208. glAttachShader_func(Program, fragShader);
  209. glLinkProgram_func(Program);
  210. CheckLink(Program);
  211. glUseProgram_func(Program);
  212. }
  213. static void
  214. SetupLighting(void)
  215. {
  216. static const GLfloat frontMat[4] = { 1.0, 0.5, 0.5, 1.0 };
  217. static const GLfloat backMat[4] = { 1.0, 0.5, 0.5, 1.0 };
  218. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, frontMat);
  219. glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, backMat);
  220. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
  221. glEnable(GL_LIGHT0);
  222. glEnable(GL_LIGHTING);
  223. }
  224. static void
  225. Init(void)
  226. {
  227. CheckExtensions();
  228. GetExtensionFuncs();
  229. SetupRenderbuffers();
  230. SetupShaders();
  231. SetupLighting();
  232. glEnable(GL_DEPTH_TEST);
  233. }
  234. int
  235. main(int argc, char *argv[])
  236. {
  237. glutInit(&argc, argv);
  238. glutInitWindowPosition(0, 0);
  239. glutInitWindowSize(Width, Height);
  240. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  241. Win = glutCreateWindow(argv[0]);
  242. glutReshapeFunc(Reshape);
  243. glutKeyboardFunc(Key);
  244. glutDisplayFunc(Display);
  245. Init();
  246. glutMainLoop();
  247. return 0;
  248. }