水面

「水面」の編集履歴(バックアップ)一覧はこちら

水面」(2014/11/18 (火) 01:14:54) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

<p>水面と集光模様です。</p> <p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&amp;act=open&amp;pageid=314&amp;file=water.png" /></p> <p>vertex.shader</p> <table border="1" cellpadding="1" cellspacing="1" style="width:600px;"><tbody><tr><td> <p>  //フラグメントシェーダーに渡す変数<br />   varying vec3 P;//位置ベクトル<br />   varying vec3 N;//法線ベクトル</p> <p>void main(void){<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><br />   //頂点シェーダーから受け取る変数<br />   varying vec3 P;//位置ベクトル<br />   varying vec3 N;//法線ベクトル<br /> uniform sampler2D smplCaustics;<br /> void main(void){<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 &lt;= 0.0) powNH = 0.0;<br />     vec4 specular = gl_FrontLightProduct[0].specular * powNH;<br />   vec4 texColor = texture2DProj(smplCaustics, gl_TexCoord[0]);<br />     gl_FragColor = (ambient + diffuse) * texColor + specular;<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><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;windows.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;stdio.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;GL/glew.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;GL/freeglut/freeglut.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;math.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include "GLSL.h"</span></p> <p>#define PAI 3.14159</p> <p>GLSL glsl;<br /> //Windowのサイズ<br /> int width = 640;<br /> int height = 480;<br /> //マウス操作<br /> int xStart, yStart;<br /> bool flagMouse = false;<br /> //テクスチャー画像<br /> #define TEX_WIDTH 128<br /> #define TEX_HEIGHT 128<br /> GLubyte texImage[TEX_HEIGHT][TEX_WIDTH][3];<br /> //経過時間<br /> double curTime, lastTime, elapseTime1, elapseTime2;<br /> int fps = 0;//frame per sec<br /> float amp = 1.0;<br /> GLfloat fov = 60.0;//透視投影マッピングの視野角<br /> float Floor_Y = -1.0f;</p> <p>struct MATRIX;</p> <p>//マトリクス構造体<br /> struct MATRIX {<br />     union {<br />         struct {<br />             float _11, _12, _13, _14;<br />             float _21, _22, _23, _24;<br />             float _31, _32, _33, _34;<br />             float _41, _42, _43, _44;<br />         };<br />         float mat_4x4[4][4];<br />         float mat_16[16];<br />     };<br />  MATRIX(){//単位行列に初期化<br />   for(int i=0;i&lt;16;i++){<br />    this-&gt;mat_16[i]=0;<br />   }<br />   this-&gt;_11=this-&gt;_22=this-&gt;_33=this-&gt;_44=1;<br />  }<br />  void PRINT(char* text){<br />   printf("%s\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n\n",<br />    text,<br />    this-&gt;_11,this-&gt;_21,this-&gt;_31,this-&gt;_41,<br />    this-&gt;_12,this-&gt;_22,this-&gt;_32,this-&gt;_42,<br />    this-&gt;_13,this-&gt;_23,this-&gt;_33,this-&gt;_43,<br />    this-&gt;_14,this-&gt;_24,this-&gt;_34,this-&gt;_44);<br />  }</p> <p> MATRIX Multiplication(MATRIX&amp; mat);//合成<br /> };<br /> //合成<br /> MATRIX MATRIX::Multiplication(MATRIX&amp; mat)<br /> {<br />  MATRIX ret;<br />  for(int y=0;y&lt;4;y++){<br />   for(int x=0;x&lt;4;x++){<br />    ret.mat_16[y*4+x]=mat.mat_16[y*4]*this-&gt;mat_16[x]+mat.mat_16[y*4+1]*this-&gt;mat_16[x+4]+mat.mat_16[y*4+2]*this-&gt;mat_16[x+8]+mat.mat_16[y*4+3]*this-&gt;mat_16[x+12];<br />   }<br />  }<br />  return ret;<br /> }</p> <p>//3つのベクトル<br /> struct Vector3f{<br />  float x;<br />  float y;<br />  float z;<br />  Vector3f(){};<br />  Vector3f(float _x,float _y,float _z){<br />   x=_x;y=_y;z=_z;<br />  };<br /> }vec3d;<br /> Vector3f &amp; operator*(Vector3f &amp;v,float size){<br />  v.x *= size;<br />  v.y *= size;<br />  v.z *= size;<br />  return v;<br /> }<br /> Vector3f &amp; operator+(Vector3f &amp;a,Vector3f &amp;b){<br />  a.x+=b.x;<br />  a.y+=b.y;<br />  a.z+=b.z;<br />  return a;<br /> }</p> <p>//正規化<br /> void normalize(Vector3f&amp; v){<br />  float m=sqrt(v.x*v.x+v.y*v.y+v.z*v.z);<br />  if(m &gt; 0.0f){m = 1.0f / m;}else{m = 0.0f;}<br />  v.x*=m;<br />  v.y*=m;<br />  v.z*=m;<br /> }<br /> //外積<br /> void cross( Vector3f&amp; src1, Vector3f&amp; src2 ,Vector3f&amp; dst){<br />  dst.x = src1.y*src2.z - src1.z*src2.y;<br />  dst.y = src1.z*src2.x - src1.x*src2.z;<br />  dst.z = src1.x*src2.y - src1.y*src2.x;<br /> }<br /> //内積<br /> void dot(Vector3f&amp; src1,Vector3f&amp; src2,float&amp; dst){<br />  dst= src1.x*src2.x+src1.y*src2.y+src1.z*src2.z;<br /> }</p> <p>//---------------------------------------------------------------------<br /> //法線方向計算ルーチン<br /> void calcNormal(float* p1,float* p2,float* p3,float* nn)<br /> {<br />     Vector3f A = Vector3f(p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]);<br />     Vector3f B = Vector3f(p3[0] - p2[0], p3[1] - p2[1], p3[2] - p2[2]);<br />     //CVector n = A ^ B;//外積<br />     Vector3f n;<br />     cross(A,B,n);<br />     nn[0] = n.x; nn[1] = n.y; nn[2] = n.z;<br /> }</p> <p> //-----------------------------------------------------------------------------<br /> //四角形のメッシュ(x-y平面,中心が原点)<br /> //x軸方向,y軸方向の幅を固定<br /> void drawElevation(int Nx, int Ny, float sizeX, float sizeY, int sideFlag, float* data)<br /> {<br />     //全体の幅,長さsizeX, sizeY<br />     //sideFlag = 0:側面表示せず<br />     //sideFlag = 1:側面表示する</p> <p>    const int NMAX = 130;<br />     int i, j;<br />     float p[NMAX][NMAX][3]; //頂点座標<br />     float a[NMAX][NMAX], b[NMAX][NMAX], c[NMAX][NMAX];//頂点の法線<br />     float pitchX, pitchY;<br />     float n1[3], n2[3], n3[3], n4[3];</p> <p>    if(Nx &gt; NMAX) printf("NxがNMAXを超えています(drawElevation1) \n");<br />     if(Ny &gt; NMAX) printf("NyがNMAXを超えています(drawElevation1) \n");</p> <p>    //セルのサイズ<br />     pitchX = sizeX / (float)Nx;<br />     pitchY = sizeY / (float)Ny;</p> <p>    //各頂点の座標<br />     for(j = 0; j &lt;= Ny; j++){<br />         for(i = 0; i &lt;= Nx; i++){<br />             p[i][j][0] = (float)(i - Nx / 2) * pitchX;<br />             p[i][j][1] = (float)(j - Ny / 2) * pitchY;<br />             p[i][j][2] = data[j * (Nx+1) + i];<br />         }<br />     }</p> <p>            <br />     //法線成分<br />     for(i = 0;i &lt;= Nx;i++)<br />         for(j = 0;j &lt;= Ny;j++)<br />         {            <br />             if(j == 0 )<br />             {<br />                 if(i == 0) <br />                 {<br />                     calcNormal(p[0][0],p[1][0],p[0][1],n1);<br />                     a[i][j] = n1[0]; b[i][j] = n1[1]; c[i][j] = n1[2]; }<br />                 else if(i == Nx) <br />                 {<br />                     calcNormal(p[Nx-1][0],p[Nx][0],p[Nx][1],n1);<br />                     a[i][j] = n1[0]; b[i][j] = n1[1]; c[i][j] = n1[2]; }<br />                 else <br />                 {<br />                     calcNormal(p[i][0],p[i][1],p[i-1][0],n1);//左側<br />                     calcNormal(p[i][0],p[i+1][0],p[i][1],n2);//右側<br />                     a[i][j] = (n1[0]+n2[0])/2.0f;<br />                     b[i][j] = (n1[1]+n2[1])/2.0f;<br />                     c[i][j] = (n1[2]+n2[2])/2.0f; }<br />             }<br />             else if(j == Ny)<br />             {<br />                 if(i == 0) <br />                 {<br />                     calcNormal(p[0][Ny],p[0][Ny-1],p[1][Ny],n1);<br />                     a[i][j] = n1[0]; b[i][j] = n1[1]; c[i][j] = n1[2]; }<br />                 else if(i == Nx) <br />                 {<br />                     calcNormal(p[Nx][Ny],p[Nx-1][Ny],p[Nx][Ny-1],n1);<br />                     a[i][j] = n1[0]; b[i][j] = n1[1]; c[i][j] = n1[2]; }<br />                 else <br />                 {<br />                     calcNormal(p[i][Ny],p[i-1][Ny],p[i][Ny-1],n1);//左側<br />                     calcNormal(p[i][Ny],p[i][Ny-1],p[i+1][Ny],n2);//右側<br />                     a[i][j] = (n1[0]+n2[0])/2.0f;<br />                     b[i][j] = (n1[1]+n2[1])/2.0f;<br />                     c[i][j] = (n1[2]+n2[2])/2.0f; }<br />             }<br />             else<br />             {<br />                 if(i == 0) <br />                 {<br />                     calcNormal(p[0][j],p[1][j],p[0][j+1],n1);//上<br />                     calcNormal(p[0][j],p[0][j-1],p[0][1],n2);//下<br />                     a[i][j] = (n1[0]+n2[0])/2.0f;<br />                     b[i][j] = (n1[1]+n2[1])/2.0f;<br />                     c[i][j] = (n1[2]+n2[2])/2.0f; }<br />                 else if(i == Nx) <br />                 {<br />                     calcNormal(p[Nx][j],p[Nx][j+1],p[Nx-1][j],n1);//上<br />                     calcNormal(p[Nx][j],p[Nx-1][j],p[Nx][j-1],n2);//下<br />                     a[i][j] = (n1[0]+n2[0])/2.0f;<br />                     b[i][j] = (n1[1]+n2[1])/2.0f;<br />                     c[i][j] = (n1[2]+n2[2])/2.0f; }<br />                 else <br />                 {//上下左右4個の三角形の平均<br />                     calcNormal(p[i][j],p[i][j+1],p[i-1][j],n1);//左上<br />                     calcNormal(p[i][j],p[i+1][j],p[i][j+1],n2);//右上<br />                     calcNormal(p[i][j],p[i-1][j],p[i][j-1],n3);//左下<br />                     calcNormal(p[i][j],p[i][j-1],p[i+1][j],n4);//右下<br />                     a[i][j] = (n1[0]+n2[0]+n3[0]+n4[0])/4.0f;<br />                     b[i][j] = (n1[1]+n2[1]+n3[1]+n4[1])/4.0f;<br />                     c[i][j] = (n1[2]+n2[2]+n3[2]+n4[2])/4.0f; }<br />             }<br />         }</p> <p>//    int nC;<br />     //三角形で面を定義<br />     glBegin(GL_TRIANGLES);<br />     for(j = 0;j &lt; Ny;j++)<br />         for(i = 0;i &lt; Nx;i++)<br />         {<br />             //左下の三角形<br />             //各頂点の法線方向,テクスチャー座標,頂点座標を与える。<br />             glNormal3f(a[i][j],b[i][j],c[i][j]);//法線方向<br />             glVertex3fv(p[i][j]);//ポリゴンの頂点座標(以下これらを繰り返す)<br />             glNormal3f(a[i+1][j],b[i+1][j],c[i+1][j]);<br />             glVertex3fv(p[i+1][j]);<br />             glNormal3f(a[i][j+1],b[i][j+1],c[i][j+1]);<br />             glVertex3fv(p[i][j+1]);<br />             //右上の三角形<br />             glNormal3f(a[i+1][j],b[i+1][j],c[i+1][j]);<br />             glVertex3fv(p[i+1][j]);<br />             glNormal3f(a[i+1][j+1],b[i+1][j+1],c[i+1][j+1]);<br />             glVertex3fv(p[i+1][j+1]);<br />             glNormal3f(a[i][j+1],b[i][j+1],c[i][j+1]);<br />             glVertex3fv(p[i][j+1]);<br />         }<br />     glEnd();</p> <p>    if(sideFlag == 1)//側面描画<br />     {<br />         glBegin(GL_QUADS);<br />         //+x方向(i=Nx)<br />         glNormal3f(1.0, 0.0, 0.0);<br />         for(j = 0; j &lt; Ny; j++)<br />         {<br />             glVertex3f(p[Nx][j][0], p[Nx][j][1], 0.0f);<br />             glVertex3f(p[Nx][j+1][0], p[Nx][j+1][1], 0.0f);<br />             glVertex3f(p[Nx][j+1][0], p[Nx][j+1][1], p[Nx][j+1][2]);<br />             glVertex3f(p[Nx][j][0], p[Nx][j][1], p[Nx][j][2]);<br />         }<br />         //-x方向(i=0)<br />         glNormal3f(-1.0, 0.0, 0.0);<br />         for(j = 0; j &lt; Ny; j++)<br />         {<br />             glVertex3f(p[0][j][0], p[0][j][1], 0.0f);<br />             glVertex3f(p[0][j][0], p[0][j][1], p[0][j][2]);<br />             glVertex3f(p[0][j+1][0], p[0][j+1][1], p[0][j+1][2]);<br />             glVertex3f(p[0][j+1][0], p[0][j+1][1], 0.0f);<br />         }<br />         //+y方向(j=Ny)<br />         glNormal3f(0.0, 1.0, 0.0);<br />         for(i = 0; i &lt; Nx; i++)<br />         {<br />             glVertex3f(p[i][Ny][0], p[i][Ny][1], 0.0f);<br />             glVertex3f(p[i][Ny][0], p[i][Ny][1], p[i][Ny][2]);<br />             glVertex3f(p[i+1][Ny][0], p[i+1][Ny][1], p[i+1][Ny][2]);<br />             glVertex3f(p[i+1][Ny][0], p[i+1][Ny][1], 0.0f);<br />         }<br />         //-y方向(j=0)<br />         glNormal3f(0.0, -1.0, 0.0);<br />         for(i = 0; i &lt; Nx; i++)<br />         {<br />             glVertex3f(p[i][0][0], p[i][0][1], 0.0f);<br />             glVertex3f(p[i+1][0][0], p[i+1][0][1], 0.0f);<br />             glVertex3f(p[i+1][0][0], p[i+1][0][1], p[i+1][0][2]);<br />             glVertex3f(p[i][0][0], p[i][0][1], p[i][0][2]);<br />         }<br />         glEnd();<br />     }<br /> }</p> <p>//waveデータ<br /> #define nMesh 128//最大分割数(両辺同じ,128が最大)<br /> int numWave = 1;//円形波の波源数(最大3)<br /> int kindWave = 1;<br /> float waveH = 3.0;//波の位置の高さ<br /> float period = 4.0;//並の速さ<br /> float lambda = 0.6;//並の細かさ<br /> //float amp0 = 1.0;<br /> float sizeX = 10.0;<br /> float sizeY = 10.0;<br /> float meshX = sizeX / (float)nMesh/4;<br /> float meshY = sizeY / (float)nMesh/4;<br /> float data[(nMesh+1)*(nMesh+1)];//Waveの高さデータ</p> <p>void drawWave()<br /> {<br />     float diffuse[] = { 0.2f, 0.3f, 0.4f, 0.02f};<br />     float ambient[] = { 0.1f, 0.1f, 0.2f, 0.02f};<br />     float specular[]= { 0.2f, 0.2f, 0.3f, 0.02f};</p> <p>  glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);<br />   glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />   glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />   glMaterialf(GL_FRONT,GL_SHININESS,100);</p> <p>  glPushMatrix();<br />   glTranslatef(0.0, waveH, 0.0);<br />   glRotatef(-90.0, 1.0, 0.0, 0.0);//x軸回転(y軸を鉛直軸にするため)<br />     glScalef(1.0, 1.0, 0.03);<br />   drawElevation(nMesh, nMesh, sizeX, sizeY, 0, data);<br />   glPopMatrix();<br /> }</p> <p>void makeWavePlane(float amp, float t)<br /> {<br />   int i, j;<br />   float x, y;<br />     double pp = 2.0 * PAI;</p> <p>    float lambdaX = lambda;<br />     float lambdaY = lambda * 5.0;</p> <p>  for(j = 0; j &lt;= nMesh; j++)<br />   {<br />       y = (float)( - nMesh / 2 + j) * meshY;<br />       for(i = 0; i &lt;= nMesh; i++)<br />       {<br />           x = (float)( - nMesh / 2 + i) * meshX ;<br />           <br />                     data[j * (nMesh + 1) + i] = amp * (<br />                          sin(pp * (t/period - x/lambdaX - y/lambdaY ) + 1.0*sin(pp * x))<br />                          + sin(pp * (t/period + x/lambdaY - y/lambdaX) + 0.5*sin(pp * y))<br />                          + 0.5 * sin(pp * (2.0*t/period - x/lambdaX - y/lambdaY))<br />                          + 0.1 * sin(pp * (3.0*t/period - x/lambdaX - y/lambdaY))<br />                          );<br />       }<br />   }<br /> }</p> <p>//光源<br /> float lightPos[] = {0.0, 10.0, 0.0, 1.0};//光源位置<br /> float lightPos0[] = {0.0, 10.0, 0.0, 1.0};//光源位置(初期値)<br /> //影のマテリアル<br /> float shadowDiffuse[] =  {0.0,0.0,0.0,0.1};//影の拡散光<br /> float shadowSpecular[] = {0.0,0.0,0.0,1.0};//影の鏡面光</p> <p>//カメラと視体積<br /> struct View<br /> {<br />   //カメラ<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.0, 0.0, 0.0,//pos(仮設定)<br />   0.0, 1.0, 0.0,//cnt <br />     15.0, 20.0, 0.0,//dist, theta, phi<br />     50.0, 1.0, 100.0//fovY,nearZ, farZ<br /> };<br /> View view0 = view;</p> <p> </p> <p>void setTexture(){<br />     glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,TEX_WIDTH,TEX_HEIGHT,0,GL_RGB,GL_UNSIGNED_BYTE,texImage);<br />     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP);<br />     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP);<br />     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);<br />     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);<br /> }<br /> 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 /> }<br /> void setCamera(){<br />   double pp = PAI / 180.0;<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 /> }<br /> void makeTexImage(){<br />   int i, j;<br />     float v, a;</p> <p>  for(j = 0; j &lt; TEX_HEIGHT; j++)<br />         for(i = 0; i &lt; TEX_WIDTH; i++){<br />             v = data[j * (nMesh + 1) + i];<br />             if(kindWave == 0){ a = 180.0 + 75.0 * v ;<br />             }else{              a = 250.0 - 100.0 * v*v  ;}<br />             if(a &gt;= 255.0) a = 255.0;<br />             if(a &lt; 120) a = 120;<br />              texImage[j][i][0] = texImage[j][i][1] = texImage[j][i][2] = (GLubyte)a;<br />     }<br /> }<br /> void idle(void){<br />   //再描画<br />   glutPostRedisplay();<br /> }</p> <p>void init(void){<br />  //背景色<br />   glClearColor(0.4, 0.6, 0.8, 1.0);</p> <p>  setCamera();//視点を求める<br />   setLight(); //光源設定<br />   glEnable(GL_DEPTH_TEST);<br />   glEnable(GL_NORMALIZE);<br />   printf("マウス/キー操作の説明には'h'キーをプッシュ \n");</p> <p>  //時間関係<br />   lastTime = timeGetTime();<br />   fps = 0;<br />   elapseTime1 = 0.0;//1sec間以内の経過時間<br />   elapseTime2 = 0.0; //init()後の総経過時間</p> <p>  glsl.InitGLSL("vertex.shader","flagment.shader");<br />   makeWavePlane(amp, elapseTime2);<br />   makeTexImage();<br />   setTexture();<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, (double)w/(double)h, view.nearZ, view.farZ);<br />   glMatrixMode(GL_MODELVIEW);<br />   glLoadIdentity();<br />   width = w;<br />   height = h;<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 />   gluPerspective(fov, 1.0, 0.1, 50.0);<br />   gluLookAt(lightPos[0], lightPos[1], lightPos[2], 0.0, waveH, 0.0, 0.0, 0.0, -1.0);<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;</p> <p>  float diffuse[][4] = {<br />     { 0.7, 0.7, 0.7, 1.0}, { 0.3f, 0.3, 0.3, 1.0} };<br />   float ambient[] = { 0.2, 0.2, 0.2, 1.0};<br />   float specular[]= { 0.5, 0.5, 0.5, 1.0};<br />   glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />   glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />   glMaterialf(GL_FRONT,GL_SHININESS,100);</p> <p>  //通常のモデルビュー変換に戻す <br />   glMatrixMode(GL_MODELVIEW);<br />   glNormal3f(0.0, 1.0, 0.0);<br />   glPushMatrix();<br />   for (j = 0; j &lt; nz; j++) {<br />     float z1 = -widthZ / 2.0 + wZ * j; float z2 = z1 + wZ;<br />     for (i = 0; i &lt; nx; i++) {<br />       float x1 = -widthX / 2.0 + wX * i; float x2 = x1 + wX;</p> <p>      glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) &amp; 1]);<br />             glBegin(GL_QUADS);<br />       glVertex3f(x1, Floor_Y, z1);<br />       glVertex3f(x1, Floor_Y, z2);<br />       glVertex3f(x2, Floor_Y, z2);<br />       glVertex3f(x2, Floor_Y, z1);<br />             glEnd();<br />     }<br />   }<br />   glPopMatrix();<br /> }</p> <p>void display(void){<br />     //時間計測<br />   curTime = timeGetTime();<br />   float dt = (float)(curTime - lastTime) * 0.001;//secに変換<br />   elapseTime1 += dt;<br />   elapseTime2 += dt;<br />   fps ++;<br />         printf("elapseTime2 = %f \n", elapseTime2);<br />   if(elapseTime1 &gt;= 1.0){<br />         printf("frame per sec = %d \n", fps);<br />         elapseTime1 = 0.0;<br />         fps = 0;<br />   }<br />   lastTime = curTime;</p> <p>    //波データを作成し、投影マップを設定<br />     makeWavePlane(amp, elapseTime2);<br />     makeTexImage();<br />     setTexture();</p> <p>    resize(width, height);<br />     //カラーバッファのクリア<br />   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);</p> <p>  if(cos(PAI * view.theta /180.0) &gt; 0.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);</p> <p>  //fragment shaderのユニフォーム変数インデックスを取得<br />   GLint texLoc = glGetUniformLocation(glsl.ShaderProg, "smplCaustics");<br />   glUniform1i(texLoc, 0);//GL_TEXTURE0を適用</p> <p>  glsl.ON();<br />   //描画<br />     drawFloor(10.0, 10.0, 5, 5);<br />   glsl.OFF();</p> <p>    //テクスチャ、半透明物体があるとき<br />     glDepthMask(GL_FALSE); //デプスバッファを書き込み禁止<br />     glEnable(GL_BLEND);//アルファブレンディングを有効にする<br />     glBlendFunc(GL_DST_ALPHA,GL_ONE_MINUS_SRC_ALPHA);//色混合係数を決める</p> <p>    //半透明描画<br />     drawWave();<br />     //テクスチャ、半透明物体があるとき<br />     glDepthMask(GL_TRUE); //デプスバッファの書き込みを許可<br />     glDisable(GL_BLEND);</p> <p>  //終了<br />   glutSwapBuffers();<br /> }</p> <p>void drawLight(void){<br />     glDisable(GL_LIGHTING);<br />     glColor3f(1.0, 1.0, 1.0);<br />   glPushMatrix();<br />     glTranslatef(lightPos[0], lightPos[1], lightPos[2]);<br />     glutSolidSphere(0.1, 10, 10);<br />   glPopMatrix();<br />     glEnable(GL_LIGHTING);<br /> }</p> <p><br /> //以下の3個の関数はマウス操作による視点の変更に必要<br /> void mouse(int button, int state, int x, int y){<br />   double pp = PAI / 180.0;</p> <p>  if(button == GLUT_LEFT_BUTTON &amp;&amp; state == GLUT_DOWN){<br />       xStart = x; yStart = y;<br />       flagMouse = true;<br />       if(x &gt; width/4 &amp;&amp; x &lt; 3*width/4 &amp;&amp; y &gt; height/4 &amp;&amp; y &lt; 3*height/4){<br />       }<br />   }else if(button == GLUT_RIGHT_BUTTON &amp;&amp; state == GLUT_DOWN){<br />       if(x &gt; width/4 &amp;&amp; x &lt; 3*width/4 &amp;&amp; y &gt; height/4 &amp;&amp; y &lt; 3*height/4){<br />       }else if(( x &lt; width/4 || x &gt; 3*width/4) &amp;&amp; (y &gt; height/4 &amp;&amp; y &lt; 3*height/4)){<br />           if(x &lt; 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 &gt; width/4 &amp;&amp; x &lt; 3*width/4) &amp;&amp; (y &lt; height/4 || y &gt; 3*height/4)){<br />           if( y &lt; height/4)<br />               view.theta += 1.0; <br />           else<br />               view.theta -= 1.0;</p> <p>          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 />       }<br />       else if(x &lt; width/8 &amp;&amp; y &gt; 7*height/8) view.fovY -= 1.0;//zoom in<br />       else if(x &gt; 7*width/8 &amp;&amp; y &gt; 7*height/8) view.fovY += 1.0;//zoom out<br />   }<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.0) &gt;= 0.0)<br />     view.phi -= 0.5 * (float)(x - xStart) ;//tumble<br />   else<br />     view.phi += 0.5 * (float)(x - xStart) ;//tumble</p> <p>  view.theta += 0.5 * (float)(y - yStart) ;//crane</p> <p>  setCamera();<br />   xStart = x;<br />   yStart = y;<br /> }</p> <p><br /> void main(int argc, char *argv[]){<br />   glutInit(&amp;argc, argv);<br />   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />   glutInitWindowSize(width, height);<br />   glutInitWindowPosition(100, 100);<br />   glutCreateWindow("水面と集光模様");<br />   glutReshapeFunc(resize);<br />   glutDisplayFunc(display);<br />   glutMouseFunc(mouse);<br />   glutMotionFunc(motion);<br />   glutIdleFunc(idle);<br />   init();<br />   glutMainLoop();<br /> }</p> </td> </tr></tbody></table><p> </p>
<p><strong>水面と集光模様です。</strong></p> <p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&amp;act=open&amp;pageid=314&amp;file=water.png" /></p> <p>vertex.shader</p> <table border="1" cellpadding="1" cellspacing="1" style="width:600px;"><tbody><tr><td> <p>  //フラグメントシェーダーに渡す変数<br />   varying vec3 P;//位置ベクトル<br />   varying vec3 N;//法線ベクトル</p> <p>void main(void){<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><br />   //頂点シェーダーから受け取る変数<br />   varying vec3 P;//位置ベクトル<br />   varying vec3 N;//法線ベクトル<br /> uniform sampler2D smplCaustics;<br /> void main(void){<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 &lt;= 0.0) powNH = 0.0;<br />     vec4 specular = gl_FrontLightProduct[0].specular * powNH;<br />   vec4 texColor = texture2DProj(smplCaustics, gl_TexCoord[0]);<br />     gl_FragColor = (ambient + diffuse) * texColor + specular;<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><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;windows.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;stdio.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;GL/glew.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;GL/freeglut/freeglut.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include &lt;math.h&gt;</span><br style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;" /><span style="color:rgb(42,42,42);font-family:arial, helvetica, '繝偵Λ繧ョ繝手ァ偵ざ Pro W3', 'Hiragino Kaku Gothic Pro', Osaka, '繝。繧、繝ェ繧ェ', Meiryo, 'MS P繧エ繧キ繝�け', clean, sans-serif;font-size:12px;line-height:19.4559993743897px;"> #include "GLSL.h"</span></p> <p>#define PAI 3.14159</p> <p>GLSL glsl;<br /> //Windowのサイズ<br /> int width = 640;<br /> int height = 480;<br /> //マウス操作<br /> int xStart, yStart;<br /> bool flagMouse = false;<br /> //テクスチャー画像<br /> #define TEX_WIDTH 128<br /> #define TEX_HEIGHT 128<br /> GLubyte texImage[TEX_HEIGHT][TEX_WIDTH][3];<br /> //経過時間<br /> double curTime, lastTime, elapseTime1, elapseTime2;<br /> int fps = 0;//frame per sec<br /> float amp = 1.0;<br /> GLfloat fov = 60.0;//透視投影マッピングの視野角<br /> float Floor_Y = -1.0f;</p> <p>struct MATRIX;</p> <p>//マトリクス構造体<br /> struct MATRIX {<br />     union {<br />         struct {<br />             float _11, _12, _13, _14;<br />             float _21, _22, _23, _24;<br />             float _31, _32, _33, _34;<br />             float _41, _42, _43, _44;<br />         };<br />         float mat_4x4[4][4];<br />         float mat_16[16];<br />     };<br />  MATRIX(){//単位行列に初期化<br />   for(int i=0;i&lt;16;i++){<br />    this-&gt;mat_16[i]=0;<br />   }<br />   this-&gt;_11=this-&gt;_22=this-&gt;_33=this-&gt;_44=1;<br />  }<br />  void PRINT(char* text){<br />   printf("%s\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n\n",<br />    text,<br />    this-&gt;_11,this-&gt;_21,this-&gt;_31,this-&gt;_41,<br />    this-&gt;_12,this-&gt;_22,this-&gt;_32,this-&gt;_42,<br />    this-&gt;_13,this-&gt;_23,this-&gt;_33,this-&gt;_43,<br />    this-&gt;_14,this-&gt;_24,this-&gt;_34,this-&gt;_44);<br />  }</p> <p> MATRIX Multiplication(MATRIX&amp; mat);//合成<br /> };<br /> //合成<br /> MATRIX MATRIX::Multiplication(MATRIX&amp; mat)<br /> {<br />  MATRIX ret;<br />  for(int y=0;y&lt;4;y++){<br />   for(int x=0;x&lt;4;x++){<br />    ret.mat_16[y*4+x]=mat.mat_16[y*4]*this-&gt;mat_16[x]+mat.mat_16[y*4+1]*this-&gt;mat_16[x+4]+mat.mat_16[y*4+2]*this-&gt;mat_16[x+8]+mat.mat_16[y*4+3]*this-&gt;mat_16[x+12];<br />   }<br />  }<br />  return ret;<br /> }</p> <p>//3つのベクトル<br /> struct Vector3f{<br />  float x;<br />  float y;<br />  float z;<br />  Vector3f(){};<br />  Vector3f(float _x,float _y,float _z){<br />   x=_x;y=_y;z=_z;<br />  };<br /> }vec3d;<br /> Vector3f &amp; operator*(Vector3f &amp;v,float size){<br />  v.x *= size;<br />  v.y *= size;<br />  v.z *= size;<br />  return v;<br /> }<br /> Vector3f &amp; operator+(Vector3f &amp;a,Vector3f &amp;b){<br />  a.x+=b.x;<br />  a.y+=b.y;<br />  a.z+=b.z;<br />  return a;<br /> }</p> <p>//正規化<br /> void normalize(Vector3f&amp; v){<br />  float m=sqrt(v.x*v.x+v.y*v.y+v.z*v.z);<br />  if(m &gt; 0.0f){m = 1.0f / m;}else{m = 0.0f;}<br />  v.x*=m;<br />  v.y*=m;<br />  v.z*=m;<br /> }<br /> //外積<br /> void cross( Vector3f&amp; src1, Vector3f&amp; src2 ,Vector3f&amp; dst){<br />  dst.x = src1.y*src2.z - src1.z*src2.y;<br />  dst.y = src1.z*src2.x - src1.x*src2.z;<br />  dst.z = src1.x*src2.y - src1.y*src2.x;<br /> }<br /> //内積<br /> void dot(Vector3f&amp; src1,Vector3f&amp; src2,float&amp; dst){<br />  dst= src1.x*src2.x+src1.y*src2.y+src1.z*src2.z;<br /> }</p> <p>//---------------------------------------------------------------------<br /> //法線方向計算ルーチン<br /> void calcNormal(float* p1,float* p2,float* p3,float* nn)<br /> {<br />     Vector3f A = Vector3f(p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]);<br />     Vector3f B = Vector3f(p3[0] - p2[0], p3[1] - p2[1], p3[2] - p2[2]);<br />     //CVector n = A ^ B;//外積<br />     Vector3f n;<br />     cross(A,B,n);<br />     nn[0] = n.x; nn[1] = n.y; nn[2] = n.z;<br /> }</p> <p> //-----------------------------------------------------------------------------<br /> //四角形のメッシュ(x-y平面,中心が原点)<br /> //x軸方向,y軸方向の幅を固定<br /> void drawElevation(int Nx, int Ny, float sizeX, float sizeY, int sideFlag, float* data)<br /> {<br />     //全体の幅,長さsizeX, sizeY<br />     //sideFlag = 0:側面表示せず<br />     //sideFlag = 1:側面表示する</p> <p>    const int NMAX = 130;<br />     int i, j;<br />     float p[NMAX][NMAX][3]; //頂点座標<br />     float a[NMAX][NMAX], b[NMAX][NMAX], c[NMAX][NMAX];//頂点の法線<br />     float pitchX, pitchY;<br />     float n1[3], n2[3], n3[3], n4[3];</p> <p>    if(Nx &gt; NMAX) printf("NxがNMAXを超えています(drawElevation1) \n");<br />     if(Ny &gt; NMAX) printf("NyがNMAXを超えています(drawElevation1) \n");</p> <p>    //セルのサイズ<br />     pitchX = sizeX / (float)Nx;<br />     pitchY = sizeY / (float)Ny;</p> <p>    //各頂点の座標<br />     for(j = 0; j &lt;= Ny; j++){<br />         for(i = 0; i &lt;= Nx; i++){<br />             p[i][j][0] = (float)(i - Nx / 2) * pitchX;<br />             p[i][j][1] = (float)(j - Ny / 2) * pitchY;<br />             p[i][j][2] = data[j * (Nx+1) + i];<br />         }<br />     }</p> <p>            <br />     //法線成分<br />     for(i = 0;i &lt;= Nx;i++)<br />         for(j = 0;j &lt;= Ny;j++)<br />         {            <br />             if(j == 0 )<br />             {<br />                 if(i == 0) <br />                 {<br />                     calcNormal(p[0][0],p[1][0],p[0][1],n1);<br />                     a[i][j] = n1[0]; b[i][j] = n1[1]; c[i][j] = n1[2]; }<br />                 else if(i == Nx) <br />                 {<br />                     calcNormal(p[Nx-1][0],p[Nx][0],p[Nx][1],n1);<br />                     a[i][j] = n1[0]; b[i][j] = n1[1]; c[i][j] = n1[2]; }<br />                 else <br />                 {<br />                     calcNormal(p[i][0],p[i][1],p[i-1][0],n1);//左側<br />                     calcNormal(p[i][0],p[i+1][0],p[i][1],n2);//右側<br />                     a[i][j] = (n1[0]+n2[0])/2.0f;<br />                     b[i][j] = (n1[1]+n2[1])/2.0f;<br />                     c[i][j] = (n1[2]+n2[2])/2.0f; }<br />             }<br />             else if(j == Ny)<br />             {<br />                 if(i == 0) <br />                 {<br />                     calcNormal(p[0][Ny],p[0][Ny-1],p[1][Ny],n1);<br />                     a[i][j] = n1[0]; b[i][j] = n1[1]; c[i][j] = n1[2]; }<br />                 else if(i == Nx) <br />                 {<br />                     calcNormal(p[Nx][Ny],p[Nx-1][Ny],p[Nx][Ny-1],n1);<br />                     a[i][j] = n1[0]; b[i][j] = n1[1]; c[i][j] = n1[2]; }<br />                 else <br />                 {<br />                     calcNormal(p[i][Ny],p[i-1][Ny],p[i][Ny-1],n1);//左側<br />                     calcNormal(p[i][Ny],p[i][Ny-1],p[i+1][Ny],n2);//右側<br />                     a[i][j] = (n1[0]+n2[0])/2.0f;<br />                     b[i][j] = (n1[1]+n2[1])/2.0f;<br />                     c[i][j] = (n1[2]+n2[2])/2.0f; }<br />             }<br />             else<br />             {<br />                 if(i == 0) <br />                 {<br />                     calcNormal(p[0][j],p[1][j],p[0][j+1],n1);//上<br />                     calcNormal(p[0][j],p[0][j-1],p[0][1],n2);//下<br />                     a[i][j] = (n1[0]+n2[0])/2.0f;<br />                     b[i][j] = (n1[1]+n2[1])/2.0f;<br />                     c[i][j] = (n1[2]+n2[2])/2.0f; }<br />                 else if(i == Nx) <br />                 {<br />                     calcNormal(p[Nx][j],p[Nx][j+1],p[Nx-1][j],n1);//上<br />                     calcNormal(p[Nx][j],p[Nx-1][j],p[Nx][j-1],n2);//下<br />                     a[i][j] = (n1[0]+n2[0])/2.0f;<br />                     b[i][j] = (n1[1]+n2[1])/2.0f;<br />                     c[i][j] = (n1[2]+n2[2])/2.0f; }<br />                 else <br />                 {//上下左右4個の三角形の平均<br />                     calcNormal(p[i][j],p[i][j+1],p[i-1][j],n1);//左上<br />                     calcNormal(p[i][j],p[i+1][j],p[i][j+1],n2);//右上<br />                     calcNormal(p[i][j],p[i-1][j],p[i][j-1],n3);//左下<br />                     calcNormal(p[i][j],p[i][j-1],p[i+1][j],n4);//右下<br />                     a[i][j] = (n1[0]+n2[0]+n3[0]+n4[0])/4.0f;<br />                     b[i][j] = (n1[1]+n2[1]+n3[1]+n4[1])/4.0f;<br />                     c[i][j] = (n1[2]+n2[2]+n3[2]+n4[2])/4.0f; }<br />             }<br />         }</p> <p>//    int nC;<br />     //三角形で面を定義<br />     glBegin(GL_TRIANGLES);<br />     for(j = 0;j &lt; Ny;j++)<br />         for(i = 0;i &lt; Nx;i++)<br />         {<br />             //左下の三角形<br />             //各頂点の法線方向,テクスチャー座標,頂点座標を与える。<br />             glNormal3f(a[i][j],b[i][j],c[i][j]);//法線方向<br />             glVertex3fv(p[i][j]);//ポリゴンの頂点座標(以下これらを繰り返す)<br />             glNormal3f(a[i+1][j],b[i+1][j],c[i+1][j]);<br />             glVertex3fv(p[i+1][j]);<br />             glNormal3f(a[i][j+1],b[i][j+1],c[i][j+1]);<br />             glVertex3fv(p[i][j+1]);<br />             //右上の三角形<br />             glNormal3f(a[i+1][j],b[i+1][j],c[i+1][j]);<br />             glVertex3fv(p[i+1][j]);<br />             glNormal3f(a[i+1][j+1],b[i+1][j+1],c[i+1][j+1]);<br />             glVertex3fv(p[i+1][j+1]);<br />             glNormal3f(a[i][j+1],b[i][j+1],c[i][j+1]);<br />             glVertex3fv(p[i][j+1]);<br />         }<br />     glEnd();</p> <p>    if(sideFlag == 1)//側面描画<br />     {<br />         glBegin(GL_QUADS);<br />         //+x方向(i=Nx)<br />         glNormal3f(1.0, 0.0, 0.0);<br />         for(j = 0; j &lt; Ny; j++)<br />         {<br />             glVertex3f(p[Nx][j][0], p[Nx][j][1], 0.0f);<br />             glVertex3f(p[Nx][j+1][0], p[Nx][j+1][1], 0.0f);<br />             glVertex3f(p[Nx][j+1][0], p[Nx][j+1][1], p[Nx][j+1][2]);<br />             glVertex3f(p[Nx][j][0], p[Nx][j][1], p[Nx][j][2]);<br />         }<br />         //-x方向(i=0)<br />         glNormal3f(-1.0, 0.0, 0.0);<br />         for(j = 0; j &lt; Ny; j++)<br />         {<br />             glVertex3f(p[0][j][0], p[0][j][1], 0.0f);<br />             glVertex3f(p[0][j][0], p[0][j][1], p[0][j][2]);<br />             glVertex3f(p[0][j+1][0], p[0][j+1][1], p[0][j+1][2]);<br />             glVertex3f(p[0][j+1][0], p[0][j+1][1], 0.0f);<br />         }<br />         //+y方向(j=Ny)<br />         glNormal3f(0.0, 1.0, 0.0);<br />         for(i = 0; i &lt; Nx; i++)<br />         {<br />             glVertex3f(p[i][Ny][0], p[i][Ny][1], 0.0f);<br />             glVertex3f(p[i][Ny][0], p[i][Ny][1], p[i][Ny][2]);<br />             glVertex3f(p[i+1][Ny][0], p[i+1][Ny][1], p[i+1][Ny][2]);<br />             glVertex3f(p[i+1][Ny][0], p[i+1][Ny][1], 0.0f);<br />         }<br />         //-y方向(j=0)<br />         glNormal3f(0.0, -1.0, 0.0);<br />         for(i = 0; i &lt; Nx; i++)<br />         {<br />             glVertex3f(p[i][0][0], p[i][0][1], 0.0f);<br />             glVertex3f(p[i+1][0][0], p[i+1][0][1], 0.0f);<br />             glVertex3f(p[i+1][0][0], p[i+1][0][1], p[i+1][0][2]);<br />             glVertex3f(p[i][0][0], p[i][0][1], p[i][0][2]);<br />         }<br />         glEnd();<br />     }<br /> }</p> <p>//waveデータ<br /> #define nMesh 128//最大分割数(両辺同じ,128が最大)<br /> int numWave = 1;//円形波の波源数(最大3)<br /> int kindWave = 1;<br /> float waveH = 3.0;//波の位置の高さ<br /> float period = 4.0;//並の速さ<br /> float lambda = 0.6;//並の細かさ<br /> //float amp0 = 1.0;<br /> float sizeX = 10.0;<br /> float sizeY = 10.0;<br /> float meshX = sizeX / (float)nMesh/4;<br /> float meshY = sizeY / (float)nMesh/4;<br /> float data[(nMesh+1)*(nMesh+1)];//Waveの高さデータ</p> <p>void drawWave()<br /> {<br />     float diffuse[] = { 0.2f, 0.3f, 0.4f, 0.02f};<br />     float ambient[] = { 0.1f, 0.1f, 0.2f, 0.02f};<br />     float specular[]= { 0.2f, 0.2f, 0.3f, 0.02f};</p> <p>  glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse);<br />   glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />   glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />   glMaterialf(GL_FRONT,GL_SHININESS,100);</p> <p>  glPushMatrix();<br />   glTranslatef(0.0, waveH, 0.0);<br />   glRotatef(-90.0, 1.0, 0.0, 0.0);//x軸回転(y軸を鉛直軸にするため)<br />     glScalef(1.0, 1.0, 0.03);<br />   drawElevation(nMesh, nMesh, sizeX, sizeY, 0, data);<br />   glPopMatrix();<br /> }</p> <p>void makeWavePlane(float amp, float t)<br /> {<br />   int i, j;<br />   float x, y;<br />     double pp = 2.0 * PAI;</p> <p>    float lambdaX = lambda;<br />     float lambdaY = lambda * 5.0;</p> <p>  for(j = 0; j &lt;= nMesh; j++)<br />   {<br />       y = (float)( - nMesh / 2 + j) * meshY;<br />       for(i = 0; i &lt;= nMesh; i++)<br />       {<br />           x = (float)( - nMesh / 2 + i) * meshX ;<br />           <br />                     data[j * (nMesh + 1) + i] = amp * (<br />                          sin(pp * (t/period - x/lambdaX - y/lambdaY ) + 1.0*sin(pp * x))<br />                          + sin(pp * (t/period + x/lambdaY - y/lambdaX) + 0.5*sin(pp * y))<br />                          + 0.5 * sin(pp * (2.0*t/period - x/lambdaX - y/lambdaY))<br />                          + 0.1 * sin(pp * (3.0*t/period - x/lambdaX - y/lambdaY))<br />                          );<br />       }<br />   }<br /> }</p> <p>//光源<br /> float lightPos[] = {0.0, 10.0, 0.0, 1.0};//光源位置<br /> float lightPos0[] = {0.0, 10.0, 0.0, 1.0};//光源位置(初期値)<br /> //影のマテリアル<br /> float shadowDiffuse[] =  {0.0,0.0,0.0,0.1};//影の拡散光<br /> float shadowSpecular[] = {0.0,0.0,0.0,1.0};//影の鏡面光</p> <p>//カメラと視体積<br /> struct View<br /> {<br />   //カメラ<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.0, 0.0, 0.0,//pos(仮設定)<br />   0.0, 1.0, 0.0,//cnt <br />     15.0, 20.0, 0.0,//dist, theta, phi<br />     50.0, 1.0, 100.0//fovY,nearZ, farZ<br /> };<br /> View view0 = view;</p> <p> </p> <p>void setTexture(){<br />     glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,TEX_WIDTH,TEX_HEIGHT,0,GL_RGB,GL_UNSIGNED_BYTE,texImage);<br />     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP);<br />     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP);<br />     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);<br />     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);<br /> }<br /> 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 /> }<br /> void setCamera(){<br />   double pp = PAI / 180.0;<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 /> }<br /> void makeTexImage(){<br />   int i, j;<br />     float v, a;</p> <p>  for(j = 0; j &lt; TEX_HEIGHT; j++)<br />         for(i = 0; i &lt; TEX_WIDTH; i++){<br />             v = data[j * (nMesh + 1) + i];<br />             if(kindWave == 0){ a = 180.0 + 75.0 * v ;<br />             }else{              a = 250.0 - 100.0 * v*v  ;}<br />             if(a &gt;= 255.0) a = 255.0;<br />             if(a &lt; 120) a = 120;<br />              texImage[j][i][0] = texImage[j][i][1] = texImage[j][i][2] = (GLubyte)a;<br />     }<br /> }<br /> void idle(void){<br />   //再描画<br />   glutPostRedisplay();<br /> }</p> <p>void init(void){<br />  //背景色<br />   glClearColor(0.4, 0.6, 0.8, 1.0);</p> <p>  setCamera();//視点を求める<br />   setLight(); //光源設定<br />   glEnable(GL_DEPTH_TEST);<br />   glEnable(GL_NORMALIZE);<br />   printf("マウス/キー操作の説明には'h'キーをプッシュ \n");</p> <p>  //時間関係<br />   lastTime = timeGetTime();<br />   fps = 0;<br />   elapseTime1 = 0.0;//1sec間以内の経過時間<br />   elapseTime2 = 0.0; //init()後の総経過時間</p> <p>  glsl.InitGLSL("vertex.shader","flagment.shader");<br />   makeWavePlane(amp, elapseTime2);<br />   makeTexImage();<br />   setTexture();<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, (double)w/(double)h, view.nearZ, view.farZ);<br />   glMatrixMode(GL_MODELVIEW);<br />   glLoadIdentity();<br />   width = w;<br />   height = h;<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 />   gluPerspective(fov, 1.0, 0.1, 50.0);<br />   gluLookAt(lightPos[0], lightPos[1], lightPos[2], 0.0, waveH, 0.0, 0.0, 0.0, -1.0);<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;</p> <p>  float diffuse[][4] = {<br />     { 0.7, 0.7, 0.7, 1.0}, { 0.3f, 0.3, 0.3, 1.0} };<br />   float ambient[] = { 0.2, 0.2, 0.2, 1.0};<br />   float specular[]= { 0.5, 0.5, 0.5, 1.0};<br />   glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />   glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />   glMaterialf(GL_FRONT,GL_SHININESS,100);</p> <p>  //通常のモデルビュー変換に戻す <br />   glMatrixMode(GL_MODELVIEW);<br />   glNormal3f(0.0, 1.0, 0.0);<br />   glPushMatrix();<br />   for (j = 0; j &lt; nz; j++) {<br />     float z1 = -widthZ / 2.0 + wZ * j; float z2 = z1 + wZ;<br />     for (i = 0; i &lt; nx; i++) {<br />       float x1 = -widthX / 2.0 + wX * i; float x2 = x1 + wX;</p> <p>      glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) &amp; 1]);<br />             glBegin(GL_QUADS);<br />       glVertex3f(x1, Floor_Y, z1);<br />       glVertex3f(x1, Floor_Y, z2);<br />       glVertex3f(x2, Floor_Y, z2);<br />       glVertex3f(x2, Floor_Y, z1);<br />             glEnd();<br />     }<br />   }<br />   glPopMatrix();<br /> }</p> <p>void display(void){<br />     //時間計測<br />   curTime = timeGetTime();<br />   float dt = (float)(curTime - lastTime) * 0.001;//secに変換<br />   elapseTime1 += dt;<br />   elapseTime2 += dt;<br />   fps ++;<br />         printf("elapseTime2 = %f \n", elapseTime2);<br />   if(elapseTime1 &gt;= 1.0){<br />         printf("frame per sec = %d \n", fps);<br />         elapseTime1 = 0.0;<br />         fps = 0;<br />   }<br />   lastTime = curTime;</p> <p>    //波データを作成し、投影マップを設定<br />     makeWavePlane(amp, elapseTime2);<br />     makeTexImage();<br />     setTexture();</p> <p>    resize(width, height);<br />     //カラーバッファのクリア<br />   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);</p> <p>  if(cos(PAI * view.theta /180.0) &gt; 0.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);</p> <p>  //fragment shaderのユニフォーム変数インデックスを取得<br />   GLint texLoc = glGetUniformLocation(glsl.ShaderProg, "smplCaustics");<br />   glUniform1i(texLoc, 0);//GL_TEXTURE0を適用</p> <p>  glsl.ON();<br />   //描画<br />     drawFloor(10.0, 10.0, 5, 5);<br />   glsl.OFF();</p> <p>    //テクスチャ、半透明物体があるとき<br />     glDepthMask(GL_FALSE); //デプスバッファを書き込み禁止<br />     glEnable(GL_BLEND);//アルファブレンディングを有効にする<br />     glBlendFunc(GL_DST_ALPHA,GL_ONE_MINUS_SRC_ALPHA);//色混合係数を決める</p> <p>    //半透明描画<br />     drawWave();<br />     //テクスチャ、半透明物体があるとき<br />     glDepthMask(GL_TRUE); //デプスバッファの書き込みを許可<br />     glDisable(GL_BLEND);</p> <p>  //終了<br />   glutSwapBuffers();<br /> }</p> <p>void drawLight(void){<br />     glDisable(GL_LIGHTING);<br />     glColor3f(1.0, 1.0, 1.0);<br />   glPushMatrix();<br />     glTranslatef(lightPos[0], lightPos[1], lightPos[2]);<br />     glutSolidSphere(0.1, 10, 10);<br />   glPopMatrix();<br />     glEnable(GL_LIGHTING);<br /> }</p> <p><br /> //以下の3個の関数はマウス操作による視点の変更に必要<br /> void mouse(int button, int state, int x, int y){<br />   double pp = PAI / 180.0;</p> <p>  if(button == GLUT_LEFT_BUTTON &amp;&amp; state == GLUT_DOWN){<br />       xStart = x; yStart = y;<br />       flagMouse = true;<br />       if(x &gt; width/4 &amp;&amp; x &lt; 3*width/4 &amp;&amp; y &gt; height/4 &amp;&amp; y &lt; 3*height/4){<br />       }<br />   }else if(button == GLUT_RIGHT_BUTTON &amp;&amp; state == GLUT_DOWN){<br />       if(x &gt; width/4 &amp;&amp; x &lt; 3*width/4 &amp;&amp; y &gt; height/4 &amp;&amp; y &lt; 3*height/4){<br />       }else if(( x &lt; width/4 || x &gt; 3*width/4) &amp;&amp; (y &gt; height/4 &amp;&amp; y &lt; 3*height/4)){<br />           if(x &lt; 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 &gt; width/4 &amp;&amp; x &lt; 3*width/4) &amp;&amp; (y &lt; height/4 || y &gt; 3*height/4)){<br />           if( y &lt; height/4)<br />               view.theta += 1.0; <br />           else<br />               view.theta -= 1.0;</p> <p>          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 />       }<br />       else if(x &lt; width/8 &amp;&amp; y &gt; 7*height/8) view.fovY -= 1.0;//zoom in<br />       else if(x &gt; 7*width/8 &amp;&amp; y &gt; 7*height/8) view.fovY += 1.0;//zoom out<br />   }<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.0) &gt;= 0.0)<br />     view.phi -= 0.5 * (float)(x - xStart) ;//tumble<br />   else<br />     view.phi += 0.5 * (float)(x - xStart) ;//tumble</p> <p>  view.theta += 0.5 * (float)(y - yStart) ;//crane</p> <p>  setCamera();<br />   xStart = x;<br />   yStart = y;<br /> }</p> <p><br /> void main(int argc, char *argv[]){<br />   glutInit(&amp;argc, argv);<br />   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />   glutInitWindowSize(width, height);<br />   glutInitWindowPosition(100, 100);<br />   glutCreateWindow("水面と集光模様");<br />   glutReshapeFunc(resize);<br />   glutDisplayFunc(display);<br />   glutMouseFunc(mouse);<br />   glutMotionFunc(motion);<br />   glutIdleFunc(idle);<br />   init();<br />   glutMainLoop();<br /> }</p> </td> </tr></tbody></table><p> </p>

表示オプション

横に並べて表示:
変化行の前後のみ表示: