「シャドウマッピング」の編集履歴(バックアップ)一覧はこちら
「シャドウマッピング」(2014/04/26 (土) 21:26:17) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p><strong>シャドウマッピングです。<br />
一時的に視点を光源に移してみると光の当たる部分を見る事ができます。<br />
その時の見えない部分=障害物=デプスバッファの値が影となります。<br />
オブジェクトが別のオブジェクトに落とす影は、もちろんの事、<br />
オブジェクト自身が自らに落とす影も描画する事ができます。</strong></p>
<p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=300&file=shadow2.png" /></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p><strong>シャドウマッピングです。<br />
一時的に視点を光源に移してみると光の当たる部分を見る事ができます。<br />
その時の見えない部分=障害物=デプスバッファの値が影となります。<br />
オブジェクトが別のオブジェクトに落とす影は、もちろんの事、<br />
オブジェクト自身が自らに落とす影も描画する事ができます。</strong></p>
<p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=300&file=shadow2.png" /></p>
<p>vertex.shader</p>
<table border="1" cellpadding="1" cellspacing="1" style="width:600px;"><tbody><tr><td>
<p>varying vec3 P;<br />
varying vec3 N;</p>
<p>void main(void)<br />
{<br />
P = vec3(gl_ModelViewMatrix * gl_Vertex);<br />
N = normalize(gl_NormalMatrix * gl_Normal);<br />
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex;<br />
gl_Position = ftransform();<br />
}</p>
</td>
</tr></tbody></table><p>flagment.shader</p>
<table border="1" cellpadding="1" cellspacing="1" style="width:600px;"><tbody><tr><td>
<p>varying vec3 P;<br />
varying vec3 N;<br />
uniform sampler2DShadow shadowMap;</p>
<p>void main(void)</p>
<p>{<br />
vec3 L = normalize(gl_LightSource[0].position.xyz - P);<br />
N = normalize(N);<br />
<br />
vec4 ambient = gl_FrontLightProduct[0].ambient;<br />
float dotNL = dot(N, L);<br />
vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(0.0, dotNL);<br />
vec3 V = normalize(-P);<br />
vec3 H = normalize(L + V);<br />
float powNH = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);<br />
if(dotNL <= 0.0) powNH = 0.0;<br />
vec4 specular = gl_FrontLightProduct[0].specular * powNH;<br />
float shadow = 0.3;//影濃度<br />
float s = shadow2DProj(shadowMap, gl_TexCoord[0]).r;<br />
diffuse *= clamp(s, shadow, 1.0);<br />
gl_FragColor = ambient + diffuse + specular * s;<br />
}</p>
</td>
</tr></tbody></table><p>GLSL.h</p>
<table border="1" cellpadding="1" cellspacing="1" style="width:600px;"><tbody><tr><td>#pragma once<br />
#include <stdio.h><br />
<br />
//GLSLクラス<br />
class GLSL{<br />
public:<br />
GLuint ShaderProg;<br />
GLuint VertexShader, FragmentShader;<br />
void ReadShaderCompile(GLuint Shader, const char *File);//shader
fileを読み込みコンパイルする<br />
void Link( GLuint Prog );//リンクする<br />
void InitGLSL(const char *VertexFile);//GLSLの初期化<br />
void InitGLSL(const char *VertexFile, const char
*FragmentFile);//GLSLの初期化<br />
void ON();//シェーダー描画に切り替え<br />
void OFF();//シェーダー解除<br />
~GLSL();<br />
};<br />
<br />
void GLSL::ReadShaderCompile(GLuint Shader, const char *File){<br />
FILE *fp;<br />
char *buf;<br />
GLsizei size, len;<br />
GLint compiled;<br />
<br />
fopen_s(&fp,File, "rb");<br />
if(!fp) printf("ファイルを開くことができません %s\n", File);<br />
<br />
fseek(fp, 0, SEEK_END);<br />
size = ftell(fp);<br />
<br />
buf = (GLchar *)malloc(size);<br />
if (buf == NULL) {<br />
printf("メモリが確保できませんでした \n");<br />
}<br />
<br />
fseek(fp, 0, SEEK_SET);<br />
fread(buf, 1, size, fp);<br />
glShaderSource(Shader, 1, (const GLchar **)&buf, &size);<br />
free(buf);<br />
fclose(fp);<br />
<br />
glCompileShader(Shader);<br />
glGetShaderiv( Shader, GL_COMPILE_STATUS, &compiled );<br />
<br />
if ( compiled == GL_FALSE )<br />
{<br />
printf( "コンパイルできませんでした!!: %s \n ", File);<br />
glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, &size );<br />
if ( size > 0 )<br />
{<br />
buf = (char *)malloc(size);<br />
glGetShaderInfoLog( Shader, size, &len, buf);<br />
printf(buf);<br />
free(buf);<br />
}<br />
}<br />
}<br />
<br />
void GLSL::Link( GLuint Prog ){<br />
GLsizei size, len;<br />
GLint linked;<br />
char *infoLog ;<br />
<br />
glLinkProgram( Prog );<br />
<br />
glGetProgramiv( Prog, GL_LINK_STATUS, &linked );<br />
<br />
if ( linked == GL_FALSE ){<br />
printf("リンクできませんでした!! \n");<br />
<br />
glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, &size );<br />
if ( size > 0 ){<br />
infoLog = (char *)malloc(size);<br />
glGetProgramInfoLog( Prog, size, &len, infoLog );<br />
printf(infoLog);<br />
free(infoLog);<br />
}<br />
}<br />
}<br />
<br />
void GLSL::InitGLSL(const char *VertexFile){<br />
GLenum err = glewInit();<br />
if (err != GLEW_OK)<br />
{<br />
printf("Error: %s\n", glewGetErrorString(err));<br />
}<br />
printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />
printf("GPU= %s \n", glGetString(GL_RENDERER));<br />
printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />
printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />
VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />
ReadShaderCompile(VertexShader, VertexFile);<br />
ShaderProg = glCreateProgram();<br />
glAttachShader(ShaderProg, VertexShader);<br />
glDeleteShader(VertexShader);<br />
Link(ShaderProg);<br />
}<br />
<br />
<br />
void GLSL::InitGLSL(const char *VertexFile, const char *FragmentFile){<br />
GLenum err = glewInit();<br />
if (err != GLEW_OK)<br />
{<br />
printf("Error: %s\n", glewGetErrorString(err));<br />
}<br />
printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />
printf("GPU= %s \n", glGetString(GL_RENDERER));<br />
printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />
printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />
<br />
VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);<br />
<br />
ReadShaderCompile(VertexShader, VertexFile);<br />
ReadShaderCompile(FragmentShader, FragmentFile);<br />
<br />
ShaderProg = glCreateProgram();<br />
<br />
glAttachShader(ShaderProg, VertexShader);<br />
glAttachShader(ShaderProg, FragmentShader);<br />
<br />
glDeleteShader(VertexShader);<br />
glDeleteShader(FragmentShader);<br />
Link(ShaderProg);<br />
}<br />
<br />
void GLSL::ON(){<br />
glUseProgram(ShaderProg);<br />
}<br />
<br />
void GLSL::OFF(){<br />
glUseProgram(0);<br />
}<br />
<br />
GLSL::~GLSL(){<br />
glDeleteProgram(ShaderProg);<br />
}<br />
</td>
</tr></tbody></table><p>main.cpp</p>
<table border="1" cellpadding="1" cellspacing="1" style="width:600px;"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#pragma comment(lib, "glew32.lib")</p>
<p>#include <stdio.h><br />
#include <windows.h><br />
#include <GL/glew.h><br />
#include "GLSL.h"<br />
#include <math.h><br />
#include <GL/freeglut/freeglut.h></p>
<p>#define PAI 3.141592f</p>
<p>float pos[][3] = { //位置(平行移動)<br />
{ 0.3f, 3.5f, 0.0f},//obj0<br />
{-0.4f, 1.5f, 0.0f} //obj1<br />
};<br />
float angle[][3] = {//姿勢(回転)<br />
{ 0.0f, 0.0f, 0.0f}, //obj0<br />
{ 0.0f, 0.0f, 0.0f} //obj1<br />
};<br />
float lightPos[] = {0.0f, 6.0f, 1.0f, 1.0f};//光源位置</p>
<p>//カメラと視体積<br />
struct View{<br />
float pos[3];//位置(視点)<br />
float cnt[3];//注視点<br />
float dist; //注視点から視点までの距離<br />
float theta; //仰角(水平面との偏角)<br />
float phi; //方位角<br />
//視体積<br />
float fovY; //視野角<br />
float nearZ; //前方クリップ面(近平面)<br />
float farZ; //後方クリップ面(遠平面)<br />
};<br />
View view = { <br />
0.0f, 0.0f, 0.0f,//pos(仮設定)<br />
0.0f, 1.0f, 0.0f,//cnt <br />
10.0f, 30.0f, 0.0f,//dist, theta, phi<br />
40.0f, 1.0f, 100.0f//fovY,nearZ, farZ<br />
};<br />
View view0 = view;</p>
<p>GLSL glsl;<br />
//Windowのサイズ<br />
int width = 512;<br />
int height = 512;<br />
//アフィン変換<br />
enum SELECT_KEY {ROTATE, SCALE, TRANSLATE, LIGHT};<br />
SELECT_KEY sKey = TRANSLATE;<br />
//マウス操作<br />
int xStart, yStart;<br />
bool flagMouse = false;<br />
//オブジェクト識別番号<br />
int objNo = 0;<br />
//回転アニメーション<br />
float ang = 0.0f;<br />
//シャドウマッピング用テクスチャー<br />
int TEX_WIDTH = width;<br />
int TEX_HEIGHT = height;<br />
float fov = 120.0;//シャドウマッピングの視野角<br />
float farZ = 50.0;//シャドウマッピングの後方クリップ面<br />
GLfloat modelview[16]; //モデルビュー変換行列の保存用 </p>
<p>void drawCylinder(float rBottom, float rTop, float height, float thick, int
nSlice, int nStack){<br />
int i, j;<br />
float x, y, z, z0, z1;<br />
float theta;<br />
float theta0 = (float)2.0*PAI/nSlice;<br />
//上底(Top)<br />
glBegin(GL_QUAD_STRIP);<br />
glNormal3f(0.0f, 0.0f, 1.0f);<br />
for(i = 0; i <= nSlice; i++) { <br />
theta = theta0 * (float)i;<br />
z = height/2.0f;<br />
//内側座標<br />
x = (rTop - thick) * cos(theta); //x成分<br />
y = (rTop - thick) * sin(theta); //y成分<br />
glVertex3f(x, y, z);<br />
//外側座標<br />
x = rTop * cos(theta); //x成分<br />
y = rTop * sin(theta); //y成分<br />
glVertex3f(x, y, z);<br />
}<br />
glEnd();</p>
<p> //下底(Bottom)<br />
glBegin(GL_QUAD_STRIP);<br />
glNormal3f(0.0f, 0.0f, -1.0f);<br />
for(i = 0; i <= nSlice; i++) { <br />
theta = theta0 * (float)i;<br />
z = -height/2.0f;<br />
//外側座標<br />
x = rBottom * cos(theta); //x成分<br />
y = rBottom * sin(theta); //y成分<br />
glVertex3f(x, y, z);<br />
//内側座標<br />
x = (rBottom - thick) * cos(theta); //x成分<br />
y = (rBottom - thick) * sin(theta); //y成分<br />
glVertex3f(x, y, z);<br />
}<br />
glEnd();</p>
<p> float t0, t1, r0, r1, phi;<br />
float p[2][3], n[3];<br />
float rr = rBottom - rTop;<br />
float nz = rr / sqrt(rr*rr + height*height);<br />
float nxy = sqrt(1.0f - nz * nz);</p>
<p> for(j = 0; j < nStack; j++){<br />
//j=0は上底(x=0, y=0, z=height/2)<br />
//2つのt座標<br />
t0 = (float)j / (float)nStack;<br />
t1 = (float)(j+1) / (float)nStack;<br />
//底面からの高さ<br />
z0 = height * (1.0f - t0);<br />
z1 = height * (1.0f - t1);<br />
//半径<br />
r0 = rBottom + (rTop - rBottom) * z0 / height;<br />
r1 = rBottom + (rTop - rBottom) * z1 / height;<br />
//頂点z座標<br />
p[0][2] = z0 - height / 2.0f;<br />
p[1][2] = z1 - height / 2.0f;<br />
<br />
glBegin(GL_QUAD_STRIP);<br />
for(i = 0; i <= nSlice; i++){<br />
phi = 2.0f * PAI * (float)i / (float)nSlice;<br />
//頂点のxy座標(i=0を真後ろ)<br />
p[0][0] = r0 * cos(phi);//x座標<br />
p[0][1] = r0 * sin(phi);//y座標<br />
p[1][0] = r1 * cos(phi);//x座標<br />
p[1][1] = r1 * sin(phi);//y座標<br />
//法線ベクトル<br />
n[0] = nxy * cos(phi);<br />
n[1] = nxy * sin(phi);<br />
n[2] = nz;</p>
<p> glNormal3fv(n);//法線ベクトル<br />
glVertex3fv(p[0]);//頂点座標<br />
glVertex3fv(p[1]);//頂点座標<br />
}<br />
glEnd();<br />
}</p>
<p> //内側側面<br />
for(j = 0; j < nStack; j++){<br />
//j=0は上底(x=0, y=0, z=height/2)<br />
//2つのt座標<br />
t0 = (float)j / (float)nStack;<br />
t1 = (float)(j+1) / (float)nStack;<br />
//底面からの高さ<br />
z0 = (float)height * (1.0f - t0);<br />
z1 = (float)height * (1.0f - t1);<br />
//半径<br />
r0 = rBottom - thick + (rTop - rBottom) * z0 / height;<br />
r1 = rBottom - thick + (rTop - rBottom) * z1 / height;<br />
//頂点z座標<br />
p[0][2] = z0 - height / 2.0f;<br />
p[1][2] = z1 - height / 2.0f;</p>
<p> glBegin(GL_QUAD_STRIP);<br />
for(i = nSlice; i >= 0; i--){<br />
phi = 2.0f * PAI * (float)i / (float)nSlice;<br />
//頂点のxy座標(i=0を真後ろ)<br />
p[0][0] = -r0 * cos(phi);//x座標<br />
p[0][1] = -r0 * sin(phi);//y座標<br />
p[1][0] = -r1 * cos(phi);//x座標<br />
p[1][1] = -r1 * sin(phi);//y座標<br />
//法線ベクトル<br />
n[0] = nxy * cos(phi);<br />
n[1] = nxy * sin(phi);<br />
n[2] = - nz;<br />
glNormal3fv(n);//法線ベクトル<br />
glVertex3fv(p[0]);//頂点座標<br />
glVertex3fv(p[1]);//頂点座標<br />
}<br />
glEnd();<br />
}<br />
}</p>
<p><br />
void setShadowMap(){<br />
//テクスチャを拡大・縮小する方法の指定 <br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); <br />
//テクスチャの繰り返し方法の指定 <br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);<br />
//テクスチャ座標rを用いてテクセル値と比較 <br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
GL_COMPARE_R_TO_TEXTURE); <br />
//rの値がテクセル値以上なら影になる <br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);<br />
//結果を輝度値として取得 <br />
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);<br />
}</p>
<p>void setTextureMatrix(){<br />
glMatrixMode(GL_TEXTURE);<br />
glLoadIdentity();<br />
glTranslatef(0.5, 0.5, 0.5);<br />
glScalef(0.5, 0.5, 0.5);<br />
glMultMatrixf(modelview);<br />
}</p>
<p>void drawTorus(void){<br />
setTextureMatrix();<br />
glTranslatef(pos[0][0], pos[0][1], pos[0][2]);<br />
glRotatef(angle[0][2], 0.0f, 0.0f, 1.0f);//z軸回転<br />
glRotatef(angle[0][1], 0.0f, 1.0f, 0.0f);//y軸回転<br />
glRotatef(angle[0][0] + ang, 1.0f, 0.0f, 0.0f);//x軸回転<br />
float ambient[] = { 0.0f, 0.0f, 0.7f, 1.0f};<br />
float diffuse[] = { 0.0f, 0.0f, 0.7f, 1.0f};<br />
float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};<br />
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />
glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);<br />
glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />
glMaterialf(GL_FRONT,GL_SHININESS,100);<br />
//モデルビュー変換行列に戻す<br />
glMatrixMode(GL_MODELVIEW);<br />
glPushMatrix();<br />
glTranslatef(pos[0][0], pos[0][1], pos[0][2]);<br />
glRotatef(angle[0][2], 0.0f, 0.0f, 1.0f);//z軸回転<br />
glRotatef(angle[0][1], 0.0f, 1.0f, 0.0f);//y軸回転<br />
glRotatef(angle[0][0] + ang, 1.0f, 0.0f, 0.0f);//x軸回転<br />
glutSolidTorus(0.2f, 0.5f, 20, 20);<br />
glPopMatrix();<br />
}</p>
<p>void drawCylinder(void){<br />
setTextureMatrix();<br />
glTranslatef(pos[1][0], pos[1][1], pos[1][2]);<br />
glRotatef(angle[1][2], 0.0f, 0.0f, 1.0f);//z軸回転<br />
glRotatef(angle[1][1], 0.0f, 1.0f, 0.0f);//y軸回転<br />
glRotatef(angle[1][0] + ang, 1.0f, 0.0f, 0.0f);//x軸回転<br />
float ambient[] = { 0.3f, 0.3f, 0.0f, 1.0f};<br />
float diffuse[] = { 0.7f, 0.7f, 0.0f, 1.0f};<br />
float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};<br />
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />
glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);<br />
glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />
glMaterialf(GL_FRONT,GL_SHININESS,100);<br />
//モデルビュー変換行列に戻す<br />
glMatrixMode(GL_MODELVIEW);<br />
glPushMatrix();<br />
glTranslatef(pos[1][0], pos[1][1], pos[1][2]);<br />
glRotatef(angle[1][2], 0.0f, 0.0f, 1.0f);//z軸回転<br />
glRotatef(angle[1][1], 0.0f, 1.0f, 0.0f);//y軸回転<br />
glRotatef(angle[1][0] + ang, 1.0f, 0.0f, 0.0f);//x軸回転<br />
drawCylinder(1.0f, 0.7f, 2.0f, 0.3f, 20, 5);<br />
glPopMatrix();<br />
}</p>
<p>void drawFloor(float widthX, float widthZ, int nx, int nz){<br />
setTextureMatrix();<br />
int i, j;<br />
//Floor1枚当たりの幅<br />
float wX = widthX / (float)nx;<br />
float wZ = widthZ / (float)nz;<br />
float diffuse[][4] = {<br />
{ 0.9f, 0.9f, 0.9f, 1.0f}, { 0.0f, 0.8f, 0.0f, 1.0f} };<br />
float ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f};<br />
float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};<br />
glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />
glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />
glMaterialf(GL_FRONT,GL_SHININESS,100);<br />
//モデルビュー変換行列に戻す<br />
glMatrixMode(GL_MODELVIEW);<br />
glNormal3f(0.0f, 1.0f, 0.0f);<br />
glPushMatrix();<br />
for (j = 0; j < nz; j++) {<br />
float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ;<br />
for (i = 0; i < nx; i++) {<br />
float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX;<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) & 1]);<br />
glBegin(GL_QUADS);<br />
glVertex3f(x1, 0.0f, z1);<br />
glVertex3f(x1, 0.0f, z2);<br />
glVertex3f(x2, 0.0f, z2);<br />
glVertex3f(x2, 0.0f, z1);<br />
glEnd();<br />
}<br />
}<br />
glPopMatrix();<br />
}</p>
<p>void resize(int w, int h){<br />
glViewport(0, 0, w, h);<br />
glMatrixMode(GL_PROJECTION);<br />
glLoadIdentity();<br />
gluPerspective(view.fovY, (float)w/(float)h, view.nearZ, view.farZ);<br />
width = w;<br />
height = h;<br />
}<br />
void display(void){<br />
//ステップ1:デプスマップの作成<br />
glClear(GL_DEPTH_BUFFER_BIT);<br />
glViewport(0, 0, TEX_WIDTH, TEX_HEIGHT);<br />
glMatrixMode(GL_PROJECTION);<br />
glLoadIdentity();<br />
//光源位置を視点とするモデルビュー変換行列を設定<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();<br />
gluPerspective(fov, (float)TEX_WIDTH / (float)TEX_HEIGHT, 1.0, farZ);<br />
gluLookAt(lightPos[0], lightPos[1], lightPos[2], 0.0, 0.0, 0.0, 0.0, 0.0,
1.0);<br />
//設定したモデルビュー行列を保存しておく(setTextureMatrixで使用する) <br />
glGetFloatv(GL_MODELVIEW_MATRIX, modelview);<br />
glColorMask(0, 0, 0, 0);<br />
//デプスバッファには背面の奥行きを記録する<br />
glCullFace(GL_FRONT);<br />
//デプスマップ作成のためにシーンを描画<br />
drawTorus();<br />
drawCylinder();<br />
// デプスバッファの内容をテクスチャメモリに転送 <br />
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, TEX_WIDTH,
TEX_HEIGHT, 0);</p>
<p> //ステップ2<br />
//通常の描画設定に戻す <br />
resize(width, height);<br />
glColorMask(1, 1, 1, 1); //フレームバッファへ書き込み許可<br />
glCullFace(GL_BACK);//背面は描画しない<br />
//カラーバッファのクリア<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();//視点を変えるときはこの位置に必要<br />
if(cos(view.theta*PAI/180.0) >= 0.0)// <=
90.0)//カメラ仰角90度でビューアップベクトル切替<br />
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);<br />
else<br />
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);</p>
<p> //光源設定//'l'を押した後光源位置可変<br />
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);<br />
glsl.ON();<br />
GLint texLoc = glGetUniformLocation(glsl.ShaderProg, "shadowMap");<br />
glUniform1i(texLoc, 0);<br />
drawTorus(); <br />
drawCylinder();<br />
drawFloor(10.0, 10.0, 10, 10);<br />
glsl.OFF();<br />
glutSwapBuffers();<br />
}</p>
<p>void setLight(){<br />
float lightAmbient0[] = {0.5, 0.5, 0.5, 1.0}; //環境光<br />
float lightDiffuse0[] = {1.0, 1.0, 1.0, 1.0}; //拡散光<br />
float lightSpecular0[] = {1.0, 1.0, 1.0, 1.0};//鏡面光<br />
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient0);<br />
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse0);<br />
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular0);<br />
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);<br />
glEnable(GL_LIGHT0);<br />
glEnable(GL_LIGHTING);<br />
}</p>
<p><br />
void setCamera(){<br />
float pp = PAI / 180.0f;<br />
view.pos[2] = view.cnt[2] + view.dist * cos(pp * view.theta) * cos(pp *
view.phi);//z<br />
view.pos[0] = view.cnt[0] + view.dist * cos(pp * view.theta) * sin(pp *
view.phi);//x<br />
view.pos[1] = view.cnt[1] + view.dist * sin(pp * view.theta);//y<br />
resize(width, height);<br />
}</p>
<p>void mouse(int button, int state, int x, int y){<br />
float pp = PAI / 180.0f;</p>
<p> if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){<br />
xStart = x; yStart = y;<br />
flagMouse = true;<br />
}else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){<br />
if(x > width/4 && x < 3*width/4 && y > height/4
&& y < 3*height/4){<br />
}else if(( x < width/4 || x > 3*width/4) && (y > height/4
&& y < 3*height/4)){<br />
if(x < width/4 ) view.phi -= 1.0;<br />
else view.phi += 1.0;<br />
view.cnt[2] = view.pos[2] - view.dist * cos(pp * view.phi) * cos(pp *
view.theta);<br />
view.cnt[0] = view.pos[0] - view.dist * sin(pp * view.phi) * cos(pp *
view.theta);<br />
}else if((x > width/4 && x < 3*width/4) && (y <
height/4 || y > 3*height/4)){<br />
if( y < height/4){<br />
view.theta += 1.0;<br />
}else{<br />
view.theta -= 1.0;<br />
}<br />
view.cnt[2] = view.pos[2] - view.dist * cos(pp * view.theta) * cos(pp *
view.phi);<br />
view.cnt[0] = view.pos[0] - view.dist * cos(pp * view.theta) * sin(pp *
view.phi);<br />
view.cnt[1] = view.pos[1] - view.dist * sin(pp * view.theta);<br />
}else if(x < width/8 && y > 7*height/8) view.fovY -=
1.0;//zoom in<br />
else if(x > 7*width/8 && y > 7*height/8) view.fovY +=
1.0;//zoom out<br />
}else flagMouse = false;<br />
if(state == GLUT_DOWN) setCamera();<br />
}</p>
<p>void motion(int x, int y){<br />
if(!flagMouse) return;<br />
if(cos(PAI * view.theta /180.0f) >= 0.0f){<br />
view.phi -= 0.5f * (float)(x - xStart) ;//tumble<br />
}else{<br />
view.phi += 0.5f * (float)(x - xStart) ;//tumble<br />
}<br />
view.theta += 0.5f * (float)(y - yStart) ;//crane</p>
<p> setCamera();<br />
xStart = x;<br />
yStart = y;<br />
}</p>
<p>void Init(void){<br />
glClearColor(0.5f, 0.5f, 0.7f, 1.0f);<br />
setCamera();<br />
setLight();<br />
glEnable(GL_DEPTH_TEST);<br />
glEnable(GL_NORMALIZE);<br />
glEnable(GL_SMOOTH);<br />
glEnable(GL_CULL_FACE);<br />
setShadowMap();<br />
glsl.InitGLSL("vertex.shader","flagment.shader");<br />
}</p>
<p>void idle(void){<br />
glutPostRedisplay();<br />
}</p>
<p>void timer(int value) {<br />
ang+=0.1f;<br />
glutTimerFunc(10 , timer , 0);<br />
}</p>
<p>void main(int argc, char *argv[]){<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(width, height);<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutCreateWindow("シャドウマッピング");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
glutMouseFunc(mouse);<br />
glutMotionFunc(motion);<br />
glutReshapeFunc(resize);<br />
glutTimerFunc(10 , timer , 0);<br />
Init();<br />
glutMainLoop();<br />
return;<br />
}</p>
</td>
</tr></tbody></table><p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>