ビルボード

「ビルボード」の編集履歴(バックアップ)一覧はこちら

ビルボード」(2015/02/22 (日) 00:33:23) の最新版変更点

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

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

<p><strong>ビルボードです。<br /> ビルボードというのは常に視点(カメラ)を向く板の事です。<br /> 古くは樹木や球のポリゴン数を減らすために用いられました。<br /> 現在では火花や雪などのパーティクルとして主に使用されます。<br /> ビルボードにはビュー行列を逆行列にする方法もありますが、<br /> 今回はもっと簡単に実装できるやり方がありましたので紹介して<br /> おきます。<br /> 3D空間のビルボードオブジェクトの中心位置を保存しておき、<br /> glLoadIdentity(); して初期化します。<br /> 中心位置から画像サイズ分だけ+-してポリゴンを描画すると<br /> 行列計算なしでビルボードができます。</strong></p> <p> <img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=billboard.png" /></p> <table border="1" cellpadding="1" cellspacing="1" style="width:100px;"><tbody><tr><td>ファイル</td> </tr><tr><td>main.cpp</td> </tr><tr><td>lodepng.cpp</td> </tr><tr><td>lodepng.h</td> </tr><tr><td>tree.png</td> </tr><tr><td>map.png</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 /> #include<br /> #include<br /> #include "lodepng.h"</p> <p>#define WIDTH 320<br /> #define HEIGHT 240</p> <p>//赤<br /> GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };<br /> //回転用<br /> float angleY=0.0f;<br /> float angleX=0.0f;<br /> bool flag=false;</p> <p>class PNG{<br /> public:<br />  LodePNG_Decoder decoder;<br />  unsigned char* buffer;<br />  unsigned char* image;<br />  size_t buffersize, imagesize;<br />  int Width,Height;<br />  GLuint texture;<br />  PNG(char* FileName);<br />  void DrawBillBoard(float x,float y,float z,float sizeX,float sizeY);<br />  void DrawPolygon(float x,float y,float z,float sizeX,float sizeY);<br /> };<br /> PNG::PNG(char* FileName)<br /> {<br />  LodePNG_Decoder_init(&amp;decoder);<br />  LodePNG_loadFile(&amp;buffer, &amp;buffersize, FileName);<br />  LodePNG_decode(&amp;decoder, &amp;image, &amp;imagesize, buffer, buffersize);<br />  Width = decoder.infoPng.width;<br />  Height = decoder.infoPng.height;<br />  glGenTextures(1, &amp;texture);<br />  glBindTexture(GL_TEXTURE_2D, texture);<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 /> }</p> <p>void PNG::DrawBillBoard(float x,float y,float z,float sizeX,float sizeY)<br /> {<br />  GLdouble v[16];<br />  glPushMatrix();<br />   glPushMatrix();<br />    glTranslated(x, y, z);<br />    glGetDoublev(GL_MODELVIEW_MATRIX, v);<br />   glPopMatrix();</p> <p>  glLoadIdentity();</p> <p>  glEnable(GL_TEXTURE_2D);<br />   glEnable( GL_TEXTURE_RECTANGLE_EXT );//拡張機能を使う<br />   glBindTexture( GL_TEXTURE_RECTANGLE_EXT, texture );<br />  glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,Width, Height, 0,GL_RGBA, GL_UNSIGNED_BYTE, image);<br />     glBegin(GL_POLYGON);<br />  <br />   glTexCoord2i(0, Height);   glVertex3d( v[12]-sizeX, v[13]-sizeY, v[14]);//左下<br />   glTexCoord2i(0, 0);      glVertex3d( v[12]-sizeX, v[13]+sizeY, v[14]);//左上<br />   glTexCoord2i(Width, 0);    glVertex3d( v[12]+sizeX, v[13]+sizeY, v[14]);//右上<br />   glTexCoord2i(Width, Height);glVertex3d( v[12]+sizeX, v[13]-sizeY, v[14]);//右下</p> <p>  glEnd();</p> <p>  glDisable( GL_TEXTURE_RECTANGLE_EXT );<br />   glDisable(GL_TEXTURE_2D);<br /> glPopMatrix();<br /> }</p> <p>void PNG::DrawPolygon(float x,float y,float z,float sizeX,float sizeY)<br /> {</p> <p>  glEnable(GL_TEXTURE_2D);<br />   glEnable( GL_TEXTURE_RECTANGLE_EXT );//拡張機能を使う<br />   glBindTexture( GL_TEXTURE_RECTANGLE_EXT, texture );<br />  glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,Width, Height, 0,GL_RGBA, GL_UNSIGNED_BYTE, image);<br />     glBegin(GL_POLYGON);<br />  <br />   glTexCoord2i(0, Height);   glVertex3d( x+sizeX, y-3, z+sizeY);//左下<br />   glTexCoord2i(0, 0);      glVertex3d( x+sizeX, y-3, z-sizeY);//左上<br />   glTexCoord2i(Width, 0);    glVertex3d( x-sizeX, y-3, z-sizeY);//右上<br />   glTexCoord2i(Width, Height);glVertex3d( x-sizeX, y-3, z+sizeY);//右下</p> <p>  glEnd();</p> <p>  glDisable( GL_TEXTURE_RECTANGLE_EXT );<br />   glDisable(GL_TEXTURE_2D);<br /> }</p> <p>PNG *Map;<br /> PNG *Tree;</p> <p>// 初期化<br /> void init(void)<br /> {<br />   glClearColor(1.0, 1.0, 1.0, 1.0);</p> <p>  glEnable(GL_DEPTH_TEST);<br />   glEnable(GL_BLEND);</p> <p>  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);</p> <p>  Map = new PNG("map.png");<br />   Tree = new PNG("tree.png");<br /> }</p> <p>void idle(void)<br /> {<br />   if(flag){angleX-=0.1f;}else{angleX+=0.1f;}<br />   if(angleX&gt;10.0f)flag=true;<br />   if(angleX&lt;-10.0f)flag=false;<br />   angleY+=0.5f;<br />   Sleep(1);<br />   glutPostRedisplay();<br /> }</p> <p> </p> <p>// 画面表示<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, 5000.0);<br />  glMatrixMode(GL_MODELVIEW);<br />     glLoadIdentity();<br />  //視点の設定<br />  gluLookAt(0.0,5.0,-50.0, //カメラの座標<br />       0.0,0.0,0.0, // 注視点の座標<br />      0.0,1.0,0.0); // 画面の上方向を指すベクトル</p> <p>  glRotatef(angleY, 0.0, 1.0, 0.0);<br />   glRotatef(angleX, 1.0, 0.0, 1.0);</p> <p>  glDisable(GL_LIGHTING);<br />   glDepthMask(GL_FALSE);</p> <p>  Map-&gt;DrawPolygon(0.0,0.0,0.0,20.0,20.0);<br />   Tree-&gt;DrawBillBoard(0.0,0.0,10.0,3.0,3.0);<br />   Tree-&gt;DrawBillBoard(0.0,0.0,-10.0,3.0,3.0);<br />   Tree-&gt;DrawBillBoard(-10.0,0.0,0.0,3.0,3.0);<br />   Tree-&gt;DrawBillBoard(10.0,0.0,0.0,3.0,3.0);</p> <p>  glDepthMask(GL_TRUE);<br />   glEnable(GL_LIGHTING);<br />   glutSwapBuffers();<br /> }</p> <p>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 />  init();<br />  glutMainLoop();<br />  return 0;<br /> }</p> </td> </tr></tbody></table><p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p>
<p><strong>ビルボードです。<br /> ビルボードというのは常に視点(カメラ)を向く板の事です。<br /> 古くは樹木や球のポリゴン数を減らすために用いられました。<br /> 現在では火花や雪などのパーティクルとして主に使用されます。<br /> ビルボードにはビュー行列を逆行列にする方法もありますが、<br /> 今回はもっと簡単に実装できるやり方がありましたので紹介して<br /> おきます。<br /> 3D空間のビルボードオブジェクトの中心位置を保存しておき、<br /> glLoadIdentity(); して初期化します。<br /> 中心位置から画像サイズ分だけ+-してポリゴンを描画すると<br /> 行列計算なしでビルボードができます。</strong></p> <p> <img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=billboard.png" /></p> <table border="1" cellpadding="1" cellspacing="1" style="width:100px;"><tbody><tr><td>ファイル</td> </tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=main.cpp"> main.cpp</a></td> </tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=lodepng.cpp"> lodepng.cpp</a></td> </tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=lodepng.h"> lodepng.h</a></td> </tr><tr><td> <p><a href="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=tree.png"> tree.png</a></p> <p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=tree.png" /></p> </td> </tr><tr><td> <p><a href="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=map.png"> map.png</a></p> <p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=50&amp;file=map.png" style="width:320px;height:320px;" /></p> </td> </tr></tbody></table><p>main.cpp</p> <table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td> <p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br /> #include &lt;gl/glew.h&gt;<br /> #include &lt;GL/freeglut/freeglut.h&gt;<br /> #include "lodepng.h"</p> <p>#define WIDTH 320<br /> #define HEIGHT 240</p> <p>//赤<br /> GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };<br /> //回転用<br /> float angleY=0.0f;<br /> float angleX=0.0f;<br /> bool flag=false;</p> <p>class PNG{<br /> public:<br />  LodePNG_Decoder decoder;<br />  unsigned char* buffer;<br />  unsigned char* image;<br />  size_t buffersize, imagesize;<br />  int Width,Height;<br />  GLuint texture;<br />  PNG(char* FileName);<br />  void DrawBillBoard(float x,float y,float z,float sizeX,float sizeY);<br />  void DrawPolygon(float x,float y,float z,float sizeX,float sizeY);<br /> };<br /> PNG::PNG(char* FileName)<br /> {<br />  LodePNG_Decoder_init(&amp;decoder);<br />  LodePNG_loadFile(&amp;buffer, &amp;buffersize, FileName);<br />  LodePNG_decode(&amp;decoder, &amp;image, &amp;imagesize, buffer, buffersize);<br />  Width = decoder.infoPng.width;<br />  Height = decoder.infoPng.height;<br />  glGenTextures(1, &amp;texture);<br />  glBindTexture(GL_TEXTURE_2D, texture);<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 /> }</p> <p>void PNG::DrawBillBoard(float x,float y,float z,float sizeX,float sizeY)<br /> {<br />  GLdouble v[16];<br />  glPushMatrix();<br />   glPushMatrix();<br />    glTranslated(x, y, z);<br />    glGetDoublev(GL_MODELVIEW_MATRIX, v);<br />   glPopMatrix();</p> <p>  glLoadIdentity();</p> <p>  glEnable(GL_TEXTURE_2D);<br />   glEnable( GL_TEXTURE_RECTANGLE_EXT );//拡張機能を使う<br />   glBindTexture( GL_TEXTURE_RECTANGLE_EXT, texture );<br />  glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,Width, Height, 0,GL_RGBA, GL_UNSIGNED_BYTE, image);<br />     glBegin(GL_POLYGON);<br />  <br />   glTexCoord2i(0, Height);   glVertex3d( v[12]-sizeX, v[13]-sizeY, v[14]);//左下<br />   glTexCoord2i(0, 0);      glVertex3d( v[12]-sizeX, v[13]+sizeY, v[14]);//左上<br />   glTexCoord2i(Width, 0);    glVertex3d( v[12]+sizeX, v[13]+sizeY, v[14]);//右上<br />   glTexCoord2i(Width, Height);glVertex3d( v[12]+sizeX, v[13]-sizeY, v[14]);//右下</p> <p>  glEnd();</p> <p>  glDisable( GL_TEXTURE_RECTANGLE_EXT );<br />   glDisable(GL_TEXTURE_2D);<br /> glPopMatrix();<br /> }</p> <p>void PNG::DrawPolygon(float x,float y,float z,float sizeX,float sizeY)<br /> {</p> <p>  glEnable(GL_TEXTURE_2D);<br />   glEnable( GL_TEXTURE_RECTANGLE_EXT );//拡張機能を使う<br />   glBindTexture( GL_TEXTURE_RECTANGLE_EXT, texture );<br />  glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,Width, Height, 0,GL_RGBA, GL_UNSIGNED_BYTE, image);<br />     glBegin(GL_POLYGON);<br />  <br />   glTexCoord2i(0, Height);   glVertex3d( x+sizeX, y-3, z+sizeY);//左下<br />   glTexCoord2i(0, 0);      glVertex3d( x+sizeX, y-3, z-sizeY);//左上<br />   glTexCoord2i(Width, 0);    glVertex3d( x-sizeX, y-3, z-sizeY);//右上<br />   glTexCoord2i(Width, Height);glVertex3d( x-sizeX, y-3, z+sizeY);//右下</p> <p>  glEnd();</p> <p>  glDisable( GL_TEXTURE_RECTANGLE_EXT );<br />   glDisable(GL_TEXTURE_2D);<br /> }</p> <p>PNG *Map;<br /> PNG *Tree;</p> <p>// 初期化<br /> void init(void)<br /> {<br />   glClearColor(1.0, 1.0, 1.0, 1.0);</p> <p>  glEnable(GL_DEPTH_TEST);<br />   glEnable(GL_BLEND);</p> <p>  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);</p> <p>  Map = new PNG("map.png");<br />   Tree = new PNG("tree.png");<br /> }</p> <p>void idle(void)<br /> {<br />   if(flag){angleX-=0.1f;}else{angleX+=0.1f;}<br />   if(angleX&gt;10.0f)flag=true;<br />   if(angleX&lt;-10.0f)flag=false;<br />   angleY+=0.5f;<br />   Sleep(1);<br />   glutPostRedisplay();<br /> }</p> <p> </p> <p>// 画面表示<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, 5000.0);<br />  glMatrixMode(GL_MODELVIEW);<br />     glLoadIdentity();<br />  //視点の設定<br />  gluLookAt(0.0,5.0,-50.0, //カメラの座標<br />       0.0,0.0,0.0, // 注視点の座標<br />      0.0,1.0,0.0); // 画面の上方向を指すベクトル</p> <p>  glRotatef(angleY, 0.0, 1.0, 0.0);<br />   glRotatef(angleX, 1.0, 0.0, 1.0);</p> <p>  glDisable(GL_LIGHTING);<br />   glDepthMask(GL_FALSE);</p> <p>  Map-&gt;DrawPolygon(0.0,0.0,0.0,20.0,20.0);<br />   Tree-&gt;DrawBillBoard(0.0,0.0,10.0,3.0,3.0);<br />   Tree-&gt;DrawBillBoard(0.0,0.0,-10.0,3.0,3.0);<br />   Tree-&gt;DrawBillBoard(-10.0,0.0,0.0,3.0,3.0);<br />   Tree-&gt;DrawBillBoard(10.0,0.0,0.0,3.0,3.0);</p> <p>  glDepthMask(GL_TRUE);<br />   glEnable(GL_LIGHTING);<br />   glutSwapBuffers();<br /> }</p> <p>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 />  init();<br />  glutMainLoop();<br />  return 0;<br /> }</p> </td> </tr></tbody></table><p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p>

表示オプション

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