Last active
April 13, 2018 06:54
-
-
Save fushime2/4d69f711fe48f71616cb39b24be415d6 to your computer and use it in GitHub Desktop.
家に影をつける
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 家に影を付ける | |
// | |
#include <cstdlib> | |
#include <cmath> | |
#include "GL/glut.h" | |
using namespace std; | |
GLfloat light0_pos[] = {7.0, 5.0, 5.0, 1.0}; | |
float plane[] = {0.0, 1.0, 0.0, 1.0}; // ax + by + cz + d = 0; | |
float ShadowMatrix[4][4]; // Shadow | |
//Polygon Offset | |
float OffsetFactor = 1.0f; | |
float OffsetUnit = 0.0f; | |
const int N = 4; | |
GLfloat yellow[N] = {1.0f, 1.0f, 0.0f, 1.0f}; | |
// 家の点 | |
GLdouble point[5][3] = { | |
{-0.0, 1.0, -0.0}, | |
{-0.7, 0.5, 0.7}, | |
{0.7, 0.5, -0.7}, | |
{0.7, 0.5, 0.7}, | |
{-0.7, 0.5, -0.7} | |
}; | |
class House { | |
protected: | |
// 表面 | |
int face[6][4] = { | |
{0, 1, 2, 3}, // ABCD | |
{1, 5, 6, 2}, // BFGC | |
{5, 4, 7, 6}, // FEHG | |
{4, 0, 3, 7}, // EADH | |
{4, 5, 1, 0}, // EFBA | |
{3, 2, 6, 7} // DCGH | |
}; | |
// 色 | |
GLfloat yellow[N] = {1.0f, 1.0f, 0.0f, 1.0f}; | |
GLfloat red[N] = {0.8f, 0.2f, 0.2f, 1.0f}; | |
GLfloat blue[N] = {0.2f, 0.2f, 0.5f, 1.0f}; | |
GLfloat brown[N] = {0.8f, 0.6f, 0.0f}; | |
GLfloat white[N] = {1.0f, 1.0f, 1.0f, 1.0f}; | |
GLfloat green[N] = {0.2f, 0.8f, 0.2f, 1.0f}; | |
}; | |
class Shikaku : public House { | |
private: | |
// 頂点 | |
GLdouble vertex[8][3] = { | |
{0.0, 0.0, 0.0}, // A | |
{1.0, 0.0, 0.0}, // B | |
{1.0, 1.0, 0.0}, // C | |
{0.0, 1.0, 0.0}, // D | |
{0.0, 0.0, 1.0}, // E | |
{1.0, 0.0, 1.0}, // F | |
{1.0, 1.0, 1.0}, // G | |
{0.0, 1.0, 1.0} // H | |
}; | |
// 法線 | |
GLdouble normal[6][3] = { | |
{0.0, 0.0,-1.0}, | |
{1.0, 0.0, 0.0}, | |
{0.0, 0.0, 1.0}, | |
{-1.0, 0.0, 0.0}, | |
{0.0,-1.0, 0.0}, | |
{0.0, 1.0, 0.0} | |
}; | |
public: | |
void disp(); | |
}; | |
void Shikaku::disp() { | |
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, brown); | |
for(int j = 0; j < 6; ++j) { | |
glNormal3dv(normal[j]); | |
for(int i = 0; i < 4; ++i) { | |
glVertex3dv(vertex[face[j][i]]); | |
} | |
} | |
}; | |
class Sankaku : public House { | |
private: | |
// 法線 | |
GLdouble normal[6][3] = { | |
{0.0, 0.5,-0.7}, | |
{0.7, 0.5, 0.0}, | |
{0.0, 0.5, 0.7}, | |
{-0.7, 0.5, 0.0}, | |
{0.0,-1.0, 0.0}, | |
{0.0, 1.0, 0.0} | |
}; | |
// 頂点 | |
GLdouble vertex[8][3] = { | |
{-0.2, 1.0,-0.2}, // A | |
{1.2, 1.0,-0.2}, // B | |
{0.5, 1.5, 0.5}, // C | |
{0.5, 1.5, 0.5}, // D | |
{-0.2, 1.0, 1.2}, // E | |
{1.2, 1.0, 1.2}, // F | |
{0.5, 1.5, 0.5}, // G | |
{0.5, 1.5, 0.5} // H | |
}; | |
public: | |
void disp(); | |
}; | |
void Sankaku::disp() { | |
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, green); | |
for(int j = 0; j < 6; ++j) { | |
glNormal3dv(normal[j]); | |
for(int i = 0; i < 4; ++i) { | |
glVertex3dv(vertex[face[j][i]]); | |
} | |
} | |
} | |
class Sphere : public House { | |
private: | |
GLdouble x, y, z, radius = 0.1; | |
GLint slices = 100, stacks = 100; | |
public: | |
Sphere(GLdouble _x, GLdouble _y, GLdouble _z); | |
void disp(); | |
}; | |
Sphere::Sphere(GLdouble _x, GLdouble _y, GLdouble _z) { | |
x = _x; y = _y; z = _z; | |
} | |
void Sphere::disp() { | |
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, yellow); | |
glTranslated(x, y, z); | |
glBegin(GL_QUADS); | |
glutSolidSphere(radius, slices, stacks); | |
glEnd(); | |
} | |
void disp_house() { | |
glTranslated(-0.5, -0.5, -0.5); | |
Shikaku shikaku; | |
Sankaku sankaku; | |
glBegin(GL_QUADS); | |
shikaku.disp(); | |
sankaku.disp(); | |
glEnd(); | |
} | |
void disp_sphere(GLdouble x, GLdouble y, GLdouble z) { | |
Sphere sphere(x, y, z); | |
sphere.disp(); | |
} | |
void DRAW_FLOOR() { | |
glTranslatef(0, -1, 0); | |
glRotatef(90, -1, 0, 0); | |
glNormal3d(0, 0, 1); | |
glRectf(-5, 5, 5, -5); | |
} | |
void display() { | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
// 床 | |
static float floorcolor[] = {0.8f, 0.8f, 0.8f, 1.0f}; | |
glEnable(GL_POLYGON_OFFSET_FILL); | |
glPushMatrix(); | |
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, floorcolor); | |
glPolygonOffset(OffsetFactor, OffsetUnit); | |
DRAW_FLOOR(); | |
glPopMatrix(); | |
glDisable(GL_POLYGON_OFFSET_FILL); | |
for(int i = 0; i < 5; i++) { | |
glPushMatrix(); | |
disp_sphere(point[i][0], point[i][1], point[i][2]); | |
glPopMatrix(); | |
} | |
glPushMatrix(); | |
disp_house(); | |
glPopMatrix(); | |
// 影 | |
glDisable(GL_LIGHTING); | |
glDisable(GL_LIGHT0); | |
glPushMatrix(); | |
glMultMatrixf(&ShadowMatrix[0][0]); | |
glColor3d(0, 0, 0); | |
disp_house(); | |
glPopMatrix(); | |
for(int i = 0; i < 5; i++) { | |
glPushMatrix(); | |
glMultMatrixf(&ShadowMatrix[0][0]); | |
glColor3d(0, 0, 0); | |
disp_sphere(point[i][0], point[i][1], point[i][2]); | |
glPopMatrix(); | |
} | |
glEnable(GL_LIGHTING); | |
glEnable(GL_LIGHT0); | |
glEnd(); | |
glFlush(); | |
glutSwapBuffers(); | |
} | |
void resize(int w, int h) { | |
glViewport(0, 0, w, h); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
gluPerspective(30.0, 1.0 * w / h, 1.0, 100.0); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
//gluLookAt(6.0, 5.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); | |
gluLookAt(-4.0, 5.0, 3.0, 0.3, 0.0, 0.0, 0.0, 1.0, 0.0); | |
} | |
void CalcShadowMatrixf() { | |
static float dot = 0; | |
// 内積 | |
for(int i = 0; i < 4; ++i) { | |
dot += plane[i] * light0_pos[i]; | |
} | |
for(int i = 0; i < 4; ++i) { | |
for(int j = 0; j < 4; ++j) { | |
ShadowMatrix[i][j] = -plane[i] * light0_pos[j]; | |
if(j == i) ShadowMatrix[i][j] += dot; | |
} | |
} | |
} | |
void init() { | |
glClearColor(1.0, 1.0, 1.0, 0.0); | |
glEnable(GL_DEPTH_TEST); | |
glEnable(GL_LIGHTING); | |
glEnable(GL_LIGHT0); | |
glEnable(GL_LIGHT1); | |
glLightfv(GL_LIGHT1, GL_DIFFUSE, yellow); | |
CalcShadowMatrixf(); //Shadow mapping | |
} | |
int main(int argc, char *argv[]) { | |
glutInitWindowPosition(100, 100); | |
glutInitWindowSize(320, 240); | |
glutInit(&argc, argv); | |
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); | |
glutCreateWindow(argv[0]); | |
glutDisplayFunc(display); | |
glutReshapeFunc(resize); | |
init(); | |
glutMainLoop(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
http://i.imgur.com/YyeXsDZ.png
出力(前から見たとき)