シャドウマッピング

シャドウマッピングです。
一時的に視点を光源に移してみると光の当たる部分を見る事ができます。
その時の見えない部分=障害物=デプスバッファの値が影となります。
オブジェクトが別のオブジェクトに落とす影は、もちろんの事、
オブジェクト自身が自らに落とす影も描画する事ができます。

vertex.shader

varying vec3 P;
varying vec3 N;

void main(void)
{
  P = vec3(gl_ModelViewMatrix * gl_Vertex);
  N = normalize(gl_NormalMatrix * gl_Normal);
    gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex;
  gl_Position = ftransform();
}

flagment.shader

varying vec3 P;
varying vec3 N;
uniform sampler2DShadow shadowMap;

void main(void)

{
  vec3 L = normalize(gl_LightSource[0].position.xyz - P);
  N = normalize(N);
  
  vec4 ambient = gl_FrontLightProduct[0].ambient;
  float dotNL = dot(N, L);
  vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL);
    vec3 V = normalize(-P);
    vec3 H = normalize(L + V);
    float powNH = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
    if(dotNL <= 0.0) powNH = 0.0;
    vec4 specular = gl_FrontLightProduct[0].specular * powNH;
    float shadow = 0.3;//影濃度
  float s = shadow2DProj(shadowMap, gl_TexCoord[0]).r;
  diffuse *= clamp(s, shadow, 1.0);
    gl_FragColor = ambient + diffuse + specular * s;
}

GLSL.h

#pragma once
 #include <stdio.h>
 
//GLSLクラス
 class GLSL{
 public:
  GLuint ShaderProg;
  GLuint VertexShader, FragmentShader;
  void ReadShaderCompile(GLuint Shader, const char *File);//shader fileを読み込みコンパイルする
  void Link( GLuint Prog );//リンクする
  void InitGLSL(const char *VertexFile);//GLSLの初期化
  void InitGLSL(const char *VertexFile, const char *FragmentFile);//GLSLの初期化
  void ON();//シェーダー描画に切り替え
  void OFF();//シェーダー解除
  ~GLSL();
 };
 
 void GLSL::ReadShaderCompile(GLuint Shader, const char *File){
    FILE *fp;
    char *buf;
    GLsizei size, len;
    GLint compiled;
 
    fopen_s(&fp,File, "rb");
    if(!fp) printf("ファイルを開くことができません %s\n", File);
 
    fseek(fp, 0, SEEK_END);
    size = ftell(fp);
 
   buf = (GLchar *)malloc(size);
    if (buf == NULL) {
      printf("メモリが確保できませんでした \n");
    }
 
    fseek(fp, 0, SEEK_SET);
    fread(buf, 1, size, fp);
    glShaderSource(Shader, 1, (const GLchar **)&buf, &size);
    free(buf);
    fclose(fp);
 
    glCompileShader(Shader);
    glGetShaderiv( Shader, GL_COMPILE_STATUS, &compiled );
 
   if ( compiled == GL_FALSE )
    {
     printf( "コンパイルできませんでした!!: %s \n ", File);
     glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, &size );
     if ( size > 0 )
     {
      buf = (char *)malloc(size);
      glGetShaderInfoLog( Shader, size, &len, buf);
      printf(buf);
      free(buf);
     }
    }
  }
 
 void GLSL::Link( GLuint Prog ){
    GLsizei size, len;
    GLint linked;
    char *infoLog ;
 
   glLinkProgram( Prog );
 
   glGetProgramiv( Prog, GL_LINK_STATUS, &linked );
 
   if ( linked == GL_FALSE ){
    printf("リンクできませんでした!! \n");
    
    glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, &size );
    if ( size > 0 ){
     infoLog = (char *)malloc(size);
     glGetProgramInfoLog( Prog, size, &len, infoLog );
     printf(infoLog);
     free(infoLog);
    }
   }
 }
 
void GLSL::InitGLSL(const char *VertexFile){
    GLenum err = glewInit();
    if (err != GLEW_OK)
    {
     printf("Error: %s\n", glewGetErrorString(err));
    }
    printf("VENDOR= %s \n", glGetString(GL_VENDOR));
    printf("GPU= %s \n", glGetString(GL_RENDERER));
    printf("OpenGL= %s \n", glGetString(GL_VERSION));
    printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));
    VertexShader = glCreateShader(GL_VERTEX_SHADER);
    ReadShaderCompile(VertexShader, VertexFile);
    ShaderProg = glCreateProgram();
    glAttachShader(ShaderProg, VertexShader);
    glDeleteShader(VertexShader);
    Link(ShaderProg);
  }
 
 
void GLSL::InitGLSL(const char *VertexFile, const char *FragmentFile){
    GLenum err = glewInit();
    if (err != GLEW_OK)
    {
     printf("Error: %s\n", glewGetErrorString(err));
    }
    printf("VENDOR= %s \n", glGetString(GL_VENDOR));
    printf("GPU= %s \n", glGetString(GL_RENDERER));
    printf("OpenGL= %s \n", glGetString(GL_VERSION));
    printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));
 
   VertexShader = glCreateShader(GL_VERTEX_SHADER);
    FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
 
   ReadShaderCompile(VertexShader, VertexFile);
    ReadShaderCompile(FragmentShader, FragmentFile);
 
   ShaderProg = glCreateProgram();
 
    glAttachShader(ShaderProg, VertexShader);
    glAttachShader(ShaderProg, FragmentShader);
 
    glDeleteShader(VertexShader);
    glDeleteShader(FragmentShader);
    Link(ShaderProg);
  }
 
void GLSL::ON(){
  glUseProgram(ShaderProg);
 }
 
void GLSL::OFF(){
  glUseProgram(0);
 }
 
GLSL::~GLSL(){
  glDeleteProgram(ShaderProg);
 }
 

main.cpp

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib, "glew32.lib")

#include <stdio.h>
#include <windows.h>
#include <GL/glew.h>
#include "GLSL.h"
#include <math.h>
#include <GL/freeglut/freeglut.h>

#define PAI 3.141592f

float pos[][3] = { //位置(平行移動)
    { 0.3f, 3.5f, 0.0f},//obj0
    {-0.4f, 1.5f, 0.0f} //obj1
};
float angle[][3] = {//姿勢(回転)
    { 0.0f, 0.0f, 0.0f}, //obj0
    { 0.0f, 0.0f, 0.0f}  //obj1
};
float lightPos[] =  {0.0f, 6.0f, 1.0f, 1.0f};//光源位置

//カメラと視体積
struct View{
  float pos[3];//位置(視点)
  float cnt[3];//注視点
  float dist;  //注視点から視点までの距離
  float theta; //仰角(水平面との偏角)
  float phi;   //方位角
  //視体積
  float fovY;  //視野角
  float nearZ; //前方クリップ面(近平面)
  float farZ;  //後方クリップ面(遠平面)
};
View view = { 
    0.0f, 0.0f, 0.0f,//pos(仮設定)
  0.0f, 1.0f, 0.0f,//cnt 
    10.0f, 30.0f, 0.0f,//dist, theta, phi
    40.0f, 1.0f, 100.0f//fovY,nearZ, farZ
};
View view0 = view;

GLSL glsl;
//Windowのサイズ
int width = 512;
int height = 512;
//アフィン変換
enum SELECT_KEY {ROTATE, SCALE, TRANSLATE, LIGHT};
SELECT_KEY sKey = TRANSLATE;
//マウス操作
int xStart, yStart;
bool flagMouse = false;
//オブジェクト識別番号
int objNo = 0;
//回転アニメーション
float ang = 0.0f;
//シャドウマッピング用テクスチャー
int TEX_WIDTH = width;
int TEX_HEIGHT = height;
float fov = 120.0;//シャドウマッピングの視野角
float farZ = 50.0;//シャドウマッピングの後方クリップ面
GLfloat modelview[16];  //モデルビュー変換行列の保存用 

void drawCylinder(float rBottom, float rTop, float height, float thick, int nSlice, int nStack){
    int i, j;
    float x, y, z, z0, z1;
    float theta;
    float theta0 = (float)2.0*PAI/nSlice;
    //上底(Top)
    glBegin(GL_QUAD_STRIP);
    glNormal3f(0.0f, 0.0f, 1.0f);
    for(i = 0; i <= nSlice; i++) { 
        theta = theta0 * (float)i;
        z = height/2.0f;
        //内側座標
        x = (rTop - thick) * cos(theta); //x成分
        y = (rTop - thick) * sin(theta); //y成分
        glVertex3f(x, y, z);
        //外側座標
        x = rTop * cos(theta); //x成分
        y = rTop * sin(theta); //y成分
        glVertex3f(x, y, z);
    }
    glEnd();

    //下底(Bottom)
    glBegin(GL_QUAD_STRIP);
    glNormal3f(0.0f, 0.0f, -1.0f);
    for(i = 0; i <= nSlice; i++) { 
        theta = theta0 * (float)i;
        z = -height/2.0f;
        //外側座標
        x = rBottom * cos(theta); //x成分
        y = rBottom * sin(theta); //y成分
        glVertex3f(x, y, z);
        //内側座標
        x = (rBottom - thick) * cos(theta); //x成分
        y = (rBottom - thick) * sin(theta); //y成分
        glVertex3f(x, y, z);
    }
    glEnd();

    float t0, t1, r0, r1, phi;
    float p[2][3], n[3];
    float rr = rBottom - rTop;
    float nz = rr / sqrt(rr*rr + height*height);
    float nxy = sqrt(1.0f - nz * nz);

    for(j = 0; j < nStack; j++){
        //j=0は上底(x=0, y=0, z=height/2)
        //2つのt座標
        t0 = (float)j / (float)nStack;
        t1 = (float)(j+1) / (float)nStack;
        //底面からの高さ
        z0 = height * (1.0f - t0);
        z1 = height * (1.0f - t1);
        //半径
        r0 = rBottom + (rTop - rBottom) * z0 / height;
        r1 = rBottom + (rTop - rBottom) * z1 / height;
        //頂点z座標
        p[0][2] = z0 - height / 2.0f;
        p[1][2] = z1 - height / 2.0f;
        
        glBegin(GL_QUAD_STRIP);
        for(i = 0; i <= nSlice; i++){
            phi = 2.0f * PAI * (float)i / (float)nSlice;
            //頂点のxy座標(i=0を真後ろ)
            p[0][0] = r0 * cos(phi);//x座標
            p[0][1] = r0 * sin(phi);//y座標
            p[1][0] = r1 * cos(phi);//x座標
            p[1][1] = r1 * sin(phi);//y座標
            //法線ベクトル
            n[0] = nxy * cos(phi);
            n[1] = nxy * sin(phi);
            n[2] =  nz;

            glNormal3fv(n);//法線ベクトル
            glVertex3fv(p[0]);//頂点座標
            glVertex3fv(p[1]);//頂点座標
        }
        glEnd();
    }

    //内側側面
    for(j = 0; j < nStack; j++){
        //j=0は上底(x=0, y=0, z=height/2)
        //2つのt座標
        t0 = (float)j / (float)nStack;
        t1 = (float)(j+1) / (float)nStack;
        //底面からの高さ
        z0 = (float)height * (1.0f - t0);
        z1 = (float)height * (1.0f - t1);
        //半径
        r0 = rBottom - thick + (rTop - rBottom) * z0 / height;
        r1 = rBottom - thick + (rTop - rBottom) * z1 / height;
        //頂点z座標
        p[0][2] = z0 - height / 2.0f;
        p[1][2] = z1 - height / 2.0f;

        glBegin(GL_QUAD_STRIP);
        for(i = nSlice; i >= 0; i--){
            phi = 2.0f * PAI * (float)i / (float)nSlice;
            //頂点のxy座標(i=0を真後ろ)
            p[0][0] = -r0 * cos(phi);//x座標
            p[0][1] = -r0 * sin(phi);//y座標
            p[1][0] = -r1 * cos(phi);//x座標
            p[1][1] = -r1 * sin(phi);//y座標
            //法線ベクトル
            n[0] = nxy * cos(phi);
            n[1] = nxy * sin(phi);
            n[2] = - nz;
            glNormal3fv(n);//法線ベクトル
            glVertex3fv(p[0]);//頂点座標
            glVertex3fv(p[1]);//頂点座標
        }
        glEnd();
    }
}


void setShadowMap(){
  //テクスチャを拡大・縮小する方法の指定 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);  
  //テクスチャの繰り返し方法の指定 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  //テクスチャ座標rを用いてテクセル値と比較 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);  
  //rの値がテクセル値以上なら影になる 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
  //結果を輝度値として取得    
  glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
}

void setTextureMatrix(){
  glMatrixMode(GL_TEXTURE);
  glLoadIdentity();
  glTranslatef(0.5, 0.5, 0.5);
  glScalef(0.5, 0.5, 0.5);
  glMultMatrixf(modelview);
}

void drawTorus(void){
  setTextureMatrix();
  glTranslatef(pos[0][0], pos[0][1], pos[0][2]);
  glRotatef(angle[0][2], 0.0f, 0.0f, 1.0f);//z軸回転
  glRotatef(angle[0][1], 0.0f, 1.0f, 0.0f);//y軸回転
  glRotatef(angle[0][0] + ang, 1.0f, 0.0f, 0.0f);//x軸回転
  float ambient[] = { 0.0f, 0.0f, 0.7f, 1.0f};
  float diffuse[] = { 0.0f, 0.0f, 0.7f, 1.0f};
  float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};
  glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
  glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);
  glMaterialfv(GL_FRONT,GL_SPECULAR,specular);
  glMaterialf(GL_FRONT,GL_SHININESS,100);
  //モデルビュー変換行列に戻す
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glTranslatef(pos[0][0], pos[0][1], pos[0][2]);
  glRotatef(angle[0][2], 0.0f, 0.0f, 1.0f);//z軸回転
  glRotatef(angle[0][1], 0.0f, 1.0f, 0.0f);//y軸回転
  glRotatef(angle[0][0] + ang, 1.0f, 0.0f, 0.0f);//x軸回転
  glutSolidTorus(0.2f, 0.5f, 20, 20);
  glPopMatrix();
}

void drawCylinder(void){
  setTextureMatrix();
  glTranslatef(pos[1][0], pos[1][1], pos[1][2]);
  glRotatef(angle[1][2], 0.0f, 0.0f, 1.0f);//z軸回転
  glRotatef(angle[1][1], 0.0f, 1.0f, 0.0f);//y軸回転
  glRotatef(angle[1][0] + ang, 1.0f, 0.0f, 0.0f);//x軸回転
  float ambient[] = { 0.3f, 0.3f, 0.0f, 1.0f};
  float diffuse[] = { 0.7f, 0.7f, 0.0f, 1.0f};
  float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};
  glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);
  glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);
  glMaterialfv(GL_FRONT,GL_SPECULAR,specular);
  glMaterialf(GL_FRONT,GL_SHININESS,100);
  //モデルビュー変換行列に戻す
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glTranslatef(pos[1][0], pos[1][1], pos[1][2]);
  glRotatef(angle[1][2], 0.0f, 0.0f, 1.0f);//z軸回転
  glRotatef(angle[1][1], 0.0f, 1.0f, 0.0f);//y軸回転
  glRotatef(angle[1][0] + ang, 1.0f, 0.0f, 0.0f);//x軸回転
  drawCylinder(1.0f, 0.7f, 2.0f, 0.3f, 20, 5);
  glPopMatrix();
}

void drawFloor(float widthX, float widthZ, int nx, int nz){
  setTextureMatrix();
  int i, j;
  //Floor1枚当たりの幅
  float wX = widthX / (float)nx;
  float wZ = widthZ / (float)nz;
  float diffuse[][4] = {
    { 0.9f, 0.9f, 0.9f, 1.0f}, { 0.0f, 0.8f, 0.0f, 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);
  //モデルビュー変換行列に戻す
  glMatrixMode(GL_MODELVIEW);
  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 resize(int w, int h){
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(view.fovY, (float)w/(float)h, view.nearZ, view.farZ);
  width = w;
  height = h;
}
void display(void){
  //ステップ1:デプスマップの作成
  glClear(GL_DEPTH_BUFFER_BIT);
  glViewport(0, 0, TEX_WIDTH, TEX_HEIGHT);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  //光源位置を視点とするモデルビュー変換行列を設定
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluPerspective(fov, (float)TEX_WIDTH / (float)TEX_HEIGHT, 1.0, farZ);
  gluLookAt(lightPos[0], lightPos[1], lightPos[2], 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
  //設定したモデルビュー行列を保存しておく(setTextureMatrixで使用する) 
  glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
  glColorMask(0, 0, 0, 0);
  //デプスバッファには背面の奥行きを記録する
  glCullFace(GL_FRONT);
  //デプスマップ作成のためにシーンを描画
  drawTorus();
  drawCylinder();
  // デプスバッファの内容をテクスチャメモリに転送 
  glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, TEX_WIDTH, TEX_HEIGHT, 0);

  //ステップ2
  //通常の描画設定に戻す 
  resize(width, height);
  glColorMask(1, 1, 1, 1); //フレームバッファへ書き込み許可
  glCullFace(GL_BACK);//背面は描画しない
  //カラーバッファのクリア
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();//視点を変えるときはこの位置に必要
  if(cos(view.theta*PAI/180.0) >= 0.0)// <= 90.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);
  glsl.ON();
  GLint texLoc = glGetUniformLocation(glsl.ShaderProg, "shadowMap");
  glUniform1i(texLoc, 0);
  drawTorus(); 
  drawCylinder();
  drawFloor(10.0, 10.0, 10, 10);
  glsl.OFF();
  glutSwapBuffers();
}

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 setCamera(){
  float pp = PAI / 180.0f;
  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 mouse(int button, int state, int x, int y){
  float pp = PAI / 180.0f;

  if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
   xStart = x; yStart = y;
   flagMouse = true;
  }else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){
   if(x > width/4 && x < 3*width/4 && y > height/4 && y < 3*height/4){
   }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.0f) >= 0.0f){
      view.phi -= 0.5f * (float)(x - xStart) ;//tumble
  }else{
      view.phi += 0.5f * (float)(x - xStart) ;//tumble
  }
  view.theta += 0.5f * (float)(y - yStart) ;//crane

  setCamera();
  xStart = x;
  yStart = y;
}

void Init(void){
  glClearColor(0.5f, 0.5f, 0.7f, 1.0f);
  setCamera();
  setLight();
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_NORMALIZE);
  glEnable(GL_SMOOTH);
  glEnable(GL_CULL_FACE);
  setShadowMap();
  glsl.InitGLSL("vertex.shader","flagment.shader");
}

void idle(void){
  glutPostRedisplay();
}

void timer(int value) {
    ang+=0.1f;
 glutTimerFunc(10 , timer , 0);
}

void main(int argc, char *argv[]){
   glutInitWindowPosition(100, 100);
   glutInitWindowSize(width, height);
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
   glutCreateWindow("シャドウマッピング");
   glutDisplayFunc(display);
   glutIdleFunc(idle);
   glutMouseFunc(mouse);
   glutMotionFunc(motion);
   glutReshapeFunc(resize);
   glutTimerFunc(10 , timer , 0);
   Init();
   glutMainLoop();
   return;
}

 

 

 

 

 

 

最終更新:2014年04月26日 21:26
添付ファイル