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

隨筆 - 32  文章 - 94  trackbacks - 0
<2010年2月>
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213

常用鏈接

留言簿(8)

隨筆分類

隨筆檔案

好友連接

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

之前的一篇文章實現的是完全基于四叉樹的動態地形渲染,雖然感覺那種方案是最優美的方案,假設CPU和GPU速度上沒有差別的話,那種方案應該是最佳的了。但是現實中CPU速度還是比GPU慢不少的,因此,參考了這篇文章:http://nvidia.e-works.net.cn/document/200908/article8938_2.htm 并按其思路實現了分塊的地形LOD算法,整體思路感覺比之前的完全動態地形渲染還要簡單些。

1、文章中的裂縫消除部分提到了要把地形塊分成5個部分,實際上只需要分成3個部分(中間獨立部分、上或下,左或右)就可以了。
2、另外文章中提到的頂高度點漸變時的插值,好像需要實時頻繁改變頂點數據,感覺對效率會影響很大,目前還不知道應該怎么處理好些,請教各位高手有沒有具體實現思路。。。
3、還有文章提到的采用Triangle strip可以減少索引數目,也沒有實現(偷懶),用四邊形代替....


目前測試程序中該地形的塊大小是33*33,總大小是1057*1057(即32*32個塊),塊距離lod比例是4,(即包圍球半徑 除以 中心到相機距離 再除以 4,如果值小于1就采用全分辨率,1--2是第2級分辨率.....直到一個塊只用一個4邊形表示的最低分辨率)
看起來效果好像還不如之前的完全動態LOD地形,可能還需要調整好每個塊大小、距離比例等參數。

地形塊之間的裂縫消除:


相關代碼
  1#pragma once
  2
  3#include "VertexBuffer.h"
  4#include "SceneObject.h"
  5#include <hash_map>
  6#include "Shader.h"
  7
  8//////////////////////////////////////////////////////////////////////////
  9#include "TGAFile.h"
 10//////////////////////////////////////////////////////////////////////////
 11
 12namespace C_Y
 13{
 14    /*
 15    每個地形塊長度:2^n+1,每個地形塊頂點數 (2^n+2)*(2^n+2)
 16
 17    地形塊數量:2^m * 2^m
 18
 19    地形總頂點數滿足:(2^n+1) * 2^m +1 的平方
 20    */

 21    class CY_GeoMipMapTerrain
 22    {
 23        struct CY_LodBlock
 24        {
 25            CY_VertexBuffer m_VertexBuffer;            //頂點buffer
 26            
 27            CY_Vector3f m_CenterPos;                //中心位置
 28            float m_BoundingRadius;                    //包圍球半徑
 29        }
;
 30        struct CY_QuadTreeNode
 31        {
 32            CY_LodBlock *m_LeafBlock;                //葉結點
 33            CY_QuadTreeNode *m_Down;                //相鄰的下結點
 34            CY_QuadTreeNode *m_Right;                //相鄰的右結點
 35
 36            CY_QuadTreeNode *m_UpLeft;                //子結點
 37            CY_QuadTreeNode *m_UpRight;
 38            CY_QuadTreeNode *m_DownLeft;
 39            CY_QuadTreeNode *m_DownRight;
 40
 41            CY_Vector3f m_CenterPos;                //中心位置
 42            float m_BoundingRadius;                    //包圍球半徑
 43            
 44            int m_StartX;                            //索引所有頂點中,起始的頂點位置X
 45            int m_EndX;
 46            int m_StartY;
 47            int m_EndY;
 48
 49            int m_SelfLevel;                        //lod級別,負數表示不渲染,level越低越精細
 50
 51            CY_QuadTreeNode():m_LeafBlock(0),m_Down(0),m_Right(0),m_UpLeft(0),m_UpRight(0),m_DownLeft(0),m_DownRight(0){}
 52            ~CY_QuadTreeNode()
 53            {
 54                if(m_LeafBlock)
 55                    delete m_LeafBlock;
 56                if(m_UpLeft)
 57                    delete m_UpLeft;
 58                if(m_UpRight)
 59                    delete m_UpRight;
 60                if(m_DownRight)
 61                    delete m_DownRight;
 62                if(m_DownLeft)
 63                    delete m_DownLeft;
 64            }

 65            void GenRender(CY_Camera*&cam,std::vector<CY_QuadTreeNode*>&renderlist,const int&maxlevel);
 66            CY_Vector3f GetCenterPos();            //逐級獲得中心點
 67            float GetBoundingRadius();            //逐級獲得包圍球半徑
 68        }
;
 69        //---------------------------------------------------------------------------------------------
 70
 71        int m_BlockSize;                        //每個塊的邊長是多少格,必須是 2^n+1
 72        int m_BlockNum;                            //總的塊數量的邊長是多少塊,寬和高一致,值必須是 2^m
 73
 74        int m_TotalSize;                        //總邊長是多少個點(邊上的頂點數),值必須是 m_BlockSize*m_BlockNum+1
 75
 76        CY_Vector3f m_UnitSize;                    //深、寬、高的比例
 77        float m_DistanceRate;                    //Lod優化程度
 78
 79        CY_QuadTreeNode *m_Root;                //根結點
 80        CY_QuadTreeNode **m_AllLeaf;            //所有葉節點,按照地形的排列進行排序
 81
 82        GLuint *m_LodBufferIndex;                //所有lod下的頂點索引緩沖,
 83        int *m_LodIndexCount;                    //緩沖的index數量
 84        int m_LodBufferCount;
 85
 86        GLuint m_RightEdgeIndex;                //右邊緣的裂縫消除
 87        unsigned *m_Right_1_Index;
 88        unsigned *m_Right_Index;
 89
 90        GLuint m_DownEdgeIndex;                    //下邊緣的裂縫消除
 91        unsigned *m_Down_1_Index;
 92        unsigned *m_Down_Index;
 93
 94        void InitIndexBuffer();
 95        void InitNode(CY_QuadTreeNode *&currNode,int Blocklength,int startX,int startY,int endX,int endY,CTargaImage&image);//處理的node,node的大小,node的起始、結束索引的頂點
 96        void InitLeaf(CY_LodBlock *&LeafBlock,int startX,int startY,int endX,int endY,CTargaImage&image);//處理葉子的block
 97        void InitAdjLeaf();
 98    public:
 99        CY_GeoMipMapTerrain();
100        ~CY_GeoMipMapTerrain();
101
102        void LoadTerrain(const std::wstring&);
103        void Render(const CY_EffectPassKind&pass);
104    }
;
105}

  1#include "GeoMipMapTerrain.h"
  2#include "SceneManager.h"
  3//////////////////////////////////////////////////////////////////////////
  4#include "TGAFile.h"
  5#include "MaterialSystem.h"
  6#include "LogManager.h"
  7//////////////////////////////////////////////////////////////////////////
  8
  9namespace C_Y
 10{
 11    void CY_GeoMipMapTerrain::CY_QuadTreeNode::GenRender(CY_Camera*&cam,std::vector<CY_QuadTreeNode*>&renderlist,const int&maxlevel)
 12    {    
 13        if(m_LeafBlock)
 14        {
 15            m_LeafBlock->m_VertexBuffer.PrepareThisGeometryChunk();
 16            m_SelfLevel=(cam->GetWorldPos()-m_CenterPos).QuickLength()/(m_BoundingRadius*4);
 17            if(m_SelfLevel>=maxlevel)
 18                m_SelfLevel=maxlevel-1;
 19            renderlist.push_back(this);
 20        }

 21        else
 22        {
 23            if(cam->GetFrustum()->SphereInFrustum(m_UpLeft->m_CenterPos,m_UpLeft->m_BoundingRadius))
 24                m_UpLeft->GenRender(cam,renderlist,maxlevel);
 25            if(cam->GetFrustum()->SphereInFrustum(m_UpRight->m_CenterPos,m_UpRight->m_BoundingRadius))
 26                m_UpRight->GenRender(cam,renderlist,maxlevel);
 27            if(cam->GetFrustum()->SphereInFrustum(m_DownLeft->m_CenterPos,m_DownLeft->m_BoundingRadius))
 28                m_DownLeft->GenRender(cam,renderlist,maxlevel);
 29            if(cam->GetFrustum()->SphereInFrustum(m_DownRight->m_CenterPos,m_DownRight->m_BoundingRadius))
 30                m_DownRight->GenRender(cam,renderlist,maxlevel);
 31        }

 32    }

 33    CY_Vector3f CY_GeoMipMapTerrain::CY_QuadTreeNode::GetCenterPos()
 34    {
 35        if(m_LeafBlock)
 36        {
 37            m_CenterPos=m_LeafBlock->m_CenterPos;
 38            return m_CenterPos;
 39        }

 40        else
 41        {
 42            m_CenterPos=(m_UpLeft->GetCenterPos()+m_DownLeft->GetCenterPos()+m_UpRight->GetCenterPos()+m_DownRight->GetCenterPos())/4;
 43            return m_CenterPos;
 44        }

 45    }

 46    float CY_GeoMipMapTerrain::CY_QuadTreeNode::GetBoundingRadius()
 47    {
 48        if(m_LeafBlock)
 49        {
 50            m_BoundingRadius=m_LeafBlock->m_BoundingRadius;
 51            return m_BoundingRadius;
 52        }

 53        else
 54        {
 55            m_BoundingRadius=0;
 56            float currr=(m_CenterPos-m_UpLeft->m_CenterPos).Length()+m_UpLeft->GetBoundingRadius();
 57            if(m_BoundingRadius<currr)
 58                m_BoundingRadius=currr;
 59            currr=(m_CenterPos-m_UpRight->m_CenterPos).Length()+m_UpRight->GetBoundingRadius();
 60            if(m_BoundingRadius<currr)
 61                m_BoundingRadius=currr;
 62            currr=(m_CenterPos-m_DownLeft->m_CenterPos).Length()+m_DownLeft->GetBoundingRadius();
 63            if(m_BoundingRadius<currr)
 64                m_BoundingRadius=currr;
 65            currr=(m_CenterPos-m_DownRight->m_CenterPos).Length()+m_DownRight->GetBoundingRadius();
 66            if(m_BoundingRadius<currr)
 67                m_BoundingRadius=currr;
 68            return m_BoundingRadius;
 69        }

 70    }

 71    //-----------------------------------------------------------------------------------------------------------------------
 72    CY_GeoMipMapTerrain::CY_GeoMipMapTerrain()
 73    {
 74        m_Root=0;
 75        m_AllLeaf=0;
 76        m_LodBufferIndex=0;
 77        m_LodIndexCount=0;
 78
 79        m_Right_1_Index=0;
 80        m_Right_Index=0;
 81        m_Down_1_Index=0;
 82        m_Down_Index=0;
 83    }

 84    CY_GeoMipMapTerrain::~CY_GeoMipMapTerrain()
 85    {
 86        if(m_Root)
 87            delete m_Root;
 88        if(m_AllLeaf)
 89            delete []m_AllLeaf;
 90        if(m_LodBufferIndex)
 91        {
 92            glDeleteBuffers(m_LodBufferCount,m_LodBufferIndex);
 93            delete []m_LodBufferIndex;
 94        }

 95        if(m_LodIndexCount)
 96            delete []m_LodIndexCount;
 97        if(m_Right_1_Index)
 98            delete []m_Right_1_Index;
 99        if(m_Right_Index)
100            delete []m_Right_Index;
101        if(m_Down_1_Index)
102            delete []m_Down_1_Index;
103        if(m_Down_Index)
104            delete []m_Down_Index;
105    }

106
107    void CY_GeoMipMapTerrain::InitIndexBuffer()
108    {
109        m_LodBufferCount=GetPow2Num(m_BlockSize-1)+1;
110        m_LodBufferIndex=new GLuint[m_LodBufferCount];
111        m_LodIndexCount=new int[m_LodBufferCount];
112
113        unsigned *AllIndex=new unsigned[(m_BlockSize-1)*(m_BlockSize-1)*4];
114        int step;
115        const int lineLength=m_BlockSize+1;
116        glGenBuffers(m_LodBufferCount,m_LodBufferIndex);
117        for(int i=0;i<m_LodBufferCount;++i)                        //計算索引值
118        {
119            step=1<<(m_LodBufferCount-i-1);
120            int n=0;
121            for(int y=0;y+step<m_BlockSize;y+=step)
122            {
123                for(int x=0;x+step<m_BlockSize;x+=step)
124                {
125                    if((y+step)*lineLength+step>=(m_BlockSize+1)*(m_BlockSize+1))
126                    {
127                        bool success;
128                        success=false;
129                    }

130                    AllIndex[n++]=y*lineLength+x+step;
131                    AllIndex[n++]=y*lineLength+x;
132
133                    AllIndex[n++]=(y+step)*lineLength+x;
134                    AllIndex[n++]=(y+step)*lineLength+step+x;
135
136                }

137            }

138            if(n!=(m_BlockSize-1)*(m_BlockSize-1)*4)
139            {
140                bool success;
141                success=false;
142            }

143            m_LodIndexCount[m_LodBufferCount-1-i]=n;
144            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_LodBufferIndex[m_LodBufferCount-1-i]);//最高精度的地形從0起
145            glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(unsigned)*n,AllIndex,GL_STATIC_DRAW);
146        }

147        delete []AllIndex;
148    }

149    void CY_GeoMipMapTerrain::InitNode(CY_QuadTreeNode *&currNode,int Blocklength,int startX,int startY,int endX,int endY,CTargaImage&image)
150    {
151        currNode=new CY_QuadTreeNode();
152        currNode->m_StartX=startX;
153        currNode->m_StartY=startY;
154        currNode->m_EndX=endX;
155        currNode->m_EndY=endY;
156        if(Blocklength>1)
157        {
158            InitNode(currNode->m_UpLeft,Blocklength/2,startX,startY,(startX+endX)/2,(startY+endY)/2,image);
159            InitNode(currNode->m_UpRight,Blocklength/2,(startX+endX)/2,startY,endX,(startY+endY)/2,image);
160            InitNode(currNode->m_DownLeft,Blocklength/2,startX,(startY+endY)/2,(startX+endX)/2,endY,image);
161            InitNode(currNode->m_DownRight,Blocklength/2,(startX+endX)/2,(startY+endY)/2,endX,endY,image);
162        }

163        else
164        {
165            InitLeaf(currNode->m_LeafBlock,startX,startY,endX,endY,image);
166            int index=startX/m_BlockSize+startY/m_BlockSize*m_BlockNum;
167            if(index>m_BlockNum*m_BlockNum)
168                bool success=false;
169            m_AllLeaf[index]=currNode;
170        }

171    }

172
173    void CY_GeoMipMapTerrain::InitLeaf(CY_LodBlock *&LeafBlock,int startX,int startY,int endX,int endY,CTargaImage&image)
174    {
175        bool success=(endX-startX)==m_BlockSize;
176        success=(endY-startY)==m_BlockSize;
177
178        LeafBlock=new CY_LodBlock();
179
180        LeafBlock->m_VertexBuffer.SetUsableVerAttr(CY_VER_ATT_POS);
181        LeafBlock->m_VertexBuffer.CreateBuffer((m_BlockSize+1)*(m_BlockSize+1));
182
183        int n=0,temp,tmpindex;
184        CY_Vector3f TotalPos(0,0,0);
185        CY_Vector3f tempPos;
186        for(int y=startY;y<=endY;++y)
187        {
188            for(int x=startX;x<=endX;++x)
189            {
190                tmpindex=x+y*m_TotalSize;                        //當前點在圖中的索引
191                temp=image.GetImage()[tmpindex*4+3];            //點alpha
192
193                tempPos.Set(x*m_UnitSize.x,temp*m_UnitSize.z,y*m_UnitSize.y);
194                TotalPos+=tempPos;
195                LeafBlock->m_VertexBuffer.GetVertex(n)->m_Pos=tempPos;
196                ++n;
197            }

198        }

199        success=n==LeafBlock->m_VertexBuffer.GetVertexCount();
200        LeafBlock->m_VertexBuffer.GenVertexBuffer();
201
202        LeafBlock->m_CenterPos=TotalPos/n;    //得到這個地形塊的中點
203
204        float r=0;
205        LeafBlock->m_BoundingRadius=0;
206        for(int i=0;i<n;++i)            //得到這個地形塊的包圍球半徑
207        {
208            r=(LeafBlock->m_VertexBuffer.GetVertex(i)->m_Pos - LeafBlock->m_CenterPos).Length();
209            if(r>LeafBlock->m_BoundingRadius)
210                LeafBlock->m_BoundingRadius=r;
211        }

212    }

213    void CY_GeoMipMapTerrain::InitAdjLeaf()
214    {
215        int n=m_BlockNum*m_BlockNum;
216        for(int i=0;i<n;++i)
217        {
218            if(i%m_BlockNum!=m_BlockNum-1)
219                m_AllLeaf[i]->m_Right=m_AllLeaf[i+1];
220            if(i/m_BlockNum<m_BlockNum-1)
221                m_AllLeaf[i]->m_Down=m_AllLeaf[i+m_BlockNum];
222        }

223    }

224
225    void CY_GeoMipMapTerrain::LoadTerrain(const std::wstring&file)
226    {
227        CTargaImage image;
228        image.Load(file);
229        //-----------------------------------設置參數
230        m_BlockSize=33;
231        m_UnitSize.Set(1.0f,1.0f,0.3f);
232        m_DistanceRate=3.0f;
233
234        m_BlockNum=(image.GetWidth()-1)/m_BlockSize;                
235        m_AllLeaf=new CY_QuadTreeNode*[m_BlockNum*m_BlockNum];
236
237        m_TotalSize=image.GetWidth();
238        //------------------------------------產生tree結構和block
239        InitNode(m_Root,m_BlockNum,0,0,m_TotalSize-1,m_TotalSize-1,image);
240        //------------------------------------產生block的右、下近鄰block
241        InitAdjLeaf();
242        //------------------------------------產生索引緩沖
243        InitIndexBuffer();
244
245        int i=0;
246        m_Right_1_Index=new unsigned[m_BlockSize];
247        for(;i<m_BlockSize;++i)                //右內邊緣的點
248        {
249            int temp=(m_BlockSize+1)*i+(m_BlockSize-1);
250            m_Right_1_Index[i]=temp;
251        }

252
253        m_Right_Index=new unsigned[m_BlockSize+1];
254        for(i=0;i<=m_BlockSize;++i)            //右外邊緣的點
255        {
256            int temp=(m_BlockSize+1)*(i+1)-1;
257            m_Right_Index[i]=temp;
258        }

259
260        m_Down_1_Index=new unsigned[m_BlockSize];
261        for(i=0;i<m_BlockSize;++i)            //下內邊緣的點
262            m_Down_1_Index[i]=(m_BlockSize+1)*(m_BlockSize-1)+i;
263
264        m_Down_Index=new unsigned[m_BlockSize+1];
265        for(i=0;i<=m_BlockSize;++i)            //下外邊緣的點
266            m_Down_Index[i]=m_BlockSize*(m_BlockSize+1)+i;
267
268        int edgesize=6*(m_BlockSize-1)+3;
269        unsigned *temp=new unsigned[edgesize];
270        for(i=0;i<edgesize;++i)
271            temp[i]=0;
272
273        temp[0]=m_BlockSize*m_BlockSize+m_BlockSize-1;
274        temp[1]=m_BlockSize*m_BlockSize+m_BlockSize-2;
275        temp[2]=(m_BlockSize+1)*(m_BlockSize+1)-1;
276
277                    
278        glGenBuffers(1,&m_RightEdgeIndex);
279        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_RightEdgeIndex);
280        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(unsigned)*edgesize,temp,GL_STREAM_DRAW);//設置了初始大小,最右下的三角形索引
281
282
283        temp[0]=m_BlockSize*m_BlockSize+m_BlockSize-2;
284        temp[1]=(m_BlockSize+1)*(m_BlockSize+1)-1;
285        temp[2]=(m_BlockSize+1)*(m_BlockSize+1)-2;
286
287        glGenBuffers(1,&m_DownEdgeIndex);
288        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_DownEdgeIndex);
289        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(unsigned)*edgesize,temp,GL_STREAM_DRAW);//設置了最右下的三角形索引
290        //------------------------------------產生包圍球
291        m_Root->GetCenterPos();
292        m_Root->GetBoundingRadius();
293    }

294    void CY_GeoMipMapTerrain::Render(const CY_EffectPassKind&pass)
295    {
296        //////////////////////////////////////////////////////////////////////////
297        CY_EffectBase *e=CY_MaterialSystem::GetInstance()->GetEffectByName("terrainEff");
298        if(e)
299            e->PrepareEffectChunk(pass);
300
301        
302        CY_Camera *camera=CY_SceneManager::GetInstance()->GetActiveCamera();
303
304        int i=0,temp;
305        for(;i<m_BlockNum*m_BlockNum;++i)
306            m_AllLeaf[i]->m_SelfLevel=-1;
307        
308        std::vector<CY_QuadTreeNode*> AllRenderBlock;
309        m_Root->GenRender(camera,AllRenderBlock,m_LodBufferCount);
310
311        for(i=0;i<(int)AllRenderBlock.size();++i)
312        {
313            AllRenderBlock[i]->m_LeafBlock->m_VertexBuffer.PrepareThisGeometryChunk();
314            temp=AllRenderBlock[i]->m_SelfLevel;
315            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_LodBufferIndex[temp]);
316            glDrawElements(GL_QUADS,m_LodIndexCount[temp],GL_UNSIGNED_INT,0);
317            
318
319            unsigned *tempIndex=new unsigned[6*(m_BlockSize-1)];
320            int r1step=(m_BlockSize-1)>>(m_LodBufferCount-1-AllRenderBlock[i]->m_SelfLevel);
321            //消除右裂縫
322            if(AllRenderBlock[i]->m_Right &&AllRenderBlock[i]->m_Right->m_SelfLevel>=0)
323            {
324                int n=0;
325                int rstep=(m_BlockSize-1)>>(m_LodBufferCount-1-AllRenderBlock[i]->m_Right->m_SelfLevel);
326
327                int currR1=0,currR=0;
328                while(currR<m_BlockSize-1 || currR1<m_BlockSize-1)
329                {
330                    if(currR<currR1)
331                    {
332                        tempIndex[n++]=m_Right_Index[currR];
333                        tempIndex[n++]=m_Right_1_Index[currR1];
334                        currR+=rstep;
335                        tempIndex[n++]=m_Right_Index[currR];
336                    }

337                    else
338                    {
339                        tempIndex[n++]=m_Right_Index[currR];
340                        tempIndex[n++]=m_Right_1_Index[currR1];
341                        currR1+=r1step;
342                        tempIndex[n++]=m_Right_1_Index[currR1];
343                    }

344                }

345
346                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_RightEdgeIndex);
347                glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,sizeof(unsigned)*3,sizeof(unsigned)*n,tempIndex);
348                glDrawElements(GL_TRIANGLES,3+n,GL_UNSIGNED_INT,0);
349            }

350            //消除下裂縫
351            if(AllRenderBlock[i]->m_Down && AllRenderBlock[i]->m_Down->m_SelfLevel>=0)
352            {
353                int n=0;
354                int rstep=(m_BlockSize-1)>>(m_LodBufferCount-1-AllRenderBlock[i]->m_Down->m_SelfLevel);
355
356                int currR1=0,currR=0;
357                while(currR<m_BlockSize-1 || currR1<m_BlockSize-1)
358                {
359                    if(currR<currR1)
360                    {
361                        tempIndex[n++]=m_Down_1_Index[currR1];
362                        tempIndex[n++]=m_Down_Index[currR];
363                        currR+=rstep;
364                        tempIndex[n++]=m_Down_Index[currR];
365                    }

366                    else
367                    {
368                        tempIndex[n++]=m_Down_1_Index[currR1];
369                        tempIndex[n++]=m_Down_Index[currR];
370                        currR1+=r1step;
371                        tempIndex[n++]=m_Down_1_Index[currR1];
372                    }

373                }

374
375
376                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_DownEdgeIndex);
377                glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,sizeof(unsigned)*3,sizeof(unsigned)*n,tempIndex);
378                glDrawElements(GL_TRIANGLES,3+n,GL_UNSIGNED_INT,0);
379            }

380            delete []tempIndex;
381        }

382
383        //////////////////////////////////////////////////////////////////////////
384    }

385}
;
posted on 2010-02-09 19:24 陳昱(CY) 閱讀(2061) 評論(0)  編輯 收藏 引用 所屬分類: C++游戲編程圖形學
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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精品国产| 久久综合久色欧美综合狠狠 | 久久久91精品国产| 久久激情视频免费观看| 免费一级欧美片在线观看| 亚洲国产成人一区| 亚洲私人影院| 久久精品91| 欧美—级高清免费播放| 国产精品高清免费在线观看| 国产一区二区三区四区在线观看| 亚洲第一在线| 亚洲一区免费看| 蜜桃av综合| 亚洲一区二区三区激情| 久久久久一区二区三区| 国产精品av一区二区| 国产精品区一区二区三区| 国产精品视频自拍| 伊人久久大香线蕉综合热线| 99riav久久精品riav| 午夜精品久久久久久久男人的天堂 | 亚洲综合第一| 狂野欧美一区| 国产日韩亚洲欧美| 一区二区免费在线视频| 老司机午夜精品视频| 亚洲精选视频免费看| 亚洲人www| 久久午夜激情| 国产精品va在线| 亚洲国产欧美在线| 亚洲欧洲在线播放| 亚洲深夜av| 欧美福利网址| 亚洲第一精品夜夜躁人人爽 | 欧美日本精品| 又紧又大又爽精品一区二区| 中日韩在线视频| 亚洲日本欧美日韩高观看| 久久精品视频在线看| 国产日韩欧美高清| 亚洲免费在线看| 亚洲精品一二三| 欧美成人午夜视频| 亚洲美女免费精品视频在线观看| 久久久无码精品亚洲日韩按摩| 亚洲视频免费看| 欧美午夜不卡视频| 亚洲欧美中文字幕| 久久精品亚洲国产奇米99| 国产一区在线播放| 欧美黄色视屏| 欧美视频在线观看免费网址| 一区二区三区四区在线| 亚洲一区二区精品| 亚洲国产91精品在线观看| 亚洲精品综合| 久久视频这里只有精品| 国产一区二区三区高清在线观看 | 亚洲欧美中文日韩在线| 国产区日韩欧美| 欧美激情乱人伦| 欧美精品网站| 久久久久国产精品一区二区| 久热国产精品| 在线亚洲精品| 欧美精品在线免费观看| 久久深夜福利| 国产精品―色哟哟| 亚洲精品三级| 一区国产精品| 久久久国产精品一区二区三区| 亚洲最新视频在线播放| 欧美ed2k| 亚洲激情一区| 99热这里只有精品8| 欧美精品电影| 91久久国产精品91久久性色| 亚洲高清不卡在线| 久久精品亚洲国产奇米99| 亚洲综合电影一区二区三区| 久久这里有精品视频| 两个人的视频www国产精品| 国产精品有限公司| 一区二区三区导航| 欧美在线视频一区二区三区| 国产精品美女久久久免费 | 亚洲风情亚aⅴ在线发布| 99精品久久久| 亚洲网在线观看| 亚洲丝袜av一区| 一本色道久久综合亚洲精品不卡| 欧美不卡在线视频| 亚洲精品视频免费| 午夜国产不卡在线观看视频| 国产一区二区三区的电影| 亚洲免费中文| 久久露脸国产精品| 亚洲国产精品电影| 国产精品日产欧美久久久久| 欧美中文字幕视频在线观看| 亚洲欧美国产精品桃花| 亚洲黄色一区二区三区| 国产精品成人av性教育| 久久疯狂做爰流白浆xx| 欧美激情亚洲激情| 午夜精彩国产免费不卡不顿大片| 好男人免费精品视频| 六月婷婷一区| 欧美日韩国产一级片| 亚洲激情av在线| 久久久久久亚洲精品杨幂换脸| 在线精品亚洲| 国产情人综合久久777777| 快she精品国产999| 中文欧美在线视频| 欧美wwwwww| 欧美成年人视频网站| 久久夜色精品国产欧美乱| 久久福利一区| 久久五月激情| 久久免费精品视频| 久久精品成人一区二区三区| 亚洲欧美伊人| 久久免费精品视频| 久久综合伊人77777尤物| 久久夜色精品一区| 老妇喷水一区二区三区| 亚洲青涩在线| 日韩午夜电影在线观看| 亚洲国产高清一区| 亚洲成在人线av| 亚洲视频第一页| 久久精品国产77777蜜臀| 蜜臀久久久99精品久久久久久| 欧美国产日韩在线| 亚洲国产成人精品女人久久久| 你懂的国产精品永久在线| 亚洲精品免费看| 久久久久九九视频| 欧美欧美天天天天操| 国产精品中文在线| 夜夜爽av福利精品导航| 久久精品一区二区三区中文字幕| 亚洲欧美影院| 一区二区三区欧美日韩| 美女主播精品视频一二三四| 欧美日韩亚洲91| 国产午夜精品在线| 制服丝袜激情欧洲亚洲| 久久黄色网页| 午夜日韩激情| 国产模特精品视频久久久久| 一个色综合av| 亚洲精品日韩一| 欧美日韩亚洲一区二区| 亚洲国产精品欧美一二99| 欧美在线观看视频一区二区| 亚洲精选中文字幕| 欧美另类一区二区三区| 91久久久久| 亚洲美女精品成人在线视频| 久久米奇亚洲| 亚洲精品日韩在线| 久久亚洲春色中文字幕| 久久爱另类一区二区小说| 欧美日韩亚洲不卡| 性欧美大战久久久久久久久| 99综合视频| 国产欧美日韩一区二区三区| 久久综合网络一区二区| 久久久久一区二区| 国产亚洲福利| 亚洲欧美日韩系列| 一区二区三区欧美日韩| 欧美日韩天天操| 噜噜噜噜噜久久久久久91| 欧美激情第三页| 久久九九精品| 欧美日韩国产不卡| 久久久久天天天天| 欧美日韩一二区| 久久视频这里只有精品| 欧美成人免费网| 久久只精品国产| 国产美女精品人人做人人爽| 欧美国产亚洲另类动漫| 国产区日韩欧美| 一本高清dvd不卡在线观看| 在线 亚洲欧美在线综合一区| 99成人免费视频| 亚洲精品在线二区| 久久av一区二区三区| 亚洲欧美日本日韩| 欧美精品久久久久久久久老牛影院| 亚洲影视在线|