把空间中的三角形组织为二叉树的代码!~(能跑,很慢!所有的数据都是现算的(包括n多矩阵乘法)!)

来源:互联网 发布:solaris系统 知乎 编辑:程序博客网 时间:2024/06/06 15:40
#include "stdafx.h"#include "OpenGL.h"#include "Map.h"#include "math.h"#include "ArrayInterTriangle.h"#include <iostream.h>#include <stdio.h>#include <bitset>extern unsigned int m_ID;#include <math.h>#include<stdexcept>#include<time.h>extern boolLbutdown;// 鼠标左键extern boolRbutdown;// 鼠标左键//////////////////////////////////////////////////////////////////////extern HWNDhWnd;//定义最近的距离视点最近的鼠标物体://定义一个结构来保存所有的物体:#include<list>int TreeDepth=0;#include<vector>using std::bitset;using std::list;using std::vector;using std::runtime_error;using std::length_error;class Triangle{public:Triangle(){for(int i=0;i<3;i++){a[i]=0;b[i]=0;c[i]=0;}}Triangle(const Triangle& tri){for(int i=0;i<3;i++){   this->a[i]=tri.a[i];   this->b[i]=tri.b[i];   this->c[i]=tri.c[i];}}   Triangle& operator =(const Triangle & tri){    for(int i=0;i<3;i++){   this->a[i]=tri.a[i];   this->b[i]=tri.b[i];   this->c[i]=tri.c[i];} return *this;}    float a[3];float b[3];float c[3];};class TheTreeObect{int maxlen;int currentFlip;Triangle *Triangles;public:static int gouzaoshu;   int n;~TheTreeObect(){delete [] this->Triangles;}void SetAsNode(const Triangle &currentFlip){   delete [] Triangles; Triangles=new Triangle[1]; Triangles[0]=currentFlip; n=1; maxlen=1;}void resetTriangle(Triangle *pTri,int n1){if(n1>maxlen){delete[] this->Triangles;Triangles=new Triangle[n1+10];this->maxlen=n1+10;}for(int i=0;i<n1;i++){     this->Triangles[i]=pTri[i];}this->n=n1;}TheTreeObect(const TheTreeObect &obj):n(obj.n),maxlen(obj.maxlen){Triangles=new Triangle[maxlen];for(int i=0;i<n;i++){ Triangles[i]=obj.Triangles[i];}}TheTreeObect & operator=(const TheTreeObect & obj){if(obj.n>maxlen){  delete [] Triangles;  Triangles=new Triangle[obj.maxlen];  this->maxlen=obj.maxlen;}for(int m=0;m<obj.n;m++){Triangles[m]=obj.getTriangles()[m];}this->n=obj.n;return *this;}TheTreeObect(){this->Triangles= new Triangle[10];this->maxlen=10;n=0;}    int add(Triangle triangle){        if(n==maxlen){maxlen=n+10;Triangle* temp=Triangles;Triangles=new Triangle[n+10];for(int i=0;i<n;i++){  Triangles[i]=temp[i];}delete [] temp;temp=NULL;  }  Triangles[n++]=triangle;    return n;}int getN() const{return n;}Triangle *getTriangles ()const{  return Triangles;}void outPutSanjiao(Triangle triangle) const{             float *a=triangle.a; float a0=a[0]; float a1=a[1]; float a2=a[2]; cout<<endl<<a0<<"  "<<a1<<"  "<<a2<<"  "<<endl; float *b=triangle.b; float b0=b[0]; float b1=b[1]; float b2=b[2]; cout<<b0<<"  "<<b1<<"  "<<b2<<"  "<<endl; float *c=triangle.c; float c0=c[0]; float c1=c[1]; float c2=c[2]; cout<<c0<<"  "<<c1<<"  "<<c2<<"  "<<endl;}void outPut() const{        for(int i=0;i<n;i++){      outPutSanjiao(Triangles[i]);   }}    TheTreeObect(float (*triangle)[3][3],int n1){//cout<<"TheTreeObect(float (*triangle)[3][3],int n1) ///begin"<<endl;Triangles= new Triangle[n1+10];this->maxlen=n1+10;this->n=n1;for(int i=0;i<n;i++){for(int j=0;j<3;j++){      Triangles[i].a[j]=triangle[i][0][j];  Triangles[i].b[j]=triangle[i][1][j];  Triangles[i].c[j]=triangle[i][2][j];}  }//cout<<"TheTreeObect(float (*triangle)[3][3],int n1) ///end"<<endl;}};int TheTreeObect::gouzaoshu=0;int NodeGouZaoShu;//而叉树节点是一个特殊的物体。。它只有一个平面。class BSPNode:public TheTreeObect{public:virtual ~BSPNode(){NodeGouZaoShu--;delete pBackChild;delete pFrontChild;}    BSPNode():TheTreeObect(){   NodeGouZaoShu++;   IsLeaf=true;   pBackChild=NULL;       pFrontChild=NULL;   n=0;}bool IsLeaf;BSPNode(const TheTreeObect& obj):TheTreeObect(obj){NodeGouZaoShu++;pBackChild=NULL;        pFrontChild=NULL;IsLeaf=true;}    BSPNode* pBackChild;BSPNode* pFrontChild;//查看物体的第index个三角形是否与既定面共面。    void outPutSanjiao(Triangle triangle) const{             float *a=triangle.a; float a0=a[0]; float a1=a[1]; float a2=a[2]; cout<<endl<<a0<<"  "<<a1<<"  "<<a2<<"  "<<"|"; float *b=triangle.b; float b0=b[0]; float b1=b[1]; float b2=b[2]; cout<<b0<<"  "<<b1<<"  "<<b2<<"  "<<"|"; float *c=triangle.c; float c0=c[0]; float c1=c[1]; float c2=c[2]; cout<<c0<<"  "<<c1<<"  "<<c2<<"  "<<endl;}void outPutSanJiaos(Triangle* pTriangle,int n) const{        for(int i=0;i<n;i++){      outPutSanjiao(pTriangle[i]);   }}void outPutVector(char *p,float *pf,int n) const{   for(int j=0;p[j]!='\0';p++)   {cout<<p[j];   }    cout<<":"<<endl;       for(int i=0;i<n;i++){ cout<<pf[i]<<endl;}   }bool IsFomFront(Triangle sanjiao,Triangle flipflat,bool &same,bool &divied){        divied=false;same=false;bitset<3> position[3];float dir[3];bool Front[3];bool IsNotInFlat[3];    float point[3];memcpy(point,sanjiao.a,3*sizeof(float));//int currentFlip=getFlip();VectBinus(flipflat.a,point,dir);IsNotInFlat[0]=IsIntersectWithTriangle(point,dir,flipflat.a,flipflat.b,flipflat.c,point,Front[0]);        memcpy(point,sanjiao.b,3*sizeof(float));VectBinus(flipflat.b,point,dir);IsNotInFlat[1]=IsIntersectWithTriangle(point,dir,flipflat.a,flipflat.b,flipflat.c,point,Front[1]);        memcpy(point,sanjiao.c,3*sizeof(float));VectBinus(flipflat.c,point,dir);IsNotInFlat[2]=IsIntersectWithTriangle(point,dir,flipflat.a,flipflat.b,flipflat.c,point,Front[2]);        for(int i=0;i<3;i++){    if(!IsNotInFlat[i])position[i].set(0);elseif(Front[i])position[i].set(1);elseposition[i].set(2);}//每个点的三个状态对应为 position[0],position[1],position[2];bitset<3> positi=position[0]&position[1]&position[2];if(positi[0]){ same=true;//查看方向是否相同            //求得他们的发线:           float flat_3_flip[3];   float flat_3_temp[3];            qiuFaXiangLiang(flipflat.a,flipflat.b,flipflat.c,flat_3_flip); qiuFaXiangLiang(sanjiao.a,sanjiao.b,sanjiao.c,flat_3_temp); float dotval=DotProduct(flat_3_flip,flat_3_temp); if(dotval<0){ //点积为负值    return false; }else //点积为正值 return true;}else {positi=position[0]|position[1]|position[2];//不共面并且没有在后面的点!!if(!positi[2]){return true;}//不共面没有前面的点else if(!positi[1]){return false;}else {//不共面,既有前面的点,也有后面的点。divied=true;return false;}}}//函数功能:判断一个三角形来自另外一个三角形所在平面的何方。//功能描述:如果共面,则same为true,divided为false,方向相同则返回true,否则返回false; //         如果不共面,则根据在前还是后,还是divided ,进行返回。bool IsFomFront(const TheTreeObect& obj,int index,const int &currentFlip,bool &same,bool &divied){        divied=false;same=false;bitset<3> position[3];float dir[3];bool Front[3];bool IsNotInFlat[3];    float point[3];memcpy(point,obj.getTriangles()[index].a,3*sizeof(float));//int currentFlip=getFlip();VectBinus(obj.getTriangles()[currentFlip].a,point,dir);IsNotInFlat[0]=IsIntersectWithTriangle(point,dir,obj.getTriangles()[currentFlip].a,obj.getTriangles()[currentFlip].b,obj.getTriangles()[currentFlip].c,point,Front[0]);        memcpy(point,obj.getTriangles()[index].b,3*sizeof(float));VectBinus(obj.getTriangles()[currentFlip].b,point,dir);IsNotInFlat[1]=IsIntersectWithTriangle(point,dir,obj.getTriangles()[currentFlip].a,obj.getTriangles()[currentFlip].b,obj.getTriangles()[currentFlip].c,point,Front[1]);        memcpy(point,obj.getTriangles()[index].c,3*sizeof(float));VectBinus(obj.getTriangles()[currentFlip].c,point,dir);IsNotInFlat[2]=IsIntersectWithTriangle(point,dir,obj.getTriangles()[currentFlip].a,obj.getTriangles()[currentFlip].b,obj.getTriangles()[currentFlip].c,point,Front[2]);        for(int i=0;i<3;i++){    if(!IsNotInFlat[i])position[i].set(0);elseif(Front[i])position[i].set(1);elseposition[i].set(2);}//每个点的三个状态对应为 position[0],position[1],position[2];bitset<3> positi=position[0]&position[1]&position[2];if(positi[0]){ same=true;//查看方向是否相同            //求得他们的发线:           float flat_3_flip[3];   float flat_3_temp[3];            qiuFaXiangLiang(obj.getTriangles()[currentFlip].a,obj.getTriangles()[currentFlip].b,obj.getTriangles()[currentFlip].c,flat_3_flip); qiuFaXiangLiang(obj.getTriangles()[index].a,obj.getTriangles()[index].b,obj.getTriangles()[index].c,flat_3_temp); float dotval=DotProduct(flat_3_flip,flat_3_temp); if(dotval<0){ //点积为负值    return false; }else //点积为正值 return true;}else {positi=position[0]|position[1]|position[2];//不共面并且没有在后面的点!!if(!positi[2]){return true;}//不共面没有前面的点else if(!positi[1]){return false;}else {//不共面,既有前面的点,也有后面的点。divied=true;return false;}}}//函数功能:从所有的备选三角形列表中找到一个最佳的分割平面。int getTheBestDivider(vector<int> TheDividerList,bool &found, const TheTreeObect& obj){   int pinggu_value;       found=false;       int theOptimizedValue;   int theOpTriagl;   bool IsInit=false;                    bool AllFront=true;   bool AllBack=true;       for(int flip=0;flip<TheDividerList.size();flip++){    int N_FRONT=0;int N_BACK=0;int N_DIVIDE=0;if( !IsTriangle(   obj.getTriangles()[TheDividerList[flip]].a,   obj.getTriangles()[TheDividerList[flip]].b,   obj.getTriangles()[TheDividerList[flip]].c   ) )continue;for(int index=0;index<obj.getN();index++){bool front;bool same;bool divided;front=IsFomFront(obj,index,flip,same,divided);if(divided){N_DIVIDE++;AllBack=false;AllFront=false;}else if(front){AllBack=false;N_FRONT++;}else {N_BACK++;AllFront=false;}}//for endif(!AllBack&&!AllFront){   found=true;}pingguvalue=fabs(N_FRONT-N_BACK)+N_DIVIDE;if(!IsInit){theOpTriagl=flip;theOptimizedValue=pinggu_value;IsInit=true;}else if(pinggu_value<theOptimizedValue){ theOpTriagl=flip;theOptimizedValue=pinggu_value;}   }   if(found){      return theOpTriagl;   }else return 0;  }   //参数:triangle:待分割的三角形//divider: 分割面//pTri:分割后的三角形//p_front:前,还是后//返回:分割后的三角形个数int divideTriangle(Triangle triangle,Triangle divider,Triangle* &pTri,bool *& p_front){//定义Bool型变量记录以顶点出发的变是否与平面相交。        bool notdivided[3];//边float dingdian[3][3];//边是向量。从对应的顶点出发的边。float bian[3][3];//构造三角形集合://记录顶点三角是否有效:bool valid[3];    //bool front[3];        float dingdiansanjiao[3][3][3];//对顶点和边向量进行赋值//平面方程系数float flat[4];unsigned char dingdianweizhi[3];if(!qiuPingMianFangCheng(divider.a,divider.b,divider.c,flat))return -1;        for(int i=0;i<3;i++){  dingdian[0][i]=triangle.a[i];  dingdian[1][i]=triangle.b[i];  dingdian[2][i]=triangle.c[i];}for(i=0;i<3;i++){ int j=i+1; if(j==3)j=0; VectBinus(dingdian[j],dingdian[i],bian[i]);}//判断各个顶点与平面的位置关系const unsigned char QIAN=0;const unsigned char SHANG=1;const unsigned char HOU=2;for(i=0;i<3;i++){  float k= flat[0]*dingdian[i][0]+flat[1]*dingdian[i][1]+flat[2]*dingdian[i][2]+flat[3];if(k>0.00001)dingdianweizhi[i]=QIAN;else if(k<-0.00001)dingdianweizhi[i]=HOU;else dingdianweizhi[i]=SHANG;}unsigned char jiaodianweizhi[3];float jiaodian[3][3];unsigned char m=0;pTri =new Triangle[1+2];p_front=new bool[3];int n=0;for(i=0;i<3;i++){if(fabs(dingdianweizhi[i]-dingdianweizhi[i==2?0:i+1])==2){jiaodianweizhi[i]=SHANG;   calInsert(dingdian[i],bian[i],flat,jiaodian[i]);notdivided[i]=false;}else{//交点退化为顶点/*for(int j=0;j<3;j++){jiaodian[i][j]=dingdian[i][j];}*/memcpy(jiaodian[i],dingdian[i],sizeof(jiaodian[i]));jiaodianweizhi[i]=dingdianweizhi[i];    notdivided[i]=true;}}        memcpy(pTri[n].a,jiaodian[0],sizeof(jiaodian[0]));memcpy(pTri[n].b,jiaodian[1],sizeof(jiaodian[1]));memcpy(pTri[n].c,jiaodian[2],sizeof(jiaodian[2]));if(jiaodianweizhi[0]==QIAN||jiaodianweizhi[1]==QIAN||jiaodianweizhi[2]==QIAN){p_front[n]=true;}else if(jiaodianweizhi[0]==HOU||jiaodianweizhi[1]==HOU||jiaodianweizhi[2]==HOU){    p_front[n]=false;}    n++;        for(i=0;i<3;i++){if(!notdivided[i]){valid[i]=true;int next;int pre;next=(i==2?0:i+1);pre=(i==0?2:i-1);dingdiansanjiao[i][0][0]=dingdian[i][0];dingdiansanjiao[i][0][1]=dingdian[i][1];dingdiansanjiao[i][0][2]=dingdian[i][2];dingdiansanjiao[i][1][0]=jiaodian[i][0];dingdiansanjiao[i][1][1]=jiaodian[i][1];dingdiansanjiao[i][1][2]=jiaodian[i][2];if(!notdivided[pre]){dingdiansanjiao[i][2][0]=jiaodian[pre][0];dingdiansanjiao[i][2][1]=jiaodian[pre][1];dingdiansanjiao[i][2][2]=jiaodian[pre][2];}else{dingdiansanjiao[i][2][0]=dingdian[pre][0];dingdiansanjiao[i][2][1]=dingdian[pre][1];dingdiansanjiao[i][2][2]=dingdian[pre][2];}memcpy(pTri[n].a,dingdiansanjiao[i][0],sizeof(float [3]));memcpy(pTri[n].b,dingdiansanjiao[i][1],sizeof(dingdiansanjiao[i][0]));              memcpy(pTri[n].c,dingdiansanjiao[i][2],sizeof(dingdiansanjiao[i][0]));if(dingdianweizhi[i]==QIAN){p_front[n]=true;}else if(dingdianweizhi[i]==HOU){p_front[n]=false;}n++;}}Triangle* tri=pTri;bool * temp_front=p_front;pTri=new Triangle[n];p_front=new bool[n];for( m=0;m<n;m++){pTri[m]=tri[m];p_front[m]=temp_front[m];}delete [] tri;delete [] temp_front;    return n;}void addObject(const TheTreeObect & obj){    vector<int> TheDividerList;if(IsLeaf){bool IsFront=false;bool NoUsed=true;int divide_index=0;TheTreeObect _obj;for(int j=0;j<getN();j++){ _obj.add(getTriangles()[j]);}for(j=0;j<obj.getN();j++){_obj.add(obj.getTriangles()[j]);}for(int i=0;i<_obj.getN();i++){NoUsed=true;for(int j=0;j<TheDividerList.size();j++){ bool sameFlat=false; bool divided=false; IsFront=IsFomFront(_obj,i,TheDividerList[j],sameFlat,divided); //int m=TheDividerList[j]; if(sameFlat){  NoUsed=false;  break;}  }if(NoUsed){TheDividerList.push_back(i); } }bool found=false;divide_index=getTheBestDivider(TheDividerList,found,_obj);if(!found){                 this->resetTriangle(_obj.getTriangles(),_obj.getN());     return;}else {TheTreeObect  Front_obj;TheTreeObect  Back_obj;for(i=0;i<_obj.getN();i++){bool sameFlat=false;bool divided=false;IsFront=IsFomFront(_obj,i,TheDividerList.at(divide_index),sameFlat,divided);//如果交叉.if(divided){//分解三角形Triangle* pTri;bool * p_front;int number=divideTriangle(_obj.getTriangles()[i],_obj.getTriangles()[TheDividerList.at(divide_index)],pTri,p_front);Triangle* temp_p= pTri;bool * temp_f=p_front;for(i=0;i<number;i++){if(*temp_f){Front_obj.add(*temp_p);}else{Back_obj.add(*temp_p);}temp_f++;temp_p++;}temp_f=NULL;temp_p=NULL;delete [] pTri;delete [] p_front;}    else if(IsFront){Front_obj.add(_obj.getTriangles()[i]);}else{Back_obj.add(_obj.getTriangles()[i]);}} IsLeaf=false;pFrontChild=new BSPNode();pBackChild=new BSPNode();pFrontChild->addObject(Front_obj);pBackChild->addObject(Back_obj);    this->SetAsNode(_obj.getTriangles()[TheDividerList.at(divide_index)]);}//(else if(!found end))       }//IsLeaf End;}//功能描述:更新节点..void UpdateByModels(const Triangle* theTriangles,int n){typedef  float   float_33[3][3];float (*p)[3][3];p=new float_33 [n];for(int i=0;i<n;i++){for(int j=0;j<3;j++){p[i][0][j]=theTriangles[i].a[j];p[i][1][j]=theTriangles[i].b[j];p[i][2][j]=theTriangles[i].c[j];}}TheTreeObect* BAK_Obj=new TheTreeObect(p,n);if(IsLeaf){this->addObject(*BAK_Obj);}else if(!IsLeaf){TheTreeObect* FrontObj=new TheTreeObect();TheTreeObect* BackObj=new TheTreeObect();for(int j=0;j<n;j++){bool front=false;bool same=false;bool divided=false;Triangle sanjiao=BAK_Obj->getTriangles()[j];Triangle flipflat=this->getTriangles()[0];front=IsFomFront(sanjiao,flipflat,same,divided);if(divided){//分解三角形Triangle* pTri;bool * p_front;int number=divideTriangle(sanjiao,flipflat,pTri,p_front);Triangle* temp_pTri= pTri;bool * temp_p_Front=p_front;for(int i=0;i<number;i++){if(*temp_p_Front)FrontObj->add(*temp_pTri);elseBackObj->add(*temp_pTri);temp_p_Front++;temp_pTri++;}delete [] pTri;delete [] p_front;}//divided End;else if(front){FrontObj->add(theTriangles[j]);   }else {BackObj->add(theTriangles[j]);}}//for End;((BSPNode*)pFrontChild)->UpdateByModels(FrontObj->getTriangles(),FrontObj->getN());      ((BSPNode*)pBackChild)->UpdateByModels(BackObj->getTriangles(),BackObj->getN());delete FrontObj;delete BackObj;FrontObj=NULL;BackObj=NULL;}//if(!leaf end)delete  BAK_Obj;BAK_Obj=NULL;delete[] p;p=NULL;}//UpdateByModelEnd;void outPut(){    if(IsLeaf){cout<<"IsLeaf:True"<<endl;outPutSanJiaos(this->getTriangles(),this->getN());}else if(!IsLeaf){cout<<"IsLeaf:false"<<endl;outPutSanjiao(this->getTriangles()[0]);((BSPNode*)pFrontChild)->outPut();((BSPNode*)pBackChild)->outPut();}}};class BSPTree{   public: BSPTree(){  pTree=new BSPNode();} ~BSPTree(){   delete[] pTree; }     BSPNode* pTree; //更新二叉树: void UpdateByModels(const Triangle* Triangle,int n){       pTree->UpdateByModels(Triangle,n);  }; void addObject(TheTreeObect obj){   pTree->addObject(obj); } void outPut(){   pTree->outPut(); }};//....class nearestobject{      private: bool IsInited; static nearestobject* const theOnlyOne; int index; float nearpoint[3];  float point[3];  float nearestDistance; nearestobject():IsInited(false),index(0),nearestDistance(0.0){point[0]=0.0;point[1]=0.0;point[2]=0.0; }  void setLookPoint(float nearpoint[3]){       this->nearpoint[0]=nearpoint[0];   this->nearpoint[1]=nearpoint[1];   this->nearpoint[2]=nearpoint[2];  }  void VectBinus(float a[3],float b[3],float c[3]){c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];  }//计算模  double calMole(float a[3]){return sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);  }   public:  static  nearestobject* GetNearestP(){            return theOnlyOne;  }  //初始化一个近裁剪面点,一个线上的点,以及点对应物体的index;      //返回:是否已经被初始化过  bool Init(float nearpoint[3],float farpoint[3]){ if(!IsInited){  setLookPoint(nearpoint);for(int i=0;i<3;i++){   this->point[i]=point[i];}    this->index=index;this->IsInited=true;float temp[3];            VectBinus(farpoint,nearpoint,temp);            this->nearestDistance=calMole(temp);return false; } return true;  }  int getIndex(){       return index;  }   //返回:以前的物体编号。  int set(int index,float point[3]){  int tempindex;  tempindex=this->index;  double distance;  float temp[3];          VectBinus(point,nearpoint,temp);          distance=calMole(temp);  if((distance-nearestDistance)<-0.000001)  {    nearestDistance=distance;this->index=index;  }  return  tempindex;  }};nearestobject* const nearestobject::theOnlyOne=new nearestobject();//定义射线求交用的变量,这些变量用来进行拾取float org[3],dir[3],a[3],b[3],c[3],point[3],end[3];bool IsFromFront;bool calculateInterWithTriangle(float a[3],float b[3],float c[3]){return IsIntersectWithTriangle(org,dir,a,b,c,point,IsFromFront);}OpenGL::OpenGL(){}OpenGL::~OpenGL(){CleanUp();}BOOL OpenGL::SetupPixelFormat(HDC hDC0)//检测安装OpenGL{int nPixelFormat;  // 象素点格式hDC=hDC0;PIXELFORMATDESCRIPTOR pfd = {     sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小     1,                                // 版本号     PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图     PFD_SUPPORT_OPENGL |              // 支持 OpenGL     PFD_DOUBLEBUFFER,                 // 双缓存模式     PFD_TYPE_RGBA,                    // RGBA 颜色模式     16,                               // 24 位颜色深度     0, 0, 0, 0, 0, 0,                 // 忽略颜色位     0,                                // 没有非透明度缓存     0,                                // 忽略移位位     0,                                // 无累加缓存     0, 0, 0, 0,                       // 忽略累加位     16,                               // 32 位深度缓存         0,                                // 无模板缓存     0,                                // 无辅助缓存     PFD_MAIN_PLANE,                   // 主层     0,                                // 保留     0, 0, 0                           // 忽略层,可见性和损毁掩模 }; if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd))){ MessageBox(NULL,"没找到合适的显示模式","Error",MB_OK|MB_ICONEXCLAMATION);      return FALSE;}SetPixelFormat(hDC,nPixelFormat,&pfd);//设置当前设备的像素点格式//利用hDC创造hRC,这句话使得windows设备句柄转化为opengl支持的设备句柄。hRC = wglCreateContext(hDC);          //获取渲染描述句柄//得到hRC后,我们激活它,,让它与当前的hDC相关联。wglMakeCurrent(hDC, hRC);             //激活渲染描述句柄;//cout<<"Init"<<endl;//m_baiscobj=new baiscobj();//m_baiscobj->light0();return TRUE;}extern int k;void OpenGL::init(int Width, int Height){     glViewport(0,0,Width,Height);// 设置OpenGL视口大小。   glMatrixMode(GL_PROJECTION);// 设置当前矩阵为投影矩阵。   glLoadIdentity();// 重置当前指定的矩阵为单位矩阵   gluPerspective// 设置透视图( 90.0f,// 透视角设置为 45 度  (GLfloat)Width/(GLfloat)Height,// 窗口的宽与高比  0.1f,// 视野透视深度:近点1.0f  3000.0f// 视野透视深度:始点0.1f远点1000.0f);// 这和照象机很类似,第一个参数设置镜头广角度,第二个参数是长宽比,后面是远近剪切。glMatrixMode(GL_MODELVIEW);// 设置当前矩阵为模型视图矩阵//glLoadIdentity();// 重置当前指定的矩阵为单位矩阵//====================================================}struct point3f//定义一个三维变量结构{double x; double y; double z;};#define MAP_W       32        // size of map along x-axis 32 #define MAP_SCALE   24.0f     // the scale of the terrain map#define MAPMAP_W*MAP_SCALE/2point3f n_vector;//float xyz[3]; floatnimh=0,sx,sz;//上一次3D鼠void picter(float x,float y,float z);double modelview[16];                           // 定义保存视图矩阵数组double projection[16];                          // 定义保存投影矩阵数组int    viewport[4]={0,0,800,600};               // 定义保存屏幕尺寸数组POINT mouse;point3f nearPoint;point3f farPoint;point3f xyz;#define FRAND   (((float)rand()-(float)rand())/RAND_MAX)void OpenGL::Render()//OpenGL图形处理{    GetCursorPos(&mouse);ScreenToClient(hWnd,&mouse);//下面对鼠标位置进行编程。//首先转化为opengl的视口坐标,视口坐标实际上就是窗口坐标,因为前面已经设定。//下面把屏幕坐标转Opengl坐标:mouse.x=mouse.x, mouse.y=Height-mouse.y;//;//cout<<mouse.x<<endl;//;//cout<<mouse.y;//;//cout<<mouse.x<<" "<<mouse.y<<endl;    //下面把屏幕坐标转化为3D坐标glGetDoublev(GL_MODELVIEW_MATRIX,modelview);    // 获取视图矩阵glGetDoublev(GL_PROJECTION_MATRIX,projection);  // 获取投影矩阵glGetIntegerv(GL_VIEWPORT,viewport);            // 获取视口大小gluUnProject( (double)mouse.x,                  // 窗口坐标X  (double)mouse.y,                  // 窗口坐标Y  0.0f,                             // 获取近裁剪面上的交点                  modelview,                        // 视图矩阵                  projection,                       // 投影矩阵                  viewport,                         // 屏幕视区                  &nearPoint.x,                        // 获得的近点3D坐标值X  &nearPoint.y,                        // 获得的近点3D坐标值Y                  &nearPoint.z                         // 获得的近点3D坐标值Z);gluUnProject( (double)mouse.x,                  // 窗口坐标X  (double)mouse.y,                  // 窗口坐标Y  1.0f,                             // 获取近裁剪面上的交点                  modelview,                        // 视图矩阵                  projection,                       // 投影矩阵                  viewport,                         // 屏幕视区                  &farPoint.x,                        // 获得的近点3D坐标值X  &farPoint.y,                        // 获得的近点3D坐标值Y                  &farPoint.z                         // 获得的近点3D坐标值Z);   //Lbutdown=false;dir[0]=n_vector.x=farPoint.x-nearPoint.x;    dir[1]=n_vector.y=farPoint.y-nearPoint.y;    dir[2]=n_vector.z=farPoint.z-nearPoint.z;    org[0]=nearPoint.x;      org[1]=nearPoint.y;org[2]=nearPoint.z;end[0]=farPoint.x;end[1]=farPoint.y;end[2]=farPoint.z;IsFromFront=false;nearestobject* pNearest=nearestobject::GetNearestP();pNearest->Init(org,end);/*for(int i=0;i<N;i++){ int n_triangle; Triangle* p_nTriangle=object[i].getTriangles(n_triangle); for(int i=0;i<n_triangle;i++) Triangle[i].get(a,b,c);     calculateInterWithTriangle(,b,c);}*/glClearColor(0.50f, 0.70f, 0.90f, 1.0f); // 设置刷新背景色glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);// 刷新背景// glLoadIdentity();// 重置当前的模型观察矩阵glPushMatrix();//压入堆栈glEnable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D);picter(-15,-25,-40);// 更新窗口glEnable(GL_TEXTURE_2D);//使用纹理glTranslatef(0,0,-280);glBindTexture(GL_TEXTURE_2D, m_ID);//  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );  glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-Width/2, -Height/2,  0.0f);// 前glTexCoord2f(1.0f, 0.0f); glVertex3f( Width/2,-Height/2,  0.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( Width/2,  Height/2,  0.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-Width/2,  Height/2,  0.0f);  glEnd();  glPopMatrix();    glFlush();  SwapBuffers(hDC);// 切换缓冲区}void OpenGL::CleanUp(){ wglMakeCurrent(hDC, NULL);                     //清除OpenGL wglDeleteContext(hRC);                         //清除OpenGL}float r=0;void picter(float x,float y,float z)//组合图形{   BSPTree myTree;static int n_iTriangles;//TheTreeObect(float *triangle[3][3],int n1)float triangle [2][3][3];for(int j=0;j<1;j=+2){triangle[j][0][0]=0+j;triangle[j][0][1]=2+j;triangle[j][0][2]=0+j;triangle[j][1][0]=0+j;triangle[j][1][1]=1+j;triangle[j][1][2]=0+j;triangle[j][2][0]=0+j;triangle[j][2][1]=0+j;triangle[j][2][2]=1+j;triangle[j+1][0][0]=1+j;triangle[j+1][0][1]=0+j;triangle[j+1][0][2]=1;triangle[j+1][1][0]=0+j;triangle[j+1][1][1]=1+j;triangle[j+1][1][2]=0+j;triangle[j+1][2][0]=-1+j;triangle[j+1][2][1]=0+j;triangle[j+1][2][2]=0+j;}TheTreeObect obj(triangle,2);//cout<<n_iTriangles++<<endl;    myTree.UpdateByModels(obj.getTriangles(),obj.getN());myTree.addObject(obj);//myTree.outPut();glPushAttrib(GL_CURRENT_BIT);//保存现有颜色属实性glTranslatef(0,0,-30);//平台的定位   glPushMatrix();//平台-==============================glTranslatef(x,y+0.5f,z);//平台的定位glColor3f(0.0f,1.0f,0.2f);//绿色auxSolidCube(1);//方台(边长)glTranslatef(0.0f,0.8f,0.0f);//架的位置调整,上升0.8glColor3f(0.0f,0.0f,1.0f);//蓝色auxSolidBox(.2f,1.3f,.2f);//长方架(宽、高、长) glPopMatrix(); glPushMatrix();//雷达==============================glTranslatef(x,y+2.5f,z);//雷达的定位1glRotatef(r-90,0.0,1.0,0.0);//雷达旋转2//=======================================glColor3f(1.0f,1.0f,1.0f);//白色glRotatef(45, 1.0, 0.0, 0.0);//盘的角度调整,仰30度auxWireCone(1.5,0.6f);//线园锥盘(底半径、高)//=======================================glRotatef(180, 1.0, 0.0, 0.0);//杆的角度调整,反方向转glTranslatef(0.0f,0.0f,-0.7f);  //杆的位置调整,缩进一点auxWireCone(0.2f,2.0f);//园锥杆(底半径、高)glColor3f(FRAND,0,0);//随机红色glTranslatef(0.0f,0.0f,2.0f);//杆的位置调整,缩进一点auxSolidSphere(0.1f);//园(半径) glPopMatrix(); glPushMatrix();//火箭=============================glTranslatef(x,y+10.0f,z);//火箭的定位glRotatef(r, 0.0, 1.0, 0.0);//火箭的旋转glTranslatef(15,0,0);//火箭的定位//=============================================glColor3f(1.0f,0.0f,0.0f);//红色glRotatef(180, 0.0, 1.0, 0.0);//角度调整,与雷达平行,箭头朝前auxSolidCone(.2,0.6);//园锥(底半径、高)//=============================================glColor3f(1.0f,1.0f,1.0f);//白色glRotatef(90, 1.0, 0.0, 0.0);//角度调整,与火箭头对接glTranslatef(0.0f,-1.0f,0);//位置调整,与火箭头对接auxSolidCylinder(.2f,1);//园柱(半径、高)glRotatef(-270, 1.0, 0.0, 0.0);glColor3f(FRAND+.6f,0.2f,0.0f);//随机色glTranslatef(0.0f,-0.0f,-0.2f); //位置调整,缩进一点auxSolidCone(.2,1.5);//园锥(底半径、高) glPopMatrix(); glPopAttrib();//恢复前一属性 r+=0.5f;if(r>360) r=0;}

 

阅读全文
0 0
原创粉丝点击