[关闭]
@Pigmon 2016-12-01T12:07:18.000000Z 字数 11670 阅读 917

图形学参考大作业3

上课


如果不知道怎么整合到cgcourse-examples里

老师的Cgcourse-examples环境的配置方法 (pdf)
链接:http://pan.baidu.com/s/1jI2ToUE 密码:yxea

拼凑大作业指南+参考大作业1指南
https://www.zybuluo.com/Pigmon/note/582224

说明

参考论文实现阴影效果那个参考大作业

修改建议

  • 加贴图
  • 换投影体
  • 多光源

仔细看中文注释,写说明时候的关键步骤,但记得文档中改成你自己的说法。
一定别忘了改注释,否则雷同作业。注释是给你们看的,不是给助教看的。

程序

  1. /*
  2. -----------------------------------------------------------------------
  3. This source file is part of "cgcourse-examples"
  4. (Examples for Computer Graphics Course of CCCE GUCAS.)
  5. Copyright (C) 2011 Xue Jian (jian.xue.cn@gmail.com)
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. -----------------------------------------------------------------------
  17. */
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <vector>
  21. #include <GL/glut.h>
  22. #include <GL/glext.h>
  23. #include "camera.h"
  24. #include "trackball.h"
  25. #define LIST_NAME_TRIANGLE 1
  26. #define LIST_NAME_PLANE 2
  27. typedef GLfloat POSITION[3];
  28. GLuint g_plan_tex_id;
  29. int g_window_width = 512;
  30. int g_window_height = 512;
  31. // light
  32. GLfloat g_light_ambient[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  33. GLfloat g_light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
  34. GLfloat g_light_position[] = { 2.0f, 4.0f, 3.0f, 1.0f };
  35. GLfloat g_light_direction[] = { 1.0f, 0.0f, 1.0f, 0.0f };
  36. GLfloat g_light_rot = 0.0f;
  37. GLfloat g_light_rot_speed = 0.2f;
  38. // material
  39. GLfloat g_material_ambient[] = { 1.0f, 0.8f, 0.8f, 1.0f };
  40. GLfloat g_material_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
  41. GLfloat g_material_specular[] = { 0.33f, 0.33f, 0.52f, 0.0f };
  42. GLfloat g_material_emission[] = { 0.0f, 0.0f, 0.0f, 0.0f };
  43. GLfloat g_material_specular_power = 80.0f;
  44. GLfloat g_material_ambient_2[] = { 0.0f, 1.0f, 1.0f, 1.0f };
  45. GLfloat g_material_diffuse_2[] = { 1.0f, 0.5f, 0.25f, 0.5f };
  46. GLfloat g_material_specular_2[] = { 0.33f, 0.33f, 0.52f, 0.0f };
  47. GLfloat g_material_emission_2[] = { 0.0f, 0.0f, 0.0f, 0.0f };
  48. GLfloat g_material_specular_power_2 = 80.0f;
  49. // bg color
  50. GLfloat g_color_background[] = { 0.0f, 0.0f, 0.0f, 0.0f };
  51. GLfloat g_color_foreground[] = { 1.0f - g_color_background[0], 1.0f - g_color_background[1], 1.0f - g_color_background[2], 1.0f };
  52. Cameraf g_cam;
  53. float g_z = 10.0f;
  54. float const Z_STEP = 0.1f;
  55. POSITION triangle[3] = { { 0, 1, 0 },{ 2, 1, 0 },{ 0, 3, 0 } };
  56. POSITION lightPosition = { g_light_position[0], g_light_position[1], g_light_position[2] };
  57. GLfloat g_pot_position[] = { 0.5f, -0.5f, -3.0f, 1.0f };
  58. bool b_volum = false;
  59. // --------------------------------------------------------
  60. // 鼠标转动 -->
  61. // --------------------------------------------------------
  62. bool g_left_button_down = false;
  63. bool g_middle_button_down = false;
  64. bool g_right_button_down = false;
  65. int g_last_x = 0;
  66. int g_last_y = 0;
  67. GLint g_viewport[4];
  68. TrackBallf g_trackball(1.5f);
  69. Matrixf g_rotm;
  70. // --------------------------------------------------------
  71. // 鼠标转动 <--
  72. // --------------------------------------------------------
  73. void set_material_scene()
  74. {
  75. GLenum face = GL_FRONT_AND_BACK;
  76. glMaterialfv(face, GL_AMBIENT, g_material_ambient);
  77. glMaterialfv(face, GL_DIFFUSE, g_material_diffuse);
  78. glMaterialfv(face, GL_SPECULAR, g_material_specular);
  79. glMaterialfv(face, GL_EMISSION, g_material_emission);
  80. glMaterialf(face, GL_SHININESS, g_material_specular_power);
  81. }
  82. void set_material_light()
  83. {
  84. GLenum face = GL_FRONT;
  85. glMaterialfv(face, GL_AMBIENT, g_material_ambient_2);
  86. glMaterialfv(face, GL_DIFFUSE, g_material_diffuse_2);
  87. glMaterialfv(face, GL_SPECULAR, g_material_specular_2);
  88. glMaterialfv(face, GL_EMISSION, g_material_emission_2);
  89. glMaterialf(face, GL_SHININESS, g_material_specular_power_2);
  90. }
  91. bool init()
  92. {
  93. g_rotm.IdentityMatrix();
  94. glEnable(GL_LIGHTING);
  95. glClearColor(g_color_background[0], g_color_background[1], g_color_background[2], g_color_background[3]); // Black Background
  96. glClearDepth(1.0f); // Depth Buffer Setup
  97. glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f);
  98. glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f);
  99. glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);
  100. glLightfv(GL_LIGHT1, GL_DIFFUSE, g_light_diffuse); // Setup The Diffuse Light
  101. glLightfv(GL_LIGHT1, GL_SPECULAR, g_light_diffuse);
  102. glLightfv(GL_LIGHT1, GL_POSITION, g_light_position); // Position The Light
  103. glEnable(GL_LIGHT1); // Enable Light One
  104. return true; // Initialization Went OK
  105. }
  106. /// 建立场景,一个地板和一个三角形
  107. void init_lists()
  108. {
  109. glNewList(LIST_NAME_TRIANGLE, GL_COMPILE);
  110. glColor3f(1.0f, 1.0f, 1.0f);
  111. glBegin(GL_TRIANGLES);
  112. glVertex3f(triangle[0][0], triangle[0][1], triangle[0][2]);
  113. glVertex3f(triangle[1][0], triangle[1][1], triangle[1][2]);
  114. glVertex3f(triangle[2][0], triangle[2][1], triangle[2][2]);
  115. glEnd();
  116. glEndList();
  117. glNewList(LIST_NAME_PLANE, GL_COMPILE);
  118. glBegin(GL_QUADS);
  119. glVertex3f(-10.0f, -1.0f, -10.0f); // tl
  120. //glTexCoord2f(1.0f, 0.0f);
  121. glVertex3f(10.0f, -1.0f, -10.0f); // tr
  122. //glTexCoord2f(1.0f, 1.0f);
  123. glVertex3f(10.0f, -1.5f, 10.0f); // br
  124. //glTexCoord2f(0.0f, 1.0f);
  125. glVertex3f(-10.0f, -1.5f, 10.0f); // bl
  126. glEnd();
  127. glDisable(GL_TEXTURE_2D);
  128. glEndList();
  129. }
  130. void keyboard(unsigned char key, int x, int y)
  131. {
  132. switch (key)
  133. {
  134. case 27:
  135. exit(0);
  136. break;
  137. case 's':
  138. b_volum = !b_volum;
  139. break;
  140. }
  141. }
  142. // --------------------------------------------------------
  143. // 鼠标转动 -->
  144. // --------------------------------------------------------
  145. void motion(int x, int y)
  146. {
  147. if (g_left_button_down)
  148. {
  149. g_last_x = x;
  150. g_last_y = y;
  151. g_trackball.Update((float)(2.0*(x - g_viewport[0]) / g_viewport[2] - 1), (float)(2.0*(g_viewport[3] - y - 1 - g_viewport[1]) / g_viewport[3] - 1));
  152. g_trackball.BuildRotMatrix(g_rotm);
  153. glutPostRedisplay();
  154. }
  155. }
  156. void mouse(int button, int state, int x, int y)
  157. {
  158. bool down = (state == GLUT_DOWN);
  159. switch (button)
  160. {
  161. case GLUT_LEFT_BUTTON: g_left_button_down = down; break;
  162. case GLUT_MIDDLE_BUTTON: g_middle_button_down = down; break;
  163. case GLUT_RIGHT_BUTTON: g_right_button_down = down; break;
  164. }
  165. if (g_left_button_down)
  166. {
  167. g_trackball.Start((float)(2.0*(x - g_viewport[0]) / g_viewport[2] - 1), (float)(2.0*(g_viewport[3] - y - 1 - g_viewport[1]) / g_viewport[3] - 1));
  168. }
  169. g_last_x = x;
  170. g_last_y = y;
  171. }
  172. // --------------------------------------------------------
  173. // 鼠标转动 <--
  174. // --------------------------------------------------------
  175. /// <summary>
  176. /// extendVolume : 参考论文中附录提供的生成Shadow Volume的函数
  177. /// </summary>
  178. /// <param name="n">投影体需要考虑的定点数</param>
  179. /// <param name="localLight">是否点光源,1 - 点光源, 0 - 平行光</param>
  180. /// <param name="lightPosition">光源位置</param>
  181. /// <param name="extendDistance">Shadow Volum的最大长度</param>
  182. /// <returns>void</returns>
  183. void extendVolume(int n, POSITION v[], int localLight, POSITION lightPosition, float extendDistance)
  184. {
  185. POSITION extendedVectex, extendDirection;
  186. int i;
  187. // If light source is infinite (directional)
  188. if (!localLight)
  189. {
  190. // compute direction opposite from light source direction
  191. extendDirection[0] = -lightPosition[0];
  192. extendDirection[1] = -lightPosition[1];
  193. extendDirection[2] = -lightPosition[2];
  194. }
  195. glBegin(GL_QUAD_STRIP);
  196. // If light source is local (positional)
  197. if (localLight)
  198. {
  199. for (i = 0; i < n; i++)
  200. {
  201. glVertex3fv(v[i]);
  202. // Compute per-vertex direction from vertex away from the light source
  203. extendDirection[0] = v[i][0] - lightPosition[0];
  204. extendDirection[1] = v[i][1] - lightPosition[1];
  205. extendDirection[2] = v[i][2] - lightPosition[2];
  206. // Compute extend vertex
  207. extendedVectex[0] = v[i][0] + extendDirection[0] * extendDistance;
  208. extendedVectex[1] = v[i][1] + extendDirection[1] * extendDistance;
  209. extendedVectex[2] = v[i][2] + extendDirection[2] * extendDistance;
  210. glVertex3fv(extendedVectex);
  211. }
  212. // Repeate initial 2 vertices to close the quad strip loop
  213. glVertex3fv(v[0]);
  214. extendDirection[0] = v[0][0] - lightPosition[0];
  215. extendDirection[1] = v[0][1] - lightPosition[1];
  216. extendDirection[2] = v[0][2] - lightPosition[2];
  217. extendedVectex[0] = v[0][0] + extendDirection[0] * extendDistance;
  218. extendedVectex[1] = v[0][1] + extendDirection[1] * extendDistance;
  219. extendedVectex[2] = v[0][2] + extendDirection[2] * extendDistance;
  220. glVertex3fv(extendedVectex);
  221. }
  222. else // otherwise, light source is infinite (directional)
  223. {
  224. for (i = 0; i < n; i++)
  225. {
  226. glVertex3fv(v[i]);
  227. // Compute extend vertex
  228. extendedVectex[0] = v[i][0] + extendDirection[0] * extendDistance;
  229. extendedVectex[1] = v[i][1] + extendDirection[1] * extendDistance;
  230. extendedVectex[2] = v[i][2] + extendDirection[2] * extendDistance;
  231. glVertex3fv(extendedVectex);
  232. }
  233. // Repeate initial 2 vertices to close the quad strip loop
  234. extendedVectex[0] = v[0][0] + extendDirection[0] * extendDistance;
  235. extendedVectex[1] = v[0][1] + extendDirection[1] * extendDistance;
  236. extendedVectex[2] = v[0][2] + extendDirection[2] * extendDistance;
  237. glVertex3fv(extendedVectex);
  238. }
  239. glEnd();
  240. }
  241. /// 渲染场景中的除阴影体以外的一切模型
  242. void renderScene()
  243. {
  244. set_material_scene();
  245. {
  246. // 地面
  247. glCallList(LIST_NAME_PLANE);
  248. // 茶壶
  249. glTranslatef(g_pot_position[0], g_pot_position[1], g_pot_position[2]);
  250. glutSolidTeapot(0.6);
  251. glTranslatef(-1 * g_pot_position[0], -1 * g_pot_position[1], -1 * g_pot_position[2]);
  252. }
  253. set_material_light();
  254. {
  255. // 投影体
  256. glCallList(LIST_NAME_TRIANGLE);
  257. // Shadow Volume 外观
  258. if (b_volum)
  259. {
  260. glEnable(GL_BLEND);
  261. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  262. extendVolume(3, triangle, 1, lightPosition, 100000.0f);
  263. glDisable(GL_BLEND);
  264. }
  265. // 画代表光源的球
  266. glTranslatef(g_light_position[0], g_light_position[1], g_light_position[2]);
  267. glutSolidSphere(0.2f, 10, 10);
  268. glTranslatef(-1 * g_light_position[0], -1 * g_light_position[1], -1 * g_light_position[2]);
  269. }
  270. }
  271. /// <summary>
  272. /// 参考论文正文中的,得到阴影体内部的模版值的函数
  273. /// </summary>
  274. void drawShadowVolumePolygons()
  275. {
  276. //glDisable(GL_CULL_FACE);
  277. glDisable(GL_LIGHTING); // lighting not needed
  278. glEnable(GL_DEPTH_TEST);
  279. glDepthFunc(GL_LESS);
  280. glDepthMask(0); // do not disturb depth buffer
  281. glColorMask(0, 0, 0, 0); // do not disturb color buffer
  282. glStencilMask(~0u);
  283. glEnable(GL_CULL_FACE); // use face culling
  284. glCullFace(GL_BACK); // increment for front facing fragments
  285. glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // that pass the depth test
  286. extendVolume(3, triangle, 1, lightPosition, 100000.0f);
  287. //for (i = 0; i<numPolygonsInScene; i++) // for every polygon in the scene
  288. // renderShadowVolumeForPolygon(i); // call extendVolume for ith polygon
  289. glCullFace(GL_FRONT); // decrement for back facing fragments
  290. glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); // that pass the depth test
  291. extendVolume(3, triangle, 1, lightPosition, 100000.0f);
  292. //for (i = 0; i<numPolygonsInScene; i++) // for every polygon in the scene
  293. // renderShadowVolumeForPolygon(i); // call extendVolume for ith polygon
  294. glDisable(GL_CULL_FACE);
  295. }
  296. void display()
  297. {
  298. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  299. glMatrixMode(GL_MODELVIEW);
  300. glLoadIdentity();
  301. g_cam.LookAt(-10.0f, 10.0f, g_z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
  302. // 鼠标转动
  303. glMultMatrixf(g_rotm);
  304. glEnable(GL_LIGHTING);
  305. ///// 参考论文正文中渲染阴影的主要步骤
  306. /// step 1
  307. /// 渲染一遍场景,得到深度值
  308. glEnable(GL_LIGHT0); // enable light source
  309. glEnable(GL_DEPTH_TEST); // standard depth testing
  310. glDepthFunc(GL_LEQUAL);
  311. glDepthMask(1);
  312. glDisable(GL_STENCIL_TEST); // no stencil testing (this pass)
  313. glColorMask(1, 1, 1, 1); // update color buffer
  314. glClearStencil(0); // clear stencil to zero
  315. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  316. renderScene();
  317. /// step 2
  318. /// 分别渲染阴影体的正面和背面,阴影体内部的面模板值为1
  319. glDisable(GL_LIGHTING); // do not waste time lighting
  320. glEnable(GL_DEPTH_TEST);
  321. glDepthFunc(GL_LESS);
  322. glDepthMask(0); // do not disturb the depth buffer
  323. glEnable(GL_STENCIL_TEST);
  324. glStencilFunc(GL_ALWAYS, 0, 0);
  325. glStencilMask(0x1); // just write least significant stencil bit
  326. glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // invert stencil bit if depth pass
  327. glColorMask(0, 0, 0, 0); // do not disturb the color buffer
  328. drawShadowVolumePolygons();
  329. /// step 3
  330. /// 根据上面的模板值将阴影绘制出来
  331. glEnable(GL_LIGHTING); // use lighting
  332. glDisable(GL_LIGHT0); // just not the shadowed light
  333. glEnable(GL_DEPTH_TEST);
  334. glDepthFunc(GL_EQUAL); // must match depth from 1st step
  335. glDepthMask(0);
  336. glEnable(GL_STENCIL_TEST); // and use stencil to update only
  337. glStencilFunc(GL_EQUAL, 0x1, 0x1); // pixels tagged as
  338. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // “in the shadow volume”
  339. glColorMask(1, 1, 1, 1);
  340. renderScene();
  341. glutSwapBuffers();
  342. }
  343. void reshape(int width, int height)
  344. {
  345. if (height == 0)
  346. {
  347. height = 1;
  348. }
  349. glViewport(0, 0, width, height);
  350. glGetIntegerv(GL_VIEWPORT, g_viewport);
  351. g_cam.Perspective(45.0f, (float)(width) / (float)(height), 1.1f, 100.0f);
  352. }
  353. int main(int argc, char *argv[])
  354. {
  355. glutInit(&argc, argv);
  356. glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  357. glutInitWindowPosition(100, 100);
  358. glutInitWindowSize(g_window_width, g_window_height);
  359. glutCreateWindow("参考大作业3");
  360. if (!init()) return -1;
  361. init_lists();
  362. glutDisplayFunc(display);
  363. glutReshapeFunc(reshape);
  364. glutKeyboardFunc(keyboard);
  365. glutMouseFunc(mouse);
  366. glutMotionFunc(motion);
  367. glutIdleFunc(display);
  368. glutMainLoop();
  369. return 0;
  370. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注