《OpenGL 超级宝典(Super Bible)第七版》 有关 PBO 的 Example

举报
ShaderJoy 发表于 2021/12/30 00:22:48 2021/12/30
【摘要】   该代码除了使用了 PBO 还是加入了 OpenMP   代码及关键注释如下:     /* * Copyright ?2012-2015 Graham Sellers * * Permission is hereby granted, free of charge, to any ...

 

该代码除了使用了 PBO 还是加入了 OpenMP

 

代码及关键注释如下:

 

 


  
  1. /*
  2. * Copyright ?2012-2015 Graham Sellers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21. * DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <sb7.h>
  24. #include <shader.h>
  25. #include <object.h>
  26. #include <vmath.h>
  27. #include <sb7textoverlay.h>
  28. #include <sb7ktx.h>
  29. #include <math.h>
  30. #include <omp.h>
  31. class pmbfractal_app : public sb7::application
  32. {
  33. public:
  34. pmbfractal_app()
  35. {
  36. }
  37. void init();
  38. void startup();
  39. void render(double currentTime);
  40. void onKey(int key, int action);
  41. void shutdown(void);
  42. protected:
  43. sb7::text_overlay overlay;
  44. void updateOverlay();
  45. void update_fractal();
  46. enum
  47. {
  48. // Use a super-low resolution fractal in debug builds to
  49. // make the application useable.
  50. #ifdef _DEBUG
  51. FRACTAL_WIDTH = 128,
  52. FRACTAL_HEIGHT = 128,
  53. #else
  54. FRACTAL_WIDTH = 512,
  55. FRACTAL_HEIGHT = 512,
  56. #endif
  57. BUFFER_SIZE = (FRACTAL_WIDTH * FRACTAL_HEIGHT)
  58. };
  59. GLuint vao;
  60. GLuint program;
  61. GLuint buffer;
  62. GLuint texture;
  63. unsigned char * mapped_buffer;
  64. float fps;
  65. struct
  66. {
  67. vmath::vec2 C;
  68. vmath::vec2 offset;
  69. float zoom;
  70. } fractparams;
  71. };
  72. void pmbfractal_app::init()
  73. {
  74. static const char title[] = "OpenGL SuperBible - Persistent Mapped Fractal";
  75. sb7::application::init();
  76. memcpy(info.title, title, sizeof(title));
  77. }
  78. void pmbfractal_app::startup()
  79. {
  80. // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
  81. // 创建用于输出到纹理的 PBO
  82. glGenBuffers(1, &buffer);
  83. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
  84. glBufferStorage(GL_PIXEL_UNPACK_BUFFER,
  85. BUFFER_SIZE,
  86. nullptr,
  87. GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
  88. mapped_buffer = (unsigned char*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,
  89. 0,
  90. BUFFER_SIZE,
  91. GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
  92. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  93. // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
  94. GLuint shaders[2] =
  95. {
  96. sb7::shader::load("media/shaders/fsq/fsq.vs.glsl", GL_VERTEX_SHADER),
  97. sb7::shader::load("media/shaders/fsq/fsq.fs.glsl", GL_FRAGMENT_SHADER)
  98. };
  99. program = sb7::program::link_from_shaders(shaders, 2, true);
  100. glGenTextures(1, &texture);
  101. glBindTexture(GL_TEXTURE_2D, texture);
  102. glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, FRACTAL_WIDTH, FRACTAL_HEIGHT);
  103. glGenVertexArrays(1, &vao);
  104. glBindVertexArray(vao);
  105. overlay.init(128, 50);
  106. int maxThreads = omp_get_max_threads();
  107. omp_set_num_threads(maxThreads);
  108. }
  109. void pmbfractal_app::update_fractal()
  110. {
  111. const vmath::vec2 C = fractparams.C; // (0.03f, -0.2f);
  112. const float thresh_squared = 256.0f;
  113. const float zoom = fractparams.zoom;
  114. const vmath::vec2 offset = fractparams.offset;
  115. // 动态调度,当有空闲线程则为其分配16次迭代,来写 mapped_buffer
  116. #pragma omp parallel for schedule (dynamic, 16)
  117. for (int y = 0; y < FRACTAL_HEIGHT; y++)
  118. {
  119. for (int x = 0; x < FRACTAL_WIDTH; x++)
  120. {
  121. vmath::vec2 Z;
  122. Z[0] = zoom * (float(x) / float(FRACTAL_WIDTH) - 0.5f) + offset[0];
  123. Z[1] = zoom * (float(y) / float(FRACTAL_HEIGHT) - 0.5f) + offset[1];
  124. unsigned char * ptr = mapped_buffer + y * FRACTAL_WIDTH + x; // ☆
  125. int it;
  126. for (it = 0; it < 256; it++)
  127. {
  128. vmath::vec2 Z_squared;
  129. Z_squared[0] = Z[0] * Z[0] - Z[1] * Z[1];
  130. Z_squared[1] = 2.0f * Z[0] * Z[1];
  131. Z = Z_squared + C;
  132. if ((Z[0] * Z[0] + Z[1] * Z[1]) > thresh_squared)
  133. break;
  134. }
  135. *ptr = it;
  136. }
  137. }
  138. }
  139. void pmbfractal_app::render(double currentTime)
  140. {
  141. static float lastTime = 0.0f;
  142. static int frames = 0;
  143. float nowTime = float(currentTime);
  144. fractparams.C = vmath::vec2(1.5f - cosf(nowTime * 0.4f) * 0.5f,
  145. 1.5f + cosf(nowTime * 0.5f) * 0.5f) * 0.3f;
  146. fractparams.offset = vmath::vec2(cosf(nowTime * 0.14f),
  147. cosf(nowTime * 0.25f)) * 0.25f;
  148. fractparams.zoom = (sinf(nowTime) + 1.3f) * 0.7f;
  149. update_fractal();
  150. glViewport(0, 0, info.windowWidth, info.windowHeight);
  151. glUseProgram(program);
  152. glActiveTexture(GL_TEXTURE0);
  153. glBindTexture(GL_TEXTURE_2D, texture);
  154. // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
  155. // 将 PBO 的数据输出到纹理中
  156. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
  157. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, FRACTAL_WIDTH, FRACTAL_HEIGHT, GL_RED, GL_UNSIGNED_BYTE, nullptr);
  158. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  159. // ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
  160. glBindVertexArray(vao);
  161. glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  162. if (nowTime > (lastTime + 0.25f))
  163. {
  164. fps = float(frames) / (nowTime - lastTime);
  165. frames = 0;
  166. lastTime = nowTime;
  167. }
  168. updateOverlay();
  169. frames++;
  170. }
  171. void pmbfractal_app::shutdown(void)
  172. {
  173. glDeleteProgram(program);
  174. glDeleteBuffers(1, &buffer);
  175. }
  176. void pmbfractal_app::updateOverlay()
  177. {
  178. char buffer[256];
  179. overlay.clear();
  180. sprintf(buffer, "%2.2fms / frame (%4.2f FPS)", 1000.0f / fps, fps);
  181. overlay.drawText(buffer, 0, 0);
  182. overlay.draw();
  183. }
  184. void pmbfractal_app::onKey(int key, int action)
  185. {
  186. if (action)
  187. {
  188. switch (key)
  189. {
  190. case 'M':
  191. break;
  192. }
  193. }
  194. }
  195. DECLARE_MAIN(pmbfractal_app)

 

 

 

 

 

运行结果如下:

 

相关阅读:

《OpenGL 超级宝典(Super Bible)第五版》 有关 PBO 的 Example

OpenGL深入探索——像素缓冲区对象 (PBO)

OpenMP并行构造的schedule子句详解

 

 

 

 

文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/53257460

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。