#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib, "glew32.lib")
#include <windows.h>
#include <GL/glew.h>
#include "GLSL.h"
#include <math.h>
#include <GL/freeglut/freeglut.h>
#include "PNG.h"
#define PAI 3.14159
GLSL glsl[2];
//affine変換用変数
float pos[][3] = { //位置(平行移動)
{ 1.5, 1.0, 0.0},//obj0
{-1.5, 1.0, 0.0} //obj1
};
float scale[][3] = {//サイズ(スケーリング)
{ 2.0, 2.0, 2.0 },//obj0
{ 2.0, 2.0, 2.0 } //obj1
};
float angle[][3] = {//姿勢(回転)
{ 0.0, 0.0, 0.0}, //obj0
{ 0.0, 0.0, 0.0} //obj1
};
//光源
float lightPos[] = {10.0, 15.0, 10.0, 1.0};//光源位置
float lightPos0[] = {10.0, 15.0, 10.0, 1.0};//光源位置(初期値)
//影のマテリアル
float shadowDiffuse[] = {0.0,0.0,0.0,0.3};//影の拡散光
float shadowSpecular[] = {0.0,0.0,0.0,1.0};//影の鏡面光
//カメラと視体積
struct View{
//カメラ
float pos[3];//位置(視点)
float cnt[3];//注視点
float dist; //注視点から視点までの距離
float theta; //仰角(水平面との偏角)
float phi; //方位角
//視体積
float fovY; //視野角
float nearZ; //前方クリップ面(近平面)
float farZ; //後方クリップ面(遠平面)
};
View view = {
0.0, 0.0, 0.0,//pos(仮設定)
0.0, 1.0, 0.0,//cnt
10.0, 30.0, 20.0,//dist, theta, phi
30.0, 1.0, 100.0//fovY,nearZ, farZ
};
View view0 = view;
//Windowのサイズ
int width = 640;
int height = 480;
//アフィン変換
enum SELECT_KEY {ROTATE, SCALE, TRANSLATE, LIGHT};
SELECT_KEY sKey = TRANSLATE;
//マウス操作
int xStart, yStart;
bool flagMouse = false;
//影のフラグ
bool flagShadow = false;
//texture
#define TEX_WIDTH 128
#define TEX_HEIGHT 128
GLubyte texImage[TEX_HEIGHT][TEX_WIDTH][4];
GLubyte normalMap[TEX_HEIGHT][TEX_WIDTH][3];
GLuint texName[6];
TEXTURE *texture[6];
float inv = 1.0;//凹凸反転
float fGrad = 5.0;//勾配強調
float fDisp = 0.15;//変位量調整
float bias = 0.3;//面変位量調整
void drawCube(float s){
float p[8][3] = { {0.5*s,0.5*s,0.5*s}, {-0.5*s,0.5*s,0.5*s},
{-0.5*s,-0.5*s,0.5*s},
{0.5*s,-0.5*s,0.5*s},{0.5*s,0.5*s,-0.5*s}, {-0.5*s,0.5*s,-0.5*s},
{-0.5*s,-0.5*s,0-0.5*s}, {0.5*s,-0.5*s,-0.5*s}
};
glBegin(GL_QUADS);
glNormal3f(0.0f,0.0f,1.0f); //z方向
glVertex3fv(p[0]); glVertex3fv(p[1]);
glVertex3fv(p[2]); glVertex3fv(p[3]);
glNormal3f(1.0f,0.0f,0.0f); //x方向(正面)
glVertex3fv(p[0]); glVertex3fv(p[3]);
glVertex3fv(p[7]); glVertex3fv(p[4]);
glNormal3f(0.0f,1.0f,0.0f); //y方向
glVertex3fv(p[0]); glVertex3fv(p[4]);
glVertex3fv(p[5]); glVertex3fv(p[1]);
glNormal3f(-1.0f,0.0f,0.0f); //-x方向
glVertex3fv(p[1]); glVertex3fv(p[5]);
glVertex3fv(p[6]); glVertex3fv(p[2]);
glNormal3f(0.0f,-1.0f,0.0f); //-y方向
glVertex3fv(p[2]); glVertex3fv(p[6]);
glVertex3fv(p[7]); glVertex3fv(p[3]);
glNormal3f(0.0f,0.0f,-1.0f); //-z方向
glVertex3fv(p[4]); glVertex3fv(p[7]);
glVertex3fv(p[6]); glVertex3fv(p[5]);
glEnd();
}
void setLight(){
float lightAmbient0[] = {0.5, 0.5, 0.5, 1.0}; //環境光
float lightDiffuse0[] = {1.0, 1.0, 1.0, 1.0}; //拡散光
float lightSpecular0[] = {1.0, 1.0, 1.0, 1.0};//鏡面光
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse0);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
}
void resize(int w, int h){
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(view.fovY, (double)w/(double)h, view.nearZ, view.farZ);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
width = w;
height = h;
}
void setCamera(){
double pp = PAI / 180.0;
view.pos[2] = view.cnt[2] + view.dist * cos(pp * view.theta) * cos(pp *
view.phi);//z
view.pos[0] = view.cnt[0] + view.dist * cos(pp * view.theta) * sin(pp *
view.phi);//x
view.pos[1] = view.cnt[1] + view.dist * sin(pp * view.theta);//y
resize(width, height);
}
void idle(void){
glutPostRedisplay();
}
void TexCreate(int NO,char* FileName){
glGenTextures(1, &texName[NO]);
texture[NO] = new TEXTURE(FileName);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//テクスチャオブジェクトの作成
glBindTexture(GL_TEXTURE_2D, texName[NO]);
//テクスチャの指定
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,texture[NO]->Width,texture[NO]->Height,0,GL_RGBA,GL_UNSIGNED_BYTE,texture[NO]->image);
//テクスチャの繰り返し方法の指定
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);//GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);//GL_CLAMP);
//テクスチャを拡大・縮小する方法の指定
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
}
void makeNormalMap(int NO, char* FileName){
//法線マップ用配列作成
int i, j, ip, jp;
float r, g;
texture[NO] = new TEXTURE(FileName);
//BMPファイルから高さマップをロード
for(j = 0; j < TEX_HEIGHT; j++){
for(i = 0; i < TEX_WIDTH; i++){
//高度マップを取得
normalMap[j][i][2] = ((texture[NO]->image[i*4+j*4 *
TEX_WIDTH])
+ (texture[NO]->image[i*4+j*4 * TEX_WIDTH+1]) +
(texture[NO]->image[i*4+j*4 * TEX_WIDTH+2])) / 3;
}
}
//高さマップから法線マップを作成
for(j = 0; j < TEX_HEIGHT; j++){
jp = j+1;
if(jp >= TEX_HEIGHT) jp = 0;
for(i = 0; i < TEX_WIDTH; i++){
ip = i+1;
if(ip >= TEX_WIDTH) ip = 0;
float deltaS = inv * (normalMap[j][ip][2] -
normalMap[j][i][2]);
float deltaT = inv * (normalMap[jp][i][2] -
normalMap[j][i][2]);
r = 127.5 + deltaS * fGrad;
if(r < 0.0) r = 0.0;
if(r > 255.0) r = 255.0;
g = 127.5 + deltaT * fGrad;
if(g < 0.0) g = 0.0;
if(g > 255.0) g = 255.0;
normalMap[j][i][0] = (GLubyte)r;
normalMap[j][i][1] = (GLubyte)g;
if(inv == -1.0)
normalMap[j][i][2] = - normalMap[j][i][2];
}
}
glBindTexture(GL_TEXTURE_2D, texName[NO]);//テクスチャをバインドする
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,TEX_WIDTH,TEX_HEIGHT,0,GL_RGB,GL_UNSIGNED_BYTE,normalMap);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);//LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);//LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);//バインドを解除
}
void init(void){
glClearColor(0.8, 0.8, 1.0, 1.0);
setCamera();
setLight();
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glsl[0].InitGLSL("vertex.shader","flagment.shader");
glsl[1].InitGLSL("displacement_vertex.shader","displacement_flagment.shader");
//テクスチャー作成
glGenTextures(4, texName);
//普通に表示
TexCreate(0,"brick128.png");
makeNormalMap(1,"bump128.png");
//バンプマップ表示
TexCreate(2,"brick128.png");
makeNormalMap(3,"bump128.png");
}
void drawFloor(float widthX, float widthZ, int nx, int nz){
int i, j;
//Floor1枚当たりの幅
float wX = widthX / (float)nx;
float wZ = widthZ / (float)nz;
float diffuse[][4] = {{ 0.7f, 0.7f, 0.7f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f}
};
float ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f};
float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
glMaterialfv(GL_FRONT,GL_SPECULAR,specular);
glMaterialf(GL_FRONT,GL_SHININESS,100);
glNormal3f(0.0f, 1.0f, 0.0f);
glPushMatrix();
for (j = 0; j < nz; j++) {
float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ;
for (i = 0; i < nx; i++) {
float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX;
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) & 1]);
glBegin(GL_QUADS);
glVertex3f(x1, 0.0f, z1);
glVertex3f(x1, 0.0f, z2);
glVertex3f(x2, 0.0f, z2);
glVertex3f(x2, 0.0f, z1);
glEnd();
}
}
glPopMatrix();
}
void CalcShadowMat(int ID, float* mat){
float ex, ey, ez;//光源の方向
float a, b, c, d;//床の面のパラメータ
float s; //object中心から光源までの距離
float x, y, z;
x = lightPos[0] - pos[ID][0];
y = lightPos[1] - pos[ID][1];
z = lightPos[2] - pos[ID][2];
//光源の方向ベクトル
s = sqrt(x * x + y * y + z * z);
ex = x / s;
ey = y / s;
ez = z / s;
//フロアの方向ベクトル(y方向)
a = 0.0;
b = 1.0;
c = 0.0;
d = -0.001; //フロアと影の干渉を防ぐため
//shadow matrix
mat[0] = b * ey + c * ez;
mat[1] = -a * ey;
mat[2] = -a * ez;
mat[3] = 0.0;
mat[4] = -b * ex;
mat[5] = a * ex + c * ez;
mat[6] = -b * ez;
mat[7] = 0.0;
mat[8] = -c * ex;
mat[9] = -c * ey;
mat[10] = a * ex + b * ey;
mat[11] = 0.0;
mat[12] = -d * ex;
mat[13] = -d * ey;
mat[14] = -d * ez;
mat[15] = a * ex + b * ey + c * ez;
}
void drawPlate(float s){
static float p[4][3] = {
{ s/2.0,-s/2.0, 0.0}, { s/2.0, s/2.0, 0.0}, {-s/2.0, s/2.0, 0.0},
{-s/2.0,-s/2.0, 0.0}};
glBegin(GL_QUADS);
glNormal3f(0.0, 0.0, 1.0); //z方向の法線
glVertex3fv(p[0]);
glVertex3fv(p[1]);
glVertex3fv(p[2]);
glVertex3fv(p[3]);
glEnd();
}
void drawBumpPlate(float size, int nRepeatS, int nRepeatT){
float tnt[3];
float s, t;
float sz = 0.5 * size;
static float p[4][3] = {
{ sz, sz, 0.0}, {-sz, sz, 0.0},
{-sz,-sz, 0.0}, { sz,-sz, 0.0}
};
s = (float)nRepeatS;
t = (float)nRepeatT;
GLuint tangentLoc = glGetAttribLocation(glsl[0].ShaderProg, "tangent");
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
tnt[0] = 1.0; tnt[1] = 0.0; tnt[2] = 0.0;
glVertexAttrib3fv(tangentLoc, tnt);
glNormal3f(0.0, 0.0, 1.0); //z方向の法線
//テクスチャー座標と頂点番号との対応付け
glTexCoord2f(0.0, 0.0); glVertex3fv(p[2]);
glTexCoord2f( s , 0.0); glVertex3fv(p[3]);
glTexCoord2f( s , t ); glVertex3fv(p[0]);
glTexCoord2f(0.0, t ); glVertex3fv(p[1]);
glEnd();
glDisable(GL_TEXTURE_2D);
}
void drawDispPlate(float size, int nDiv, int nRepeatS, int nRepeatT){
float tnt[3];
float s, t;
float q[4][3];//平面上の分割頂点
float s0, s1, t0, t1, d0, d1;
int i, j;
float sz = 0.5 * size;
static float p[4][3] = {
{ sz, sz, 0.0}, {-sz, sz, 0.0},
{-sz,-sz, 0.0}, { sz,-sz, 0.0}
};
s = (float)nRepeatS;
t = (float)nRepeatT;
GLuint tangentLoc = glGetAttribLocation(glsl[1].ShaderProg, "tangent");
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
tnt[0] = 1.0; tnt[1] = 0.0; tnt[2] = 0.0;
glVertexAttrib3fv(tangentLoc, tnt);
glNormal3f(0.0, 0.0, 1.0); //z方向の法線
for(j = 0; j < nDiv; j++){
d0 = (float)j / (float)nDiv;
d1 = (float)(j+1) / (float)nDiv;
//z座標
q[0][2] = q[1][2] = q[2][2] = q[3][2] = p[0][2];
//y座標
q[0][1] = q[1][1] = p[2][1] + (p[1][1] - p[2][1]) * d0;
q[2][1] = q[3][1] = p[2][1] + (p[1][1] - p[2][1]) * d1;
//t テクスチャ座標
t0 = t * d0; t1 = t * d1;
for(i = 0; i < nDiv; i++){
d0 = (float)i / (float)nDiv;
d1 = (float)(i+1) / (float)nDiv;
//x座標
q[0][0] = q[3][0] = p[1][0] + (p[0][0] - p[1][0]) * d0;
q[1][0] = q[2][0] = p[1][0] + (p[0][0] - p[1][0]) * d1;
//s テクスチャ座標
s0 = s * d0; s1 = s * d1;
glTexCoord2f( s0, t0); glVertex3fv(q[0]);
glTexCoord2f( s1, t0); glVertex3fv(q[1]);
glTexCoord2f( s1, t1); glVertex3fv(q[2]);
glTexCoord2f( s0, t1); glVertex3fv(q[3]);
}
}
glEnd();
glDisable(GL_TEXTURE_2D);
}
void DrawBumpPlate(void){
float ambient[] = { 0.3, 0.3, 0.3, 1.0};
float diffuse[] = { 0.7, 0.7, 0.7, 1.0};
float specular[]= { 0.5, 0.5, 0.5, 1.0};
if(flagShadow){
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular);
}else{
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,specular);
glMaterialf(GL_FRONT,GL_SHININESS,100);
}
glPushMatrix();
glTranslatef(pos[1][0], pos[1][1], pos[1][2]);
glRotatef(angle[1][2], 0.0, 0.0, 1.0);//z軸回転
glRotatef(angle[1][1], 0.0, 1.0, 0.0);//y軸回転
glRotatef(angle[1][0], 1.0, 0.0, 0.0);//x軸回転
glScalef(scale[1][0], scale[1][1], scale[1][2]);
//オブジェクト形状
if(!flagShadow){
drawBumpPlate(1.0,1,1);
}else{//影表示のときはTextureを付けない
drawPlate(1.0);
}
glPopMatrix();
}
void DrawDispPlate(void){
float ambient[] = { 0.3, 0.3, 0.3, 1.0};
float diffuse[] = { 0.7, 0.7, 0.7, 1.0};
float specular[]= { 0.5, 0.5, 0.5, 1.0};
if(flagShadow){
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular);
}else{
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,specular);
glMaterialf(GL_FRONT,GL_SHININESS,100);
}
glPushMatrix();
glTranslatef(pos[0][0], pos[0][1], pos[0][2]);
glRotatef(angle[0][2], 0.0, 0.0, 1.0);//z軸回転
glRotatef(angle[0][1], 0.0, 1.0, 0.0);//y軸回転
glRotatef(angle[0][0], 1.0, 0.0, 0.0);//x軸回転
glScalef(scale[0][0], scale[0][1], scale[0][2]);
//オブジェクト形状
if(!flagShadow){
drawDispPlate(1.0,100,1,1);
}else{//影表示のときはTextureを付けない
drawPlate(1.0);
}
glPopMatrix();
}
void drawShadow(){
//計算は平行光線に対する影
//オブジェクトごとに光源の方向を変え、疑似的に点光源に対する影を作る
float mat[16]; //影行列の要素
flagShadow = true;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE);
//影の描画
CalcShadowMat(0, mat);
glPushMatrix();
glMultMatrixf(mat);
DrawBumpPlate();
glPopMatrix();
CalcShadowMat(1, mat);
glPushMatrix();
glMultMatrixf(mat);
DrawDispPlate();
glPopMatrix();
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
flagShadow = false;
}
void display(void){
//カラーバッファ,デプスバッファのクリア
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();//視点を変えるときはこの位置に必要
if(cos(PAI * view.theta /180.0) >= 0.0)//カメラ仰角90度でビューアップベクトル切替
gluLookAt(view.pos[0], view.pos[1], view.pos[2], view.cnt[0],
view.cnt[1], view.cnt[2], 0.0, 1.0, 0.0);
else
gluLookAt(view.pos[0], view.pos[1], view.pos[2], view.cnt[0],
view.cnt[1], view.cnt[2], 0.0, -1.0, 0.0);
//光源設定//'l'を押した後光源位置可変
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texName[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texName[1]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texName[2]);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, texName[3]);
// シェーダプログラムの適用
glUseProgram(glsl[0].ShaderProg);
//バンプマッピング描画
GLint texColorLoc = glGetUniformLocation(glsl[0].ShaderProg, "colorMap");
GLint texNormalLoc = glGetUniformLocation(glsl[0].ShaderProg,
"normalMap");
glUniform1i(texColorLoc, 2);
glUniform1i(texNormalLoc, 3);
DrawBumpPlate();
// シェーダプログラムの適用を解除
glUseProgram(0);
// シェーダプログラムの適用
glUseProgram(glsl[1].ShaderProg);
//ディスプレイスメントマップ描画
GLint dispLoc = glGetUniformLocation(glsl[1].ShaderProg, "fDisp");
GLint invLoc = glGetUniformLocation(glsl[1].ShaderProg, "inv");
GLint biasLoc = glGetUniformLocation(glsl[1].ShaderProg, "bias");
texColorLoc = glGetUniformLocation(glsl[1].ShaderProg, "colorMap");
texNormalLoc = glGetUniformLocation(glsl[1].ShaderProg, "normalMap");
glUniform1f(dispLoc, fDisp);
glUniform1f(invLoc, inv);
glUniform1f(biasLoc, bias);
glUniform1i(texColorLoc, 0);//GL_TEXTURE0を適用
glUniform1i(texNormalLoc, 1);//GL_TEXTURE1を適用
DrawDispPlate();
glPopMatrix();
// シェーダプログラムの適用を解除
glUseProgram(0);
drawFloor(10.0, 10.0, 5, 5);
//影
drawShadow();
//終了
glutSwapBuffers();
}
//以下の3個の関数はマウス操作による視点の変更に必要
void mouse(int button, int state, int x, int y){
double pp = PAI / 180.0;
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
xStart = x; yStart = y;
flagMouse = true;
if(x > width/4 && x < 3*width/4 && y > height/4
&& y < 3*height/4)//dolly
{
}
}else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){
if(x > width/4 && x < 3*width/4 && y > height/4
&& y < 3*height/4)//dolly
{
}else if(( x < width/4 || x > 3*width/4) && (y >
height/4 && y < 3*height/4)){
if(x < width/4 ) view.phi -= 1.0;
else view.phi += 1.0;
view.cnt[2] = view.pos[2] - view.dist * cos(pp * view.phi) * cos(pp *
view.theta);
view.cnt[0] = view.pos[0] - view.dist * sin(pp * view.phi) * cos(pp *
view.theta);
}else if((x > width/4 && x < 3*width/4) && (y <
height/4 || y > 3*height/4)){
if( y < height/4)
view.theta += 1.0;
else
view.theta -= 1.0;
view.cnt[2] = view.pos[2] - view.dist * cos(pp * view.theta) *
cos(pp * view.phi);
view.cnt[0] = view.pos[0] - view.dist * cos(pp * view.theta) * sin(pp
* view.phi);
view.cnt[1] = view.pos[1] - view.dist * sin(pp * view.theta);
}
else if(x < width/8 && y > 7*height/8) view.fovY -=
1.0;//zoom in
else if(x > 7*width/8 && y > 7*height/8) view.fovY +=
1.0;//zoom out
}
else flagMouse = false;
if(state == GLUT_DOWN) setCamera();
}
void motion(int x, int y){
if(!flagMouse) return;
if(cos(PAI * view.theta /180.0) >= 0.0)
view.phi -= 0.5 * (float)(x - xStart) ;//tumble
else
view.phi += 0.5 * (float)(x - xStart) ;//tumble
view.theta += 0.5 * (float)(y - yStart) ;//crane
setCamera();
xStart = x;
yStart = y;
}
void main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(width, height);
glutInitWindowPosition(100, 100);
glutCreateWindow("ディスプレイスメントマップ");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutIdleFunc(idle);
init();
glutMainLoop();
glDeleteTextures(4, texName);
}
|