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

隨筆 - 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在线精品观看| 欧美午夜电影在线| 欧美一区二区三区精品| 欧美一区二区视频免费观看| 韩国av一区| 免费在线成人| 毛片一区二区| 日韩亚洲一区二区| 一本色道综合亚洲| 国产女主播在线一区二区| 久久久91精品| 男女精品网站| 一区二区三区鲁丝不卡| 中文亚洲免费| 国产亚洲电影| 免费观看一区| 欧美激情亚洲视频| 亚洲欧美综合一区| 久久精品国产视频| 日韩午夜高潮| 亚洲欧美日韩在线播放| 激情欧美日韩| 亚洲精品日产精品乱码不卡| 国产精品日韩二区| 欧美a级片网| 欧美精品一区二区三区一线天视频| 亚洲无亚洲人成网站77777| 亚洲精品一区二区三| 国产午夜亚洲精品理论片色戒| 久久黄金**| 麻豆精品在线播放| 亚洲一区久久久| 久久精品视频在线| 夜久久久久久| 香蕉成人啪国产精品视频综合网| 在线观看视频欧美| 一本久久知道综合久久| 国产亚洲高清视频| 91久久精品国产91性色| 欧美视频中文在线看| 久久一区二区三区av| 欧美色网在线| 免费人成精品欧美精品| 欧美日韩专区| 欧美国产激情二区三区| 国产麻豆成人精品| 日韩视频免费在线观看| 在线欧美小视频| 亚洲欧美日韩人成在线播放| 亚洲精品日韩在线观看| 久久成人精品一区二区三区| 亚洲一区二区久久| 欧美成人激情视频| 巨胸喷奶水www久久久免费动漫| 欧美色一级片| 亚洲三级影院| 91久久国产综合久久| 欧美在线在线| 亚洲欧美网站| 欧美日韩精品中文字幕| 欧美韩国日本一区| 伊人久久婷婷| 午夜在线电影亚洲一区| 亚洲欧美激情一区二区| 欧美激情网友自拍| 欧美黄污视频| 在线国产精品播放| 久久精品免费观看| 久久九九久精品国产免费直播| 国产精品a久久久久久| 亚洲欧洲一区二区在线播放| 亚洲人成在线观看| 嫩模写真一区二区三区三州| 欧美h视频在线| 在线免费精品视频| 久久久青草青青国产亚洲免观| 久久精品一区二区三区不卡| 国产精品入口66mio| 在线亚洲免费视频| 亚洲自拍三区| 国产精品影音先锋| 亚洲男人天堂2024| 欧美中文字幕不卡| 国产主播精品在线| 久久久久.com| 欧美jizzhd精品欧美巨大免费| 在线不卡中文字幕播放| 卡通动漫国产精品| 亚洲激情av| 一本久道久久综合婷婷鲸鱼| 欧美日韩中文| 亚洲免费视频在线观看| 久久爱另类一区二区小说| 国产亚洲精品福利| 麻豆精品精华液| 亚洲欧美另类综合偷拍| 亚洲一区二区在线| 午夜视频在线观看一区二区| 国产精品视频精品视频| 午夜国产精品视频免费体验区| 久久国产99| 激情文学一区| 欧美福利影院| 亚洲午夜激情网页| 久久深夜福利| 9l视频自拍蝌蚪9l视频成人| 国产精品福利在线观看| 久久成人精品电影| 亚洲品质自拍| 欧美中文字幕在线播放| 亚洲国产精品高清久久久| 欧美日韩国产综合在线| 亚洲专区一区二区三区| 欧美成人亚洲成人日韩成人| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产日韩亚洲欧美综合| 欧美成人有码| 亚洲女女女同性video| 欧美大片免费观看| 亚洲综合色视频| 在线国产亚洲欧美| 国产精品青草久久久久福利99| 久久青草欧美一区二区三区| 99香蕉国产精品偷在线观看| 久久五月天婷婷| 亚洲一区免费| 亚洲国产精品视频| 国产乱码精品| 欧美巨乳在线| 久久一区二区精品| 亚洲你懂的在线视频| 亚洲经典一区| 久热精品视频| 欧美一区二区视频免费观看| 日韩视频不卡中文| **性色生活片久久毛片| 国产日韩欧美一区| 国产精品二区在线| 欧美美女福利视频| 免费久久99精品国产自| 欧美一区二区三区四区在线 | 亚洲视频一区| 欧美国产第二页| 久久久国产精品一区| 午夜精品久久久久久久久| 一区二区三区黄色| 亚洲精品久久7777| 亚洲黄色成人久久久| 国产一区二区三区在线观看视频 | 亚洲国产乱码最新视频| 久久―日本道色综合久久| 亚洲欧美国产视频| 亚洲永久在线观看| 亚洲专区国产精品| 这里是久久伊人| 一本色道久久综合亚洲精品按摩 | 欧美激情欧美激情在线五月| 久久免费少妇高潮久久精品99| 篠田优中文在线播放第一区| 午夜精品亚洲| 一区二区三区视频观看| 亚洲免费观看高清完整版在线观看熊| 欧美韩日一区| 亚洲国产经典视频| 亚洲第一黄网| 亚洲人成免费| 日韩图片一区| 一本色道综合亚洲| 亚洲女同精品视频| 欧美一区二区高清在线观看| 欧美一区二区精品| 久久久久网址| 美女国产一区| 欧美精品七区| 国产精品久久久久久久久久直播| 国产精品视频免费观看| 国产片一区二区| 影音先锋亚洲电影| 亚洲另类黄色|