C:/ScoutCGC/ScoutCGLib.cpp

説明を見る。
00001 #include "ScoutCGLib.h"
00002 
00003 
00004 
00005 using namespace SCGL;
00006 
00007 /*--------------------------------------------------------------/
00008 |                                                                                                                               |
00009 |                                                                                                                               |
00010 |                                               実体:便利関数                                                  |
00011 |                                                                                                                               |
00012 |                                                                                                                               |
00013 /--------------------------------------------------------------*/
00014 
00015 const double SCGL::ToRadian(const double &degree)
00016 {
00017         return degree * 3.14159265358979323846 / 180.0;
00018 }
00019 
00020 const double SCGL::ToDegree(const double &radian)
00021 {
00022         return radian * 180.0 / 3.14159265358979323846;
00023 }
00024 
00025 
00026 /*--------------------------------------------------------------/
00027 |                                                                                                                               |
00028 |                                                                                                                               |
00029 |                                               実体:VECTOR3                                                   |
00030 |                                                                                                                               |
00031 |                                                                                                                               |
00032 /--------------------------------------------------------------*/
00033 
00034 VECTOR3::VECTOR3():x(0.0),y(0.0),z(0.0){}
00035 VECTOR3::VECTOR3(const VECTOR3& vec):x(vec.x),y(vec.y),z(vec.z){}
00036 VECTOR3::VECTOR3(const double &vx,
00037                                  const double &vy,
00038                                  const double &vz ):x(vx),y(vy),z(vz){}
00039 
00040 VECTOR3::~VECTOR3(){}
00041 
00042 void VECTOR3::init(){x=0.0;y=0.0;z=0.0;}
00043 
00044 //長さ・ノルム
00045 const double VECTOR3::norm() const
00046 {
00047         return sqrt(x*x+y*y+z*z);
00048 }
00049 
00050 //正規化
00051 const bool VECTOR3::unit()
00052 {
00053         const double l = norm();
00054         if(l>0)
00055         {       
00056                 x/=l; y/=l; z/=l;
00057                 return true;
00058         }else return false;
00059 }
00060 
00061 //演算の定義
00062 const VECTOR3 VECTOR3::operator+(const VECTOR3 &a) const
00063 {
00064         return VECTOR3(x + a.x,
00065                                    y + a.y,
00066                                    z + a.z);
00067 }
00068 
00069 const VECTOR3 VECTOR3::operator-(const VECTOR3 &a) const
00070 {
00071         return VECTOR3(x - a.x,
00072                                    y - a.y,
00073                                    z - a.z);
00074 }
00075 
00076 const VECTOR3 VECTOR3::operator*(const double &a) const
00077 {
00078         return VECTOR3(x*a,y*a,z*a);
00079 }
00080 
00081 const VECTOR3 VECTOR3::operator/(const double &a) const
00082 {
00083         return VECTOR3(x/a,y/a,z/a);
00084 }
00085 
00086 VECTOR3& VECTOR3::operator+=(const VECTOR3 &a)
00087 {       
00088         x+=a.x;
00089         y+=a.y;
00090         z+=a.z;                                         
00091         return *this;
00092 }
00093 
00094 VECTOR3& VECTOR3::operator-=(const VECTOR3 &a)
00095 {       
00096         x-=a.x;
00097         y-=a.y;
00098         z-=a.z;                                         
00099         return *this;
00100 }
00101 
00102 VECTOR3& VECTOR3::operator+=(const double &a)
00103 {       
00104         x+=a;
00105         y+=a;
00106         z+=a;                                           
00107         return *this;
00108 }
00109 
00110 VECTOR3& VECTOR3::operator-=(const double &a)
00111 {       
00112         x-=a;
00113         y-=a;
00114         z-=a;                                           
00115         return *this;
00116 }
00117 
00118 VECTOR3& VECTOR3::operator*=(const double &a)
00119 {       
00120         x*=a;
00121         y*=a;
00122         z*=a;                                           
00123         return *this;
00124 }
00125 
00126 VECTOR3& VECTOR3::operator/=(const double &a)
00127 {       
00128         x/=a;
00129         y/=a;
00130         z/=a;                                           
00131         return *this;
00132 }
00133 
00134 //内積
00135 const double  VECTOR3::operator&(const VECTOR3 &a) const
00136 {
00137         return (x * a.x + y * a.y + z * a.z);
00138 }
00139 
00140 //外積
00141 const VECTOR3 VECTOR3::operator*(const VECTOR3 &a) const
00142 {
00143         return VECTOR3(y * a.z - z * a.y ,
00144                                    z * a.x - x * a.z ,
00145                                    x * a.y - y * a.x );
00146 }
00147 
00148 VECTOR3& VECTOR3::operator*=(const VECTOR3 &a)
00149 {
00150         const double tx = y * a.z - z * a.y;
00151         const double ty = z * a.x - x * a.z;
00152 
00153         z = x * a.y - y * a.x;
00154         x = tx;
00155         y = ty;
00156 
00157         return (*this);
00158 }
00159 
00160 //比較
00161 bool VECTOR3::operator==(const VECTOR3 &a) const
00162 {
00163         return (x==a.x && y==a.y && z==a.z);
00164 }
00165 
00166 //符号の反転
00167 const VECTOR3 VECTOR3::operator-() const
00168 {
00169         return VECTOR3(-x,-y,-z);
00170 }
00171 
00172 
00173 /*--------------------------------------------------------------/
00174 |                                                                                                                               |
00175 |                                                                                                                               |
00176 |                                               実体:CBasic3DObject                                    |
00177 |                                                                                                                               |
00178 |                                                                                                                               |
00179 /--------------------------------------------------------------*/
00180 
00181 
00182 
00183 //初期化
00184 CBasic3DObject::CBasic3DObject(){}
00185 CBasic3DObject::~CBasic3DObject(){}
00186 
00187 //初期化
00188 void CBasic3DObject::Init()
00189 {
00190         m_Vertex.clear();
00191         m_Triangle.clear();
00192         m_Texture.Init();
00193 }
00194 
00195 //面の追加:頂点番号1,2,3
00196 const ID_TRIANGLE  CBasic3DObject::AddTriangle(const ID_VERTEX &Vec1,
00197                                                                                            const ID_VERTEX &Vec2,
00198                                                                                            const ID_VERTEX &Vec3)       
00199 {
00200         TRIANGLE Triangle;
00201         Triangle.Vec1 = Vec1;
00202         Triangle.Vec2 = Vec2;
00203         Triangle.Vec3 = Vec3;
00204 
00205         if(Vec1>=m_Vertex.size()||Vec2>=m_Vertex.size()||Vec3>=m_Vertex.size())return 0;
00206 
00207         VECTOR3 V12 = m_Vertex[Vec2].Position - m_Vertex[Vec1].Position;
00208         VECTOR3 V13 = m_Vertex[Vec3].Position - m_Vertex[Vec1].Position;
00209         Triangle.Normal =  V12*V13;
00210 
00211         if(Triangle.Normal.unit())
00212         {
00213                 Triangle.GravPoint += m_Vertex[Vec1].Position;
00214                 Triangle.GravPoint += m_Vertex[Vec2].Position;
00215                 Triangle.GravPoint += m_Vertex[Vec3].Position;
00216                 Triangle.GravPoint/=3;
00217 
00218                 const double cos_val = (V12&V13)/(V12.norm()*V13.norm());
00219                 const double sin_val = sqrt(1.0-cos_val*cos_val);
00220 
00221                 Triangle.S = V12.norm()*V13.norm()*sin_val/2;
00222 
00223                 const ID_TRIANGLE ID = m_Triangle.push(Triangle);
00224 
00225                 m_Vertex[Vec1].JointPlane.push_back(ID);
00226                 m_Vertex[Vec2].JointPlane.push_back(ID);
00227                 m_Vertex[Vec3].JointPlane.push_back(ID);
00228                 return ID;
00229         }else return 0;
00230 }
00231 
00232 //頂点の追加
00233 const ID_VERTEX CBasic3DObject::AddVertex(const VERTEX &Vertex) 
00234 {       
00235         return m_Vertex.push(Vertex);
00236 }
00237 
00238 //座標データのみを与え頂点追加
00239 const ID_VERTEX  CBasic3DObject::AddVertex(const VECTOR3 &Vector)
00240 {
00241         VERTEX Vertex;
00242         Vertex.Position = Vector;
00243 
00244         return AddVertex(Vertex);
00245 }
00246 
00247 //座標データのみを与え頂点追加
00248 const ID_VERTEX  CBasic3DObject::AddVertex(double x,double y,double z)
00249 {
00250         VERTEX Vertex;
00251         Vertex.Position.x = x;
00252         Vertex.Position.y = y;
00253         Vertex.Position.z = z;
00254 
00255         return AddVertex(Vertex);
00256 }
00257 
00258 //初期化された頂点を追加
00259 const ID_VERTEX CBasic3DObject::AddVertex()
00260 {
00261         return AddVertex(VERTEX());
00262 }
00263 
00264 const ID_LIST_VERTEX CBasic3DObject::AddVertexList(const std::vector<VERTEX> &VertexList)
00265 {
00266         ID_LIST_VERTEX ID_List;
00267 
00268         for(int t=0;t<VertexList.size();t++)
00269                 ID_List.push_back(AddVertex(VertexList[t]));
00270 
00271         return ID_List;
00272 }
00273 const ID_LIST_VERTEX CBasic3DObject::AddVertexList(const std::vector<VECTOR3> &VectorList)
00274 {
00275         ID_LIST_VERTEX ID_List;
00276 
00277         for(int t=0;t<VectorList.size();t++)
00278                 ID_List.push_back(AddVertex(VectorList[t]));
00279 
00280         return ID_List;
00281 }
00282 const ID_LIST_VERTEX CBasic3DObject::AddVertexList(const std::vector<double> &PointList)
00283 {
00284         ID_LIST_VERTEX ID_List;
00285 
00286         if(PointList.size()%3 == 0)
00287         {
00288                 for(int t=0;t<PointList.size();t+=3)
00289                         ID_List.push_back(AddVertex(PointList[t],PointList[t+1],PointList[t+2]));
00290         }
00291 
00292         return ID_List;
00293 }
00294 
00295 const ID_LIST_VERTEX CBasic3DObject::AddVertexList(const int Num)
00296 {
00297         ID_LIST_VERTEX ID_List;
00298 
00299         for(int t=0;t<Num;t++)
00300                 ID_List.push_back(AddVertex());
00301 
00302         return ID_List;
00303 }
00304 
00305 //テクスチャを設定
00306 bool CBasic3DObject::SetTexture(char* pFileName){return m_Texture.LoadTexture(pFileName);}
00307 
00308 //テクスチャ読み込み
00309 void CBasic3DObject::SetTexture(TextureData Tex){m_Texture.LoadTexture(Tex);}
00310 
00311 // テクスチャデータの詳細を返す
00312 TextureData CBasic3DObject::GetTexture() const {return m_Texture.GetTextureData();}
00313 
00314 
00315 //コピー
00316 CBasic3DObject& CBasic3DObject::operator=(const CBasic3DObject &sorce)
00317 {
00318         Init();
00319         for(int v=0;v<sorce.GetVertexNum();v++)
00320                 m_Vertex.push(sorce.Vertex(v));
00321         for(int t=0;t<sorce.GetTriangleNum();t++)
00322                 m_Triangle.push(sorce.Triangle(t));
00323         m_Texture.LoadTexture(sorce.GetTexture());
00324 
00325         return *this;
00326 }
00327 
00328 //座標変換 Object×Trans
00329 CBasic3DObject& CBasic3DObject::operator*=(const C3DTrans &trans)
00330 {
00331         for(int v=0;v<m_Vertex.size();v++)
00332                 m_Vertex[v].Position = trans.TransVec(m_Vertex[v].Position);
00333         return *this;
00334 }
00335 
00336 
00337 //オブジェクトの追加
00338 CBasic3DObject& CBasic3DObject::operator+=(CBasic3DObject &sorce)
00339 {
00340         unsigned int *TransTable;
00341 
00342         TransTable = new unsigned int[sorce.GetVertexNum()];
00343 
00344         for(int v=0;v<sorce.GetVertexNum();v++)
00345                 TransTable[v] = m_Vertex.push(sorce.Vertex(v));
00346         
00347         for(int t=0;t<sorce.GetTriangleNum();t++)
00348         {
00349                 TRIANGLE &tri = sorce.Triangle(t);
00350                 AddTriangle(TransTable[tri.Vec1],
00351                                         TransTable[tri.Vec2],
00352                                         TransTable[tri.Vec3]);
00353         }
00354 
00355         delete[] TransTable;
00356         return *this;
00357 }
00358 
00359 
00360 //頂点番号から頂点を取得
00361 VERTEX& CBasic3DObject::Vertex(unsigned int VertexID) const 
00362 {
00363         if(VertexID < m_Vertex.size())return m_Vertex[VertexID];
00364         else return (*((VERTEX*)NULL));
00365 }
00366 
00367 
00368 //頂点番号から頂点を取得
00369 TRIANGLE& CBasic3DObject::Triangle(unsigned int TriangleID) const 
00370 {
00371         if(TriangleID < m_Triangle.size())return m_Triangle[TriangleID];
00372         else return (*((TRIANGLE*)NULL));
00373 }
00374 
00375 //頂点数
00376 const int CBasic3DObject::GetVertexNum() const  {return m_Vertex.size();}
00377 //面の数
00378 const int CBasic3DObject::GetTriangleNum() const {return m_Triangle.size();}
00379 
00380 //頂点の法線ベクトルを求める
00381 void CBasic3DObject::Normalize() 
00382 {
00383         for(int v=0;v<m_Vertex.size();v++)
00384         {
00385                 m_Vertex[v].Normal.init();
00386 
00387                 for(int p=0;p<m_Vertex[v].JointPlane.size();p++)
00388                         m_Vertex[v].Normal+=m_Triangle[m_Vertex[v].JointPlane[p]].Normal;
00389 
00390                 m_Vertex[v].Normal.unit();
00391         }
00392 }
00393 
00394 
00395 
00396 /*--------------------------------------------------------------/
00397 |                                                                                                                               |
00398 |                                                                                                                               |
00399 |                                               実体:C3DObject                                                 |
00400 |                                                                                                                               |
00401 |                                                                                                                               |
00402 /--------------------------------------------------------------*/
00403 
00404 
00405 
00406 //初期化
00407 C3DObject::C3DObject():VertexIsCached(false){}
00408 C3DObject::~C3DObject(){}
00409 
00410 //初期化
00411 void C3DObject::Init()
00412 {
00413         CBasic3DObject::Init();
00414         VertexIsCached = false;
00415 }
00416 
00417 //面の追加:頂点番号1,2,3
00418 const ID_TRIANGLE  C3DObject::AddVertex(const VERTEX &Vertex)
00419 {
00420         const ID = CBasic3DObject::AddVertex(Vertex);
00421 
00422         if(VertexIsCached)
00423                 m_VertexCache.push_back(ID);
00424 
00425         return ID;
00426 }
00427 
00428 void C3DObject::BeginVertexCache()
00429 {
00430         m_VertexCache.clear();
00431         VertexIsCached = true;
00432 }
00433 
00434 void C3DObject::EndVertexCache()
00435 {
00436         VertexIsCached = false;
00437 }
00438 
00439 void C3DObject::TransVC(const C3DTrans &Trans)
00440 {
00441         for(int t=0;t<m_VertexCache.size();t++)
00442         {
00443                 VECTOR3 &vec = m_Vertex[m_VertexCache[t]].Position;
00444                 vec = Trans.TransVec(vec);
00445         }
00446 }
00447 
00448 const ID_LIST_VERTEX C3DObject::CopyVC()
00449 {
00450         ID_LIST_VERTEX ID_List;
00451 
00452         for(int t=0;t<m_VertexCache.size();t++)
00453                 ID_List.push_back(AddVertex(m_Vertex[m_VertexCache[t]]));
00454 
00455         return ID_List;
00456 }
00457 
00458 const ID_LIST_VERTEX C3DObject::CopyWithTransVC(const C3DTrans &Trans)
00459 {
00460         ID_LIST_VERTEX ID_List;
00461 
00462         for(int t=0;t<m_VertexCache.size();t++)
00463         {
00464                 VERTEX NewVec(m_Vertex[m_VertexCache[t]]);
00465 
00466                 VECTOR3 &vec = NewVec.Position;
00467                 vec = Trans.TransVec(vec);
00468 
00469                 ID_List.push_back(AddVertex(NewVec));
00470         }
00471 
00472         return ID_List;
00473 }
00474 
00475 const ID_LIST_VERTEX C3DObject::MakeWall(const ID_LIST_VERTEX &VertexList1,
00476                                                                                  const ID_LIST_VERTEX &VertexList2,
00477                                                                                  const bool IsLoop)
00478 {
00479         ID_LIST_VERTEX ID_List;
00480 
00481         if(VertexList1.size() == VertexList2.size())
00482         {
00483                 for(int t=0;t<VertexList1.size()-1;t++)
00484                 {
00485                         ID_List.push_back(AddTriangle(VertexList1[t+1],
00486                                                                                   VertexList1[t],
00487                                                                                   VertexList2[t]));
00488 
00489                         ID_List.push_back(AddTriangle(VertexList1[t+1],
00490                                                                                   VertexList2[t],
00491                                                                                   VertexList2[t+1]));
00492                 }
00493                 if(IsLoop)
00494                 {
00495                         ID_List.push_back(AddTriangle(VertexList1[0],
00496                                                                                   VertexList1[t],
00497                                                                                   VertexList2[t]));
00498 
00499                         ID_List.push_back(AddTriangle(VertexList1[0],
00500                                                                                   VertexList2[t],
00501                                                                                   VertexList2[0]));
00502                 }
00503         }
00504 
00505         return ID_List;
00506 }
00507 
00508 const ID_LIST_VERTEX C3DObject::MakeWallFromVC(const ID_LIST_VERTEX &VertexList,
00509                                                                                            const bool IsLoop)
00510 {
00511         ID_LIST_VERTEX ID_List;
00512 
00513         if(VertexList.size() == m_VertexCache.size())
00514         {
00515                 for(int t=0;t<VertexList.size()-1;t++)
00516                 {
00517                         ID_List.push_back(AddTriangle(m_VertexCache[t+1],
00518                                                                                   m_VertexCache[t],
00519                                                                                   VertexList[t]));
00520 
00521                         ID_List.push_back(AddTriangle(m_VertexCache[t+1],
00522                                                                                   VertexList[t],
00523                                                                                   VertexList[t+1]));
00524                 }
00525                 if(IsLoop)
00526                 {
00527                         ID_List.push_back(AddTriangle(m_VertexCache[0],
00528                                                                                   m_VertexCache[t],
00529                                                                                   VertexList[t]));
00530 
00531                         ID_List.push_back(AddTriangle(m_VertexCache[0],
00532                                                                                   VertexList[t],
00533                                                                                   VertexList[0]));
00534                 }
00535         }
00536 
00537         return ID_List;
00538 }
00539 
00540 void C3DObject::MakeWallByVC(const C3DTrans &Trans,const bool IsLoop)
00541 {
00542 
00543         const ID_LIST_VERTEX OldVC = m_VertexCache;
00544 
00545         for(int t=0;t<OldVC.size();t++)
00546         {
00547                 VERTEX NewVec(m_Vertex[OldVC[t]]);
00548 
00549                 VECTOR3 &vec = NewVec.Position;
00550                 vec = Trans.TransVec(vec);
00551 
00552                 m_VertexCache[t] = AddVertex(NewVec);
00553         }
00554 
00555 
00556         for(t=0;t<OldVC.size()-1;t++)
00557         {
00558                 AddTriangle(OldVC[t+1],OldVC[t],m_VertexCache[t]);
00559                 AddTriangle(OldVC[t+1],m_VertexCache[t],m_VertexCache[t+1]);
00560         }
00561         if(IsLoop)
00562         {
00563                 AddTriangle(OldVC[0],OldVC[t],m_VertexCache[t]);
00564                 AddTriangle(OldVC[0],m_VertexCache[t],m_VertexCache[0]);
00565         }
00566 }
00567 
00568 
00569 const ID_LIST_VERTEX C3DObject::MakeCircle(double Radius,
00570                                                                                    const int VertexNum,
00571                                                                                    VECTOR3 &Normal,
00572                                                                                    VECTOR3 &Center)
00573 {
00574         ID_LIST_VERTEX ID_List;
00575         VECTOR3 ZVec(0.0,0.0,1.0);
00576         VECTOR3 Vec(Radius,0.0,0.0);
00577         
00578         CQuaternion Axis;
00579 
00580         Axis.Rotate(-Normal,ZVec);
00581 
00582         CQuaternion Rot;
00583 
00584         if(VertexNum%2 == 0)
00585         {
00586                 Rot.SetRotate(ZVec,-180.0/VertexNum);
00587                 Axis*=Rot;
00588         }
00589 
00590         Rot.SetRotate(ZVec,360.0/VertexNum);
00591 
00592         for(int t=0;t<VertexNum;t++)
00593         {
00594                 ID_List.push_back(AddVertex(Axis*Vec+Center));
00595                 Axis*=Rot;
00596         }
00597 
00598         return ID_List;
00599 }
00600 
00601 void C3DObject::MakeSolidRotation(const ID_LIST_VERTEX &VertexList,
00602                                                                   int Div,
00603                                                                   const bool IsLoop,
00604                                                                   const VECTOR3 &BasePos,
00605                                                                   const double Theta,
00606                                                                   const VECTOR3 &Axis)
00607 {
00608         const ID_LIST_VERTEX BK_Cache = m_VertexCache;
00609 
00610         m_VertexCache = VertexList;
00611 
00612         
00613         C3DTrans Trans;
00614 
00615         Trans.Translate(BasePos);
00616         Trans.Rotate(Axis,Theta/Div);
00617         Trans.Translate(-BasePos);
00618         
00619         if(Theta == 360.0)Div--;
00620 
00621         for(int t=0;t<Div;t++)
00622                 MakeWallByVC(Trans,IsLoop);
00623 
00624         if(Theta == 360.0)MakeWall(m_VertexCache,VertexList);
00625 
00626         m_VertexCache = BK_Cache;
00627 }
00628 
00629 void C3DObject::MakeSolidRotationVC(int Div,
00630                                                                         const bool IsLoop,
00631                                                                         const VECTOR3 &BasePos,
00632                                                                         const double Theta,
00633                                                                         const VECTOR3 &Axis)
00634 {
00635         const ID_LIST_VERTEX BK_Cache = m_VertexCache;
00636 
00637         C3DTrans Trans;
00638 
00639         Trans.Translate(BasePos);
00640         Trans.Rotate(Axis,Theta/Div);
00641         Trans.Translate(-BasePos);
00642         
00643         if(Theta == 360.0)Div--;
00644 
00645         for(int t=0;t<Div;t++)
00646                 MakeWallByVC(Trans,IsLoop);
00647 
00648         if(Theta == 360.0)MakeWall(m_VertexCache,BK_Cache);
00649 }
00650 
00651 
00652 //単位球形状の生成
00653 void C3DObject::SetSphere(int detail)
00654 {
00655         const double X = 0.525731112;
00656         const double Z = 0.850650808;
00657 
00658         const VECTOR3 vdata[12] =
00659         {
00660                 VECTOR3(-X ,0.0,Z)  ,VECTOR3(X  ,0.0,Z)  ,VECTOR3(-X ,0.0,-Z) ,VECTOR3(X  ,0.0,-Z),
00661                 VECTOR3(0.0,Z  ,X)  ,VECTOR3(0.0,Z  ,-X) ,VECTOR3(0.0,-Z ,X)  ,VECTOR3(0.0,-Z ,-X),
00662                 VECTOR3(Z  ,X  ,0.0),VECTOR3(-Z ,X  ,0.0),VECTOR3(Z  ,-X ,0.0),VECTOR3(-Z ,-X ,0.0)
00663         };
00664 
00665         const ID_TRIANGLE tindices[20][3]={
00666                 {0,4,1},{0,9,4},{9,5,4},{4,5,8},{4,8,1},
00667                 {8,10,1},{8,3,10},{5,3,8},{5,2,3},{2,7,3},
00668                 {7,10,3},{7,6,10},{7,11,6},{11,0,6},{0,1,6},
00669                 {6,1,10},{9,0,11},{9,11,2},{9,2,5},{7,2,11},
00670         };
00671         
00672         const ID_TRIANGLE offset = m_Vertex.size();
00673 
00674         for(int t=0;t<12;t++)
00675                 AddVertex(vdata[t]);
00676 
00677         for(int i=0;i<20;i++)
00678                 subdivide(tindices[i][2]+offset,tindices[i][1]+offset,tindices[i][0]+offset,detail);
00679 }
00680 
00681 //三角形を再分割
00682 void C3DObject::subdivide(ID_TRIANGLE V1_ID, ID_TRIANGLE V2_ID, ID_TRIANGLE V3_ID,int depth)
00683 {
00684         VECTOR3 Vec12,Vec23,Vec31;
00685         
00686         Vec12=m_Vertex[V1_ID].Position+m_Vertex[V2_ID].Position;
00687         Vec23=m_Vertex[V2_ID].Position+m_Vertex[V3_ID].Position;
00688         Vec31=m_Vertex[V3_ID].Position+m_Vertex[V1_ID].Position;
00689         
00690         Vec12.unit();
00691         Vec23.unit();
00692         Vec31.unit();
00693 
00694         ID_TRIANGLE V12_ID;
00695         ID_TRIANGLE V23_ID;
00696         ID_TRIANGLE V31_ID;
00697 
00698         if((V12_ID = FindVertex(Vec12))>m_Vertex.size())V12_ID = AddVertex(Vec12);
00699         if((V23_ID = FindVertex(Vec23))>m_Vertex.size())V23_ID = AddVertex(Vec23);
00700         if((V31_ID = FindVertex(Vec31))>m_Vertex.size())V31_ID = AddVertex(Vec31);
00701 
00702 
00703         if(--depth == 0)
00704         {
00705                 AddTriangle(V1_ID, V12_ID,V31_ID);
00706                 AddTriangle(V2_ID, V23_ID,V12_ID);
00707                 AddTriangle(V3_ID, V31_ID,V23_ID);
00708                 AddTriangle(V12_ID,V23_ID,V31_ID);
00709         }
00710         else
00711         {
00712                 subdivide(V1_ID, V12_ID, V31_ID,depth);
00713                 subdivide(V2_ID, V23_ID, V12_ID,depth);
00714                 subdivide(V3_ID, V31_ID, V23_ID,depth);
00715                 subdivide(V12_ID,V23_ID, V31_ID,depth);
00716         }
00717 }
00718 
00719 //座標から頂点を検索する
00720 const ID_TRIANGLE C3DObject::FindVertex(const VECTOR3 &Vector) const 
00721 {
00722         for(int VID=0;VID<m_Vertex.size();VID++)
00723                 if(m_Vertex[VID].Position == Vector)return VID;
00724 
00725         return -1;
00726 }
00727 
00728 //座標から頂点を検索する
00729 const ID_TRIANGLE C3DObject::FineVertex(double x,double y,double z) const 
00730 {
00731         VECTOR3 Vector(x,y,z);
00732 
00733         for(int VID=0;VID<m_Vertex.size();VID++)
00734                 if(m_Vertex[VID].Position == Vector)return VID;
00735 
00736         return -1;
00737 }
00738 
00739 
00740 bool C3DObject::LoadOBJFile(char* FileName)
00741 {
00742 
00743         FILE *fp = fopen(FileName,"ra");
00744         if(fp==NULL)return false;
00745 
00746         Init();
00747 
00748         char buf[256];
00749 
00750     while( fscanf(fp, "%s", buf) != EOF )
00751         {
00752                 if(buf[0] == '#')
00753                 { // comment
00754             fgets(buf, sizeof(buf), fp);
00755         }
00756         else if(buf[0] == 'v' && buf[1] == '\0')
00757                 {
00758                         VECTOR3 NewVec;
00759                         char ValBuf[3][32];
00760 
00761             if(fscanf(fp, "%s %s %s\n", &ValBuf[0],&ValBuf[1],&ValBuf[2]) > 0)
00762                         {
00763                                 NewVec.v[0] = atof(ValBuf[0]);
00764                                 NewVec.v[1] = atof(ValBuf[1]);
00765                                 NewVec.v[2] = atof(ValBuf[2]);
00766 
00767                                 AddVertex(NewVec);
00768                         }
00769         }
00770         else if(buf[0] == 'f')
00771                 {
00772                         std::vector<unsigned int> VectorIndex;
00773                         int VID = 0,tmp;
00774 
00775                         tmp = m_Vertex.size();
00776 
00777                         while(fscanf(fp,"%d/%d/%d",&VID,&tmp,&tmp)>0)
00778                                 VectorIndex.push_back(VID-1);
00779                         
00780 
00781                         if(VectorIndex.size() > 2)
00782                         {
00783                                 unsigned int FirstVec = VectorIndex[0];
00784                                 for(int t=1;t<VectorIndex.size()-1;t++)
00785                                 {
00786                                         //subdivide(FirstVec,VectorIndex[t],VectorIndex[t+1],1);
00787                                         AddTriangle(FirstVec,VectorIndex[t],VectorIndex[t+1]);
00788                                 }
00789                         }
00790         }
00791         else 
00792             fgets(buf, sizeof(buf), fp);
00793   
00794         }
00795 
00796         fclose(fp);
00797 
00798         return true;
00799 }
00800 
00801 
00802 /*--------------------------------------------------------------/
00803 |                                                                                                                               |
00804 |                                                                                                                               |
00805 |                                               実体:CTexture                                                  |
00806 |                                                                                                                               |
00807 |                                                                                                                               |
00808 /--------------------------------------------------------------*/
00809 
00810 CTexture::CTexture()
00811 {
00812         m_Texture_Data.pColor = NULL;
00813         bIsBinded = false;
00814         m_TextureNumber = -1;
00815 }
00816 
00817 CTexture::~CTexture()
00818 {
00819         if(m_Texture_Data.pColor != NULL)
00820                 delete[] m_Texture_Data.pColor;
00821 }
00822 
00823 bool CTexture::LoadJpegFile(FILE *fp)
00824 {
00825         // jpeg ライブラリでは次の2つの構造体が使われる
00826     struct jpeg_decompress_struct cinfo;
00827     struct jpeg_error_mgr jerr;
00828 
00829     JSAMPARRAY buffer;              /* 行出力バッファ */
00830     int   row_stride;               /* 出力バッファの物理行幅 */
00831 
00832     RGBA_BYTE *bmp_image;
00833     int   bmp_row;
00834     int   bmp_row_bytes;
00835     int   bmp_image_size;
00836 
00837 
00838     // エラーのハンドリング
00839     cinfo.err = jpeg_std_error(&jerr);
00840 
00841     // 構造体の初期設定
00842     jpeg_create_decompress(&cinfo);
00843 
00844     // ファイル入力ハンドルの設定
00845     jpeg_stdio_src(&cinfo, fp);
00846 
00847     // ファイルの情報ヘッダの読込み
00848     jpeg_read_header(&cinfo, TRUE);
00849 
00850     // 解凍の開始
00851     jpeg_start_decompress(&cinfo);
00852 
00853     // 行バッファの領域設定
00854     row_stride = cinfo.output_width * cinfo.output_components;
00855 
00856     buffer = (*cinfo.mem->alloc_sarray)
00857                 ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
00858 
00859     if( !buffer ) goto SKIP1;
00860 
00861     // DIB のイメージ領域確保
00862     m_Texture_Data.Width  = cinfo.image_width;
00863     m_Texture_Data.Height = cinfo.image_height;
00864 
00865     // DIB の行は、DWORD 境界で終わる必要がある
00866     bmp_row_bytes = m_Texture_Data.Width*4;
00867     bmp_image_size = bmp_row_bytes * m_Texture_Data.Height;
00868 
00869     // LIBJPEG 展開後のピクセル形式変換
00870     m_Texture_Data.pColor = new RGBA_BYTE[m_Texture_Data.Width*m_Texture_Data.Height];
00871     if( !m_Texture_Data.pColor ) goto END1;
00872 
00873     bmp_image = m_Texture_Data.pColor;
00874 
00875     // 1行ずつ読み、バッファへ格納する
00876     bmp_row = 0;
00877     while (cinfo.output_scanline < cinfo.output_height) {
00878         int i;
00879         BYTE *src;
00880                 RGBA_BYTE *dest;
00881 
00882         (void) jpeg_read_scanlines(&cinfo, buffer, 1);
00883 
00884         src = buffer[0];
00885         dest = &bmp_image[m_Texture_Data.Width*bmp_row++];
00886 
00887         for( i = row_stride-1; i > 0; i-=3 ) 
00888                 {
00889            dest->Blue  = src[i-2];
00890            dest->Green = src[i-1];
00891            dest->Red   = src[i];
00892                    dest->Alpha = 255;
00893                    dest++;
00894         }
00895     }
00896 
00897     SKIP1:;
00898     (void) jpeg_finish_decompress(&cinfo);
00899 
00900     jpeg_destroy_decompress(&cinfo);
00901         
00902         END1:;
00903 
00904         return true;
00905 }
00906 
00907 //読み込みコールバック関数
00908 void CTexture::PNGReader(png_structp png_ptr,png_bytep data,png_size_t length)
00909 {
00910     FILE* fp=(FILE*)png_get_io_ptr(png_ptr);
00911         fread((char*)data,length,1,fp);
00912 }
00913 
00914 bool CTexture::LoadPngFile(FILE *fp)
00915 {
00916         // PNG読み込み開始
00917     png_structp png_ptr;
00918     png_infop   info_ptr;
00919     
00920         //読み込みオブジェクト作成
00921         png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
00922     if(png_ptr==NULL)return false;
00923         
00924         //Info構造体作成
00925         info_ptr=png_create_info_struct(png_ptr);
00926     if(info_ptr==NULL)
00927         {
00928                 png_destroy_read_struct(&png_ptr,NULL,NULL);
00929                 return false;
00930         }
00931 
00932         //読み込みコールバック関数の指定
00933     png_set_read_fn(png_ptr,fp,PNGReader);
00934     
00935 
00936     // 画像情報の取得
00937     png_uint_32 width,height;
00938     int bit_depth,color_type,interlace_type;
00939     int compression_type,filter_type;
00940     
00941         png_read_info(png_ptr,info_ptr);
00942         png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,&color_type,
00943                   &interlace_type,&compression_type,&filter_type);
00944 
00945 
00946         std::vector<png_bytep> row_pointers;
00947     {
00948         for(int y=0;y<height;y++){
00949                         unsigned int size = png_get_rowbytes(png_ptr, info_ptr);
00950                         png_bytep OneLine = new BYTE[size];
00951             row_pointers.push_back(OneLine);
00952         }
00953     }
00954 
00955     png_set_bgr(png_ptr);
00956     png_read_image(png_ptr,row_pointers.begin());
00957 
00958     png_read_end(png_ptr,info_ptr);
00959 
00960         m_Texture_Data.Width  = width;
00961         m_Texture_Data.Height = height;
00962         m_Texture_Data.pColor = new RGBA_BYTE[m_Texture_Data.Width*m_Texture_Data.Height];
00963 
00964         for(int y=0;y<height;y++)
00965         {
00966                 for(int x=0;x<width;x++)
00967                 {
00968                         switch(color_type)
00969                         {
00970                         case PNG_COLOR_TYPE_RGB:
00971                                 m_Texture_Data.pColor[x+y*width].Blue  = row_pointers[y][x*3];
00972                                 m_Texture_Data.pColor[x+y*width].Green = row_pointers[y][x*3+1];
00973                                 m_Texture_Data.pColor[x+y*width].Red   = row_pointers[y][x*3+2];
00974                                 m_Texture_Data.pColor[x+y*width].Alpha = 255;
00975                         break;
00976                         case PNG_COLOR_TYPE_RGBA:
00977                                 m_Texture_Data.pColor[x+y*width].Blue  = row_pointers[y][x*4];
00978                                 m_Texture_Data.pColor[x+y*width].Green = row_pointers[y][x*4+1];
00979                                 m_Texture_Data.pColor[x+y*width].Red   = row_pointers[y][x*4+2];
00980                                 m_Texture_Data.pColor[x+y*width].Alpha = row_pointers[y][x*4+3];
00981                         break;
00982                         case PNG_COLOR_TYPE_GRAY:
00983                                 m_Texture_Data.pColor[x+y*width].Red   = row_pointers[y][x];
00984                                 m_Texture_Data.pColor[x+y*width].Green = row_pointers[y][x];
00985                                 m_Texture_Data.pColor[x+y*width].Blue  = row_pointers[y][x];
00986                                 m_Texture_Data.pColor[x+y*width].Alpha = 255;
00987                         break;
00988                         }
00989                 }
00990                 delete[] row_pointers[y];
00991         }
00992    
00993     png_destroy_read_struct(&png_ptr,&info_ptr,(png_infopp)NULL);
00994         return true;
00995 }
00996 
00997 void  CTexture::BindTextureOGL()
00998 {
00999         if(m_Texture_Data.pColor == NULL)
01000                 return;
01001 
01002         glEnable(GL_TEXTURE_2D);
01003 
01004         if(bIsBinded)
01005         {
01006                 glBindTexture(GL_TEXTURE_2D, m_TextureNumber);
01007                 return;
01008         }
01009         
01010         glGenTextures(1, (unsigned int*)&m_TextureNumber);
01011 
01012         glBindTexture(GL_TEXTURE_2D, m_TextureNumber);
01013         
01014         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_Texture_Data.Width, 
01015                                 m_Texture_Data.Height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_Texture_Data.pColor);
01016 
01017         bIsBinded = true;
01018 }
01019 
01020 TextureData CTexture::GetTextureData() const 
01021 {
01022         return m_Texture_Data;
01023 }
01024 
01025 bool CTexture::LoadTexture(char* pFileName)
01026 {
01027         Init();
01028         return true;
01029 }
01030 
01031 void CTexture::LoadTexture(TextureData Tex)
01032 {
01033         Init();
01034         if(Tex.pColor==NULL)return;
01035 
01036         m_Texture_Data.Height = Tex.Height;
01037         m_Texture_Data.Width  = Tex.Width;
01038         m_Texture_Data.pColor = new RGBA_BYTE[m_Texture_Data.Width*m_Texture_Data.Height];
01039 
01040         for(int i=0;i<m_Texture_Data.Width*m_Texture_Data.Height;i++)
01041                 m_Texture_Data.pColor[i]=Tex.pColor[i];
01042 
01043 }
01044 
01045 void CTexture::Init()
01046 {
01047         if(m_Texture_Data.pColor != NULL)
01048         {
01049                 delete m_Texture_Data.pColor;
01050                 glDeleteTextures(1 , (unsigned int*)&m_TextureNumber);
01051         }
01052 
01053         m_Texture_Data.pColor = NULL;
01054         bIsBinded = false;
01055         m_TextureNumber = -1;
01056 }
01057 
01058 
01059 
01060 /*--------------------------------------------------------------/
01061 |                                                                                                                               |
01062 |                                                                                                                               |
01063 |                                               実体:CQuaternion                                               |
01064 |                                                                                                                               |
01065 |                                                                                                                               |
01066 /--------------------------------------------------------------*/
01067 
01068 CQuaternion::CQuaternion():w(1.0),x(0.0),y(0.0),z(0.0){}
01069 CQuaternion::CQuaternion(double val):w(val),x(0.0),y(0.0),z(0.0){}
01070 CQuaternion::CQuaternion(double qw,double qx,double qy,double qz):w(qw),x(qx),y(qy),z(qz){}
01071 CQuaternion::CQuaternion(double ww,const VECTOR3 &vec):w(ww),x(vec.x),y(vec.y),z(vec.z){}
01072 
01073 //デストラクタ
01074 CQuaternion::~CQuaternion(){}
01075 
01076 //単位クォータニオンで初期化
01077 void CQuaternion::init(){w=1;x=0;y=0;z=0;}
01078 
01079 //カメラの視線制御
01080 CQuaternion::CQuaternion(VECTOR3 dir, VECTOR3 up)
01081 {
01082         // ワールド座標の単位ベクトル
01083         VECTOR3 eye_y; eye_y.y=1.0;
01084         VECTOR3 eye_z; eye_y.z=1.0;
01085         // 単位ベクトルにする
01086         dir.unit();
01087         up.unit();
01088         // 視線方向を合わせるクォータニオンを作成
01089         CQuaternion q1;
01090         q1.Rotate( eye_z, dir );
01091         
01092         // Y軸を回転させる
01093         eye_y = q1.Rotate( eye_y );
01094 
01095         // 上向き方向を合わせるクォータニオンを作成
01096         CQuaternion q2 = Rotate( eye_y, up, dir );
01097 
01098         // 回転を合成する
01099         (*this) = ( q2 * q1 );
01100 }
01101 
01102 // 任意軸回転
01103 void CQuaternion::SetRotate(const VECTOR3 &axis,const double &theta)
01104 {
01105         double rad = ToRadian(theta) / 2.0;
01106 
01107         double s = sin( rad );
01108         w = cos( rad );
01109         x = s * axis.x;
01110         y = s * axis.y;
01111         z = s * axis.z;
01112 }
01113 
01114 //コピー
01115 CQuaternion& CQuaternion::operator=(const CQuaternion &q )
01116 {
01117         w = q.w;
01118         x = q.x;
01119         y = q.y;
01120         z = q.z;
01121         return (*this);
01122 }
01123 
01124 //符号の反転
01125 const CQuaternion CQuaternion::operator -() const { return (CQuaternion( -w, -x, -y, -z ));}
01126 
01127 //加算代入
01128 CQuaternion& CQuaternion::operator+=(const CQuaternion &q)
01129 {
01130         w += q.w;
01131         x += q.x;
01132         y += q.y;
01133         z += q.z;
01134         return (*this);
01135 }
01136 
01137 //加算代入(w成分)
01138 CQuaternion& CQuaternion::operator+=(const double &val ){w+=val;return (*this);}
01139 
01141 CQuaternion& CQuaternion::operator-=(const CQuaternion &q)
01142 {
01143         w -= q.w;
01144         x -= q.x;
01145         y -= q.y;
01146         z -= q.z;
01147         return (*this);
01148 }
01149 //減算代入(w成分)
01150 CQuaternion& CQuaternion::operator-=(const double &val ){w-=val;return (*this);}
01151 
01152 
01154 CQuaternion& CQuaternion::operator*=(const CQuaternion &q)
01155 {
01156         const double tw = w * q.w - x * q.x - y * q.y - z * q.z;
01157         const double tx = w * q.x + x * q.w + y * q.z - z * q.y;
01158         const double ty = w * q.y + y * q.w + z * q.x - x * q.z;
01159         const double tz = w * q.z + z * q.w + x * q.y - y * q.x;
01160 
01161         w = tw; x = tx; y = ty; z = tz;
01162         return (*this);
01163 }
01164 //乗算代入(w成分)
01165 CQuaternion& CQuaternion::operator*=(const double &val)
01166 {
01167         w *= val;
01168         x *= val;
01169         y *= val;
01170         z *= val;
01171         return (*this);
01172 }
01173 
01174 //乗算
01175 const CQuaternion CQuaternion::operator*(const CQuaternion &q) const 
01176 {
01177         const double tw = w * q.w - x * q.x - y * q.y - z * q.z;
01178         const double tx = w * q.x + x * q.w + y * q.z - z * q.y;
01179         const double ty = w * q.y + y * q.w + z * q.x - x * q.z;
01180         const double tz = w * q.z + z * q.w + x * q.y - y * q.x;
01181 
01182         return CQuaternion( tw, tx, ty, tz );
01183 }
01184 
01185 //除算代入
01186 CQuaternion& CQuaternion::operator /=(const CQuaternion &q){return (*this) *= (q.inv());}
01187 
01188 //除算代入(w成分)
01189 CQuaternion& CQuaternion::operator /=(const double &val)
01190 {
01191         w /= val;
01192         x /= val;
01193         y /= val;
01194         z /= val;
01195         return (*this);
01196 }
01197 
01198 //除算
01199 const CQuaternion  CQuaternion::operator/(const CQuaternion &q) const {return CQuaternion((*this) * q.inv());}
01200 //除算(各成分)
01201 const CQuaternion  CQuaternion::operator/(const double &val) const {return CQuaternion( w/val , x/val , y/val , z/val );}
01202 
01203 //ノルム・長さ
01204 const double CQuaternion::norm() const{ return sqrt(w*w + x*x + y*y + z*z);}
01205 
01206 //ノルム・長さの2乗
01207 const double CQuaternion::norm2() const{ return (w*w + x*x + y*y + z*z);}
01208 
01209 //共役クォータニオン
01210 const CQuaternion CQuaternion::conjugate() const {return CQuaternion( w, -x, -y, -z );}
01211 
01212 //逆クォータニオン
01213 const CQuaternion CQuaternion::inv() const
01214 {
01215         const double length2 = norm2();
01216         return CQuaternion( w/length2, -x/length2, -y/length2, -z/length2);
01217 }
01218 
01219 //単位クォータニオン
01220 const CQuaternion CQuaternion::unit() const
01221 {
01222         const double length = norm( );
01223         return CQuaternion( w/length, x/length, y/length, z/length);
01224 }
01225 
01226 //内積
01227 double CQuaternion::operator&(CQuaternion &q){return (w * q.w + x * q.x + y * q.y + z * q.z);}
01228 
01229 //ベクトルを回転する
01230 VECTOR3 CQuaternion::Rotate(const VECTOR3 &vec) const 
01231 {
01232         const CQuaternion &q = ( *this ) * CQuaternion(0,vec.x,vec.y,vec.z) * inv();
01233         return VECTOR3(q.x,q.y,q.z);
01234 }
01235 
01236 
01237 const VECTOR3 CQuaternion::operator*(const VECTOR3 &vec) const 
01238 {
01239         const CQuaternion &q = ( *this ) * CQuaternion(0,vec.x,vec.y,vec.z) * inv();
01240         return VECTOR3(q.x,q.y,q.z);
01241 }
01242 
01243 void CQuaternion::Rotate(VECTOR3 v1, VECTOR3 v2)
01244 {
01245         // 単位ベクトルにする
01246         v1.unit( );
01247         v2.unit( );
01248 
01249         // 回転角度を計算する
01250         double dot = v1&v2;
01251 
01252         if( dot < -1.0 )
01253         {
01254                 w=-1.0;
01255                 x=0.0; y=0.0; z=0.0;
01256                 return;
01257         }
01258 
01259         double c = sqrt( ( dot + 1.0 ) * 0.5 );
01260 
01261         VECTOR3 rt = ( v1*v2 );
01262                         rt.unit();
01263                         rt *= sqrt(1.0 - c*c);
01264                         
01265 
01266 
01267         if( fabs( c - 1.0 ) < 1.0e-6 || c > 1.0  )
01268         {
01269                 w=1.0;
01270                 x=0.0; y=0.0; z=0.0;
01271         }
01272         else if( fabs( c + 1.0 ) < 1.0e-6 || c < -1.0 )
01273         {
01274                 w=-1.0;
01275                 x=0.0; y=0.0; z=0.0;
01276         }
01277         else
01278         {
01279                 w = c;
01280                 if(w==0 && rt.norm() == 0)
01281                 {
01282                         rt.x = v1.y;
01283                         rt.y = v1.z;
01284                         rt.z = v1.x;
01285                 }
01286                 x=rt.x; y=rt.y; z=rt.z;
01287         }
01288 }
01289 
01290 CQuaternion CQuaternion::Rotate(VECTOR3 v1,VECTOR3 v2,VECTOR3 axis)
01291 {
01292         // 単位ベクトルにする
01293         v1.unit( );
01294         v2.unit( );
01295         
01296         // 回転角度を計算する
01297         double dot = v1&v2;
01298         if( dot < -1.0 ) return CQuaternion( -1, 0, 0, 0 );
01299 
01300         double c = sqrt( ( dot + 1.0 ) * 0.5 );
01301 
01302         if( fabs( c - 1.0 ) < 1.0e-6 || c > 1.0 )      return CQuaternion(  1, 0, 0, 0 );
01303         else if( fabs( c + 1.0 ) < 1.0e-6 || c < -1.0 )return CQuaternion( -1, 0, 0, 0 );
01304 
01305         double s = sqrt( 1.0 - c * c );
01306         if( (axis&( v1*v2 )) < 0.0 ) s = -s;
01307         return CQuaternion( c, axis*s );
01308 }
01309 
01310 // 変換行列を求める
01311 MATRIX44 CQuaternion::GetMatrix()
01312 {
01313         MATRIX44 Matrix;
01314         Matrix._11 = w*w + x*x - y*y - z*z;
01315         Matrix._12 = 2.0 * ( x*y - w*z );
01316         Matrix._13 = 2.0 * ( x*z + w*y );
01317         Matrix._14 = 0.0;
01318 
01319         Matrix._21 = 2.0 * ( x*y + w * z );
01320         Matrix._22 = w * w-x * x + y*y - z*z;
01321         Matrix._23 = 2.0 * ( y*z - w * x );
01322         Matrix._24 = 0.0;
01323 
01324         Matrix._31 = 2.0 * ( x*z - w*y );
01325         Matrix._32 = 2.0 * ( y*z + w*x );
01326         Matrix._33 = w*w - x*x - y*y + z*z;
01327         Matrix._34 = 0.0;
01328 
01329         Matrix._41 = 0.0;
01330         Matrix._42 = 0.0;
01331         Matrix._43 = 0.0;
01332         Matrix._44 = 1.0;
01333 
01334         return Matrix;
01335 }
01336 
01337 bool CQuaternion::operator ==( const CQuaternion &q ) const { return (    w == q.w && x == q.x && y == q.y && z == q.z ); }
01338 bool CQuaternion::operator !=( const CQuaternion &q ) const { return ( !( w == q.w && x == q.x && y == q.y && z == q.z ));}
01339 bool CQuaternion::operator <=( const CQuaternion &q ) const { return (    w >= q.w && x >= q.x && y >= q.y && z >= q.z ) ;}
01340 bool CQuaternion::operator > ( const CQuaternion &q ) const { return ( !( w >= q.w && x >= q.x && y >= q.y && z >= q.z ));}
01341 bool CQuaternion::operator >=( const CQuaternion &q ) const { return (    w <= q.w && x <= q.x && y <= q.y && z <= q.z ) ;}
01342 bool CQuaternion::operator < ( const CQuaternion &q ) const { return ( !( w <= q.w && x <= q.x && y <= q.y && z <= q.z ));}
01343 
01344 
01345 
01346 
01347 /*--------------------------------------------------------------/
01348 |                                                                                                                               |
01349 |                                                                                                                               |
01350 |                                               実体:CGLObject                                                 |
01351 |                                                                                                                               |
01352 |                                                                                                                               |
01353 /--------------------------------------------------------------*/
01354 
01355 // VBO Extension 関数のポインタ
01356 PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;                  // VBO 名前生成
01357 PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;                  // VBO 結びつけ
01358 PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;                  // VBO データロード
01359 PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;            // VBO 削除
01360 
01361 
01362 CGLObject::CGLObject()
01363 {
01364         C3DObject::Init();
01365 
01366         m_IBO_ID = -1;
01367 
01368         m_VBO_VERTEX    = -1;
01369         m_VBO_NORMAL    = -1;
01370         m_VBO_TEXCODE   = -1;
01371         m_VBO_COLOR             = -1;
01372 
01373         m_DrawOption = (GLObjectOptions)(GLOps_Normal | GLOps_ObjectMaterial);  
01374         IsStatic=false;
01375 }
01376 
01377 CGLObject::~CGLObject()
01378 {
01379 }
01380 
01381 CGLObject::init()
01382 {
01383         C3DObject::Init();
01384         m_IndexList.clear();
01385 
01386         if(glDeleteBuffersARB != NULL)
01387         {
01388                 if(m_VBO_VERTEX != -1)  glDeleteBuffersARB( 1, &m_VBO_VERTEX );
01389                 if(m_VBO_NORMAL != -1)  glDeleteBuffersARB( 1, &m_VBO_NORMAL );
01390                 if(m_VBO_TEXCODE != -1) glDeleteBuffersARB( 1, &m_VBO_TEXCODE );
01391                 if(m_VBO_COLOR != -1)   glDeleteBuffersARB( 1, &m_VBO_COLOR );
01392 
01393                 if(m_IBO_ID != -1)glDeleteBuffersARB( 1, &m_IBO_ID );
01394         }
01395 
01396         m_VBO_VERTEX    = -1;
01397         m_VBO_NORMAL    = -1;
01398         m_VBO_TEXCODE   = -1;
01399         m_VBO_COLOR             = -1;
01400 
01401         m_IBO_ID = -1;
01402 
01403         IsStatic=false;
01404 }
01405 
01406 void CGLObject::SetDrawOption(enum GLObjectOptions OptionFlag)
01407 {
01408         if(OptionFlag&GLOps_VertexMaterial)
01409                 OptionFlag = (GLObjectOptions)(OptionFlag | GLOps_Normal);
01410         
01411 
01412         if(OptionFlag&GLOps_VBO)
01413         {
01414                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_PlaneMaterial);
01415                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_VertexMaterial);
01416                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_PlaneColor);
01417         }
01418 
01419         if(OptionFlag&GLOps_VertexMaterial)
01420         {
01421                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_ObjectMaterial);
01422                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_PlaneMaterial);
01423         }
01424 
01425         if(OptionFlag&GLOps_PlaneMaterial)
01426                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_ObjectMaterial);
01427         
01428 
01429         if(OptionFlag&GLOps_VertexColor)
01430                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_PlaneColor);
01431 
01432         if(OptionFlag&GLOps_Texture)
01433         {
01434                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_PlaneColor);
01435                 OptionFlag = (GLObjectOptions)(OptionFlag & ~GLOps_VertexColor);
01436         }
01437         m_DrawOption = OptionFlag;
01438 }
01439 
01440 
01441 void CGLObject::Draw()
01442 {
01443         glPushMatrix();
01444 
01445         glTranslated(Position.m_Trans.x,Position.m_Trans.y,Position.m_Trans.z);
01446 
01447         const double angle = ToDegree(acos(Position.m_Quaternion.w)); 
01448 
01449         if(angle != 0)
01450         {
01451                 VECTOR3 RotVec(Position.m_Quaternion.x,
01452                                            Position.m_Quaternion.y,
01453                                            Position.m_Quaternion.z);
01454                 RotVec.unit();
01455                 glRotated(angle,RotVec.x,RotVec.y,RotVec.z);
01456         }
01457 
01458         IfEnable(GLOps_VBO)
01459                 DrawVBO();
01460         else
01461                 DrawStandard();
01462 
01463         glPopMatrix();
01464 }
01465 
01466 
01467 void CGLObject::DrawStandard()
01468 {
01469         if(!IsStatic)
01470                 if(m_DrawOption&GLOps_Normal)Normalize();
01471         
01472         IfEnable(GLOps_ALPHA)
01473         {
01474                 glEnable(GL_BLEND);
01475                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01476                 glDepthMask(GL_FALSE);
01477         }
01478 
01479         IfEnable(GLOps_Texture)
01480         {
01481                 m_Texture.BindTextureOGL();
01482                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
01483                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
01484                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01485                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
01486                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
01487         }
01488 
01489         IfEnable(GLOps_ObjectMaterial)
01490         {
01491                 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT ,Material.Ambient. Colors);
01492                 glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE ,Material.Diffuse. Colors);
01493                 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Material.Specular.Colors);
01494         }
01495 
01496 
01497         glBegin(GL_TRIANGLES);
01498         for(int TID=0;TID<m_Triangle.size();TID++)
01499         {
01500                 IfEnable(GLOps_PlaneMaterial)
01501                 {
01502                         glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT ,m_Triangle[TID].Material.Ambient. Colors);
01503                         glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE ,m_Triangle[TID].Material.Diffuse. Colors);
01504                         glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,m_Triangle[TID].Material.Specular.Colors);
01505                 }
01506                 else IfEnable(GLOps_PlaneColor)
01507                         glColor4ubv(m_Triangle[TID].PlaneColor.Colors);
01508 
01509                 IfEnable(GLOps_VertexMaterial)
01510                 {
01511                         glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT ,m_Vertex[m_Triangle[TID].Vec1].Material.Ambient. Colors);
01512                         glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE ,m_Vertex[m_Triangle[TID].Vec1].Material.Diffuse. Colors);
01513                         glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,m_Vertex[m_Triangle[TID].Vec1].Material.Specular.Colors);
01514                 }
01515                 else IfEnable(GLOps_VertexColor)
01516                         glColor4ubv(m_Vertex[m_Triangle[TID].Vec1].VertexColor.Colors);
01517 
01518                 IfEnable(GLOps_Normal)  glNormal3dv  (m_Vertex[m_Triangle[TID].Vec1].Normal.v);
01519                 IfEnable(GLOps_Texture) glTexCoord2dv(m_Vertex[m_Triangle[TID].Vec1].Texture_Coordinate.val);
01520                 glVertex3dv(m_Vertex[m_Triangle[TID].Vec1].Position.v);
01521 
01522 
01523                 IfEnable(GLOps_VertexMaterial)
01524                 {
01525                         glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT ,m_Vertex[m_Triangle[TID].Vec2].Material.Ambient. Colors);
01526                         glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE ,m_Vertex[m_Triangle[TID].Vec2].Material.Diffuse. Colors);
01527                         glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,m_Vertex[m_Triangle[TID].Vec2].Material.Specular.Colors);
01528                 }
01529                 else IfEnable(GLOps_VertexColor)
01530                         glColor4ubv(m_Vertex[m_Triangle[TID].Vec2].VertexColor.Colors);
01531 
01532                 IfEnable(GLOps_Normal)  glNormal3dv  (m_Vertex[m_Triangle[TID].Vec2].Normal.v);
01533                 IfEnable(GLOps_Texture) glTexCoord2dv(m_Vertex[m_Triangle[TID].Vec2].Texture_Coordinate.val);
01534                 glVertex3dv(m_Vertex[m_Triangle[TID].Vec2].Position.v);
01535 
01536 
01537 
01538                 IfEnable(GLOps_VertexMaterial)
01539                 {
01540                         glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT ,m_Vertex[m_Triangle[TID].Vec3].Material.Ambient. Colors);
01541                         glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE ,m_Vertex[m_Triangle[TID].Vec3].Material.Diffuse. Colors);
01542                         glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,m_Vertex[m_Triangle[TID].Vec3].Material.Specular.Colors);
01543                 }
01544                 else IfEnable(GLOps_VertexColor)
01545                         glColor4ubv(m_Vertex[m_Triangle[TID].Vec3].VertexColor.Colors);
01546 
01547                 IfEnable(GLOps_Normal)  glNormal3dv  (m_Vertex[m_Triangle[TID].Vec3].Normal.v);
01548                 IfEnable(GLOps_Texture) glTexCoord2dv(m_Vertex[m_Triangle[TID].Vec3].Texture_Coordinate.val);
01549                 glVertex3dv(m_Vertex[m_Triangle[TID].Vec3].Position.v);
01550         }
01551         glEnd();
01552 
01553         IfEnable(GLOps_ALPHA)
01554         {
01555                 glDisable(GL_BLEND);
01556                 glDepthMask(GL_TRUE);
01557         }
01558 }
01559 
01560 void CGLObject::DrawVBO()
01561 {
01562         //各種機能を有効化
01563         glEnableClientState( GL_VERTEX_ARRAY );//頂点配列
01564         IfEnable(GLOps_Normal)          glEnableClientState( GL_NORMAL_ARRAY );//法線配列
01565         IfEnable(GLOps_Texture)         glEnableClientState( GL_TEXTURE_COORD_ARRAY );//テクスチャ座標配列
01566         IfEnable(GLOps_VertexColor)     glEnableClientState( GL_COLOR_ARRAY  );//色配列
01567 
01568         if(!IsStatic)//頂点データを常に書き換えるならば
01569         {
01570                 IfEnable(GLOps_Normal)Normalize();//頂点法線の計算
01571                 if(glGenBuffersARB==NULL)InitVBO();//VBO初期化
01572                 CreateVBO();//VBO作成
01573         }
01574 
01575         IfEnable(GLOps_ALPHA)
01576         {
01577                 glEnable(GL_BLEND);
01578                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01579 
01580                 glDepthMask(GL_FALSE);
01581         }
01582 
01583         IfEnable(GLOps_ObjectMaterial)
01584         {
01585                 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT ,Material.Ambient. Colors);
01586                 glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE ,Material.Diffuse. Colors);
01587                 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Material.Specular.Colors);
01588         }
01589         
01590         IfEnable(GLOps_Normal)
01591         {
01592                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBO_NORMAL );
01593                 glNormalPointer(GL_FLOAT, 0,0);
01594         }
01595 
01596         IfEnable(GLOps_Texture)
01597         {
01598                 //テクスチャを有効化
01599                 glEnable(GL_TEXTURE_2D);
01600                 //テクスチャをバインド
01601                 m_Texture.BindTextureOGL();
01602 
01603                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
01604                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
01605                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01606                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
01607                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
01608         
01609                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBO_TEXCODE );
01610                 glTexCoordPointer( 2, GL_FLOAT, 0 , 0 );
01611         }
01612 
01613         //色情報の場所
01614         IfEnable(GLOps_VertexColor)
01615         {
01616                 glDisable(GL_LIGHTING);
01617                 glDisable(GL_TEXTURE_2D);
01618 
01619                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBO_COLOR );
01620                 glColorPointer(4,GL_UNSIGNED_BYTE ,0,0);
01621         }
01622 
01623         //頂点
01624         glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBO_VERTEX );
01625         glVertexPointer( 3, GL_FLOAT, 0, 0 );
01626 
01627         //インデックスバッファを呼び出し
01628         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_IBO_ID );
01629         //図形描画
01630         glDrawElements(GL_TRIANGLES, m_Triangle.size()*3, GL_UNSIGNED_INT, 0);
01631         
01632 
01633         IfEnable(GLOps_ALPHA)
01634         {
01635                 glDisable(GL_BLEND);
01636                 glDepthMask(GL_TRUE);
01637         }
01638 
01639         //各種機能を無効化
01640         glDisableClientState( GL_VERTEX_ARRAY );
01641         IfEnable(GLOps_Normal)          glDisableClientState( GL_NORMAL_ARRAY );//法線配列
01642         IfEnable(GLOps_Texture)         glDisableClientState( GL_TEXTURE_COORD_ARRAY );//テクスチャ座標配列
01643         IfEnable(GLOps_VertexColor)     glDisableClientState( GL_COLOR_ARRAY  );//色配列
01644 }
01645 
01646 void CGLObject::InitVBO()
01647 {       
01648         if(IsExtensionSupported( "GL_ARB_vertex_buffer_object" ) )
01649         {
01650                  // VBO関連の関数ポインタを所得する
01651                 glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffersARB");
01652                 glBindBufferARB = (PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBufferARB");
01653                 glBufferDataARB = (PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferDataARB");
01654                 glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) wglGetProcAddress("glDeleteBuffersARB");
01655         }
01656 }
01657 
01658 bool CGLObject::IsExtensionSupported( char* szTargetExtension )
01659 {
01660         const unsigned char *pszExtensions = NULL;
01661         const unsigned char *pszStart;
01662         unsigned char *pszWhere, *pszTerminator;
01663 
01664         // Extension の名前が正しいか調べる(NULLや空白が入っちゃ駄目)
01665         pszWhere = (unsigned char *) strchr( szTargetExtension, ' ' );
01666         if( pszWhere || *szTargetExtension == '\0' )return false;
01667 
01668         // Extension の文字列を所得する
01669         pszExtensions = glGetString( GL_EXTENSIONS );
01670 
01671         // 文字列の中に必要な extension があるか調べる
01672         pszStart = pszExtensions;
01673         for(;;)
01674         {
01675                 pszWhere = (unsigned char *) strstr( (const char *) pszStart, szTargetExtension );
01676                 if( !pszWhere )break;
01677                 pszTerminator = pszWhere + strlen( szTargetExtension );
01678                 if( pszWhere == pszStart || *( pszWhere - 1 ) == ' ' )
01679                         if( *pszTerminator == ' ' || *pszTerminator == '\0' )return true;
01680                 pszStart = pszTerminator;
01681         }
01682         return false;
01683 }
01684 
01685 void CGLObject::CreateVBO()
01686 {
01687 
01688         m_VertexList.clear();
01689         m_NormalList.clear();
01690         m_TexCodeList.clear();
01691         m_ColorList.clear();
01692 
01693         for(int v=0;v<m_Vertex.size();v++)
01694         {
01695                 m_VertexList.push(m_Vertex[v].Position.x);
01696                 m_VertexList.push(m_Vertex[v].Position.y);
01697                 m_VertexList.push(m_Vertex[v].Position.z);
01698 
01699                 IfEnable(GLOps_Normal)
01700                 {
01701                         m_NormalList.push(m_Vertex[v].Normal.x);
01702                         m_NormalList.push(m_Vertex[v].Normal.y);
01703                         m_NormalList.push(m_Vertex[v].Normal.z);
01704                 }
01705 
01706                 IfEnable(GLOps_Texture)
01707                 {
01708                         m_TexCodeList.push(m_Vertex[v].Texture_Coordinate.u);
01709                         m_TexCodeList.push(m_Vertex[v].Texture_Coordinate.v);
01710                 }
01711 
01712                 IfEnable(GLOps_VertexColor)
01713                 {
01714                         m_ColorList.push(m_Vertex[v].VertexColor.Red);
01715                         m_ColorList.push(m_Vertex[v].VertexColor.Green);
01716                         m_ColorList.push(m_Vertex[v].VertexColor.Blue);
01717                 }
01718         }
01719 
01720 
01721         if(m_VBO_VERTEX != -1)glDeleteBuffersARB( 1, &m_VBO_VERTEX );
01722 
01723         glGenBuffersARB( 1, &m_VBO_VERTEX );                                    // ID を得る
01724         glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBO_VERTEX );   // バッファを結びつける
01725         glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_VertexList.size()*sizeof(float), m_VertexList.GetFirstAdder(), GL_STATIC_DRAW_ARB );
01726 
01727         IfEnable(GLOps_Texture)
01728         {
01729                 if(m_VBO_TEXCODE != -1)glDeleteBuffersARB( 1, &m_VBO_TEXCODE );
01730 
01731                 glGenBuffersARB( 1, &m_VBO_TEXCODE );                                   // ID を得る
01732                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBO_TEXCODE );  // バッファを結びつける
01733                 glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_TexCodeList.size()*sizeof(float), m_TexCodeList.GetFirstAdder(), GL_STATIC_DRAW_ARB );
01734 
01735         }
01736 
01737         IfEnable(GLOps_Normal)
01738         {
01739                 if(m_VBO_NORMAL != -1)glDeleteBuffersARB( 1, &m_VBO_NORMAL );
01740 
01741                 glGenBuffersARB( 1, &m_VBO_NORMAL );                                    // ID を得る
01742                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBO_NORMAL );   // バッファを結びつける
01743                 glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_NormalList.size()*sizeof(float), m_NormalList.GetFirstAdder(), GL_STATIC_DRAW_ARB );
01744         }
01745 
01746         IfEnable(GLOps_VertexColor)
01747         {
01748                 if(m_VBO_COLOR != -1)glDeleteBuffersARB( 1, &m_VBO_COLOR );
01749 
01750                 glGenBuffersARB( 1, &m_VBO_COLOR );                                     // ID を得る
01751                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBO_COLOR );    // バッファを結びつける
01752                 glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_ColorList.size()*sizeof(float), m_ColorList.GetFirstAdder(), GL_STATIC_DRAW_ARB );
01753         }
01754 
01755         if(m_IBO_ID != -1)glDeleteBuffersARB( 1, &m_IBO_ID );
01756         glGenBuffersARB( 1, &m_IBO_ID );                                        // ID を得る
01757         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_IBO_ID );       // バッファを結びつける
01758         glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_Triangle.size()*sizeof(unsigned int)*3, m_IndexList.GetFirstAdder(), GL_STATIC_DRAW_ARB );
01759 }
01760 
01761 //インデックスリスト作成のためオーバーライド
01762 const unsigned int  CGLObject::AddTriangle(const unsigned int &Vec1,
01763                                                                                    const unsigned int &Vec2,
01764                                                                                    const unsigned int &Vec3)
01765 {
01766         unsigned int ID = C3DObject::AddTriangle(Vec1,Vec2,Vec3);
01767         
01768         if(ID<m_Triangle.size())
01769         {
01770                 m_IndexList.push(Vec1);
01771                 m_IndexList.push(Vec2);
01772                 m_IndexList.push(Vec3);
01773         }
01774 
01775         return ID;
01776 }
01777 
01778 void CGLObject::Lock()
01779 {
01780         if(m_DrawOption&GLOps_Normal)Normalize();//頂点法線の計算
01781 
01782         if(m_DrawOption & GLOps_VBO)
01783         {
01784                 if(glGenBuffersARB==NULL)InitVBO();//VBO初期化
01785 
01786                 if(glGenBuffersARB!=NULL)
01787                         CreateVBO();//VBO作成
01788                 else//初期化失敗
01789                         m_DrawOption = (GLObjectOptions)(m_DrawOption & ~GLOps_VBO);
01790         }
01791 
01792         IsStatic=true;
01793 }
01794 
01795 
01796 void CGLObject::Unlock()
01797 {
01798         IsStatic=false;
01799 }

ScoutCGLibに対してSat Jun 17 15:19:36 2006に生成されました。  doxygen 1.4.6-NO