トップページ
ひらく | たたむ | ページトップ
↓マウスで反転選択した文字を検索
OpenGL
   
ページ内検索 ページ外検索
検索したい文字を入力して
ENTERを押すと移動します。
\n
[ トップページ ]
[ ____CommandPrompt ] [ ____JScript ] [ ____MySQL ] [ ____Cygwin ] [ ____Java ] [ ____Emacs ] [ ____Make ] [ ____Perl ] [ ____Python ] [ ____OpenGL ] [ ____C# ] [ ____StyleSheet ] [ ____C++ ] [ ____Winsock ] [ ____Thread ] [ ____VisualStudio ] [ ____C ] [ ____Win32API ] [ ____Lua ] [ ____PhotoShop ]
ヘッダ検索
___

■ 頂点スキニング


  SAMPLE
     頂点スキニング 
     頂点スキニングを使ったバネモデル 





    App::onDraw() {

      float m0[16], m1[16];

      // 現在の骨の位置に移動する。
      glLoadIdentity();
      glTranslatef( 0, 50, 0 );

      // 回転する。
      glRotatef( m_timer, 0,0,1 );
      
      // 骨の位置を基準(Pivot)にして回転するため、逆行列をかけて原点に移動する。
      glTranslatef( 0, -50, 0 );

      glGetFloatv( GL_MODELVIEW_MATRIX, mb0 );


      // 2番目の骨も同じように計算      
      glLoadIdentity();
      glTranslatef( 100, 50, 0 );
      glRotatef( m_timer, 0,0,1 );
      glTranslatef( -100, -50, 0 );
      glGetFloatv( GL_MODELVIEW_MATRIX, mb1 );


      {
        CGparameter param;

      // 頂点シェーダで変形させるため、骨の行列をシェーダに渡す。
        float m[] = {
          m0[0], m0[4], m0[ 8], m0[12],
          m0[1], m0[5], m0[ 9], m0[13],
          m0[2], m0[6], m0[10], m0[14],
          m0[3], m0[7], m0[11], m0[15],

          m1[0], m1[4], m1[ 8], m1[12],
          m1[1], m1[5], m1[ 9], m1[13],
          m1[2], m1[6], m1[10], m1[14],
          m1[3], m1[7], m1[11], m1[15],
        };

      param = cgGetNamedParameter( shdV, "m");
      cgGLSetParameterArray4f( param, 0, 2*4, m );

      
      // モデルビュー, プロジェクションを渡す。
      glMatrixMode( GL_MODELVIEW_MATRIX );
      glLoadIdentity();
      convertCameraSpace();

      param = cgGetNamedParameter( shdV, "mvp");
      cgGLSetStateMatrixParameter( param,
                                   CG_GL_MODELVIEW_PROJECTION_MATRIX,
                                   CG_GL_MATRIX_IDENTITY
                                   );
      }

      // 描画する。( ウェイトの値は glNormal で指定しておく。 )
      glBegin( GL_TRIANGLE_STRIP );
      {
        glColor4f(1,1,1,1);
        for( int j=0; j< 2*7; j++ ){

          // ウェイト値
          float w0 = 1 - 1/7.0f*(j/2);
          float w1 = 1 - w0;
          glNormal3f( w0, w1, 1 );


          float x = 2*(w1 - 0.5f) * 100;
          float y = 100 * (j%2);
          glVertex3f( x, y, 0 );
        } 
      }      
      glEnd();            
    }
頂点シェーダで頂点を変形する

  float4x4 mtx0 = float4x4( m[0], m[1], m[2], m[3] );
  float4x4 mtx1 = float4x4( m[4], m[5], m[6], m[7] );

  // ウェイト
  float w0 = IN.nrm.x;
  float w1 = IN.nrm.y;

  // 変形
  float4 p = w0 * mul( mtx0, IN.pos ) + w1 * mul( mtx1, IN.pos );

  // モデルビュープロジェクション変換
  OUT.pos = mul( mvp, pt );
___

■ CPUで変形する

CPUで計算するには頂点座標を指定する( glVertex() )前に変換をしておく。
    float v[2*7*3];

    for( int j=0; j< 2*7; j++ ){
      // ウェイト値
      float w0 = 1 - 1/7.0f*(j/2);
      float w1 = 1 - w0;

      float x = 2*(w1 - 0.5f) * 100;
      float y = 100 * (j%2);


      // 行列とベクトルの積
      multiMatrix( mb0, v0, v0 );
      multiMatrix( mb1, v1, v1 );
          
      // ウェイトをかけてブレンドする
      v[3*j+0] = w0*v0[0] + w1*v1[0];
      v[3*j+1] = w0*v0[1] + w1*v1[1];
      v[3*j+2] = 0;
    }

    glBegin( GL_TRIANGLE_STRIP );
    glColor4f(1,1,1,1);
    for( int j=0; j< 2*7; j++ ){
      // 事前計算した頂点を指定する
      glVertex3fv( v + 3*j );
    }      
    glEnd();            
行列とベクトルの積には glMultMatrix() を利用する。
    void multiMatrix( const float *m, float *v, float *vout ) {

      glMatrixMode( GL_MODELVIEW );
      glLoadMatrixf( m );

      float mt[16] = {
        v[0], v[1], v[2], 1, // 第1列をベクトル扱いにする。
        0, 0, 0, 0,          // 残りの3列は仮
        0, 0, 0, 0,
        0, 0, 0, 0,
        };

      // 右からかける
      glMultMatrixf( mt );  

      // 計算結果として行列同士の積の結果の第一列を取得する
      glGetFloatv(GL_MODELVIEW_MATRIX, mt );
      vout[0] = mt[0];  
      vout[1] = mt[1];
      vout[2] = mt[2];
    }
___

■ 頂点配列でウェイトを指定する

頂点の属性としてウェイトを指定するには glVertexAttribPointer() を利用して 汎用型の属性のひとつとして指定する。

    App::onInit() {
      glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)wglGetProcAddress("glVertexAttribPointer");
    }

    #define ATTR1   1

    App::onDraw() {

        struct Vertex {
          float pos[3];
          float col[3];
          float weight[4];
        };

       Vertex v[2*NR];

       {
         for( int i=0; i< 2*NR; i++ ){
           float w0 = 1 - 1.0f/(NR-1)*(i/2);
           float w1 = 1 - w0;
           float x = 2*(w1 - 0.5f) * 100;
           float y = 100 * (i%2);

           v[i].pos[0] = x;
           v[i].pos[1] = y;
           v[i].pos[2] = 0;

           v[i].col[0] = 1;
           v[i].col[1] = 0;
           v[i].col[2] = 0;

           v[i].weight[0] = w0;
         } 
       }

      glEnableClientState( GL_VERTEX_ARRAY );
      glEnableClientState( GL_COLOR_ARRAY );
      glEnableVertexAttribArray( ATTR1 );

      glVertexPointer( 3, GL_FLOAT, sizeof(Vertex),  v );
      glColorPointer ( 3, GL_FLOAT,  sizeof(Vertex), v[0].col );
      glVertexAttribPointer( ATTR1, 1, GL_FLOAT, false, sizeof(Vertex), v[0].weight );

      // シェーダを有効にする。
      cgGLEnableProfile( pfV );

      glDrawArrays( GL_TRIANGLE_STRIP, 0, m_nr*2 );
    }
頂点シェーダではアプリケーションで指定した頂点インデックスからウェイトを取得する。
   struct app {
     float4 pos     : POSITION;
     float4 weight  : ATTR1;
   };
    
  float4x4 mtx0 = float4x4( m[0], m[1], m[2], m[3] );
  float4x4 mtx1 = float4x4( m[4], m[5], m[6], m[7] );

  // ウェイト
  float w0 = IN.weight[0]
  float w1 = 1 - w0;

  // 変形
  float4 p = w0 * mul( mtx0, IN.pos ) + w1 * mul( mtx1, IN.pos );

  // モデルビュープロジェクション変換
  OUT.pos = mul( mvp, p );







金利比較.COM
NINJAIDX 9