모델의 렌더링
여기에서는 3D모델의 기본적인 렌더링 방법에 대해 설명합니다.
목차
1. 모델의 구성요소
3D 모델은 아래 3가지의 요소로부터 구성되어 있습니다.
- 모델 데이터 ( Figure )
3D 모델의 뼈대가 되는 부분입니다. MBAC 데이터를 로드하는 것으로 취득합니다. - 텍스쳐 데이터 ( Texture )
모델에 붙이는 texture나 배경 등입니다. BMP(비트맵) 데이터를 로드하는 것으로 취득합니다. - 액션 데이터 ( ActTable )
모델의 에니메이션에 대한 정보입니다. MTRA 데이터를 로드하는 것으로 취득합니다.
2. 모델의 렌더링 순서
여기에서는 샘플 코드를 이용해 3D모델을 렌더링 하는 순서를 설명합니다.

Sample 렌더링 결과
2.1. 데이터 오브젝트의 바이트 데이터의 작성
WIPI에서는 각 데이터 오브젝트 ( Figure, Texture, ActionTable ) 작성을 각각 대응하는 MBAC, BMP, MTRA 파일의 바이트 데이터를 로드하는 것으로 실행합니다. 그 때문에 각 파일의 바이트 배열을 준비해 둘 필요가 있습니다. 또, 데이터를 로드할 때에는 그 파일의 바이트 배열의 사이즈도 알고 있을 필요가 있습니다.
0xeb ,0x0 ,0x28 ,0x1 ,0x41 ,0x0 ,0x6 ,0x0 ,0xa ,0x0 ,
0x2 ,0x0 ,0x1 ,0x0 ,0x1 ,0x0 ,0x6 ,0x0 ,0xa ,0x0 ,
0xd5 ,0x23 ,0x1c ,0xe9 ,0x64 ,0x92 ,0x64 ,0x92 ,0x64 ,0x92
};
const ByteData dragon_mbac = { _dragon_mbac, sizeof( _dragon_mbac ) };
const ByteData dragon_bmp = { _dragon_bmp, sizeof( _dragon_bmp ) };
const ByteData dragon_bg = { _dragon_bg, sizeof( _dragon_bg ) };
const ByteData dragon_mtra = { _dragon_mtra, sizeof( _dragon_mtra ) };
2.2. 3D 관련 오브젝트의 초기화
3D모델을 렌더링하기 위한 각 데이터를 로드하기 위해 초기화 처리를 실행해서 사용하는 오브젝트와 Memory Allocater를 관련지어 실행합니다. 그리고 각 데이터는 3D모델의 구조체의 멤버로서 보관 유지해 두면 알기 쉬워집니다. 이 샘플에서는 헤더 파일 내에서 모델의 구조체를 정의하고 있습니다.
*/
{
hi_bool rval;
g_vram_image = 0;
g_IAllocator = 0;
g_dif_time = 0;
g_key_mask = 0;
/* allocater를 초기화, VRAM의 확보 등*/
if ( M3DTest_machInitialize() == HI_FALSE )
/* 3D 렌더링 관련 오브젝트의 초기화 */
OEMC_Micro3D_Figure_initialize ( &dragon.fig, g_IAllocator );
OEMC_Micro3D_Texture_initialize ( &dragon.tex, g_IAllocator );
OEMC_Micro3D_Texture_initialize ( &dragon.bg, g_IAllocator );
OEMC_Micro3D_ActTable_initialize ( &dragon.act, g_IAllocator );
OEMC_Micro3D_Render_initialize ( &render, g_IAllocator );
2.3. 데이터의 로드
사용하는 데이터 오브젝트(Figure, Texture, ActTable)에 모델 데이터, 텍스처 데이터, 액션 데이터를 인풋스트림을 사용하여 로드 합니다. 인풋스트림은 이 처리를 하기까지 사용할 수 있는 상태일 필요가 있습니다.
그리고, 하나의 모델 데이터에 대해 복수의 텍스처를 사용하는 경우, 그것들의 데이터의 포인터를 격납한 배열 texArray를 준비해 둘 필요가 있습니다.
MemIstream_initialize( &mis, dragon_mbac.addr, dragon_bmp.size );
rval = OEMC_Micro3D_Figure_loadMbacData(
/* 텍스쳐 데이터를 로드 */
MemIstream_initialize( &mis, dragon_bmp.addr, dragon_bmp.size );
rval = OEMC_Micro3D_Texture_loadBmpData(
MemIstream_getIIstream( &mis ), TEXTURE_TYPE_NORMAL );
rval = OEMC_Micro3D_Texture_loadBmpData(
MemIstream_getIIstream( &mis ), TEXTURE_TYPE_NORMAL );
return HI_FALSE;
/* 텍스쳐 배열의 작성 */
dragon.texArray.num = 2;
dragon.texArray.texture[0] = &dragon.tex;
dragon.texArray.texture[1] = &dragon.bg;
/* 액션 데이터를 로드 */
MemIstream_initialize( &mis, dragon_mtra.addr, dragon_mtra.size );
rval = OEMC_Micro3D_ActTable_loadMtraData(
2.4. 라이트•카메라의 초기화
라이트와 카메라의 초기화를 실시합니다. 라이트에 대해서는 사용하는 라이트 각각에 관해 밝기나 방향 등을 설정합니다. 카메라에 관해서는 위치/시점방향/up 벡터/니어클립/파클립/화각을 설정하여 카메라 좌표로의 변환 행렬을 작성합니다.
amb_light_intensity = 4096*50/100;
OEMC_Micro3D_Render_setAmbientLight(&render, amb_light_intensity );
/* 시점설정 */
/* 위치 */
cam_frame.pos.x = 0;
cam_frame.pos.y = 1024;
cam_frame.pos.z = 7000;
/* 시점방향 */
cam_frame.dir.x = 0;
cam_frame.dir.y = 0;
cam_frame.dir.z = -4096;
/* up 벡터 */
cam_frame.up.x = 0;
cam_frame.up.y = 4096;
cam_frame.up.z = 0;
/* near_crip, far_crip, 화각의 설정 */
cam_frame.z_near = NEAR_CLIP;
cam_frame.z_far = FAR_CLIP;
cam_frame.angle = ANGLE;
/* 카메라 좌표로의 변환 */
OEMC_Micro3D_Atrans3i_setViewTrans( &view_trans, &cam_frame.pos,
2.5. 렌더링 환경의 설정
렌더링 환경의 설정을 합니다. 구체적으로는
- 프레임버퍼의 설정
- 스크린 중앙 위치의 설정
- 투영 방법의 설정
등을 실행합니다.
이러한 각 설정에 대해서는 변경되지 않는 한 Render로 설정된 채로 있기 때문에 같은 설정을 사용하는 경우는 각 설정은 최초의 한 번으로 괜찮습니다.
투영 방법에 대해서는 투시투영과 평행투영의 2종류가 있습니다.
-
투시투영의 경우에는,
- OEMC_Micro3D_Render_serPerspectiveFov(
Render* render, hi_sint32 z_near, hi_sint32 z_far, hi_sint32 angle ) - OEMC_Micro3D_Render_serPerspectiveWH(
Render* render, hi_sint32 z_near, hi_sint32 z_far, hi_sint32 vw, hi_sint32 vh ) - OEMC_Micro3D_Render_serPerspectiveW(
Render* render, hi_sint32 z_near, hi_sint32 z_far, hi_sint32 vw )
- OEMC_Micro3D_Render_serPerspectiveFov(
- 의 어느 것,
-
평행투영의 경우에는,
- OEMC_Micro3D_Render_serOrthographicScale( Render* render, hi_sint32 sx, hi_sint32 sy )
- OEMC_Micro3D_Render_serOrthographicWH( Render* render, hi_sint32 vw, hi_sint32 vh )
- OEMC_Micro3D_Render_serOrthographicW( Render* render, hi_sint32 vw )
- OEMC_Micro3D_Render_serOrthographicScale( Render* render, hi_sint32 sx, hi_sint32 sy )
- 의 어느 것을 지정해 주세요.
OEMC_Micro3D_Render_setVram( &render, VRAM_WIDTH,
/* 스크린 중앙 위치의 설정 */
OEMC_Micro3D_Render_setScreenCenter( &render,
/* 투시투영의 설정 */
OEMC_Micro3D_Render_setPerspectiveFov( &render, cam_frame.z_near, cam_frame.z_far, cam_frame.angle );
return HI_TRUE;
}
2.6. 모델의 액션의 설정
모델에 애니메이션이 설정되어 있는 경우, 대상이 되는 렌더링 시각에 있어서의 모델의 자세를 설정합니다. 모델의 자세는 OEMC_Micro3D_Figure_setPosture( Figure* figure, struct ActTable* act, hi_sint32 act_idx, hi_sint32 frame)으로 렌더링 하는 프레임을 설정하는 것으로 실행합니다. 액션 데이터의 최대 프레임수는 OEMC_Micro3D_ActTable_getNumFrames(const ActTable* act, hi_sint32 act_idx)로 취득할 수 있습니다.
*/
{
if ( maxframe != 0 ) {
}
}
/* 모델에 액션을 설정 */
OEMC_Micro3D_Figure_setPosture( &dragon.fig , &dragon.act , dragon.actID, dragon.currentFrame);
2.7. 모델의 렌더링
취득한 각 오브젝트를 렌더링하여 VRAM에 전송 합니다. 렌더링은 렌더링 등록 밖에 실시하지 않으므로, 이것만으로는 frame buffer로의 렌더링 처리는 실행되지 않습니다. 마지막으로 OEMC_Micro3D_Render_flush( Render* render )를 호출함으로 인해 그때까지 등록되어 있던 오브젝트의 렌더링 처리가 실행됩니다.
또한, 1개의 Figure에 대해 복수의 texture를 사용하는 경우는, 그러한 texture의 포인터를 격납한 배열을 설정하는 OEMC_Micro3D_Render_setTextureArray(Render* render, TextureArray* texArray) 를 사용해 주세요.
* 렌더링 처리
*/
static void draw_( void )
{
setAction();
/* Texture를 설정 */
OEMC_Micro3D_Render_setTextureArray(&render, &dragon.texArray );
/* 시점 변환 행렬 설정 */
OEMC_Micro3D_Render_setViewTrans( &render, &view_trans );
/* Figure를 설정 */
OEMC_Micro3D_Render_drawFigure( &render, &dragon.fig );
/* VRAM으로 전송 */
OEMC_Micro3D_Render_flush( &render );
}

Sample 렌더링 결과
2.8.종료 처리
사용하지 않게 된 오브젝트의 종료 처리 함수를 호출하여 리소스를 개방합니다. 종료 처리의 호출이 필요한 오브젝트는
- ActTable
- Atrans3iArray
- Figure
- Texture
- Render
의 5가지 입니다.
*/
{
OEMC_Micro3D_Render_finalize( &render );
/* ActTable 종료 처리 */
OEMC_Micro3D_ActTable_finalize( &dragon.act );
/* Texture 종료 처리 */
OEMC_Micro3D_Texture_finalize( &dragon.bg );
OEMC_Micro3D_Texture_finalize( &dragon.tex );
/* Figure 종료 처리 */
OEMC_Micro3D_Figure_finalize( &dragon.fig );
M3DTest_machTerminate();

