@Pigmon
2016-12-01T12:07:18.000000Z
字数 11670
阅读 1350
上课
老师的Cgcourse-examples环境的配置方法 (pdf)
链接:http://pan.baidu.com/s/1jI2ToUE 密码:yxea
拼凑大作业指南+参考大作业1指南
https://www.zybuluo.com/Pigmon/note/582224
参考论文实现阴影效果那个参考大作业
- 加贴图
- 换投影体
- 多光源
仔细看中文注释,写说明时候的关键步骤,但记得文档中改成你自己的说法。
一定别忘了改注释,否则雷同作业。注释是给你们看的,不是给助教看的。
/*-----------------------------------------------------------------------This source file is part of "cgcourse-examples"(Examples for Computer Graphics Course of CCCE GUCAS.)Copyright (C) 2011 Xue Jian (jian.xue.cn@gmail.com)This program is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program. If not, see <http://www.gnu.org/licenses/>.-----------------------------------------------------------------------*/#include <stdlib.h>#include <stdio.h>#include <vector>#include <GL/glut.h>#include <GL/glext.h>#include "camera.h"#include "trackball.h"#define LIST_NAME_TRIANGLE 1#define LIST_NAME_PLANE 2typedef GLfloat POSITION[3];GLuint g_plan_tex_id;int g_window_width = 512;int g_window_height = 512;// lightGLfloat g_light_ambient[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat g_light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };GLfloat g_light_position[] = { 2.0f, 4.0f, 3.0f, 1.0f };GLfloat g_light_direction[] = { 1.0f, 0.0f, 1.0f, 0.0f };GLfloat g_light_rot = 0.0f;GLfloat g_light_rot_speed = 0.2f;// materialGLfloat g_material_ambient[] = { 1.0f, 0.8f, 0.8f, 1.0f };GLfloat g_material_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };GLfloat g_material_specular[] = { 0.33f, 0.33f, 0.52f, 0.0f };GLfloat g_material_emission[] = { 0.0f, 0.0f, 0.0f, 0.0f };GLfloat g_material_specular_power = 80.0f;GLfloat g_material_ambient_2[] = { 0.0f, 1.0f, 1.0f, 1.0f };GLfloat g_material_diffuse_2[] = { 1.0f, 0.5f, 0.25f, 0.5f };GLfloat g_material_specular_2[] = { 0.33f, 0.33f, 0.52f, 0.0f };GLfloat g_material_emission_2[] = { 0.0f, 0.0f, 0.0f, 0.0f };GLfloat g_material_specular_power_2 = 80.0f;// bg colorGLfloat g_color_background[] = { 0.0f, 0.0f, 0.0f, 0.0f };GLfloat g_color_foreground[] = { 1.0f - g_color_background[0], 1.0f - g_color_background[1], 1.0f - g_color_background[2], 1.0f };Cameraf g_cam;float g_z = 10.0f;float const Z_STEP = 0.1f;POSITION triangle[3] = { { 0, 1, 0 },{ 2, 1, 0 },{ 0, 3, 0 } };POSITION lightPosition = { g_light_position[0], g_light_position[1], g_light_position[2] };GLfloat g_pot_position[] = { 0.5f, -0.5f, -3.0f, 1.0f };bool b_volum = false;// --------------------------------------------------------// 鼠标转动 -->// --------------------------------------------------------bool g_left_button_down = false;bool g_middle_button_down = false;bool g_right_button_down = false;int g_last_x = 0;int g_last_y = 0;GLint g_viewport[4];TrackBallf g_trackball(1.5f);Matrixf g_rotm;// --------------------------------------------------------// 鼠标转动 <--// --------------------------------------------------------void set_material_scene(){GLenum face = GL_FRONT_AND_BACK;glMaterialfv(face, GL_AMBIENT, g_material_ambient);glMaterialfv(face, GL_DIFFUSE, g_material_diffuse);glMaterialfv(face, GL_SPECULAR, g_material_specular);glMaterialfv(face, GL_EMISSION, g_material_emission);glMaterialf(face, GL_SHININESS, g_material_specular_power);}void set_material_light(){GLenum face = GL_FRONT;glMaterialfv(face, GL_AMBIENT, g_material_ambient_2);glMaterialfv(face, GL_DIFFUSE, g_material_diffuse_2);glMaterialfv(face, GL_SPECULAR, g_material_specular_2);glMaterialfv(face, GL_EMISSION, g_material_emission_2);glMaterialf(face, GL_SHININESS, g_material_specular_power_2);}bool init(){g_rotm.IdentityMatrix();glEnable(GL_LIGHTING);glClearColor(g_color_background[0], g_color_background[1], g_color_background[2], g_color_background[3]); // Black BackgroundglClearDepth(1.0f); // Depth Buffer SetupglLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f);glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f);glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);glLightfv(GL_LIGHT1, GL_DIFFUSE, g_light_diffuse); // Setup The Diffuse LightglLightfv(GL_LIGHT1, GL_SPECULAR, g_light_diffuse);glLightfv(GL_LIGHT1, GL_POSITION, g_light_position); // Position The LightglEnable(GL_LIGHT1); // Enable Light Onereturn true; // Initialization Went OK}/// 建立场景,一个地板和一个三角形void init_lists(){glNewList(LIST_NAME_TRIANGLE, GL_COMPILE);glColor3f(1.0f, 1.0f, 1.0f);glBegin(GL_TRIANGLES);glVertex3f(triangle[0][0], triangle[0][1], triangle[0][2]);glVertex3f(triangle[1][0], triangle[1][1], triangle[1][2]);glVertex3f(triangle[2][0], triangle[2][1], triangle[2][2]);glEnd();glEndList();glNewList(LIST_NAME_PLANE, GL_COMPILE);glBegin(GL_QUADS);glVertex3f(-10.0f, -1.0f, -10.0f); // tl//glTexCoord2f(1.0f, 0.0f);glVertex3f(10.0f, -1.0f, -10.0f); // tr//glTexCoord2f(1.0f, 1.0f);glVertex3f(10.0f, -1.5f, 10.0f); // br//glTexCoord2f(0.0f, 1.0f);glVertex3f(-10.0f, -1.5f, 10.0f); // blglEnd();glDisable(GL_TEXTURE_2D);glEndList();}void keyboard(unsigned char key, int x, int y){switch (key){case 27:exit(0);break;case 's':b_volum = !b_volum;break;}}// --------------------------------------------------------// 鼠标转动 -->// --------------------------------------------------------void motion(int x, int y){if (g_left_button_down){g_last_x = x;g_last_y = y;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));g_trackball.BuildRotMatrix(g_rotm);glutPostRedisplay();}}void mouse(int button, int state, int x, int y){bool down = (state == GLUT_DOWN);switch (button){case GLUT_LEFT_BUTTON: g_left_button_down = down; break;case GLUT_MIDDLE_BUTTON: g_middle_button_down = down; break;case GLUT_RIGHT_BUTTON: g_right_button_down = down; break;}if (g_left_button_down){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));}g_last_x = x;g_last_y = y;}// --------------------------------------------------------// 鼠标转动 <--// --------------------------------------------------------/// <summary>/// extendVolume : 参考论文中附录提供的生成Shadow Volume的函数/// </summary>/// <param name="n">投影体需要考虑的定点数</param>/// <param name="localLight">是否点光源,1 - 点光源, 0 - 平行光</param>/// <param name="lightPosition">光源位置</param>/// <param name="extendDistance">Shadow Volum的最大长度</param>/// <returns>void</returns>void extendVolume(int n, POSITION v[], int localLight, POSITION lightPosition, float extendDistance){POSITION extendedVectex, extendDirection;int i;// If light source is infinite (directional)if (!localLight){// compute direction opposite from light source directionextendDirection[0] = -lightPosition[0];extendDirection[1] = -lightPosition[1];extendDirection[2] = -lightPosition[2];}glBegin(GL_QUAD_STRIP);// If light source is local (positional)if (localLight){for (i = 0; i < n; i++){glVertex3fv(v[i]);// Compute per-vertex direction from vertex away from the light sourceextendDirection[0] = v[i][0] - lightPosition[0];extendDirection[1] = v[i][1] - lightPosition[1];extendDirection[2] = v[i][2] - lightPosition[2];// Compute extend vertexextendedVectex[0] = v[i][0] + extendDirection[0] * extendDistance;extendedVectex[1] = v[i][1] + extendDirection[1] * extendDistance;extendedVectex[2] = v[i][2] + extendDirection[2] * extendDistance;glVertex3fv(extendedVectex);}// Repeate initial 2 vertices to close the quad strip loopglVertex3fv(v[0]);extendDirection[0] = v[0][0] - lightPosition[0];extendDirection[1] = v[0][1] - lightPosition[1];extendDirection[2] = v[0][2] - lightPosition[2];extendedVectex[0] = v[0][0] + extendDirection[0] * extendDistance;extendedVectex[1] = v[0][1] + extendDirection[1] * extendDistance;extendedVectex[2] = v[0][2] + extendDirection[2] * extendDistance;glVertex3fv(extendedVectex);}else // otherwise, light source is infinite (directional){for (i = 0; i < n; i++){glVertex3fv(v[i]);// Compute extend vertexextendedVectex[0] = v[i][0] + extendDirection[0] * extendDistance;extendedVectex[1] = v[i][1] + extendDirection[1] * extendDistance;extendedVectex[2] = v[i][2] + extendDirection[2] * extendDistance;glVertex3fv(extendedVectex);}// Repeate initial 2 vertices to close the quad strip loopextendedVectex[0] = v[0][0] + extendDirection[0] * extendDistance;extendedVectex[1] = v[0][1] + extendDirection[1] * extendDistance;extendedVectex[2] = v[0][2] + extendDirection[2] * extendDistance;glVertex3fv(extendedVectex);}glEnd();}/// 渲染场景中的除阴影体以外的一切模型void renderScene(){set_material_scene();{// 地面glCallList(LIST_NAME_PLANE);// 茶壶glTranslatef(g_pot_position[0], g_pot_position[1], g_pot_position[2]);glutSolidTeapot(0.6);glTranslatef(-1 * g_pot_position[0], -1 * g_pot_position[1], -1 * g_pot_position[2]);}set_material_light();{// 投影体glCallList(LIST_NAME_TRIANGLE);// Shadow Volume 外观if (b_volum){glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);extendVolume(3, triangle, 1, lightPosition, 100000.0f);glDisable(GL_BLEND);}// 画代表光源的球glTranslatef(g_light_position[0], g_light_position[1], g_light_position[2]);glutSolidSphere(0.2f, 10, 10);glTranslatef(-1 * g_light_position[0], -1 * g_light_position[1], -1 * g_light_position[2]);}}/// <summary>/// 参考论文正文中的,得到阴影体内部的模版值的函数/// </summary>void drawShadowVolumePolygons(){//glDisable(GL_CULL_FACE);glDisable(GL_LIGHTING); // lighting not neededglEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);glDepthMask(0); // do not disturb depth bufferglColorMask(0, 0, 0, 0); // do not disturb color bufferglStencilMask(~0u);glEnable(GL_CULL_FACE); // use face cullingglCullFace(GL_BACK); // increment for front facing fragmentsglStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // that pass the depth testextendVolume(3, triangle, 1, lightPosition, 100000.0f);//for (i = 0; i<numPolygonsInScene; i++) // for every polygon in the scene// renderShadowVolumeForPolygon(i); // call extendVolume for ith polygonglCullFace(GL_FRONT); // decrement for back facing fragmentsglStencilOp(GL_KEEP, GL_KEEP, GL_DECR); // that pass the depth testextendVolume(3, triangle, 1, lightPosition, 100000.0f);//for (i = 0; i<numPolygonsInScene; i++) // for every polygon in the scene// renderShadowVolumeForPolygon(i); // call extendVolume for ith polygonglDisable(GL_CULL_FACE);}void display(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();g_cam.LookAt(-10.0f, 10.0f, g_z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);// 鼠标转动glMultMatrixf(g_rotm);glEnable(GL_LIGHTING);///// 参考论文正文中渲染阴影的主要步骤/// step 1/// 渲染一遍场景,得到深度值glEnable(GL_LIGHT0); // enable light sourceglEnable(GL_DEPTH_TEST); // standard depth testingglDepthFunc(GL_LEQUAL);glDepthMask(1);glDisable(GL_STENCIL_TEST); // no stencil testing (this pass)glColorMask(1, 1, 1, 1); // update color bufferglClearStencil(0); // clear stencil to zeroglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);renderScene();/// step 2/// 分别渲染阴影体的正面和背面,阴影体内部的面模板值为1glDisable(GL_LIGHTING); // do not waste time lightingglEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);glDepthMask(0); // do not disturb the depth bufferglEnable(GL_STENCIL_TEST);glStencilFunc(GL_ALWAYS, 0, 0);glStencilMask(0x1); // just write least significant stencil bitglStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // invert stencil bit if depth passglColorMask(0, 0, 0, 0); // do not disturb the color bufferdrawShadowVolumePolygons();/// step 3/// 根据上面的模板值将阴影绘制出来glEnable(GL_LIGHTING); // use lightingglDisable(GL_LIGHT0); // just not the shadowed lightglEnable(GL_DEPTH_TEST);glDepthFunc(GL_EQUAL); // must match depth from 1st stepglDepthMask(0);glEnable(GL_STENCIL_TEST); // and use stencil to update onlyglStencilFunc(GL_EQUAL, 0x1, 0x1); // pixels tagged asglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // “in the shadow volume”glColorMask(1, 1, 1, 1);renderScene();glutSwapBuffers();}void reshape(int width, int height){if (height == 0){height = 1;}glViewport(0, 0, width, height);glGetIntegerv(GL_VIEWPORT, g_viewport);g_cam.Perspective(45.0f, (float)(width) / (float)(height), 1.1f, 100.0f);}int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);glutInitWindowPosition(100, 100);glutInitWindowSize(g_window_width, g_window_height);glutCreateWindow("参考大作业3");if (!init()) return -1;init_lists();glutDisplayFunc(display);glutReshapeFunc(reshape);glutKeyboardFunc(keyboard);glutMouseFunc(mouse);glutMotionFunc(motion);glutIdleFunc(display);glutMainLoop();return 0;}