基本信息
源码名称:OpenGL应用实例2(碰撞检测)
源码大小:2.69M
文件格式:.rar
开发语言:C/C++
更新时间:2020-02-18
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍
OpenGL  2D  动画运行 界面开发



glEnable(GL_TEXTURE_2D);                                      /**< 启用纹理映射 */
char* file[] = {"data/marble.bmp","data/spark.bmp","data/boden.bmp","data/wand.bmp"};

/** 循环读入位图纹理 */
for(int i = 0; i < 4; i )
{
if(!m_texture[i].LoadBitmap(file[i]))                    /**< 载入位图文件 */
{
MessageBox(NULL,"装载位图文件失败!","错误",MB_OK);  /**< 如果载入失败则弹出对话框 */
return false;
}
glGenTextures(1, &m_texture[i].ID);                      /**< 生成一个纹理对象名称 */
 
glBindTexture(GL_TEXTURE_2D, m_texture[i].ID);            /**< 创建纹理对象 */

/** 控制滤波 */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

/** 创建纹理 */
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, m_texture[i].imageWidth,
m_texture[i].imageHeight, GL_RGB, GL_UNSIGNED_BYTE,
m_texture[i].image);
}
return true;
}

/** 初始化OpenGL */
bool Test::Init()
{
/** 用户自定义的初始化过程 */
glClearColor(0,0,0,0);
  glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();  

///设置光源参数
GLfloat spec[] = { 1.0, 1.0 ,1.0 ,1.0 };      
GLfloat posl[] = { 0, 400, 0, 1 };               
GLfloat amb[]  = { 0.2f, 0.2f, 0.2f ,1.0f };   
GLfloat amb2[] = { 0.3f, 0.3f, 0.3f ,1.0f };  
float df=100.0;

glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_CULL_FACE);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

/** 设置材质属性 */
glMaterialfv(GL_FRONT,GL_SPECULAR,spec);
glMaterialfv(GL_FRONT,GL_SHININESS,&df);

/** 设置光源 */
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0,GL_POSITION,posl);
glLightfv(GL_LIGHT0,GL_AMBIENT,amb2);
glEnable(GL_LIGHT0);

glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
   
/** 开启混合 */
glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
   
/** 开启纹理映射,并载入纹理 */
glEnable(GL_TEXTURE_2D);
    LoadTexture();

/** 用两个互相垂直的平面模拟爆炸效果 */
    glNewList( dlist = glGenLists(1), GL_COMPILE);  /**< 创建显示列表 */
    glBegin(GL_QUADS);
glRotatef(-45,0,1,0);
glNormal3f(0,0,1);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-50,-40,0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(50,-40,0);
glTexCoord2f(1.0f, 1.0f); glVertex3f(50,40,0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-50,40,0);
    glNormal3f(0,0,-1);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-50,40,0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(50,40,0);
glTexCoord2f(1.0f, 1.0f); glVertex3f(50,-40,0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-50,-40,0);

glNormal3f(1,0,0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0,-40,50);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0,-40,-50);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0,40,-50);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0,40,50);
    glNormal3f(-1,0,0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0,40,50);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0,40,-50);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0,-40,-50);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0,-40,50);
glEnd();
    glEndList();                                   /**< 结束显示列表定义 */

/** 初始化变量 */
InitVars();    

/** 初始化字体 */
if(!m_Font.InitFont())
MessageBox(NULL,"初始化字体失败!","错误",MB_OK);

ResizeDraw(true);

return true;                                            /**< 成功返回 */
}

/** 用户自定义的卸载函数 */
void Test::Uninit()
{
for(int i=0; i < 4; i ) 
{
m_texture[i].FreeImage();               /**< 释放纹理图像占用的内存 */
    glDeleteTextures(1, &m_texture[i].ID);  /**< 删除纹理对象 */
}

/** 释放二次对象 */
if(cylinder_obj != NULL)
gluDeleteQuadric(cylinder_obj);
}

/** 程序更新函数 */
void Test::Update(DWORD milliseconds)
{
if (m_Keys.IsPressed(VK_ESCAPE) == true) /**< 按ESC退出 */
{
TerminateApplication();
}

    
}

/** 计算帧速 */
void Test::CaculateFrameRate()
{
static float framesPerSecond    = 0.0f;      /**< 保存显示帧数 */
    static float lastTime = 0.0f;      /**< 记录上次时间 */
    float currentTime = GetTickCount() * 0.001f; /**< 获得当前时间 */

framesPerSecond;                           /**< 显示帧数递增1 */
    /** 如果时间差大于1.0秒 */
if( currentTime - lastTime > 1.0f )          
    {

    lastTime = currentTime;                   /**< 保存当前时间 */
m_Fps = framesPerSecond;                  /**< 当前帧数传给m_Fps */
        framesPerSecond = 0;                      /**< 将帧数置零 */                    
    }
}

/** 输出文字信息 */
void  Test::PrintText()
{
char string[128];                               /**< 用于保存输出字符串 */
glPushAttrib(GL_CURRENT_BIT);                   /**< 保存现有颜色属性信息 */
glColor3f(0.0f,1.0f,0.0f);                      /**< 设置文字颜色 */

/** 输出帧速 */
CaculateFrameRate();                               /**< 计算帧速 */
    sprintf(string,"FPS:%3.0f",m_Fps);                 /**< 字符串赋值 */
m_Font.PrintText(string, -5.0f,3.0f);              /**< 输出字符串 */
glPopAttrib();

}

/** 检测是否与平面碰撞 */
int Test::TestIntersionPlane(const Plane& plane,const Vector3& position,const Vector3& direction, double& lamda, Vector3& pNormal)
{
double dotProduct = direction.dot(plane._Normal);
double l2;

    ///判断是否平行于平面
    if ((dotProduct < ZERO) && (dotProduct > -ZERO)) 
return 0;

    l2 = (plane._Normal.dot(plane._Position - position))/dotProduct;

///交点在射线相反方向,此时不发生碰撞
    if (l2 < -ZERO) 
return 0;

    pNormal = plane._Normal;
lamda = l2;
    return 1;
}

/** 检测是否与圆柱体碰撞 */
int Test::TestIntersionCylinder(const Cylinder& cylinder,const Vector3& position,const Vector3& direction, double& lamda, Vector3& pNormal,Vector3& newposition)
{
Vector3 RC;
double d;
double t,s;
Vector3 n,D,O;
double ln;
double in,out;


Vector3::subtract(position,cylinder._Position,RC);
Vector3::cross(direction,cylinder._Axis,n);

    ln = n.mag();

if ( (ln<ZERO)&&(ln>-ZERO) ) return 0;

n.unit();

d =  fabs( RC.dot(n) );

    if (d <= cylinder._Radius)
{
Vector3::cross(RC,cylinder._Axis,O);
t =  - O.dot(n)/ln;
Vector3::cross(n,cylinder._Axis,O);
O.unit();
s =  fabs( sqrt(cylinder._Radius*cylinder._Radius - d*d) / direction.dot(O) );

in = t-s;
out = t s;

if (in<-ZERO){
if (out<-ZERO) return 0;
else lamda = out;
}
else
        if (out<-ZERO) {
      lamda = in;
}
else
if (in<out) lamda = in;
else lamda = out;

    newposition = position direction*lamda;
Vector3 HB = newposition-cylinder._Position;
pNormal = HB - cylinder._Axis*(HB.dot(cylinder._Axis));
pNormal.unit();

return 1;
}
    
return 0;
}

int Test::FindBallCol(Vector3& point, double& TimePoint, double Time2, int& BallNr1, int& BallNr2)
{
Vector3 RelativeV;
TRay rays;
double MyTime = 0.0, Add = Time2/150.0, Timedummy = 10000, Timedummy2 = -1;
Vector3 posi;

///判断球和球是否相交
for (int i = 0;i<NrOfBalls-1;i )
{
for (int j = i 1;j<NrOfBalls;j )
{
    RelativeV = ArrayVel[i]-ArrayVel[j];
rays = TRay(OldPos[i],Vector3::unit(RelativeV));
MyTime = 0.0;

if ( (rays.dist(OldPos[j])) > 40) continue; 

while (MyTime<Time2)
{
   MyTime = Add;
   posi = OldPos[i] RelativeV*MyTime;
   if (posi.dist(OldPos[j]) <= 40) {
   point = posi;
   if (Timedummy>(MyTime-Add)) Timedummy = MyTime-Add;
   BallNr1 = i;
   BallNr2 = j;
   break;
}

}
}

}

if (Timedummy != 10000) { TimePoint = Timedummy;
                        return 1;
}

return 0;
}

/** 主要的处理过程 */
void Test::process()
{
double rt,rt2,rt4,lamda = 10000;
  Vector3 norm,uveloc;
  Vector3 normal,point,time;
  double RestTime,BallTime;
  Vector3 Pos2;
  int BallNr = 0,dummy = 0,BallColNr1,BallColNr2;
  Vector3 Nc;

  ///如果没有锁定到球上,旋转摄像机
 // if (!hook_toball1)
 // {
  camera_rotation = 0.1f;
  if (camera_rotation>360)
  camera_rotation = 0;
 // }
 
  RestTime = Time;
  lamda = 1000;

///计算重力加速度
for (int j = 0;j<NrOfBalls;j )