距離減衰

「距離減衰」の編集履歴(バックアップ)一覧はこちら

距離減衰」(2014/05/01 (木) 18:06:34) の最新版変更点

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

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

<p><strong>距離による光の減衰です。</strong></p> <p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=183&amp;file=att.png" /></p> <p>vertex.shader</p> <table width="600" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td><span style="font-size:small;"> //フラグメントシェーダーに渡す変数<br />  varying vec3 P;//位置ベクトル<br />  varying vec3 N;//法線ベクトル<br />  <br /> void main(void)<br />  {<br />    P = vec3(gl_ModelViewMatrix * gl_Vertex);<br />    N = normalize(gl_NormalMatrix * gl_Normal);<br />    gl_Position = ftransform();<br />  }</span></td> </tr></tbody></table><p>flagment.shader</p> <table width="600" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td> <p> <span style="font-size:small;">//頂点シェーダーから受け取る変数<br />  varying vec3 P;//位置ベクトル<br />  varying vec3 N;//法線ベクトル<br />  <br /> void main(void)<br />  {<br />  vec3 L = gl_LightSource[0].position.xyz - P;<br />  float d = length(L);//光源までの距離<br />  //減衰計数<br />  float attenuation = 1.0 / (gl_LightSource[0].constantAttenuation<br />                      + gl_LightSource[0].linearAttenuation * d<br />                      + gl_LightSource[0].quadraticAttenuation * d * d );<br />  L = normalize(L);<br />  N = normalize(N);</span></p> <p><span style="font-size:small;"> <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 />   //統合<br />   gl_FragColor = ambient + diffuse + specular;<br />   //減衰率を乗じる<br />   gl_FragColor *= attenuation;<br />  }</span></p> </td> </tr></tbody></table><p>GLSL.h</p> <table width="600" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td> <p><span style="font-size:small;">#pragma once<br /> #include &lt;stdio.h&gt;</span></p> <p><span style="font-size:small;">//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(&amp;fp,File, "rb");<br />    if(!fp) printf("ファイルを開くことができません %s\n", File);<br />  <br />    fseek(fp, 0, SEEK_END);<br />    size = ftell(fp);</span></p> <p><span style="font-size:small;">   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 **)&amp;buf, &amp;size);<br />    free(buf);<br />    fclose(fp);<br />  <br />    glCompileShader(Shader);<br />    glGetShaderiv( Shader, GL_COMPILE_STATUS, &amp;compiled );<br />  <br />   if ( compiled == GL_FALSE )<br />    {<br />     printf( "コンパイルできませんでした!!: %s \n ", File);<br />     glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, &amp;size );<br />     if ( size &gt; 0 )<br />     {<br />      buf = (char *)malloc(size);<br />      glGetShaderInfoLog( Shader, size, &amp;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, &amp;linked );<br />  <br />   if ( linked == GL_FALSE ){<br />    printf("リンクできませんでした!! \n");<br />     <br />    glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, &amp;size );<br />    if ( size &gt; 0 ){<br />     infoLog = (char *)malloc(size);<br />     glGetProgramInfoLog( Prog, size, &amp;len, infoLog );<br />     printf(infoLog);<br />     free(infoLog);<br />    }<br />   }<br /> }</span></p> <p><span style="font-size:small;">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 />  </span></p> <p><span style="font-size:small;">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));</span></p> <p><span style="font-size:small;">   VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />    FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);</span></p> <p><span style="font-size:small;">   ReadShaderCompile(VertexShader, VertexFile);<br />    ReadShaderCompile(FragmentShader, FragmentFile);</span></p> <p><span style="font-size:small;">   ShaderProg = glCreateProgram();<br />  <br />    glAttachShader(ShaderProg, VertexShader);<br />    glAttachShader(ShaderProg, FragmentShader);<br />  <br />    glDeleteShader(VertexShader);<br />    glDeleteShader(FragmentShader);<br />    Link(ShaderProg);<br />  }</span></p> <p><span style="font-size:small;">void GLSL::ON(){<br />  glUseProgram(ShaderProg);<br /> }</span></p> <p><span style="font-size:small;">void GLSL::OFF(){<br />  glUseProgram(0);<br /> }</span></p> <p><span style="font-size:small;">GLSL::~GLSL(){<br />  glDeleteProgram(ShaderProg);<br /> }</span></p> </td> </tr></tbody></table><p>main.cpp</p> <table width="600" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td> <p><span style="font-size:small;">#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br /> #pragma comment(lib, "glew32.lib")<br />  <br /> #include &lt;GL/glew.h&gt;<br /> #include &lt;GL/freeglut/freeglut.h&gt;<br /> #include "GLSL.h"<br /> #include &lt;math.h&gt;</span></p> <p><span style="font-size:small;">#define PAI 3.141592f</span></p> <p><span style="font-size:small;">#define WIDTH 640<br /> #define HEIGHT 480</span></p> <p><span style="font-size:small;">GLSL glsl;<br />  <br /> //回転用<br /> float anglex = 0.0f;<br /> //ライトの位置<br /> GLfloat lightpos[] = { 0.0, 4.0, 0.0, 1.0 };<br />  <br /> float Ambient[] = {0.2f, 0.1f, 0.2f, 1.0f};<br /> float Diffuse[] = {0.8f, 0.0f, 0.0f, 1.0f};<br /> float Specular[]= { 0.4f, 0.4f, 0.4f, 1.0f};//鏡面反射</span></p> <p><span style="font-size:small;">float AmbientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f};<br /> float DiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f};<br /> float SpecularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};//鏡面光</span></p> <p><span style="font-size:small;">float pos[] = {-0.7f, 2.0f, 0.0f};//位置</span></p> <p><span style="font-size:small;">float constAtt = 1.0;<br /> float linearAtt = 0.0;<br /> float quadraAtt = 0.0;</span></p> <p><span style="font-size:small;">//影のマテリアル<br /> float shadowDiffuse[] =  {0.0f,0.0f,0.0f,0.3f};//影の拡散光<br /> float shadowSpecular[] = {0.0f,0.0f,0.0f,1.0f};//影の鏡面光</span></p> <p><span style="font-size:small;">void draw(bool flag){</span></p> <p><span style="font-size:small;"> if(flag) {<br />    glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse);<br />    glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular);<br />   }else{ <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,8);<br />   }</span></p> <p><span style="font-size:small;">  glPushMatrix();<br />   glTranslatef(pos[0], pos[1], pos[2]);<br />   glRotatef( anglex, 1.0f, 0.0f, 0.0f);//x軸回転<br />   glutSolidCube(1.0);<br />   glPopMatrix();<br /> }</span></p> <p><span style="font-size:small;">void drawFloor(float widthX, float widthZ, int nx, int nz){<br />   int i, j;<br />   //Floor1枚当たりの幅<br />   float wX = widthX / (float)nx;<br />   float wZ = widthZ / (float)nz;</span></p> <p><span style="font-size:small;">  float diffuse[][4] = {<br />  { 0.9f, 0.9f, 0.9f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f} };<br />   float ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f};<br />   float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};</span></p> <p><span style="font-size:small;">  glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />   glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />   glMaterialf(GL_FRONT,GL_SHININESS,10);</span></p> <p><span style="font-size:small;">  glNormal3d(0.0, 1.0, 0.0);<br />   glPushMatrix();<br />   for (j = 0; j &lt; nz; j++) {<br />     float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ;<br />     for (i = 0; i &lt; nx; i++) {<br />       float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX;</span></p> <p><span style="font-size:small;">      glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) &amp; 1]);<br />    glBegin(GL_QUADS);<br />       glVertex3d(x1, 0.0, z1);<br />       glVertex3d(x1, 0.0, z2);<br />       glVertex3d(x2, 0.0, z2);<br />       glVertex3d(x2, 0.0, z1);<br />    glEnd();<br />     }<br />   }<br />   glPopMatrix();<br /> }</span></p> <p><span style="font-size:small;"><br /> void CalcShadowMat(float* mat)<br /> {<br />   float ex, ey, ez;//光源の方向<br />   float s; //object中心から光源までの距離<br />   float x, y, z;</span></p> <p><span style="font-size:small;">  x = lightpos[0] - pos[0];<br />   y = lightpos[1] - pos[1];<br />   z = lightpos[2] - pos[2];</span></p> <p><span style="font-size:small;">  //光源の方向ベクトル<br />   s = sqrt(x * x + y * y + z * z);<br />   ex = x / s;<br />   ey = y / s;<br />   ez = z / s;</span></p> <p><span style="font-size:small;">  //shadow matrix<br />   mat[0] = ey;<br />   mat[1] = 0.0f;<br />   mat[2] = 0.0f;<br />   mat[3] = 0.0f;<br />   mat[4] = -ex;<br />   mat[5] = 0.0f;<br />   mat[6] = -ez;<br />   mat[7] = 0.0f;<br />   mat[8] = 0.0f;<br />   mat[9] = 0.0f;<br />   mat[10] = ey;<br />   mat[11] = 0.0f;<br />   mat[12] = 0.0f;<br />   mat[13] = 0.001f * ey;<br />   mat[14] = 0.0f;<br />   mat[15] = ey;<br /> }</span></p> <p><span style="font-size:small;">void drawShadow()<br /> {<br />   float mat[16];</span></p> <p><span style="font-size:small;">  glEnable(GL_BLEND);<br />   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);</span></p> <p><span style="font-size:small;">  glDepthMask(GL_FALSE);<br />   CalcShadowMat( mat);<br />   glPushMatrix();<br />   glMultMatrixf(mat);<br />   draw(true);<br />   glPopMatrix();</span></p> <p><span style="font-size:small;">  glDepthMask(GL_TRUE);<br />   glDisable(GL_BLEND);<br /> }</span></p> <p><span style="font-size:small;">void setLight()<br /> {<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);</span></p> <p><span style="font-size:small;"><br />   constAtt = 0.0f; linearAtt = 0.0f;<br />   quadraAtt = 1.0f / (lightpos[1] * lightpos[1]);</span></p> <p><span style="font-size:small;">  glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, constAtt);<br />   glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, linearAtt);<br />   glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, quadraAtt);</span></p> <p><span style="font-size:small;">  glEnable(GL_LIGHT0);<br />   glEnable(GL_LIGHTING);<br /> }</span></p> <p><span style="font-size:small;">void drawLight(void)<br /> {<br />  glDisable(GL_LIGHTING);<br />  glColor3f(0.8f, 0.8f, 0.0f);<br />  glPushMatrix();<br />  glTranslatef(lightpos[0], lightpos[1], lightpos[2]);<br />  glutSolidSphere(0.1f, 10, 10);<br />  glPopMatrix();<br />  glEnable(GL_LIGHTING);<br /> }</span></p> <p><span style="font-size:small;">void display(void)<br /> {<br />  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />  glViewport(0, 0, WIDTH, HEIGHT);<br />  glMatrixMode(GL_PROJECTION);<br />  glLoadIdentity();<br />  //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)<br />  gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);<br />  glMatrixMode(GL_MODELVIEW);<br />  glLoadIdentity();<br />  //視点の設定<br />  gluLookAt(10.0,10.0,-2.0, //カメラの座標<br />        0.0,0.0,0.0, // 注視点の座標<br />       0.0,1.0,0.0); // 画面の上方向を指すベクトル</span></p> <p><span style="font-size:small;">  //ライトの設定<br />   setLight();<br />   drawLight();</span></p> <p><span style="font-size:small;">  glsl.ON();</span></p> <p><span style="font-size:small;">  draw(false);<br />   drawFloor(10.0, 10.0, 10, 10);</span></p> <p><span style="font-size:small;">  drawShadow();<br />   glsl.OFF();  glutSwapBuffers();<br /> }<br /> void idle(void)<br /> {<br />  anglex+=0.02f;<br />  glutPostRedisplay();<br /> }<br /> void Init(){<br />  glsl.InitGLSL("vertex.shader","flagment.shader");<br />  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);<br />  glEnable(GL_DEPTH_TEST);<br />  glEnable(GL_LIGHTING);<br />  glEnable(GL_LIGHT0);<br />  glEnable(GL_NORMALIZE);<br /> }<br /> int main(int argc, char *argv[])<br /> {<br />   glutInitWindowPosition(100, 100);<br />   glutInitWindowSize(WIDTH, HEIGHT);<br />   glutInit(&amp;argc, argv);<br />   glutCreateWindow("距離減衰");<br />   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />   glutDisplayFunc(display);<br />   glutIdleFunc(idle);<br />   Init();<br />   glutMainLoop();<br />   return 0;<br /> }</span></p> </td> </tr></tbody></table><p> </p> <p> </p> <p> </p> <p> </p> <p> </p>
<p><strong>距離による光の減衰です。</strong></p> <p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&amp;act=open&amp;pageid=183&amp;file=att.png" /></p> <p>vertex.shader</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td><span style="font-size:small;"> //フラグメントシェーダーに渡す変数<br />  varying vec3 P;//位置ベクトル<br />  varying vec3 N;//法線ベクトル<br />  <br /> void main(void)<br />  {<br />    P = vec3(gl_ModelViewMatrix * gl_Vertex);<br />    N = normalize(gl_NormalMatrix * gl_Normal);<br />    gl_Position = ftransform();<br />  }</span></td> </tr></tbody></table><p>flagment.shader</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td> <p> <span style="font-size:small;">//頂点シェーダーから受け取る変数<br />  varying vec3 P;//位置ベクトル<br />  varying vec3 N;//法線ベクトル<br />  <br /> void main(void)<br />  {<br />  vec3 L = gl_LightSource[0].position.xyz - P;<br />  float d = length(L);//光源までの距離<br />  //減衰計数<br />  float attenuation = 1.0 / (gl_LightSource[0].constantAttenuation<br />                      + gl_LightSource[0].linearAttenuation * d<br />                      + gl_LightSource[0].quadraticAttenuation * d * d );<br />  L = normalize(L);<br />  N = normalize(N);</span></p> <p><span style="font-size:small;"> <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 />   //統合<br />   gl_FragColor = ambient + diffuse + specular;<br />   //減衰率を乗じる<br />   gl_FragColor *= attenuation;<br />  }</span></p> </td> </tr></tbody></table><p>GLSL.h</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td> <p>#pragma once<br />  #include &lt;stdio.h&gt;<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(&amp;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 **)&amp;buf, &amp;size);<br />     free(buf);<br />     fclose(fp);<br />  <br />     glCompileShader(Shader);<br />     glGetShaderiv( Shader, GL_COMPILE_STATUS, &amp;compiled );<br />  <br />    if ( compiled == GL_FALSE )<br />     {<br />      printf( "コンパイルできませんでした!!: %s \n ", File);<br />      glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, &amp;size );<br />      if ( size &gt; 0 )<br />      {<br />       buf = (char *)malloc(size);<br />       glGetShaderInfoLog( Shader, size, &amp;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, &amp;linked );<br />  <br />    if ( linked == GL_FALSE ){<br />     printf("リンクできませんでした!! \n");<br />     <br />     glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, &amp;size );<br />     if ( size &gt; 0 ){<br />      infoLog = (char *)malloc(size);<br />      glGetProgramInfoLog( Prog, size, &amp;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 />  </p> <p> </p> </td> </tr></tbody></table><p>main.cpp</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td> <p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br /> #pragma comment(lib, "glew32.lib")<br />  <br /> #include &lt;GL/glew.h&gt;<br /> #include &lt;GL/freeglut/freeglut.h&gt;<br /> #include "GLSL.h"<br /> #include &lt;math.h&gt;</p> <p>#define PAI 3.141592f</p> <p>#define WIDTH 640<br /> #define HEIGHT 480</p> <p>GLSL glsl;<br />  <br /> //回転用<br /> float anglex = 0.0f;<br /> //ライトの位置<br /> GLfloat lightpos[] = { 0.0, 4.0, 0.0, 1.0 };<br />  <br /> float Ambient[] = {0.2f, 0.1f, 0.2f, 1.0f};<br /> float Diffuse[] = {0.8f, 0.0f, 0.0f, 1.0f};<br /> float Specular[]= { 0.4f, 0.4f, 0.4f, 1.0f};//鏡面反射</p> <p>float AmbientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f};<br /> float DiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f};<br /> float SpecularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};//鏡面光</p> <p>float pos[] = {-0.7f, 2.0f, 0.0f};//位置</p> <p>float constAtt = 1.0;<br /> float linearAtt = 0.0;<br /> float quadraAtt = 0.0;</p> <p>//影のマテリアル<br /> float shadowDiffuse[] =  {0.0f,0.0f,0.0f,0.3f};//影の拡散光<br /> float shadowSpecular[] = {0.0f,0.0f,0.0f,1.0f};//影の鏡面光</p> <p>void draw(bool flag){<br />  if(flag) {<br />    glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse);<br />    glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular);<br />   }else{ <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,8);<br />   }<br />   glPushMatrix();<br />   glTranslatef(pos[0], pos[1], pos[2]);<br />   glRotatef( anglex, 1.0f, 0.0f, 0.0f);//x軸回転<br />   glutSolidCube(1.0);<br />   glPopMatrix();<br /> }</p> <p>void drawFloor(float widthX, float widthZ, int nx, int nz){<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.9f, 0.9f, 0.9f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f} };<br />   float ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f};<br />   float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};</p> <p>  glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />   glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />   glMaterialf(GL_FRONT,GL_SHININESS,10);</p> <p>  glNormal3d(0.0, 1.0, 0.0);<br />   glPushMatrix();<br />   for (j = 0; j &lt; nz; j++) {<br />     float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ;<br />     for (i = 0; i &lt; nx; i++) {<br />       float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX;</p> <p>      glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) &amp; 1]);<br />    glBegin(GL_QUADS);<br />       glVertex3d(x1, 0.0, z1);<br />       glVertex3d(x1, 0.0, z2);<br />       glVertex3d(x2, 0.0, z2);<br />       glVertex3d(x2, 0.0, z1);<br />    glEnd();<br />     }<br />   }<br />   glPopMatrix();<br /> }</p> <p>void CalcShadowMat(float* mat){<br />   float ex, ey, ez;//光源の方向<br />   float s; //object中心から光源までの距離<br />   float x, y, z;<br />   x = lightpos[0] - pos[0];<br />   y = lightpos[1] - pos[1];<br />   z = lightpos[2] - pos[2];<br />   //光源の方向ベクトル<br />   s = sqrt(x * x + y * y + z * z);<br />   ex = x / s;<br />   ey = y / s;<br />   ez = z / s;<br />   //shadow matrix<br />   mat[0] = ey;<br />   mat[1] = 0.0f;<br />   mat[2] = 0.0f;<br />   mat[3] = 0.0f;<br />   mat[4] = -ex;<br />   mat[5] = 0.0f;<br />   mat[6] = -ez;<br />   mat[7] = 0.0f;<br />   mat[8] = 0.0f;<br />   mat[9] = 0.0f;<br />   mat[10] = ey;<br />   mat[11] = 0.0f;<br />   mat[12] = 0.0f;<br />   mat[13] = 0.001f * ey;<br />   mat[14] = 0.0f;<br />   mat[15] = ey;<br /> }</p> <p>void drawShadow(){<br />   float mat[16];<br />   glEnable(GL_BLEND);<br />   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);<br />   glDepthMask(GL_FALSE);<br />   CalcShadowMat( mat);<br />   glPushMatrix();<br />   glMultMatrixf(mat);<br />   draw(true);<br />   glPopMatrix();<br />   glDepthMask(GL_TRUE);<br />   glDisable(GL_BLEND);<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 />   constAtt = 0.0f; linearAtt = 0.0f;<br />   quadraAtt = 1.0f / (lightpos[1] * lightpos[1]);<br />   glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, constAtt);<br />   glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, linearAtt);<br />   glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, quadraAtt);<br />   glEnable(GL_LIGHT0);<br />   glEnable(GL_LIGHTING);<br /> }</p> <p>void drawLight(void){<br />  glDisable(GL_LIGHTING);<br />  glColor3f(0.8f, 0.8f, 0.0f);<br />  glPushMatrix();<br />  glTranslatef(lightpos[0], lightpos[1], lightpos[2]);<br />  glutSolidSphere(0.1f, 10, 10);<br />  glPopMatrix();<br />  glEnable(GL_LIGHTING);<br /> }</p> <p>void display(void){<br />  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />  glViewport(0, 0, WIDTH, HEIGHT);<br />  glMatrixMode(GL_PROJECTION);<br />  glLoadIdentity();<br />  //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)<br />  gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);<br />  glMatrixMode(GL_MODELVIEW);<br />  glLoadIdentity();<br />  //視点の設定<br />  gluLookAt(10.0,10.0,-2.0, //カメラの座標<br />        0.0,0.0,0.0, // 注視点の座標<br />       0.0,1.0,0.0); // 画面の上方向を指すベクトル<br />   //ライトの設定<br />   setLight();<br />   drawLight();<br />   glsl.ON();<br />   draw(false);<br />   drawFloor(10.0, 10.0, 10, 10);<br />   drawShadow();<br />   glsl.OFF();  glutSwapBuffers();<br /> }<br /> void idle(void){<br />  anglex+=2.0f;<br />  Sleep(1);<br />  glutPostRedisplay();<br /> }<br /> void Init(){<br />  glsl.InitGLSL("vertex.shader","flagment.shader");<br />  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);<br />  glEnable(GL_DEPTH_TEST);<br />  glEnable(GL_LIGHTING);<br />  glEnable(GL_LIGHT0);<br />  glEnable(GL_NORMALIZE);<br /> }<br /> void main(int argc, char *argv[]){<br />   glutInitWindowPosition(100, 100);<br />   glutInitWindowSize(WIDTH, HEIGHT);<br />   glutInit(&amp;argc, argv);<br />   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />   glutCreateWindow("距離減衰");<br />   glutDisplayFunc(display);<br />   glutIdleFunc(idle);<br />   Init();<br />   glutMainLoop();<br />   return;<br /> }</p> </td> </tr></tbody></table><p> </p> <p> </p> <p> </p> <p> </p> <p> </p>

表示オプション

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