「GLSL:テクスチャマッピング」の編集履歴(バックアップ)一覧はこちら
「GLSL:テクスチャマッピング」(2014/05/01 (木) 18:31:56) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p><strong>GLSLでテクスチャを描画します。</strong></p>
<p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=188&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 <= 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 <stdio.h><br />
<br />
//GLSLクラス<br />
class GLSL{<br />
public:<br />
GLuint ShaderProg;<br />
GLuint VertexShader, FragmentShader;<br />
void ReadShaderCompile(GLuint Shader, const char *File);//shader
fileを読み込みコンパイルする<br />
void Link( GLuint Prog );//リンクする<br />
void InitGLSL(const char *VertexFile);//GLSLの初期化<br />
void InitGLSL(const char *VertexFile, const char
*FragmentFile);//GLSLの初期化<br />
void ON();//シェーダー描画に切り替え<br />
void OFF();//シェーダー解除<br />
~GLSL();<br />
};<br />
<br />
void GLSL::ReadShaderCompile(GLuint Shader, const char *File){<br />
FILE *fp;<br />
char *buf;<br />
GLsizei size, len;<br />
GLint compiled;<br />
<br />
fopen_s(&fp,File, "rb");<br />
if(!fp) printf("ファイルを開くことができません %s\n", File);<br />
<br />
fseek(fp, 0, SEEK_END);<br />
size = ftell(fp);<br />
<br />
buf = (GLchar *)malloc(size);<br />
if (buf == NULL) {<br />
printf("メモリが確保できませんでした \n");<br />
}<br />
<br />
fseek(fp, 0, SEEK_SET);<br />
fread(buf, 1, size, fp);<br />
glShaderSource(Shader, 1, (const GLchar **)&buf, &size);<br />
free(buf);<br />
fclose(fp);<br />
<br />
glCompileShader(Shader);<br />
glGetShaderiv( Shader, GL_COMPILE_STATUS, &compiled );<br />
<br />
if ( compiled == GL_FALSE )<br />
{<br />
printf( "コンパイルできませんでした!!: %s \n ", File);<br />
glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, &size );<br />
if ( size > 0 )<br />
{<br />
buf = (char *)malloc(size);<br />
glGetShaderInfoLog( Shader, size, &len, buf);<br />
printf(buf);<br />
free(buf);<br />
}<br />
}<br />
}<br />
<br />
void GLSL::Link( GLuint Prog ){<br />
GLsizei size, len;<br />
GLint linked;<br />
char *infoLog ;<br />
<br />
glLinkProgram( Prog );<br />
<br />
glGetProgramiv( Prog, GL_LINK_STATUS, &linked );<br />
<br />
if ( linked == GL_FALSE ){<br />
printf("リンクできませんでした!! \n");<br />
<br />
glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, &size );<br />
if ( size > 0 ){<br />
infoLog = (char *)malloc(size);<br />
glGetProgramInfoLog( Prog, size, &len, infoLog );<br />
printf(infoLog);<br />
free(infoLog);<br />
}<br />
}<br />
}<br />
<br />
void GLSL::InitGLSL(const char *VertexFile){<br />
GLenum err = glewInit();<br />
if (err != GLEW_OK)<br />
{<br />
printf("Error: %s\n", glewGetErrorString(err));<br />
}<br />
printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />
printf("GPU= %s \n", glGetString(GL_RENDERER));<br />
printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />
printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />
VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />
ReadShaderCompile(VertexShader, VertexFile);<br />
ShaderProg = glCreateProgram();<br />
glAttachShader(ShaderProg, VertexShader);<br />
glDeleteShader(VertexShader);<br />
Link(ShaderProg);<br />
}<br />
<br />
<br />
void GLSL::InitGLSL(const char *VertexFile, const char *FragmentFile){<br />
GLenum err = glewInit();<br />
if (err != GLEW_OK)<br />
{<br />
printf("Error: %s\n", glewGetErrorString(err));<br />
}<br />
printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />
printf("GPU= %s \n", glGetString(GL_RENDERER));<br />
printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />
printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />
<br />
VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);<br />
<br />
ReadShaderCompile(VertexShader, VertexFile);<br />
ReadShaderCompile(FragmentShader, FragmentFile);<br />
<br />
ShaderProg = glCreateProgram();<br />
<br />
glAttachShader(ShaderProg, VertexShader);<br />
glAttachShader(ShaderProg, FragmentShader);<br />
<br />
glDeleteShader(VertexShader);<br />
glDeleteShader(FragmentShader);<br />
Link(ShaderProg);<br />
}<br />
<br />
void GLSL::ON(){<br />
glUseProgram(ShaderProg);<br />
}<br />
<br />
void GLSL::OFF(){<br />
glUseProgram(0);<br />
}<br />
<br />
GLSL::~GLSL(){<br />
glDeleteProgram(ShaderProg);<br />
}</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(&decoder);<br />
//ロード<br />
LodePNG_loadFile(&buffer, &buffersize, FileName);<br />
//デコード<br />
LodePNG_decode(&decoder, &image, &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 <GL/glew.h><br />
#include <GL/freeglut/freeglut.h><br />
#include "GLSL.h"<br />
#include <math.h><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 < nz; j++) {<br />
float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ;<br />
for (i = 0; i < nx; i++) {<br />
float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX;<br />
<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) & 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, &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->Width,texture->Height,0,GL_RGBA,GL_UNSIGNED_BYTE,texture->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(&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&act=open&pageid=188&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 <= 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 <stdio.h><br />
<br />
//GLSLクラス<br />
class GLSL{<br />
public:<br />
GLuint ShaderProg;<br />
GLuint VertexShader, FragmentShader;<br />
void ReadShaderCompile(GLuint Shader, const char *File);//shader
fileを読み込みコンパイルする<br />
void Link( GLuint Prog );//リンクする<br />
void InitGLSL(const char *VertexFile);//GLSLの初期化<br />
void InitGLSL(const char *VertexFile, const char
*FragmentFile);//GLSLの初期化<br />
void ON();//シェーダー描画に切り替え<br />
void OFF();//シェーダー解除<br />
~GLSL();<br />
};<br />
<br />
void GLSL::ReadShaderCompile(GLuint Shader, const char *File){<br />
FILE *fp;<br />
char *buf;<br />
GLsizei size, len;<br />
GLint compiled;<br />
<br />
fopen_s(&fp,File, "rb");<br />
if(!fp) printf("ファイルを開くことができません %s\n", File);<br />
<br />
fseek(fp, 0, SEEK_END);<br />
size = ftell(fp);<br />
<br />
buf = (GLchar *)malloc(size);<br />
if (buf == NULL) {<br />
printf("メモリが確保できませんでした \n");<br />
}<br />
<br />
fseek(fp, 0, SEEK_SET);<br />
fread(buf, 1, size, fp);<br />
glShaderSource(Shader, 1, (const GLchar **)&buf, &size);<br />
free(buf);<br />
fclose(fp);<br />
<br />
glCompileShader(Shader);<br />
glGetShaderiv( Shader, GL_COMPILE_STATUS, &compiled );<br />
<br />
if ( compiled == GL_FALSE )<br />
{<br />
printf( "コンパイルできませんでした!!: %s \n ", File);<br />
glGetProgramiv( Shader, GL_INFO_LOG_LENGTH, &size );<br />
if ( size > 0 )<br />
{<br />
buf = (char *)malloc(size);<br />
glGetShaderInfoLog( Shader, size, &len, buf);<br />
printf(buf);<br />
free(buf);<br />
}<br />
}<br />
}<br />
<br />
void GLSL::Link( GLuint Prog ){<br />
GLsizei size, len;<br />
GLint linked;<br />
char *infoLog ;<br />
<br />
glLinkProgram( Prog );<br />
<br />
glGetProgramiv( Prog, GL_LINK_STATUS, &linked );<br />
<br />
if ( linked == GL_FALSE ){<br />
printf("リンクできませんでした!! \n");<br />
<br />
glGetProgramiv( Prog, GL_INFO_LOG_LENGTH, &size );<br />
if ( size > 0 ){<br />
infoLog = (char *)malloc(size);<br />
glGetProgramInfoLog( Prog, size, &len, infoLog );<br />
printf(infoLog);<br />
free(infoLog);<br />
}<br />
}<br />
}<br />
<br />
void GLSL::InitGLSL(const char *VertexFile){<br />
GLenum err = glewInit();<br />
if (err != GLEW_OK)<br />
{<br />
printf("Error: %s\n", glewGetErrorString(err));<br />
}<br />
printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />
printf("GPU= %s \n", glGetString(GL_RENDERER));<br />
printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />
printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />
VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />
ReadShaderCompile(VertexShader, VertexFile);<br />
ShaderProg = glCreateProgram();<br />
glAttachShader(ShaderProg, VertexShader);<br />
glDeleteShader(VertexShader);<br />
Link(ShaderProg);<br />
}<br />
<br />
<br />
void GLSL::InitGLSL(const char *VertexFile, const char *FragmentFile){<br />
GLenum err = glewInit();<br />
if (err != GLEW_OK)<br />
{<br />
printf("Error: %s\n", glewGetErrorString(err));<br />
}<br />
printf("VENDOR= %s \n", glGetString(GL_VENDOR));<br />
printf("GPU= %s \n", glGetString(GL_RENDERER));<br />
printf("OpenGL= %s \n", glGetString(GL_VERSION));<br />
printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));<br />
<br />
VertexShader = glCreateShader(GL_VERTEX_SHADER);<br />
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);<br />
<br />
ReadShaderCompile(VertexShader, VertexFile);<br />
ReadShaderCompile(FragmentShader, FragmentFile);<br />
<br />
ShaderProg = glCreateProgram();<br />
<br />
glAttachShader(ShaderProg, VertexShader);<br />
glAttachShader(ShaderProg, FragmentShader);<br />
<br />
glDeleteShader(VertexShader);<br />
glDeleteShader(FragmentShader);<br />
Link(ShaderProg);<br />
}<br />
<br />
void GLSL::ON(){<br />
glUseProgram(ShaderProg);<br />
}<br />
<br />
void GLSL::OFF(){<br />
glUseProgram(0);<br />
}<br />
<br />
GLSL::~GLSL(){<br />
glDeleteProgram(ShaderProg);<br />
}<br />
<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(&decoder);<br />
//ロード<br />
LodePNG_loadFile(&buffer, &buffersize, FileName);<br />
//デコード<br />
LodePNG_decode(&decoder, &image, &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 <GL/glew.h><br />
#include <GL/freeglut/freeglut.h><br />
#include "GLSL.h"<br />
#include <math.h><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 < nz; j++) {<br />
float z1 = -widthZ / 2.0f + wZ * j; float z2 = z1 + wZ;<br />
for (i = 0; i < nx; i++) {<br />
float x1 = -widthX / 2.0f + wX * i; float x2 = x1 + wX;<br />
<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse[(i + j) & 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, &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->Width,texture->Height,0,GL_RGBA,GL_UNSIGNED_BYTE,texture->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(&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>