「gluPerspectiveを置き換える」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
<p><strong>gluPerspectiveを置き換えてみます。<br />
gluPerspective(fovy, aspect, near, far) の作り出す行列は</strong></p>
<p><strong><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=130&file=pers.png" /></strong></p>
<p><strong>となっています。<br />
そして</strong></p>
<p><strong><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=130&file=cot.png" /></strong></p>
<p><strong>と定義されます。<br />
cotangent(余接、コタンジェント)は math.h にありませんので<br />
自作します。</strong></p>
<p><strong><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=130&file=per.png" /></strong></p>
<table border="1" cellspacing="1" cellpadding="1" width="600"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#include <GL/freeglut/freeglut.h><br />
#include <math.h></p>
<p>#define PI 3.1415926</p>
<p>#define WIDTH 320<br />
#define HEIGHT 240</p>
<p>//平行移動用<br />
float x = 0.0f;<br />
bool flag = false;<br />
//緑<br />
GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };<br />
//ライトの位置<br />
GLfloat lightpos[] = { 200.0, 150.0, -500.0, 1.0 };<br />
//単位行列<br />
GLfloat mat[]={<br />
1,0,0,0,<br />
0,1,0,0,<br />
0,0,1,0,<br />
0,0,0,1<br />
};<br />
//平行移動用<br />
GLfloat move[]={<br />
1,0,0,0,<br />
0,1,0,0,<br />
0,0,1,0,<br />
0,0,0,1<br />
};</p>
<p>GLfloat modelview[16];<br />
GLfloat multi[16];</p>
<p>//合成 glMultMatrixfの代わり<br />
void multiplication(GLfloat* src1,GLfloat* src2,GLfloat* dst)<br />
{<br />
for(int y=0;y<4;y++){<br />
for(int x=0;x<4;x++){<br />
dst[y*4+x]=src2[y*4]*src1[x]+src2[y*4+1]*src1[x+4]+src2[y*4+2]*src1[x+8]+src2[y*4+3]*src1[x+12];<br />
}<br />
}<br />
}</p>
<p>//gluPerspectiveと同じ<br />
void perspective(float fovy,float aspect,float znear,float zfar)<br />
{<br />
float radian=2*PI*fovy/360.0;<br />
float t = (float)(1.0 / tan(radian/2));<br />
GLfloat m[]={<br />
t / aspect,0,0,0,<br />
0,t,0,0,<br />
0,0,(zfar + znear) / (znear - zfar),-1,<br />
0,0,(2 * zfar * znear) / (znear - zfar),0<br />
};<br />
glLoadMatrixf(m);<br />
}</p>
<p>void display(void)<br />
{</p>
<p> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glViewport(0, 0, WIDTH, HEIGHT);<br />
glMatrixMode(GL_PROJECTION);</p>
<p> //glLoadIdentity();と同じ↓<br />
glLoadMatrixf(mat);</p>
<p> //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)<br />
//gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);と同じ↓<br />
perspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);<br />
glMatrixMode(GL_MODELVIEW);</p>
<p> //glLoadIdentity();と同じ↓<br />
glLoadMatrixf(mat);</p>
<p> //視点の設定<br />
gluLookAt(150.0,100.0,-200.0, //カメラの座標<br />
0.0,0.0,0.0, // 注視点の座標<br />
0.0,1.0,0.0); // 画面の上方向を指すベクトル<br />
//ライトの設定<br />
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);<br />
//マテリアルの設定<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, green);<br />
//平行移動<br />
//glTranslatef(x,0.0f,0.0f);と同じ↓<br />
move[12]=x; //X軸の平行移動成分を設定<br />
//glMultMatrixf(move);と同じ↓<br />
glGetFloatv(GL_MODELVIEW_MATRIX,modelview);<br />
multiplication(modelview,move,multi);<br />
glLoadMatrixf(multi);</p>
<p> glutSolidSphere(40.0,16,16);</p>
<p> glutSwapBuffers();<br />
}<br />
void idle(void)<br />
{<br />
if(flag){x-=0.05f;}else{x+=0.05f;}<br />
if(x>50.0f)flag=true;<br />
if(x<-50.0f)flag=false;<br />
glutPostRedisplay();<br />
}<br />
void Init(){<br />
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);<br />
glEnable(GL_DEPTH_TEST);<br />
glEnable(GL_LIGHTING);<br />
glEnable(GL_LIGHT0);<br />
}<br />
int main(int argc, char *argv[])<br />
{<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(WIDTH, HEIGHT);<br />
glutInit(&argc, argv);<br />
glutCreateWindow("gluPerspectiveを置き換える");<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
<p> </p>
</td>
</tr></tbody></table><p> </p>
<p><strong>gluPerspectiveを置き換えてみます。<br />
gluPerspective(fovy, aspect, near, far) の作り出す行列は</strong></p>
<p><strong><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=130&file=pers.png" /></strong></p>
<p><strong>となっています。<br />
そして</strong></p>
<p><strong><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=130&file=cot.png" /></strong></p>
<p><strong>と定義されます。<br />
cotangent(余接、コタンジェント)は math.h にありませんので<br />
自作します。</strong></p>
<p><strong><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=130&file=per.png" /></strong></p>
<table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#include <GL/freeglut/freeglut.h><br />
#include <math.h></p>
<p>#define PI 3.1415926</p>
<p>#define WIDTH 320<br />
#define HEIGHT 240</p>
<p>//平行移動用<br />
float x = 0.0f;<br />
bool flag = false;<br />
//緑<br />
GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };<br />
//ライトの位置<br />
GLfloat lightpos[] = { 200.0, 150.0, -500.0, 1.0 };<br />
//単位行列<br />
GLfloat mat[]={<br />
1,0,0,0,<br />
0,1,0,0,<br />
0,0,1,0,<br />
0,0,0,1<br />
};<br />
//平行移動用<br />
GLfloat move[]={<br />
1,0,0,0,<br />
0,1,0,0,<br />
0,0,1,0,<br />
0,0,0,1<br />
};</p>
<p>GLfloat modelview[16];<br />
GLfloat multi[16];</p>
<p>//合成 glMultMatrixfの代わり<br />
void multiplication(GLfloat* src1,GLfloat* src2,GLfloat* dst)<br />
{<br />
for(int y=0;y<4;y++){<br />
for(int x=0;x<4;x++){<br />
dst[y*4+x]=src2[y*4]*src1[x]+src2[y*4+1]*src1[x+4]+src2[y*4+2]*src1[x+8]+src2[y*4+3]*src1[x+12];<br />
}<br />
}<br />
}</p>
<p>//gluPerspectiveと同じ<br />
void perspective(float fovy,float aspect,float znear,float zfar)<br />
{<br />
float radian=2*PI*fovy/360.0;<br />
float t = (float)(1.0 / tan(radian/2));<br />
GLfloat m[]={<br />
t / aspect,0,0,0,<br />
0,t,0,0,<br />
0,0,(zfar + znear) / (znear - zfar),-1,<br />
0,0,(2 * zfar * znear) / (znear - zfar),0<br />
};<br />
glLoadMatrixf(m);<br />
}</p>
<p>void display(void)<br />
{</p>
<p> glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glViewport(0, 0, WIDTH, HEIGHT);<br />
glMatrixMode(GL_PROJECTION);</p>
<p> //glLoadIdentity();と同じ↓<br />
glLoadMatrixf(mat);</p>
<p> //視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)<br />
//gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);と同じ↓<br />
perspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 1000.0);<br />
glMatrixMode(GL_MODELVIEW);</p>
<p> //glLoadIdentity();と同じ↓<br />
glLoadMatrixf(mat);</p>
<p> //視点の設定<br />
gluLookAt(150.0,100.0,-200.0, //カメラの座標<br />
0.0,0.0,0.0, // 注視点の座標<br />
0.0,1.0,0.0); // 画面の上方向を指すベクトル<br />
//ライトの設定<br />
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);<br />
//マテリアルの設定<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, green);<br />
//平行移動<br />
//glTranslatef(x,0.0f,0.0f);と同じ↓<br />
move[12]=x; //X軸の平行移動成分を設定<br />
//glMultMatrixf(move);と同じ↓<br />
glGetFloatv(GL_MODELVIEW_MATRIX,modelview);<br />
multiplication(modelview,move,multi);<br />
glLoadMatrixf(multi);</p>
<p> glutSolidSphere(40.0,16,16);</p>
<p> glutSwapBuffers();<br />
}<br />
void idle(void)<br />
{<br />
if(flag){x-=1.0f;}else{x+=1.0f;}<br />
if(x>50.0f)flag=true;<br />
if(x<-50.0f)flag=false;<br />
Sleep(1);<br />
glutPostRedisplay();<br />
}<br />
void Init(){<br />
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);<br />
glEnable(GL_DEPTH_TEST);<br />
glEnable(GL_LIGHTING);<br />
glEnable(GL_LIGHT0);<br />
}<br />
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("gluPerspectiveを置き換える");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
</td>
</tr></tbody></table><p> </p>