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 °ree)
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
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
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
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
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
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
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 {
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
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
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
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
00862 m_Texture_Data.Width = cinfo.image_width;
00863 m_Texture_Data.Height = cinfo.image_height;
00864
00865
00866 bmp_row_bytes = m_Texture_Data.Width*4;
00867 bmp_image_size = bmp_row_bytes * m_Texture_Data.Height;
00868
00869
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
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
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
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
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
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
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
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
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
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
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
01351
01352
01353
01354
01355
01356 PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
01357 PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
01358 PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
01359 PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;
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();
01572 CreateVBO();
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
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
01665 pszWhere = (unsigned char *) strchr( szTargetExtension, ' ' );
01666 if( pszWhere || *szTargetExtension == '\0' )return false;
01667
01668
01669 pszExtensions = glGetString( GL_EXTENSIONS );
01670
01671
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 );
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 );
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 );
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 );
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 );
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();
01785
01786 if(glGenBuffersARB!=NULL)
01787 CreateVBO();
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 }