OpenGL中用矩陣調色板混合頂點

擴展:

GL_ARB_matrix_palette

GL_ARB_vertex_blend

 

頂點混合函數:

V = V*Mat[0]*Weight[1] + V*Mat[1]*Weight[1] + … + V*Mat[n]*Weight[n]

 

  OpenGL增加了前面兩個ARB擴展以支持矩陣調色板合頂點混合,這兩項功能是硬件實現骨骼動畫的基礎。首先要用glEnbale( GL_MATRIX_PALETTE_ARB )glEnable( GL_VERTEX_BLEND_ARB )激活這兩項功能,然後使用glMatrixMode( GL_MATRIX_PALETTE_ARB )將當前矩陣切換成矩陣調色板。

  在激活矩陣調色板之後,原來的GL_MODELVIEW(包括GL_MODELVIEWn)都不再起作用,頂點混合結果是在攝像機空間(世界座標系)中的。但是一般我們的骨骼變換矩陣都是基於本地空間的,因此在繪製之前還要做點小動作。

  矩陣調色板的大小由不同的實現決定,用glGetIntegerv( GL_MAX_PALETTE_MATRICES_ARB , &I )可以獲得調色板大小。矩陣調色板棧大小至少爲1matrix_palette_arb擴展說明上說該棧基本上不需要更大,而且更大的棧也浪費空間,具體棧大小可以通過glGetIntergerv( GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB , &I )獲得。

  其他的懶得說,直接看下面的例子吧(說明上抄的):

 

glEnable( GL_MATRIX_PALETTE_ARB );

glEnable( GL_VERTEX_BLEND_ARB );

// 獲得頂點單元數量和矩陣調色板大小。頂點單元數量即一個頂點最多能用多少個骨骼

glGetIntegerv(MAX_VERTEX_UNITS_ARB, *max_blends);
glGetIntegerv(MAX_PALETTE_MATRICES_ARB, *max_matrices);
// 激活
0-3頂點單元
glEnable(VERTEX_UNIT_0_ARB);
glEnable(VERTEX_UNIT_1_ARB);
glEnable(VERTEX_UNIT_2_ARB);
glEnable(VERTEX_UNIT_3_ARB);
// 保存視圖變換矩陣(攝像機變換)

Float mv[16];

glGetFloatv( GL_MODELVIEW );

// 加載矩陣調色板

glMatrixMode(MATRIX_PALETTE_ARB);
for (i=0; i<palette_size; i++)
{
glCurrentPaletteMatrix(i);
// 選擇調色板中的當前矩陣

glLoadMatrix( mv );
gl
MultiMatrix(bone_mat[i]);
}
// 頂點數組、紋理座標數組等數組分開來的做法

// 激活數組狀態
glEnableClientState(VERTEX_ARRAY);
glEnableClientState(NORMAL_ARRAY);
glEnableClientState(COLOR_ARRAY);
glEnableClientState(TEXTURE_COORD_ARRAY);
glEnableClientState(WEIGHT_ARRAY_ARB);
glEnableClientState(MATRIX_INDEX_ARRAY_ARB);
glVertexPointer(3, FLOAT, 3, vertices);
glNormalPointer(FLOAT, 3, normals);
glColorPointer(4, UNSIGNED_BYTE, 4, colors);
glTexCoordPointer(4, FLOAT, 4, texcoords);
glWeightPointerARB(4, FLOAT, 4, weights);
glMatrixIndexPointerARB(4, UNSIGNED_BYTE, 4, indices);
// 繪製三角形

glDrawArrays(TRIANGLES, 0, vert_array_size);

 

 

// 繪圖數據合在一起的做法(有點像DX中的FVF

typdef struct st_interleaved_vertex {
FLOAT position[4];
FLOAT weights[4];
UNSIGNED_BYTE indices[4];
FLOAT normal[3];
FLOAT color[4];
FLOAT texcoord[4];
} interleaved_vertex;
interleaved_vertex vertices[NUM_VERTS];
// the rest as above, except the Array Pointer definition:
int stride = sizeof(interleaved_vertex);
glVertexPointer( 3, FLOAT, stride, &(vertices[0].position) );
glNormalPointer( FLOAT, stride, &(vertices[0].normal) );
glColorPointer( 4, UNSIGNED_BYTE, stride, &(vertices[0].color) );
glTexCoordPointer( 4, FLOAT, stride, &(vertices[0].texcoords) );
glWeightPointerARB( 4, FLOAT, stride, &(vertices[0].weights) );
glMatrixIndexPointerARB( 4, UNSIGNED_BYTE, stride,
&(vertices[0].indices) );

 
發佈了58 篇原創文章 · 獲贊 5 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章