青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

  C++博客 :: 首頁(yè) :: 聯(lián)系 ::  :: 管理
  163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

常用鏈接

留言簿(48)

我參與的團(tuán)隊(duì)

搜索

  •  

積分與排名

  • 積分 - 402531
  • 排名 - 59

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

這篇渲染模型的文章是由Brett Porter所寫的。
這篇教程的代碼是從PortaLib3D中提取出來(lái)的,PortaLib3D是一個(gè)可以讀取3D文件實(shí)用庫(kù)。
這篇教程的代碼是以第六課為基礎(chǔ)的,我們只討論改變的部分。

這課中使用的模型是從Milkshape3D中提取出來(lái)的,Milkshape3D是一個(gè)非常好的建模軟件,它包含了自己的文件格式,所以你能很容易去分析和理解。

但是文件格式并不能使你加載一個(gè)模型,你必須自己定義一個(gè)結(jié)構(gòu)去保存數(shù)據(jù),接著把數(shù)據(jù)讀入那個(gè)結(jié)構(gòu),我們將告訴你如何定義這樣一個(gè)結(jié)構(gòu)。

模型的定義在model.h中,好吧我們開(kāi)始吧:
 
  

// 頂點(diǎn)結(jié)構(gòu)
struct Vertex
{
    char m_boneID;    // 頂點(diǎn)所在的骨骼
    float m_location[3];
};

// 頂點(diǎn)的個(gè)數(shù)和數(shù)據(jù)
int m_numVertices;
Vertex *m_pVertices;

  
 在這一課你,你可以忽略m_boneID,我們將在以后的教程中介紹骨骼動(dòng)畫。m_location定義頂點(diǎn)的位置。
下面是三角形結(jié)構(gòu)
 
  

// 三角形結(jié)構(gòu)
struct Triangle
{
    float m_vertexNormals[3][3];
    float m_s[3], m_t[3];
    int m_vertexIndices[3];
};

// 使用的三角形
int m_numTriangles;
Triangle *m_pTriangles;

  
 3個(gè)頂點(diǎn)構(gòu)成一個(gè)三角形,m_vertexIndices保存了三個(gè)頂點(diǎn)的索引。 m_s 和 m_t儲(chǔ)存了三個(gè)頂點(diǎn)的紋理坐標(biāo)。m_vertexNormals保存了三個(gè)頂點(diǎn)的法線。
下面我們定義網(wǎng)格結(jié)構(gòu)
 
  

// 網(wǎng)格結(jié)構(gòu)
struct Mesh
{
    int m_materialIndex;
    int m_numTriangles;
    int *m_pTriangleIndices;
};

// 使用的網(wǎng)格
int m_numMeshes;
Mesh *m_pMeshes;

  
 m_pTriangleIndices指向包含在網(wǎng)格中三角形的數(shù)據(jù),它是動(dòng)態(tài)分配的。 m_materialIndex 指向了這個(gè)網(wǎng)格所用的材質(zhì)。 
  

// 材質(zhì)屬性
struct Material
{
    float m_ambient[4], m_diffuse[4], m_specular[4], m_emissive[4];
    float m_shininess;
    GLuint m_texture;
    char *m_pTextureFilename;
};

// 使用的紋理
int m_numMaterials;
Material *m_pMaterials;

  
 這里我們使用與OpenGL中相對(duì)的材質(zhì)。
下面的代碼用來(lái)載入模型,我們通過(guò)重載loadModelData函數(shù)來(lái)實(shí)現(xiàn)它。

我們創(chuàng)建了一個(gè)新類MilkshapeModel,它是從Model繼承而來(lái)的。 
  

bool MilkshapeModel::loadModelData( const char *filename )
{
    ifstream inputFile( filename, ios::in | ios::binary | ios::nocreate );
    if ( inputFile.fail())
        return false;    // 不能打開(kāi)文件,返回失敗

  
 以二進(jìn)制的方式打開(kāi)文件,如果失敗則返回 
  

    inputFile.seekg( 0, ios::end );
    long fileSize = inputFile.tellg();
    inputFile.seekg( 0, ios::beg );

  
 返回文件大小 
  

    byte *pBuffer = new byte[fileSize];
    inputFile.read( pBuffer, fileSize );
    inputFile.close();

  
 分配一個(gè)內(nèi)存,載入文件,并關(guān)閉文件 
  

    const byte *pPtr = pBuffer;
    MS3DHeader *pHeader = ( MS3DHeader* )pPtr;
    pPtr += sizeof( MS3DHeader );

    if ( strncmp( pHeader->m_ID, "MS3D000000", 10 ) != 0 )
        return false;    // 如果不是一個(gè)有效的MS3D文件則返回

    if ( pHeader->m_version < 3 || pHeader->m_version > 4 )
        return false;    // 如果不能支持這種版本的文件,則返回失敗
  
 上面的文件讀取文件頭 
  

    int nVertices = *( word* )pPtr;
    m_numVertices = nVertices;
    m_pVertices = new Vertex[nVertices];
    pPtr += sizeof( word );

    int i;
    for ( i = 0; i < nVertices; i++ )
    {
        MS3DVertex *pVertex = ( MS3DVertex* )pPtr;
        m_pVertices[i].m_boneID = pVertex->m_boneID;
        memcpy( m_pVertices[i].m_location, pVertex->m_vertex, sizeof( float )*3 );
        pPtr += sizeof( MS3DVertex );
    }

  
 上面的代碼讀取頂點(diǎn)數(shù)據(jù) 
  

    int nTriangles = *( word* )pPtr;
    m_numTriangles = nTriangles;
    m_pTriangles = new Triangle[nTriangles];
    pPtr += sizeof( word );

    for ( i = 0; i < nTriangles; i++ )
    {
        MS3DTriangle *pTriangle = ( MS3DTriangle* )pPtr;
        int vertexIndices[3] = { pTriangle->m_vertexIndices[0], pTriangle->m_vertexIndices[1], pTriangle->m_vertexIndices[2] };
        float t[3] = { 1.0f-pTriangle->m_t[0], 1.0f-pTriangle->m_t[1], 1.0f-pTriangle->m_t[2] };
        memcpy( m_pTriangles[i].m_vertexNormals, pTriangle->m_vertexNormals, sizeof( float )*3*3 );
        memcpy( m_pTriangles[i].m_s, pTriangle->m_s, sizeof( float )*3 );
        memcpy( m_pTriangles[i].m_t, t, sizeof( float )*3 );
        memcpy( m_pTriangles[i].m_vertexIndices, vertexIndices, sizeof( int )*3 );
        pPtr += sizeof( MS3DTriangle );
    }

  
 上面的代碼用來(lái)讀取三角形信息,因?yàn)镸S3D使用窗口坐標(biāo)系而OpenGL使用笛卡兒坐標(biāo)系,所以需要反轉(zhuǎn)每個(gè)頂點(diǎn)Y方向的紋理坐標(biāo) 
  

    int nGroups = *( word* )pPtr;
    m_numMeshes = nGroups;
    m_pMeshes = new Mesh[nGroups];
    pPtr += sizeof( word );
    for ( i = 0; i < nGroups; i++ )
    {
        pPtr += sizeof( byte );   
        pPtr += 32;   

        word nTriangles = *( word* )pPtr;
        pPtr += sizeof( word );
        int *pTriangleIndices = new int[nTriangles];
        for ( int j = 0; j < nTriangles; j++ )
        {
            pTriangleIndices[j] = *( word* )pPtr;
            pPtr += sizeof( word );
        }

        char materialIndex = *( char* )pPtr;
        pPtr += sizeof( char );

        m_pMeshes[i].m_materialIndex = materialIndex;
        m_pMeshes[i].m_numTriangles = nTriangles;
        m_pMeshes[i].m_pTriangleIndices = pTriangleIndices;
    }

  
 上面的代碼填充網(wǎng)格結(jié)構(gòu) 
  

    int nMaterials = *( word* )pPtr;
    m_numMaterials = nMaterials;
    m_pMaterials = new Material[nMaterials];
    pPtr += sizeof( word );
    for ( i = 0; i < nMaterials; i++ )
    {
        MS3DMaterial *pMaterial = ( MS3DMaterial* )pPtr;
        memcpy( m_pMaterials[i].m_ambient, pMaterial->m_ambient, sizeof( float )*4 );
        memcpy( m_pMaterials[i].m_diffuse, pMaterial->m_diffuse, sizeof( float )*4 );
        memcpy( m_pMaterials[i].m_specular, pMaterial->m_specular, sizeof( float )*4 );
        memcpy( m_pMaterials[i].m_emissive, pMaterial->m_emissive, sizeof( float )*4 );
        m_pMaterials[i].m_shininess = pMaterial->m_shininess;
        m_pMaterials[i].m_pTextureFilename = new char[strlen( pMaterial->m_texture )+1];
        strcpy( m_pMaterials[i].m_pTextureFilename, pMaterial->m_texture );
        pPtr += sizeof( MS3DMaterial );
    }

    reloadTextures();

  
 上面的代碼加載紋理數(shù)據(jù) 
  

    delete[] pBuffer;

    return true;
}

  
 上面的代碼設(shè)置好了一切參數(shù),但紋理還沒(méi)有載入內(nèi)存,下面的代碼完成這個(gè)功能。 
  

void Model::reloadTextures()
{
    for ( int i = 0; i < m_numMaterials; i++ )
        if ( strlen( m_pMaterials[i].m_pTextureFilename ) > 0 )
            m_pMaterials[i].m_texture = LoadGLTexture( m_pMaterials[i].m_pTextureFilename );
        else
            m_pMaterials[i].m_texture = 0;
}

  
 有了數(shù)據(jù),就可以寫出繪制函數(shù)了,下面的函數(shù)根據(jù)模型的信息,按網(wǎng)格分組,分別繪制每一組的數(shù)據(jù)。 
  

void Model::draw()
{
    GLboolean texEnabled = glIsEnabled( GL_TEXTURE_2D );

    // 按網(wǎng)格分組繪制
    for ( int i = 0; i < m_numMeshes; i++ )
    {

        int materialIndex = m_pMeshes[i].m_materialIndex;
        if ( materialIndex >= 0 )
        {
            glMaterialfv( GL_FRONT, GL_AMBIENT, m_pMaterials[materialIndex].m_ambient );
            glMaterialfv( GL_FRONT, GL_DIFFUSE, m_pMaterials[materialIndex].m_diffuse );
            glMaterialfv( GL_FRONT, GL_SPECULAR, m_pMaterials[materialIndex].m_specular );
            glMaterialfv( GL_FRONT, GL_EMISSION, m_pMaterials[materialIndex].m_emissive );
            glMaterialf( GL_FRONT, GL_SHININESS, m_pMaterials[materialIndex].m_shininess );

            if ( m_pMaterials[materialIndex].m_texture > 0 )
            {
                glBindTexture( GL_TEXTURE_2D, m_pMaterials[materialIndex].m_texture );
                glEnable( GL_TEXTURE_2D );
            }
            else
                glDisable( GL_TEXTURE_2D );
        }
        else
        {
            glDisable( GL_TEXTURE_2D );
        }

        glBegin( GL_TRIANGLES );
        {
            for ( int j = 0; j < m_pMeshes[i].m_numTriangles; j++ )
            {
                int triangleIndex = m_pMeshes[i].m_pTriangleIndices[j];
                const Triangle* pTri = &m_pTriangles[triangleIndex];

                for ( int k = 0; k < 3; k++ )
                {
                    int index = pTri->m_vertexIndices[k];

                    glNormal3fv( pTri->m_vertexNormals[k] );
                    glTexCoord2f( pTri->m_s[k], pTri->m_t[k] );
                    glVertex3fv( m_pVertices[index].m_location );
                }
            }
        }
        glEnd();
    }

    if ( texEnabled )
        glEnable( GL_TEXTURE_2D );
    else
        glDisable( GL_TEXTURE_2D );
}

  
 有了上面的函數(shù),我們來(lái)看看如何使用它們。首先,我們定義一個(gè)MilkshapeModel類。 
  

    Model *pModel = NULL;    // 定義一個(gè)指向模型類的指針

  
 接著加載模型文件 
  

    pModel = new MilkshapeModel();
    if ( pModel->loadModelData( "data/model.ms3d" ) == false )
    {
        MessageBox( NULL, "不能加載data/model.ms3d文件", "加載錯(cuò)誤", MB_OK | MB_ICONERROR );
        return 0;                                    // 返回失敗
    }

  
 接著載入紋理 
  

    pModel->reloadTextures();

  
 完成了初始化操作,我們來(lái)實(shí)際繪制我們的模型 
  

int DrawGLScene(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 情況緩存
    glLoadIdentity();               
    gluLookAt( 75, 75, 75, 0, 0, 0, 0, 1, 0 );

    glRotatef(yrot,0.0f,1.0f,0.0f);

    //繪制模型
    pModel->draw();

    yrot+=1.0f;
    return TRUE;                        //成功返回
}

  
 簡(jiǎn)單吧?下一步我們?cè)撟鍪裁??在以后的教程中,我將?huì)加入骨骼動(dòng)畫的知識(shí),到時(shí)候見(jiàn)吧!
 
 
posted on 2007-12-22 15:08 sdfasdf 閱讀(1598) 評(píng)論(0)  編輯 收藏 引用 所屬分類: OPENGL
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产综合精品| 亚洲欧美在线另类| 亚洲欧美国产精品专区久久| 99精品热视频只有精品10| 一区二区三区|亚洲午夜| 一区二区三区高清不卡| 午夜国产精品影院在线观看| 午夜在线一区| 蜜臀av性久久久久蜜臀aⅴ四虎 | 伊人激情综合| 91久久精品www人人做人人爽| 日韩视频免费观看高清完整版| 一区二区三区免费看| 欧美一区在线看| 欧美激情精品久久久久久免费印度| 亚洲欧洲视频在线| 中日韩高清电影网| 久久精品盗摄| 欧美日韩国产另类不卡| 国产视频久久| 一区二区国产精品| 久久全国免费视频| 日韩视频国产视频| 久久亚洲国产成人| 国产欧美日韩亚洲| 亚洲精品视频啊美女在线直播| 亚洲欧美日韩国产中文| 亚洲成人直播| 欧美影院视频| 国产一级一区二区| 国产日韩一区| 日韩午夜av在线| 免费在线观看成人av| 亚洲一区二区欧美日韩| 欧美激情1区| 伊人久久大香线蕉综合热线| 亚洲欧美www| 日韩午夜在线| 欧美另类高清视频在线| 亚洲欧洲精品成人久久奇米网| 久久精品国产99精品国产亚洲性色 | 欧美激情第三页| 久久成人资源| 国产欧美日韩免费看aⅴ视频| 亚洲视频一二| 亚洲精品视频二区| 欧美日韩的一区二区| 1024精品一区二区三区| 久久一区二区三区av| 午夜欧美大尺度福利影院在线看| 国产精品igao视频网网址不卡日韩| 99亚洲精品| 日韩小视频在线观看| 欧美精品日韩综合在线| 亚洲美女福利视频网站| 91久久国产精品91久久性色| 你懂的国产精品| 亚洲日本欧美| 亚洲精品久久久久久下一站| 欧美黄色aaaa| 亚洲永久免费av| 在线综合+亚洲+欧美中文字幕| 国产精品久久二区| 久久精品网址| 久久视频一区二区| 亚洲国产精品成人久久综合一区| 欧美成人高清视频| 久久久噜噜噜久噜久久| 亚洲国产va精品久久久不卡综合| 亚洲电影免费观看高清| 免费视频一区| 一区二区av在线| 亚洲私人黄色宅男| 国产一区二区三区丝袜| 免费亚洲一区二区| 欧美日韩国产a| 欧美一区二区三区日韩| 久久国内精品视频| 亚洲精品日韩精品| 亚洲一区二区三区高清不卡| 国产有码在线一区二区视频| 欧美jizz19性欧美| 欧美理论电影在线播放| 亚洲欧美综合国产精品一区| 久久综合伊人77777| 蜜臀av国产精品久久久久| 欧美sm视频| 亚洲免费网址| 久久亚洲综合| 亚洲一区二区三区高清| 性色av一区二区怡红| 亚洲国产免费| 亚洲制服av| 亚洲靠逼com| 欧美一级在线视频| 一本色道久久综合亚洲精品小说| 亚洲欧美日韩国产综合| 日韩五码在线| 久久精品欧美日韩| 亚洲欧美清纯在线制服| 欧美电影美腿模特1979在线看| 亚洲欧美影音先锋| 欧美aaa级| 久久中文字幕一区| 国产精品美女www爽爽爽| 亚洲第一中文字幕| 狠狠久久亚洲欧美专区| 亚洲一区二区在线视频| 夜夜嗨av一区二区三区| 久久性色av| 久久综合网hezyo| 国产精品久久久久免费a∨大胸| 欧美高清免费| 国内精品视频一区| 欧美一级淫片播放口| 亚洲专区在线视频| 欧美精品久久久久久久久久| 欧美成人高清视频| 在线免费日韩片| 久久国产成人| 久久久久久久久久久一区 | 亚洲天天影视| 中文一区字幕| 欧美日韩国产高清视频| 亚洲高清资源| 亚洲国产日韩在线| 久久精品国产亚洲a| 欧美一区网站| 国产一区在线免费观看| 久久不射电影网| 久久婷婷蜜乳一本欲蜜臀| 国产一区在线观看视频| 久久9热精品视频| 久久久亚洲国产美女国产盗摄| 国产欧美va欧美不卡在线| 亚洲性线免费观看视频成熟| 先锋影音久久| 国产欧美在线观看一区| 亚洲主播在线播放| 欧美在线免费视屏| 国产色爱av资源综合区| 久久国产婷婷国产香蕉| 欧美a级大片| 日韩亚洲欧美中文三级| 能在线观看的日韩av| 亚洲乱码国产乱码精品精天堂| 99国产欧美久久久精品| 国产精品都在这里| 欧美在线免费观看视频| 久久福利毛片| 亚洲欧美日韩网| 亚洲在线第一页| 国产精品啊v在线| 亚洲尤物影院| 免费在线观看精品| 亚洲最新在线视频| 国产精品日韩在线一区| 亚洲欧美日韩另类精品一区二区三区| 欧美一区二区三区免费大片| 韩国在线视频一区| 欧美激情精品久久久久久| 99热这里只有精品8| 欧美一进一出视频| 影音先锋一区| 欧美日韩国产一级片| 亚洲欧美精品suv| 免费日韩av| 亚洲综合另类| 国内精品久久久久久久影视麻豆 | 亚洲视频每日更新| 国产一区二区在线观看免费播放| 久久香蕉国产线看观看av| 99精品视频免费观看视频| 久久久精品日韩| 一区二区三区视频在线| 国产色爱av资源综合区| 欧美精品入口| 久久亚洲捆绑美女| 这里只有精品视频在线| 欧美成人免费va影院高清| 亚洲影院在线| 日韩一级视频免费观看在线| 激情欧美一区二区三区| 欧美日韩免费观看中文| 久久久综合网站| 亚洲欧美精品| 一区二区三区产品免费精品久久75| 欧美jizz19性欧美| 久久精品视频播放| 亚洲欧美在线视频观看| 一本到高清视频免费精品| 精品动漫3d一区二区三区免费| 欧美午夜精品久久久久免费视| 欧美mv日韩mv亚洲| 久久久www成人免费无遮挡大片| 亚洲网站在线| 99热在这里有精品免费| 亚洲精品小视频| 亚洲区在线播放| 亚洲福利在线看|