「オフスクリーンレンダリング」の編集履歴(バックアップ)一覧はこちら
「オフスクリーンレンダリング」(2014/03/01 (土) 22:49:18) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p><strong>オフスクリーンレンダリングです。<br />
レースゲームのバックミラーの描画等で使われます。<br />
metasequiaに付属のviolin.mqoを.xに変換して使用しています。<br /><a href="http://cdn21.atwikiimg.com/opengl/pub/png/violin.x">violin.x</a>は<a href="http://cdn21.atwikiimg.com/opengl/pub/png/violin.x">ここ</a>からダウンロードして下さい。<br />
右クリックして名前を付けてリンク先を保存でダウンロードできます。</strong></p>
<p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=295&file=off.png" /></p>
<p>violin.png</p>
<p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=295&file=violin.png" /></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p><strong>オフスクリーンレンダリングです。<br />
レースゲームのバックミラーの描画等で使われます。<br />
metasequiaに付属のviolin.mqoを.xに変換して使用しています。<br /><a href="http://cdn21.atwikiimg.com/opengl/pub/png/violin.x">violin.x</a>は<a href="http://cdn21.atwikiimg.com/opengl/pub/png/violin.x">ここ</a>からダウンロードして下さい。<br />
右クリックして名前を付けてリンク先を保存でダウンロードできます。</strong></p>
<p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=295&file=off.png" /></p>
<p>violin.png</p>
<p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=295&file=violin.png" /></p>
<p> vertex.shader</p>
<table cellspacing="1" cellpadding="1" width="600" border="1"><tbody><tr><td>
<p>varying vec3 P;<br />
varying vec3 N;</p>
<p>void main(void)<br />
{<br />
P = vec3(gl_ModelViewMatrix * gl_Vertex);<br />
N = normalize(gl_NormalMatrix * gl_Normal).xyz;<br />
gl_TexCoord[0] = gl_MultiTexCoord0;<br />
gl_Position = ftransform();<br />
}<br />
</p>
</td>
</tr></tbody></table><p>flagment.shader</p>
<table cellspacing="1" cellpadding="1" width="600" border="1"><tbody><tr><td>
<p>varying vec3 P;<br />
varying vec3 N;<br />
uniform sampler2D sampler;</p>
<p>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 />
//任意の混合比<br />
// gl_FragColor = mix(ambient + diffuse, texColor, 0.5) + specular; <br />
}</p>
</td>
</tr></tbody></table><p>GLSL.h</p>
<table cellspacing="1" cellpadding="1" width="600" border="1"><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 cellspacing="1" cellpadding="1" width="600" border="1"><tbody><tr><td> #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 />
}<br />
</td>
</tr></tbody></table><p>xfile.h</p>
<table cellspacing="1" cellpadding="1" width="600" border="1"><tbody><tr><td>
<p>#include "PNG.h"</p>
<p>using namespace std;<br />
//3つのベクトル<br />
struct Vector3f{<br />
float x;<br />
float y;<br />
float z;<br />
}vec3d;<br />
Vector3f & operator*(Vector3f &v,float size){<br />
v.x *= size;<br />
v.y *= size;<br />
v.z *= size;<br />
return v;<br />
}<br />
//4つのベクトル<br />
struct Vector4f{<br />
float x;<br />
float y;<br />
float z;<br />
float w;<br />
}vec4d;<br />
//4つのカラー<br />
struct Color4{<br />
float r;<br />
float g;<br />
float b;<br />
float a;<br />
};<br />
//4つの反射<br />
struct Reflection4{<br />
Color4 diffuse;<br />
Color4 ambient;<br />
Color4 emission;<br />
Color4 specular;<br />
};<br />
//UV座標<br />
struct UV{<br />
float u;//u値<br />
float v;//v値<br />
}vec2d;<br />
//ポリゴンデータ<br />
struct Triangle{<br />
Vector3f TriVer;<br />
Vector3f TriNor;<br />
UV TriUV;<br />
}Tri;<br />
//ポリゴンデータ<br />
struct Quadrangle{<br />
Vector3f QuadVer;<br />
Vector3f QuadNor;<br />
UV QuadUV;<br />
}Quad;<br />
//マテリアル構造体<br />
struct MATERIAL{<br />
string MaterialName;//マテリアル名<br />
Reflection4 MaterialColor;//反射<br />
float Shininess;//shininess<br />
string TextureName;//テクスチャ名<br />
int TexNo;//テクスチャNO.<br />
vector <Triangle> Tridata;//三角面データ<br />
vector <Quadrangle> Quaddata;//四角面データ<br />
}mtl;<br />
//モデルクラス<br />
class MODEL{<br />
protected:<br />
vector <MATERIAL> Material;//マテリアル<br />
vector <TEXTURE*> TexData;//テクスチャデータ<br />
vector<GLuint> TexID;//テクスチャID<br />
GLuint TexID2;//代入用<br />
TEXTURE* tex;//代入用<br />
public:<br />
MODEL();<br />
MODEL(char* FileName,int size);//コンストラクタ<br />
bool XFILE_Load(char* FileName,int size);//ロード<br />
void Draw();<br />
};<br />
MODEL::MODEL(){<br />
}<br />
MODEL::MODEL(char* FileName,int size){<br />
XFILE_Load(FileName, size);<br />
}<br />
//描画<br />
void MODEL::Draw(){<br />
glEnableClientState(GL_VERTEX_ARRAY);<br />
glEnableClientState(GL_NORMAL_ARRAY);<br />
for(int i=0;i<(signed)Material.size();i++){<br />
glPushMatrix();<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,(const GLfloat
*)&Material[i].MaterialColor.ambient);<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,(const GLfloat
*)&Material[i].MaterialColor.diffuse);<br />
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,(const GLfloat
*)&Material[i].MaterialColor.specular);<br />
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,Material[i].Shininess);<br />
if(Material[i].TexNo>0){<br />
glEnableClientState(GL_TEXTURE_COORD_ARRAY);<br />
glEnable(GL_TEXTURE_2D);<br />
glBindTexture(GL_TEXTURE_2D, TexID[Material[i].TexNo-1]);<br />
}else{<br />
glDisable(GL_TEXTURE_2D);<br />
glDisableClientState(GL_TEXTURE_COORD_ARRAY);<br />
}<br />
if(Material[i].Tridata.size()>1){<br />
glVertexPointer(3, GL_FLOAT,sizeof(Tri) ,
&Material[i].Tridata[0].TriVer.x);<br />
glNormalPointer(GL_FLOAT,sizeof(Tri),&Material[i].Tridata[0].TriNor.x);<br />
if(Material[i].TexNo>0)glTexCoordPointer(2, GL_FLOAT, sizeof(Tri),
&Material[i].Tridata[0].TriUV.u);<br />
glDrawArrays(GL_TRIANGLES,0,Material[i].Tridata.size());<br />
}<br />
if(Material[i].Quaddata.size()>1){<br />
glVertexPointer(3, GL_FLOAT,sizeof(Quad) ,
&Material[i].Quaddata[0].QuadVer.x);<br />
glNormalPointer(GL_FLOAT,sizeof(Quad),&Material[i].Quaddata[0].QuadNor.x);<br />
if(Material[i].TexNo>0)glTexCoordPointer(2, GL_FLOAT, sizeof(Quad),
&Material[i].Quaddata[0].QuadUV.u);<br />
glDrawArrays(GL_QUADS,0,Material[i].Quaddata.size());<br />
}<br />
glPopMatrix();<br />
}<br />
glDisableClientState(GL_VERTEX_ARRAY);<br />
glDisableClientState(GL_NORMAL_ARRAY);<br />
glDisableClientState(GL_TEXTURE_COORD_ARRAY);<br />
glDisable(GL_TEXTURE_2D);<br />
}</p>
<p>//Xファイル読み込み<br />
bool MODEL::XFILE_Load(char* FileName,int size){<br />
vector <Vector3f> Vertex;//頂点<br />
vector <Vector3f> Normal;//法線<br />
vector <UV> uv;//UV<br />
vector <int> VertexIndex;<br />
vector <int> NormalIndex;<br />
vector <int> MaterialIndex;<br />
vector <int> FaceIndex;</p>
<p> char key[255];<br />
char buf[255];<br />
//Xファイルを開いて内容を読み込む<br />
FILE* fp=NULL;<br />
fopen_s(&fp,FileName,"rt");<br />
<br />
int v1=0,v2=0,v3=0,v4=0;<br />
int Count=0;<br />
bool flag=false;<br />
string str="";</p>
<p> //読み込み<br />
fseek(fp,SEEK_SET,0);<br />
while(!feof(fp))<br />
{<br />
//キーワード 読み込み<br />
ZeroMemory(key,sizeof(key));<br />
fscanf_s(fp,"%s ",key,sizeof(key));</p>
<p> //テンプレート読み飛ばし<br />
if(strcmp(key,"template")==0){<br />
while(strcmp(key,"}")){<br />
fscanf_s(fp,"%s ",key,sizeof(key));<br />
}<br />
continue;<br />
}</p>
<p> //マテリアル読み込み<br />
if(strcmp(key,"Material")==0)<br />
{<br />
if(flag)Material.push_back(mtl);<br />
flag=true;<br />
fgets(buf,sizeof(buf),fp);//直後の行にあると推定 改行する<br />
//ディフューズ<br />
fscanf_s(fp,"%f;%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z,&vec4d.w);<br />
mtl.MaterialColor.diffuse=(const Color4 &)vec4d;<br />
//SHININESS <br />
fscanf_s(fp,"%f;",&mtl.Shininess);<br />
//スペキュラー<br />
fscanf_s(fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);<br />
mtl.MaterialColor.specular=(const Color4 &)vec4d;<br />
//エミッシブ<br />
fscanf_s(fp,"%f;%f;%f;;",&vec4d.x,&vec4d.y,&vec4d.z);<br />
mtl.MaterialColor.ambient=(const Color4 &)vec4d;</p>
<p> //テクスチャー<br />
fscanf_s(fp,"%s ",key,sizeof(key));<br />
if(strcmp(key,"TextureFilename")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//直後の行にあると推定 改行する<br />
//map_Kd テクスチャー<br />
fscanf_s(fp,"%s",buf,255);<br />
mtl.TextureName=buf;<br />
str=mtl.TextureName;<br />
mtl.TextureName=str.substr(str.find_first_of('\"',0)+1,str.find_last_of('\"',255)-1);<br />
//テクスチャを作成<br />
TexData.push_back(tex);<br />
TexData[TexData.size()-1] = new TEXTURE(mtl.TextureName.c_str());;<br />
mtl.TexNo=TexData.size();<br />
TexID.push_back(TexID2);<br />
glGenTextures(1, (GLuint *)&TexID[TexData.size()-1]);<br />
glBindTexture(GL_TEXTURE_2D, TexID[TexData.size()-1]);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);<br />
<br />
glEnable(GL_TEXTURE_2D);<br />
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,TexData[TexData.size()-1]->Width,
TexData[TexData.size()-1]->Height,<br />
0,GL_RGBA, GL_UNSIGNED_BYTE, TexData[TexData.size()-1]->image);<br />
glDisable(GL_TEXTURE_2D);<br />
}<br />
}<br />
//頂点 読み込み<br />
if(strcmp(key,"Mesh")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;%f;,",&vec3d.x,&vec3d.y,&vec3d.z);<br />
Vertex.push_back(vec3d*(float)size);<br />
}<br />
//頂点インデックス読み込み <br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf); <br />
for(int i=0;i<Count ;i++)<br />
{<br />
int dammy=0;<br />
fgets(buf,sizeof(buf),fp);<br />
str=buf;<br />
string::size_type first = str.find_first_not_of(" ");<br />
string::size_type index = str.find("3;");<br />
if(index-first==0){<br />
sscanf_s(buf,"%d;%d,%d,%d;,",&dammy,&v1,&v2,&v3);<br />
VertexIndex.push_back(v1);<br />
VertexIndex.push_back(v2);<br />
VertexIndex.push_back(v3);<br />
}<br />
if((index==-1)||(index-first>1)){<br />
sscanf_s(buf,"%d;%d,%d,%d,%d;,",&dammy,&v1,&v2,&v3,&v4);<br />
VertexIndex.push_back(v1);<br />
VertexIndex.push_back(v2);<br />
VertexIndex.push_back(v3);<br />
VertexIndex.push_back(v4);<br />
}<br />
FaceIndex.push_back(dammy);<br />
}<br />
}</p>
<p> //法線 読み込み<br />
if(strcmp(key,"MeshNormals")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;%f;,",&vec3d.x,&vec3d.y,&vec3d.z);<br />
Normal.push_back(vec3d);<br />
}<br />
//法線インデックス読み込み <br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf); <br />
for(int i=0;i<Count ;i++)<br />
{<br />
int dammy=0;<br />
fgets(buf,sizeof(buf),fp);<br />
str=buf;<br />
string::size_type first = str.find_first_not_of(" ");<br />
string::size_type index = str.find("3;");<br />
if(index-first==0){<br />
sscanf_s(buf,"%d;%d,%d,%d;,",&dammy,&v1,&v2,&v3);<br />
NormalIndex.push_back(v1);<br />
NormalIndex.push_back(v2);<br />
NormalIndex.push_back(v3);<br />
}<br />
if((index==-1)||(index-first>1)){<br />
sscanf_s(buf,"%d;%d,%d,%d,%d;,",&dammy,&v1,&v2,&v3,&v4);<br />
NormalIndex.push_back(v1);<br />
NormalIndex.push_back(v2);<br />
NormalIndex.push_back(v3);<br />
NormalIndex.push_back(v4);<br />
}<br />
}<br />
}</p>
<p> //テクスチャー座標 読み込み<br />
if(strcmp(key,"MeshTextureCoords")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//データは2行下にあると推定 改行する<br />
fgets(buf,sizeof(buf),fp);<br />
while(strchr(buf,';')==NULL){fgets(buf,sizeof(buf),fp);}//空行対策<br />
Count=atoi(buf);<br />
for(int i=0;i<Count ;i++)<br />
{<br />
fscanf_s(fp,"%f;%f;,",&vec2d.u,&vec2d.v);<br />
uv.push_back(vec2d);<br />
} <br />
}<br />
//マテリアルリスト<br />
if(strcmp(key,"MeshMaterialList")==0)<br />
{<br />
fgets(buf,sizeof(buf),fp);//空改行<br />
fgets(buf,sizeof(buf),fp);//マテリアル数<br />
fgets(buf,sizeof(buf),fp);//リスト要素数<br />
Count=atoi(buf);<br />
for(int i=0;i<Count;i++)<br />
{<br />
fgets(buf,sizeof(buf),fp);<br />
int test=atoi(buf);<br />
MaterialIndex.push_back(test);<br />
}<br />
}<br />
}<br />
if(flag)Material.push_back(mtl);</p>
<p> fclose(fp);</p>
<p> Count=0;<br />
//マテリアル毎のデータを作成<br />
for(int i=0;i<(signed)MaterialIndex.size();i++){<br />
if(FaceIndex[i]==3){<br />
for(int j=0;j<3;j++){<br />
Tri.TriVer=Vertex[VertexIndex[Count+j]];<br />
Tri.TriNor=Normal[NormalIndex[Count+j]];<br />
Tri.TriUV=uv[VertexIndex[Count+j]];<br />
Material[MaterialIndex[i]].Tridata.push_back(Tri);<br />
}<br />
Count+=3;<br />
}else{<br />
for(int j=0;j<4;j++){<br />
Quad.QuadVer=Vertex[VertexIndex[Count+j]];<br />
Quad.QuadNor=Normal[NormalIndex[Count+j]];<br />
Quad.QuadUV=uv[VertexIndex[Count+j]];<br />
Material[MaterialIndex[i]].Quaddata.push_back(Quad);<br />
}<br />
Count+=4;<br />
}<br />
}</p>
<p> Vertex.clear();<br />
Normal.clear();<br />
uv.clear();<br />
VertexIndex.clear();<br />
NormalIndex.clear();<br />
MaterialIndex.clear();<br />
FaceIndex.clear();</p>
<p> return true;<br />
}<br />
</p>
</td>
</tr></tbody></table><p>main.cpp</p>
<table cellspacing="1" cellpadding="1" width="600" border="1"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#pragma comment(lib, "glew32.lib")</p>
<p>#include <windows.h><br />
#include <GL/glew.h><br />
#include "GLSL.h"<br />
#include <math.h><br />
#include <GL/freeglut/freeglut.h><br />
#include "xfile.h"</p>
<p>float pos[] = { 0.0, 1.0, 0.0};<br />
float scale[][3] = { 1.0, 1.0, 1.0 };<br />
float angle[][3] = { 0.0, 0.0, 0.0};</p>
<p>float lightPos[] = {-5.0, 5.0, 5.0, 1.0};<br />
float lightPosR[] = {5.0,-5.0, -5.0, 1.0};//光源位置(反射用)<br />
float shadowDiffuse[] = {0.0,0.0,0.0,0.3};<br />
float shadowSpecular[] = {0.0,0.0,0.0,1.0};</p>
<p>struct View{<br />
float pos[3];<br />
float cnt[3];<br />
float dist;<br />
float theta;<br />
float phi;<br />
float fovY;<br />
float nearZ;<br />
float farZ;<br />
};<br />
View view = {<br />
0.0, 0.0, 0.0,<br />
0.0, 1.0, 0.0,<br />
10.0, 30.0, 20.0,<br />
30.0, 1.0, 100.0<br />
};<br />
View view0 = view;</p>
<p><br />
GLSL glsl;<br />
TEXTURE *texture[2];<br />
MODEL* model;<br />
#define PAI 3.141592f<br />
int width = 640;<br />
int height = 480;</p>
<p>GLuint texName[2];<br />
int xStart, yStart;<br />
bool flagMouse = false;<br />
bool flagShadow = false;<br />
int objNo = 0;<br />
float ang = 0.0;<br />
float dang = 0.1;</p>
<p>#define TEX_WIDTH 512<br />
#define TEX_HEIGHT 512</p>
<p>void drawCube(float s){<br />
float p[8][3] = {<br />
{0.5*s,0.5*s,0.5*s}, {-0.5*s,0.5*s,0.5*s}, {-0.5*s,-0.5*s,0.5*s},<br />
{0.5*s,-0.5*s,0.5*s},{0.5*s,0.5*s,-0.5*s}, {-0.5*s,0.5*s,-0.5*s},<br />
{-0.5*s,-0.5*s,0-0.5*s}, {0.5*s,-0.5*s,-0.5*s}<br />
};</p>
<p> glBegin(GL_QUADS);<br />
glNormal3f(0.0f,0.0f,1.0f); //z方向<br />
glVertex3fv(p[0]); glVertex3fv(p[1]);<br />
glVertex3fv(p[2]); glVertex3fv(p[3]);<br />
glNormal3f(1.0f,0.0f,0.0f); //x方向(正面)<br />
glVertex3fv(p[0]); glVertex3fv(p[3]);<br />
glVertex3fv(p[7]); glVertex3fv(p[4]);<br />
glNormal3f(0.0f,1.0f,0.0f); //y方向<br />
glVertex3fv(p[0]); glVertex3fv(p[4]);<br />
glVertex3fv(p[5]); glVertex3fv(p[1]);<br />
glNormal3f(-1.0f,0.0f,0.0f); //-x方向<br />
glVertex3fv(p[1]); glVertex3fv(p[5]);<br />
glVertex3fv(p[6]); glVertex3fv(p[2]);<br />
glNormal3f(0.0f,-1.0f,0.0f); //-y方向<br />
glVertex3fv(p[2]); glVertex3fv(p[6]);<br />
glVertex3fv(p[7]); glVertex3fv(p[3]);<br />
glNormal3f(0.0f,0.0f,-1.0f); //-z方向<br />
glVertex3fv(p[4]); glVertex3fv(p[7]);<br />
glVertex3fv(p[6]); glVertex3fv(p[5]);<br />
glEnd();<br />
}</p>
<p>void drawTexCube(float size, int nRepeatS, int nRepeatT){<br />
float sz = 0.5 * size;<br />
float p[8][3] ={<br />
{ sz, sz, sz}, {-sz, sz, sz}, {-sz,-sz, sz},<br />
{ sz,-sz, sz}, { sz, sz,-sz}, {-sz, sz,-sz},<br />
{-sz,-sz,-sz}, { sz,-sz,-sz}<br />
};</p>
<p> float s = (float)nRepeatS;<br />
float t = (float)nRepeatT;</p>
<p> glEnable(GL_TEXTURE_2D);<br />
glBegin(GL_QUADS);<br />
//top(z軸が鉛直軸のときz方向)<br />
glNormal3f(0.0f,0.0f,1.0f);<br />
glTexCoord2f( s , 0.0); glVertex3fv(p[0]);<br />
glTexCoord2f( s , t ); glVertex3fv(p[1]);<br />
glTexCoord2f(0.0, t ); glVertex3fv(p[2]);<br />
glTexCoord2f(0.0, 0.0); glVertex3fv(p[3]);<br />
//x方向(正面)<br />
glNormal3f(1.0f,0.0f,0.0f);<br />
glTexCoord2f( s , t ); glVertex3fv(p[0]);<br />
glTexCoord2f(0.0, t ); glVertex3fv(p[3]);<br />
glTexCoord2f(0.0, 0.0); glVertex3fv(p[7]);<br />
glTexCoord2f( s , 0.0); glVertex3fv(p[4]);<br />
//y方向<br />
glNormal3f(0.0f,1.0f,0.0f);<br />
glTexCoord2f(0.0, t ); glVertex3fv(p[0]);<br />
glTexCoord2f(0.0, 0.0); glVertex3fv(p[4]);<br />
glTexCoord2f( s , 0.0); glVertex3fv(p[5]);<br />
glTexCoord2f( s , t ); glVertex3fv(p[1]);<br />
//-x方向<br />
glNormal3f(-1.0f,0.0f,0.0f);<br />
glTexCoord2f(0.0, t ); glVertex3fv(p[6]);<br />
glTexCoord2f(0.0, 0.0); glVertex3fv(p[2]);<br />
glTexCoord2f( s , 0.0); glVertex3fv(p[1]);<br />
glTexCoord2f( s , t ); glVertex3fv(p[5]);<br />
//-y方向<br />
glNormal3f(0.0f,-1.0f,0.0f);<br />
glTexCoord2f(0.0, t ); glVertex3fv(p[2]);<br />
glTexCoord2f(0.0, 0.0); glVertex3fv(p[6]);<br />
glTexCoord2f( s , 0.0); glVertex3fv(p[7]);<br />
glTexCoord2f( s , t ); glVertex3fv(p[3]);<br />
//-z方向<br />
glNormal3f(0.0f,0.0f,-1.0f);<br />
glTexCoord2f(0.0, 0.0); glVertex3fv(p[6]);<br />
glTexCoord2f( s , 0.0); glVertex3fv(p[5]);<br />
glTexCoord2f( s , t ); glVertex3fv(p[4]);<br />
glTexCoord2f(0.0, t ); glVertex3fv(p[7]);<br />
glEnd();<br />
glDisable(GL_TEXTURE_2D);<br />
}</p>
<p>void TexCreate(int NO,char* FileName){<br />
glGenTextures(1, &texName[NO]);<br />
texture[NO] = new TEXTURE(FileName);<br />
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);<br />
//テクスチャオブジェクトの作成<br />
glBindTexture(GL_TEXTURE_2D, texName[NO]);<br />
//テクスチャの指定<br />
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,texture[NO]->Width,texture[NO]->Height,0,GL_RGBA,GL_UNSIGNED_BYTE,texture[NO]->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 />
}<br />
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 />
}<br />
void setCamera(){<br />
float pp = PAI / 180.0f;<br />
view.pos[2] = view.cnt[2] + view.dist * cos(pp * view.theta) * cos(pp *
view.phi);//z<br />
view.pos[0] = view.cnt[0] + view.dist * cos(pp * view.theta) * sin(pp *
view.phi);//x<br />
view.pos[1] = view.cnt[1] + view.dist * sin(pp * view.theta);//y<br />
resize(width, height);</p>
<p>}<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);</p>
<p> glEnable(GL_LIGHT0);<br />
glEnable(GL_LIGHTING);<br />
}<br />
void Init(void){<br />
glsl.InitGLSL("vertex.shader","flagment.shader");<br />
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);<br />
setCamera();<br />
setLight();<br />
glEnable(GL_DEPTH_TEST);<br />
glEnable(GL_NORMALIZE);<br />
TexCreate(0,"marble.png");<br />
TexCreate(1,"marble.png");<br />
model = new MODEL("violin.x",2);<br />
}<br />
void idle(void){<br />
//再描画<br />
glutPostRedisplay();<br />
}</p>
<p>void drawFloor(float widthX, float widthZ){<br />
float diffuse[] = { 0.8, 0.8, 0.8, 1.0};<br />
float ambient[] = { 0.2, 0.2, 0.2, 1.0};<br />
float specular[]= { 0.5, 0.5, 0.5, 1.0};</p>
<p> glMaterialfv(GL_FRONT,GL_AMBIENT,ambient);<br />
glMaterialfv(GL_FRONT,GL_SPECULAR,specular);<br />
glMaterialf(GL_FRONT,GL_SHININESS,10);<br />
glEnable(GL_TEXTURE_2D);<br />
glNormal3d(0.0, 1.0, 0.0);<br />
glPushMatrix();<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);<br />
glBegin(GL_QUADS);<br />
glTexCoord2f(0.0, 0.0);glVertex3d(widthX, 0.0, widthZ);<br />
glTexCoord2f( 1.0 , 0.0);glVertex3d(widthX, 0.0, -widthZ);<br />
glTexCoord2f( 1.0 , 1.0 );glVertex3d(-widthX, 0.0, -widthZ);<br />
glTexCoord2f(0.0, 1.0 );glVertex3d(-widthX, 0.0, widthZ);<br />
glEnd();<br />
glPopMatrix();<br />
glDisable(GL_TEXTURE_2D);<br />
}<br />
void draw_obj(void){<br />
float ambient[] = { 0.3, 0.3, 0.3, 1.0};<br />
float diffuse[] = { 0.7, 0.7, 0.7, 1.0};<br />
float specular[]= { 0.5, 0.5, 0.5, 1.0};</p>
<p> if(flagShadow)<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 />
}</p>
<p> glPushMatrix();<br />
glTranslatef(pos[0], pos[1], pos[2]);<br />
glRotatef(angle[0][2], 0.0, 0.0, 1.0);//z軸回転<br />
glRotatef(angle[0][1]+ ang, 0.0, 1.0, 0.0);//y軸回転<br />
glRotatef(angle[0][0], 1.0, 0.0, 0.0);//x軸回転<br />
glScalef(scale[0][0], scale[0][1], scale[0][2]);<br />
//オブジェクト形状<br />
if(!flagShadow)<br />
{<br />
drawTexCube(1.5, 1, 1);<br />
}<br />
else<br />
{//影表示のときはTextureを付けない<br />
drawCube(1.5);<br />
}<br />
glPopMatrix();<br />
}<br />
void mouse(int button, int state, int x, int y){<br />
float pp = PAI / 180.0f;</p>
<p> if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){<br />
xStart = x; yStart = y;<br />
flagMouse = true;<br />
}else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){<br />
if(x > width/4 && x < 3*width/4 && y > height/4
&& y < 3*height/4){<br />
}else if(( x < width/4 || x > 3*width/4) && (y > height/4
&& y < 3*height/4)){<br />
if(x < width/4 ) view.phi -= 1.0;<br />
else view.phi += 1.0;<br />
view.cnt[2] = view.pos[2] - view.dist * cos(pp * view.phi) * cos(pp *
view.theta);<br />
view.cnt[0] = view.pos[0] - view.dist * sin(pp * view.phi) * cos(pp *
view.theta);<br />
}else if((x > width/4 && x < 3*width/4) && (y <
height/4 || y > 3*height/4)){<br />
if( y < height/4){<br />
view.theta += 1.0;<br />
}else{<br />
view.theta -= 1.0;<br />
}<br />
view.cnt[2] = view.pos[2] - view.dist * cos(pp * view.theta) * cos(pp *
view.phi);<br />
view.cnt[0] = view.pos[0] - view.dist * cos(pp * view.theta) * sin(pp *
view.phi);<br />
view.cnt[1] = view.pos[1] - view.dist * sin(pp * view.theta);<br />
}else if(x < width/8 && y > 7*height/8) view.fovY -=
1.0;//zoom in<br />
else if(x > 7*width/8 && y > 7*height/8) view.fovY +=
1.0;//zoom out<br />
}else flagMouse = false;<br />
if(state == GLUT_DOWN) setCamera();<br />
}</p>
<p>void motion(int x, int y){<br />
if(!flagMouse) return;<br />
if(cos(PAI * view.theta /180.0f) >= 0.0f){<br />
view.phi -= 0.5f * (float)(x - xStart) ;//tumble<br />
}else{<br />
view.phi += 0.5f * (float)(x - xStart) ;//tumble<br />
}<br />
view.theta += 0.5f * (float)(y - yStart) ;//crane</p>
<p> setCamera();<br />
xStart = x;<br />
yStart = y;<br />
}</p>
<p><br />
void CalcShadowMat(int ID, float* mat){<br />
float ex, ey, ez;//光源の方向<br />
float a, b, c, d;//床の面のパラメータ<br />
float s; //object中心から光源までの距離<br />
float x, y, z;</p>
<p> x = lightPos[0];<br />
y = lightPos[1];<br />
z = lightPos[2];</p>
<p> //光源の方向ベクトル<br />
s = sqrt(x * x + y * y + z * z);<br />
ex = x / s;<br />
ey = y / s;<br />
ez = z / s;</p>
<p> //フロアの方向ベクトル(y方向)<br />
a = 0.0f;<br />
b = 1.0f;<br />
c = 0.0f;<br />
d = -0.001f; //フロアと影の干渉を防ぐため<br />
mat[0] = b * ey + c * ez;<br />
mat[1] = -a * ey;<br />
mat[2] = -a * ez;<br />
mat[3] = 0.0f;<br />
mat[4] = -b * ex;<br />
mat[5] = a * ex + c * ez;<br />
mat[6] = -b * ez;<br />
mat[7] = 0.0f;<br />
mat[8] = -c * ex;<br />
mat[9] = -c * ey;<br />
mat[10] = a * ex + b * ey;<br />
mat[11] = 0.0f;<br />
mat[12] = -d * ex;<br />
mat[13] = -d * ey;<br />
mat[14] = -d * ez;<br />
mat[15] = a * ex + b * ey + c * ez;<br />
}</p>
<p>void drawShadow(int objNo){<br />
float mat[16];</p>
<p> flagShadow = true;<br />
glEnable(GL_BLEND);<br />
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);</p>
<p> glDepthMask(GL_FALSE);<br />
CalcShadowMat(objNo, mat);<br />
glPushMatrix();<br />
glMultMatrixf(mat);<br />
if(objNo == 0) draw_obj();</p>
<p> glDepthMask(GL_TRUE);<br />
glDisable(GL_BLEND);<br />
flagShadow = false;<br />
}</p>
<p>void display(void){<br />
//textureの作成<br />
glClearColor( 1.0, 1.0, 1.0, 1.0 );<br />
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );<br />
glViewport( 0, 0, TEX_WIDTH, TEX_HEIGHT );<br />
<br />
glMatrixMode( GL_PROJECTION );<br />
glLoadIdentity();<br />
gluPerspective(view.fovY, (double)TEX_WIDTH/(double)TEX_HEIGHT, view.nearZ,
view.farZ);<br />
glMatrixMode( GL_MODELVIEW );<br />
glLoadIdentity();<br />
if(cos(PAI * view.theta /180.0) >= 0.0)<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> glPushMatrix();<br />
glTranslatef(0.0, 1.0, 0.0);<br />
glRotatef(-90.0, 1.0, 0.0, 0.0);<br />
glRotatef(-90.0, 0.0, 0.0, 1.0);<br />
model->Draw();<br />
glPopMatrix();<br />
glBindTexture(GL_TEXTURE_2D, texName[1]);<br />
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TEX_WIDTH, TEX_HEIGHT);<br />
glBindTexture(GL_TEXTURE_2D, 0);</p>
<p> //通常のrendering<br />
resize(width, height);<br />
glClearColor(0.7, 0.7, 0.9, 1.0);<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glLoadIdentity();<br />
if(cos(PAI * view.theta /180.0) >= 0.0)<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> glLightfv(GL_LIGHT0, GL_POSITION, lightPos);</p>
<p> //描画<br />
glBindTexture(GL_TEXTURE_2D, texName[1]);<br />
glsl.ON();<br />
GLint samplerLoc = glGetUniformLocation(glsl.ShaderProg, "sampler");<br />
glUniform1i(samplerLoc, 0);//GL_TEXTURE0を適用<br />
draw_obj();<br />
glBindTexture(GL_TEXTURE_2D, texName[0]);<br />
drawFloor(10.0, 10.0);<br />
glsl.OFF();<br />
glBindTexture(GL_TEXTURE_2D, 0);</p>
<p> drawShadow(0);</p>
<p> glutSwapBuffers();<br />
}<br />
//タイマー<br />
void timer(int value){<br />
ang += dang;<br />
if(ang >= 360.0f)ang = 0.0f;<br />
glutTimerFunc(10 , timer , 0);<br />
}<br />
int main(int argc, char *argv[]){<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(TEX_WIDTH, TEX_HEIGHT);<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutCreateWindow("オフスクリーンレンダリング");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
glutMouseFunc(mouse);<br />
glutMotionFunc(motion);<br />
glutReshapeFunc(resize);<br />
glutTimerFunc(10 , timer , 0);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
<p> </p>
</td>
</tr></tbody></table><p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>