GLSL:テクスチャマッピング

「GLSL:テクスチャマッピング」の編集履歴(バックアップ)一覧はこちら

GLSL:テクスチャマッピング」(2014/05/01 (木) 18:31:56) の最新版変更点

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

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

<p><strong>GLSLでテクスチャを描画します。</strong></p> <p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=188&amp;file=tex.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).xyz;<br />     gl_TexCoord[0] = gl_MultiTexCoord0;<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><span style="font-size:small;">  //頂点シェーダーから受け取る変数<br />   varying vec3 P;//位置ベクトル<br />   varying vec3 N;//法線ベクトル<br />   uniform sampler2D sampler;<br />  <br />  void main(void)<br />   {<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);//max(0.0, 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 />    vec4 texColor = texture2D(sampler, gl_TexCoord[0].st);<br />    //GL_MODULATEモード<br />    gl_FragColor = (ambient + diffuse) * texColor + specular;<br />    }</span></td> </tr></tbody></table><p>GLSL.h</p> <table width="600" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td><span style="font-size:small;"> #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 />  }</span><br />  </td> </tr></tbody></table><p>PNG.h</p> <table width="600" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td><span style="font-size:small;"> #pragma once<br />  #include "lodepng.h"<br />  <br /> //テクスチャクラス<br />  class TEXTURE{<br />  protected:<br />   LodePNG_Decoder decoder;//デコーダ<br />   unsigned char* buffer;//バッファ<br />   size_t buffersize, imagesize;//サイズ<br />  public:<br />   TEXTURE();<br />   TEXTURE(const char* FileName);//コンストラクタ<br />   void LOAD_PNG(const char* FileName);//PNG読み込み<br />   unsigned char* image;//イメージポインタ<br />   unsigned int Width,Height;//画像サイズ<br />  };<br />  TEXTURE::TEXTURE(){<br />  }<br />  TEXTURE::TEXTURE(const char* FileName){<br />   LOAD_PNG(FileName);<br />  }<br />  void TEXTURE::LOAD_PNG(const char* FileName){<br />   LodePNG_Decoder_init(&amp;decoder);<br />   //ロード<br />   LodePNG_loadFile(&amp;buffer, &amp;buffersize, FileName);<br />   //デコード<br />   LodePNG_decode(&amp;decoder, &amp;image, &amp;imagesize, buffer, buffersize);<br />   //幅,高さ<br />   Width = decoder.infoPng.width;Height = decoder.infoPng.height;<br />  }</span></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;<br /> #include "PNG.h"<br />  <br /> #define PAI 3.141592f<br />  <br /> #define WIDTH 640<br />  #define HEIGHT 480<br />  <br /> GLSL glsl;<br />  <br />  //回転用<br />  float anglex = 0.0f;<br />  //ライトの位置<br />  GLfloat lightpos[] = { 10.0f, 15.0f, 0.0f, 1.0f };<br />  <br />  float Ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};<br />  float Diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};<br />  float Specular[]= { 0.4f, 0.4f, 0.4f, 1.0f};//鏡面反射<br />  <br /> float AmbientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f};<br />  float DiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f};<br />  float SpecularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};//鏡面光<br />  <br /> float lightDiffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; //拡散光<br />  float lightSpecular[4] = {1.0f, 1.0f, 1.0f, 1.0f}; //鏡面光<br />  float pos[] = {0.0f, 2.0f, 0.0f};//位置<br />  bool flag = true;<br />  <br />  <br /> //影のマテリアル<br />  float shadowDiffuse[] =  {0.0f,0.0f,0.0f,0.3f};//影の拡散光<br />  float shadowSpecular[] = {0.0f,0.0f,0.0f,1.0f};//影の鏡面光<br />  GLuint texID;<br /> TEXTURE *texture;</span></p> <p><span style="font-size:small;"><br /> void drawTexPlate(float size, int nRepeatS, int nRepeatT)//x-y平面<br /> {<br />  float sz = 0.5f * size;<br />  static float p[4][3] = //z:上方向<br />  {<br />   { sz,-sz, 0.0}, { sz, sz, 0.0},<br />   {-sz, sz, 0.0}, {-sz,-sz, 0.0}<br />  };</span></p> <p><span style="font-size:small;"> float s = (float)nRepeatS;<br />  float t = (float)nRepeatT;<br />  glEnable(GL_TEXTURE_2D);<br />  glBegin(GL_QUADS);<br />   glNormal3f(0.0, 0.0, 1.0); //z方向の法線<br />   //テクスチャー座標と頂点番号との対応付け<br />   glTexCoord2f(0.0, 0.0); glVertex3fv(p[3]);<br />   glTexCoord2f( s , 0.0); glVertex3fv(p[0]);<br />   glTexCoord2f( s ,  t ); glVertex3fv(p[1]);<br />   glTexCoord2f(0.0,  t ); glVertex3fv(p[2]);<br />  glEnd();<br />  glDisable(GL_TEXTURE_2D);<br /> }</span></p> <p><span style="font-size:small;">void draw(bool flag){</span></p> <p><span style="font-size:small;"> if(flag)<br />   {<br />    glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,shadowDiffuse);<br />    glMaterialfv(GL_FRONT,GL_SPECULAR,shadowSpecular);<br />   }<br />   else<br />   { <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 />   }</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 />   //オブジェクト形状<br />   if(!flag)<br />   {<br />    drawTexPlate(2.0f,1,1);<br />   }<br />   else<br />   {<br />    drawTexPlate(2.0f,1,1);<br />   }<br />   glPopMatrix();<br />  }<br />  <br /> 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;<br />  <br />   float diffuse[][4] = {<br />   { 0.9f, 0.9f, 0.9f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f} };<br />    float ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f};<br />    float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};<br />  <br />   glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />    glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />    glMaterialf(GL_FRONT,GL_SHININESS,100);<br />  <br />   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;<br />  <br />       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 />  }<br />  </span></p> <p><span style="font-size:small;">void CalcShadowMat(float* mat)<br />  {<br />    float ex, ey, ez;//光源の方向<br />    float s; //object中心から光源までの距離<br />    float x, y, z;<br />  <br />   x = lightpos[0] - pos[0];<br />    y = lightpos[1] - pos[1];<br />    z = lightpos[2] - pos[2];<br />  <br />   //光源の方向ベクトル<br />    s = sqrt(x * x + y * y + z * z);<br />    ex = x / s;<br />    ey = y / s;<br />    ez = z / s;<br />  <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 />  }<br />  <br /> void drawShadow()<br />  {<br />    float mat[16];<br />  <br />   glEnable(GL_BLEND);<br />    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);<br />  <br />   glDepthMask(GL_FALSE);<br />    CalcShadowMat( mat);<br />    glPushMatrix();<br />    glMultMatrixf(mat);<br />    draw(true);<br />    glPopMatrix();<br />  <br />   glDepthMask(GL_TRUE);<br />    glDisable(GL_BLEND);<br />  }<br />  <br /> void setLight()<br />  {</span></p> <p><span style="font-size:small;">   glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);<br />    glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);<br />    glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight);<br />    glLightfv(GL_LIGHT0, GL_POSITION, lightpos);<br />  <br />   glEnable(GL_LIGHT0);<br />    glEnable(GL_LIGHTING);<br />  }</span></p> <p><span style="font-size:small;"><br />  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(0.0,10.0,-10.0, //カメラの座標<br />         0.0,0.0,0.0, // 注視点の座標<br />        0.0,1.0,0.0); // 画面の上方向を指すベクトル<br />  <br />   //ライトの設定<br />    setLight();<br />  <br />      glActiveTexture(GL_TEXTURE1);<br />   glBindTexture(GL_TEXTURE_2D, texID);<br />   glsl.ON();<br />   GLint samplerLoc = glGetUniformLocation(glsl.ShaderProg, "sampler");<br />   glUniform1i(samplerLoc, 1);//GL_TEXTURE1を適用</span></p> <p><span style="font-size:small;">   draw(false);<br />  <br />    glsl.OFF();<br />    drawFloor(10.0, 10.0, 10, 10);<br />  <br />   drawShadow();<br />  <br />   glutSwapBuffers();<br />  }<br />  void idle(void)<br />  {<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_NORMALIZE);<br />    //テクスチャー<br />   glGenTextures(1, &amp;texID);//テクスチャオブジェクトの名前付け<br />   texture = new TEXTURE("tip.png");</span></p> <p><span style="font-size:small;">  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);<br />    //テクスチャオブジェクトの作成<br />   glBindTexture(GL_TEXTURE_2D, texID);<br />   //テクスチャの指定<br />   glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,texture-&gt;Width,texture-&gt;Height,0,GL_RGBA,GL_UNSIGNED_BYTE,texture-&gt;image);<br />   //テクスチャの繰り返し方法の指定<br />   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);//GL_CLAMP);<br />   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);//GL_CLAMP);<br />   //テクスチャを拡大・縮小する方法の指定<br />   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//NEAREST);<br />   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//NEAREST);<br />   glBindTexture(GL_TEXTURE_2D, 0);<br />  }</span></p> <p><span style="font-size:small;"> //タイマー<br />  void timer(int value){<br />   anglex+=1.0f;<br />   glutTimerFunc(100 , timer , 0);<br />  }</span></p> <p><span style="font-size:small;"> int main(int argc, char *argv[])<br />  {<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 />    glutTimerFunc(100 , timer , 0);<br />    Init();<br />    glutMainLoop();<br />    return 0;<br />  }<br /></span></p> </td> </tr></tbody></table><p> </p> <p> </p> <p> </p> <p> </p> <p> </p>
<p><strong>GLSLでテクスチャを描画します。</strong></p> <p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&amp;act=open&amp;pageid=188&amp;file=tex.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).xyz;<br />     gl_TexCoord[0] = gl_MultiTexCoord0;<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><span style="font-size:small;">  //頂点シェーダーから受け取る変数<br />   varying vec3 P;//位置ベクトル<br />   varying vec3 N;//法線ベクトル<br />   uniform sampler2D sampler;<br />  <br />  void main(void)<br />   {<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);//max(0.0, 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 />    vec4 texColor = texture2D(sampler, gl_TexCoord[0].st);<br />    //GL_MODULATEモード<br />    gl_FragColor = (ambient + diffuse) * texColor + specular;<br />    }</span></td> </tr></tbody></table><p>GLSL.h</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>#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 />  <br /></td> </tr></tbody></table><p>PNG.h</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td><span style="font-size:small;"> #pragma once<br />  #include "lodepng.h"<br />  <br /> //テクスチャクラス<br />  class TEXTURE{<br />  protected:<br />   LodePNG_Decoder decoder;//デコーダ<br />   unsigned char* buffer;//バッファ<br />   size_t buffersize, imagesize;//サイズ<br />  public:<br />   TEXTURE();<br />   TEXTURE(const char* FileName);//コンストラクタ<br />   void LOAD_PNG(const char* FileName);//PNG読み込み<br />   unsigned char* image;//イメージポインタ<br />   unsigned int Width,Height;//画像サイズ<br />  };<br />  TEXTURE::TEXTURE(){<br />  }<br />  TEXTURE::TEXTURE(const char* FileName){<br />   LOAD_PNG(FileName);<br />  }<br />  void TEXTURE::LOAD_PNG(const char* FileName){<br />   LodePNG_Decoder_init(&amp;decoder);<br />   //ロード<br />   LodePNG_loadFile(&amp;buffer, &amp;buffersize, FileName);<br />   //デコード<br />   LodePNG_decode(&amp;decoder, &amp;image, &amp;imagesize, buffer, buffersize);<br />   //幅,高さ<br />   Width = decoder.infoPng.width;Height = decoder.infoPng.height;<br />  }</span></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;<br /> #include "PNG.h"<br />  <br /> #define PAI 3.141592f<br />  <br /> #define WIDTH 640<br /> #define HEIGHT 480<br />  <br /> GLSL glsl;<br />  <br /> //回転用<br /> float anglex = 0.0f;<br /> //ライトの位置<br /> GLfloat lightpos[] = { 10.0f, 15.0f, 0.0f, 1.0f };<br />  <br /> float Ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};<br /> float Diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};<br /> float Specular[]= { 0.4f, 0.4f, 0.4f, 1.0f};//鏡面反射<br />  <br /> float AmbientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f};<br /> float DiffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f};<br /> float SpecularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};//鏡面光<br />  <br /> float lightDiffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f}; //拡散光<br /> float lightSpecular[4] = {1.0f, 1.0f, 1.0f, 1.0f}; //鏡面光<br /> float pos[] = {0.0f, 2.0f, 0.0f};//位置<br /> bool flag = true;<br />  <br /> //影のマテリアル<br /> float shadowDiffuse[] =  {0.0f,0.0f,0.0f,0.3f};//影の拡散光<br /> float shadowSpecular[] = {0.0f,0.0f,0.0f,1.0f};//影の鏡面光<br /> GLuint texID;<br /> TEXTURE *texture;</p> <p>void drawTexPlate(float size, int nRepeatS, int nRepeatT){//x-y平面<br />  float sz = 0.5f * size;<br />  static float p[4][3] = {//z:上方向<br />   { sz,-sz, 0.0}, { sz, sz, 0.0},<br />   {-sz, sz, 0.0}, {-sz,-sz, 0.0}<br />  };<br />  float s = (float)nRepeatS;<br />  float t = (float)nRepeatT;<br />  glEnable(GL_TEXTURE_2D);<br />  glBegin(GL_QUADS);<br />  glNormal3f(0.0, 0.0, 1.0); //z方向の法線<br />  //テクスチャー座標と頂点番号との対応付け<br />  glTexCoord2f(0.0, 0.0); glVertex3fv(p[3]);<br />  glTexCoord2f( s , 0.0); glVertex3fv(p[0]);<br />  glTexCoord2f( s ,  t ); glVertex3fv(p[1]);<br />  glTexCoord2f(0.0,  t ); glVertex3fv(p[2]);<br />  glEnd();<br />  glDisable(GL_TEXTURE_2D);<br /> }</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,100);<br />   }<br />   glPushMatrix();<br />   glTranslatef(pos[0], pos[1], pos[2]);<br />   glRotatef( anglex, 1.0f, 0.0f, 0.0f);//x軸回転<br />   //オブジェクト形状<br />   if(!flag){<br />    drawTexPlate(2.0f,1,1);<br />   }else{<br />    drawTexPlate(2.0f,1,1);<br />   }<br />   glPopMatrix();<br />  }<br />  <br /> 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;<br />  <br />   float diffuse[][4] = {<br />   { 0.9f, 0.9f, 0.9f, 1.0f}, { 0.1f, 0.1f, 0.1f, 1.0f} };<br />    float ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f};<br />    float specular[]= { 0.5f, 0.5f, 0.5f, 1.0f};<br />  <br />   glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />    glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />    glMaterialf(GL_FRONT,GL_SHININESS,100);<br />  <br />   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;<br />  <br />       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 />  }<br />  <br /> 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 />  }<br />  <br /> void setLight(){<br />   glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);<br />   glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);<br />   glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight);<br />   glLightfv(GL_LIGHT0, GL_POSITION, lightpos);<br />   glEnable(GL_LIGHT0);<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(0.0,10.0,-10.0, //カメラの座標<br />         0.0,0.0,0.0, // 注視点の座標<br />        0.0,1.0,0.0); // 画面の上方向を指すベクトル<br />   //ライトの設定<br />   setLight();<br />   glActiveTexture(GL_TEXTURE1);<br />   glBindTexture(GL_TEXTURE_2D, texID);<br />   glsl.ON();<br />   GLint samplerLoc = glGetUniformLocation(glsl.ShaderProg, "sampler");<br />   glUniform1i(samplerLoc, 1);//GL_TEXTURE1を適用<br />   draw(false);<br />   glsl.OFF();<br />   drawFloor(10.0, 10.0, 10, 10);<br />   drawShadow();<br />   glutSwapBuffers();<br />  }</p> <p> void idle(void){<br />   glutPostRedisplay();<br />  }</p> <p> 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_NORMALIZE);<br />   //テクスチャー<br />   glGenTextures(1, &amp;texID);//テクスチャオブジェクトの名前付け<br />   texture = new TEXTURE("tip.png");</p> <p>  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);<br />   //テクスチャオブジェクトの作成<br />   glBindTexture(GL_TEXTURE_2D, texID);<br />   //テクスチャの指定<br />   glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,texture-&gt;Width,texture-&gt;Height,0,GL_RGBA,GL_UNSIGNED_BYTE,texture-&gt;image);<br />   //テクスチャの繰り返し方法の指定<br />   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);//GL_CLAMP);<br />   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);//GL_CLAMP);<br />   //テクスチャを拡大・縮小する方法の指定<br />   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//NEAREST);<br />   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//NEAREST);<br />   glBindTexture(GL_TEXTURE_2D, 0);<br />  }</p> <p> //タイマー<br />  void timer(int value){<br />   anglex+=1.0f;<br />   glutTimerFunc(100 , timer , 0);<br />  }</p> <p> 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 />    glutTimerFunc(100 , timer , 0);<br />    Init();<br />    glutMainLoop();<br />    return;<br />  }</p> </td> </tr></tbody></table><p> </p> <p> </p> <p> </p> <p> </p> <p> </p>

表示オプション

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