• <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>

            天行健 君子當(dāng)自強(qiáng)而不息

            D3D中的地形繪制基礎(chǔ)(2)

            新建網(wǎng)頁(yè) 1

            13.2.1 計(jì)算頂點(diǎn)

            在圖13.4中,計(jì)算三角形網(wǎng)格上的頂點(diǎn),我們只是在開始產(chǎn)生頂點(diǎn)的地方,一行一行的生成頂點(diǎn)數(shù)據(jù),直到結(jié)束為止。單元格的頂點(diǎn)與頂點(diǎn)之間有一塊空白區(qū)域,這會(huì)讓我們?nèi)〉脁、z坐標(biāo),但y坐標(biāo)是什么呢?得到y(tǒng)坐標(biāo)很容易,當(dāng)讀取高度圖數(shù)據(jù)結(jié)構(gòu)時(shí)會(huì)找到對(duì)應(yīng)的入口。

            注意:這個(gè)操作使用一個(gè)巨大的頂點(diǎn)緩存去保存所有地形上的所有頂點(diǎn)。這可能會(huì)引起硬件局限性的問(wèn)題。例如:3D設(shè)備都預(yù)設(shè)了最大圖元數(shù)和最大頂點(diǎn)索引值。檢查D3DCAPS9結(jié)構(gòu)的MaxPrimitiveCount和MaxVertexlndex成員來(lái)獲得你的設(shè)備的限定值。

            計(jì)算紋理坐標(biāo),看圖13.5,給我們一個(gè)簡(jiǎn)單的設(shè)定,允許我們用(u, v)紋理坐標(biāo)去對(duì)應(yīng)地形頂點(diǎn)坐標(biāo)。

            最后,用代碼生成頂點(diǎn):

                bool cTerrain::generate_vertices()
                {
                    
            if(FAILED(m_device->CreateVertexBuffer(m_num_vertices * sizeof(cTerrainVertex), D3DUSAGE_WRITEONLY,
                        TERRAIN_VERTEX_FVF, D3DPOOL_MANAGED, &m_vertex_buffer, NULL)))
                    {
                        
            return false;
                    }
                
                    
            // coordinates to start generating vertices at
                
                int start_x = -m_width / 2;
                    
            int start_z =  m_depth / 2;
                
                    
            // coordinates to end generating vertices at
                
                int end_x =  m_width / 2;
                    
            int end_z = -m_depth / 2;
                
                    
            // compute the increment size of the texture coordinates from one vertex to the next
                
                float u_coord_increment_size = 1.0f / m_num_cells_per_row;
                    
            float v_coord_increment_size = 1.0f / m_num_cells_per_col;
                
                    cTerrainVertex* v;
                
                    m_vertex_buffer->Lock(0, 0, (
            void**)&v, 0);
                
                    
            int row = 0;
                
                    
            for(int z = start_z; z >= end_z; z -= m_cell_spacing)
                    {
                        
            int column = 0;
                
                        
            for(int x = start_x; x <= end_x; x += m_cell_spacing)
                        {
                            
            int index = row * m_num_verts_per_row + column;
                
                            v[index] = cTerrainVertex(x, m_height_map[index], z,
                                                      column * u_coord_increment_size, row * v_coord_increment_size);
                
                            column++;
                        }
                
                        row++;
                    }
                
                
                    m_vertex_buffer->Unlock();
                    
                    
            return true;
                }

            13.2.2 計(jì)算索引-定義三角形

            計(jì)算三角形網(wǎng)格的索引,只需要循環(huán)訪問(wèn)每一個(gè)格子,從左上到右下,如圖13.4,并且計(jì)算組成格子的2個(gè)三角形。

            代碼生成索引:

                bool cTerrain::generate_indices()
                {
                    
            if(FAILED(m_device->CreateIndexBuffer(
                        m_num_triangles * 3 * 
            sizeof(WORD),    // 3 indices per triangle
                
                        D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_index_buffer, NULL)))
                    {
                        
            return false;
                    }
                
                    WORD* indices;
                
                    m_index_buffer->Lock(0, 0, (
            void**)&indices, 0);
                
                    
            // index to start of a group of 6 indices that describe the two triangles that make up a quad
                
                int base_index = 0;
                
                    
            // loop through and compute the triangles of each quad
                
                for(int row = 0; row < m_num_cells_per_col; row++)
                    {
                        
            for(int col = 0; col < m_num_cells_per_row; col++)
                        {
                            indices[base_index]        = row      * m_num_verts_per_row + col;
                            indices[base_index + 1] = row      * m_num_verts_per_row + (col+1);
                            indices[base_index + 2] = (row+1) * m_num_verts_per_row + col;
                
                            indices[base_index + 3]    = (row+1) * m_num_verts_per_row + col;
                            indices[base_index + 4] = row      * m_num_verts_per_row + (col+1);
                            indices[base_index + 5] = (row+1) * m_num_verts_per_row + (col+1);
                
                            base_index += 6;    
            // next quad
                
                    }
                    }
                
                    m_index_buffer->Unlock();
                
                    
            return true;
                }

            13.3紋理

            cTerrain類提供2個(gè)方法去處理地形的紋理。最簡(jiǎn)單的方法是讀取一個(gè)已經(jīng)制作好的紋理文件并使用它:
                bool cTerrain::load_texture(const string& filename)
                {
                    
            if(FAILED(D3DXCreateTextureFromFile(m_device, filename.c_str(), &m_texture)))
                        
            return false;
                
                    
            return true;
                }

            13.3.1 程序上的處理方法

            一個(gè)可選擇的方法是用程序計(jì)算地形的紋理,就是說(shuō),我們創(chuàng)建一個(gè)空紋理,根據(jù)定義的參數(shù)用代碼計(jì)算每一個(gè)部分的顏色,在例子中,參數(shù)是地形的高度。

            我們用cTerrain::generate_texture方法去生成紋理,首先用D3DXCreateTexture方法創(chuàng)建一個(gè)空的紋理,鎖定高度級(jí)別(top level,紋理圖的一個(gè)成員,有多個(gè)級(jí)別),不斷的循環(huán)每一個(gè)texel圖素)并給它上色,texel的顏色取決于與方格對(duì)應(yīng)的高度(近似高度)。我們的想法是:地形中較低的地方是沙灘色,中間的地方像是綠色的小山丘,較高的地方顏色好像雪山。我們定義的高度是方格中左上角的近似高度。

            一旦每個(gè)texel都有了顏色,我們想讓每一個(gè)texel變暗或是變亮,這基于光打在格子中對(duì)應(yīng)的texel上的角度,由Terrain::lightTerrain方法實(shí)現(xiàn)。
                bool cTerrain::generate_texture(D3DXVECTOR3* dir_to_light)
                {
                    
            // Method fills the top surface of a texture procedurally, then lights the top surface.
                    // Finally, it fills the other mipmap surfaces based on the top surface data using D3DXFilterTexture.
                
                    // texel for each quad cell
                
                int texture_width  = m_num_cells_per_row;
                    
            int texture_height = m_num_cells_per_col;
                
                    
            // create an empty texture with a complete mipmap chain
                
                if(FAILED(D3DXCreateTexture(m_device, texture_width, texture_height, 0, 0, D3DFMT_X8R8G8B8,
                                                D3DPOOL_MANAGED, &m_texture)))
                    {
                        
            return false;
                    }
                
                    D3DSURFACE_DESC texture_desc;
                    m_texture->GetLevelDesc(0, &texture_desc);
                
                    
            // make sure we got the requested format because our code that fills the texture is
                    // hard coded to a 32 bit pixel depth.
                
                if(texture_desc.Format != D3DFMT_X8R8G8B8)
                        
            return false;
                
                    
            // lock top entire texture surface
                
                D3DLOCKED_RECT locked_rect;
                    m_texture->LockRect(0, &locked_rect, NULL, 0);
                
                    DWORD* image_data = (DWORD*) locked_rect.pBits;
                
                    
            for(int row = 0; row < texture_height; row++)
                    {
                        
            for(int col = 0; col < texture_width; col++)
                        {
                            D3DXCOLOR color;
                
                            
            // get height of upper left vertex of quad
                
                        float height = get_height_map_entry(row, col) / m_height_scale;
                
                            
            if(height < 42.5f)          color = BEACH_SAND;
                            
            else if(height < 85.0f)  color = LIGHT_YELLOW_GREEN;
                            
            else if(height < 127.5f) color = PUREGREEN;
                            
            else if(height < 170.0f) color = DARK_YELLOW_GREEN;
                            
            else if(height < 212.5f) color = DARKBROWN;
                            
            else                     color = WHITE;
                
                            
            // fill locked data, note we divide the pitch by four because the pitch is given in bytes
                            // and there are 4 bytes per DWORD.
                
                            image_data[row * (locked_rect.Pitch / 4) + col] = (D3DCOLOR) color;
                        }
                    }
                
                    m_texture->UnlockRect(0);
                
                    
            if(! light_terrain(dir_to_light))
                    {
                        MessageBox(NULL, "light_terrain() - FAILED", "ERROR", MB_OK);
                        
            return false;
                    }
                
                    
            if(FAILED(D3DXFilterTexture(m_texture, NULL, 0, D3DX_DEFAULT)))
                    {
                        MessageBox(NULL, "D3DXFilterTexture() - FAILED", "ERROR", MB_OK);
                        
            return false;
                    }
                
                    
            return true;
                }

            posted on 2008-04-02 19:41 lovedday 閱讀(1912) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            久久er国产精品免费观看8| 国产欧美一区二区久久| 欧美激情精品久久久久| 久久精品国产91久久麻豆自制| www性久久久com| 91精品国产色综久久| 人人狠狠综合久久亚洲高清| 国内精品久久久久影院亚洲| 97久久婷婷五月综合色d啪蜜芽 | 成人综合伊人五月婷久久| 精品久久久久久成人AV| 久久国产福利免费| 亚洲va中文字幕无码久久| 国产精品青草久久久久福利99| 老男人久久青草av高清| 伊人久久大香线焦综合四虎| 久久人人爽人人爽人人片AV东京热| 97久久超碰国产精品2021| 日韩美女18网站久久精品| MM131亚洲国产美女久久| 麻豆久久久9性大片| 精品国产热久久久福利| 久久精品99久久香蕉国产色戒| 综合久久给合久久狠狠狠97色| 久久99精品久久久久久| 久久精品国产亚洲AV影院| 精品久久久久久无码人妻热| 久久精品国产一区| 东京热TOKYO综合久久精品| 久久久久人妻一区二区三区vr| 亚洲国产精品一区二区三区久久| 国产99久久久国产精免费| 久久se精品一区精品二区| 国产91久久精品一区二区| 久久久免费精品re6| 久久无码人妻一区二区三区| 国产成人久久精品一区二区三区| 精品国产日韩久久亚洲| 午夜天堂精品久久久久| 国产亚洲美女精品久久久2020| 无码人妻久久一区二区三区蜜桃|