Skip to content

Instantly share code, notes, and snippets.

@fushime2
Last active April 13, 2018 06:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fushime2/4d69f711fe48f71616cb39b24be415d6 to your computer and use it in GitHub Desktop.
Save fushime2/4d69f711fe48f71616cb39b24be415d6 to your computer and use it in GitHub Desktop.
家に影をつける
//
// 家に影を付ける
//
#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;
}
@fushime2
Copy link
Author

http://i.imgur.com/YyeXsDZ.png
出力(前から見たとき)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment