projectilehandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 881 行 · 第 1/2 页
CPP
881 行
numFlyingPieces += fpl->size();
for(std::list<FlyingPiece*>::iterator pi=fpl->begin();pi!=fpl->end();++pi){
CMatrix44f m;
m.Rotate((*pi)->rot,(*pi)->rotAxis);
float3 interPos=(*pi)->pos+(*pi)->speed*gu->timeOffset;
SS3OVertex * verts = (*pi)->verts;
float3 tp, tn;
for (int i = 0; i < 4; i++){
tp=m.Mul(verts[i].pos);
tn=m.Mul(verts[i].normal);
tp+=interPos;
va->AddVertexTN(tp,verts[i].textureX,verts[i].textureY,tn);
}
}
drawnPieces+=va->drawIndex/32;
va->DrawArrayTN(GL_QUADS);
}
}
unitDrawer->CleanUpS3ODrawing();
/*
* TODO Nearly cut here.
*/
unitDrawer->SetupForUnitDrawing();
Projectile_List::iterator psi;
distlist.clear();
for(psi=ps.begin();psi != ps.end();++psi){
if(camera->InView((*psi)->pos,(*psi)->drawRadius) && (gu->spectatingFullView || loshandler->InLos(*psi,gu->myAllyTeam) || ((*psi)->owner && gs->Ally((*psi)->owner->allyteam,gu->myAllyTeam)))){
if(drawReflection){
if((*psi)->pos.y < -(*psi)->drawRadius)
continue;
float dif=(*psi)->pos.y-camera->pos.y;
float3 zeroPos=camera->pos*((*psi)->pos.y/dif) + (*psi)->pos*(-camera->pos.y/dif);
if(ground->GetApproximateHeight(zeroPos.x,zeroPos.z)>3+0.5f*(*psi)->drawRadius)
continue;
}
if(drawRefraction && (*psi)->pos.y>(*psi)->drawRadius)
continue;
if((*psi)->s3domodel){
if((*psi)->s3domodel->textureType){
unitDrawer->QueS3ODraw(*psi,(*psi)->s3domodel->textureType);
} else {
(*psi)->DrawUnitPart();
}
}
struct projdist tmp;
tmp.proj=*psi;
tmp.dist=(*psi)->pos.dot(camera->forward);
distlist.push_back(tmp);
}
}
unitDrawer->CleanUpUnitDrawing();
unitDrawer->DrawQuedS3O();
sort(distlist.begin(), distlist.end(), CompareProjDist);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
textureAtlas->BindTexture();
glEnable(GL_BLEND);
glDepthMask(0);
glColor4f(1,1,1,0.2f);
glAlphaFunc(GL_GREATER,0.0f);
glEnable(GL_ALPHA_TEST);
// glFogfv(GL_FOG_COLOR,FogLand);
glDisable(GL_FOG);
currentParticles=0;
CProjectile::inArray=false;
CProjectile::va=GetVertexArray();
CProjectile::va->Initialize();
for(int a=0;a<distlist.size();a++){
distlist.at(a).proj->Draw();
}
if(CProjectile::inArray)
CProjectile::DrawArray();
glDisable(GL_TEXTURE_2D);
glDepthMask(1);
currentParticles=(int)(ps.size()*0.8f+currentParticles*0.2f);
currentParticles+=(int)(0.2f*drawnPieces+0.3f*numFlyingPieces);
particleSaturation=(float)currentParticles/(float)maxParticles;
// glFogfv(GL_FOG_COLOR,FogLand);
}
void CProjectileHandler::DrawShadowPass(void)
{
distlist.clear();
Projectile_List::iterator psi;
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, projectileShadowVP );
glEnable( GL_VERTEX_PROGRAM_ARB );
glDisable(GL_TEXTURE_2D);
for(psi=ps.begin();psi != ps.end();++psi){
if((loshandler->InLos(*psi,gu->myAllyTeam) || gu->spectatingFullView ||
((*psi)->owner && gs->Ally((*psi)->owner->allyteam,gu->myAllyTeam)))){
if((*psi)->s3domodel)
(*psi)->DrawUnitPart();
if((*psi)->castShadow){
struct projdist tmp;
tmp.proj = *psi;
distlist.push_back(tmp);
}
}
}
glEnable(GL_TEXTURE_2D);
textureAtlas->BindTexture();
glColor4f(1,1,1,1);
glAlphaFunc(GL_GREATER,0.3f);
glEnable(GL_ALPHA_TEST);
glShadeModel(GL_SMOOTH);
CProjectile::inArray=false;
CProjectile::va=GetVertexArray();
CProjectile::va->Initialize();
for(int b=0;b<distlist.size();b++){
distlist.at(b).proj->Draw();
}
if(CProjectile::inArray)
CProjectile::DrawArray();
glShadeModel(GL_FLAT);
glDisable(GL_ALPHA_TEST);
glDisable(GL_TEXTURE_2D);
glDisable( GL_VERTEX_PROGRAM_ARB );
}
void CProjectileHandler::AddProjectile(CProjectile* p)
{
ps.push_back(p);
// toBeAddedProjectile.push(p);
}
void CProjectileHandler::CheckUnitCol()
{
Projectile_List::iterator psi;
CUnit* tempUnits[MAX_UNITS];
CFeature* tempFeatures[MAX_UNITS];
for(psi=ps.begin();psi != ps.end();++psi){
CProjectile* p=(*psi);
if(p->checkCol && !p->deleteMe){
float speedf=p->speed.Length();
CUnit** endUnit = tempUnits;
CFeature** endFeature = tempFeatures;
qf->GetUnitsAndFeaturesExact(p->pos, p->radius+speedf, endUnit, endFeature);
for(CUnit** ui=tempUnits;ui!=endUnit;++ui){
CUnit* unit=*ui;
if(p->owner == unit || ((p->collisionFlags&COLLISION_NOFRIENDLY) && p->owner && (unit->allyteam==p->owner->allyteam)) )
continue;
float ispeedf=1.0f/speedf;
float3 normSpeed=p->speed*ispeedf;
float totalRadius=unit->radius+p->radius;
float3 dif(unit->midPos-p->pos);
float closeTime=dif.dot(normSpeed)*ispeedf;
if(closeTime<0)
closeTime=0;
if(closeTime>1)
closeTime=1;
float3 closeVect=dif-(p->speed*closeTime);
if(closeVect.SqLength() < totalRadius*totalRadius){
if(unit->isMarkedOnBlockingMap && unit->physicalState != CSolidObject::Flying){
float3 closePos(p->pos+p->speed*closeTime);
int square=(int)max(0.0f,min((float)(gs->mapSquares-1),closePos.x*(1.0f/8.0f)+int(closePos.z*(1.0f/8.0f))*gs->mapx));
if(readmap->groundBlockingObjectMap[square]!=unit)
continue;
}
//adjust projectile position so explosion happens at the correct position
p->pos = p->pos + p->speed*closeTime;
p->Collision(*ui);
break;
}
float diflength = dif.Length();
float closesqlength = closeVect.SqLength();
assert(! ((!(closesqlength < totalRadius*totalRadius)) && (diflength<totalRadius)));
}
if(!(p->collisionFlags&COLLISION_NOFEATURE))
{
for(CFeature** fi=tempFeatures;fi!=endFeature;++fi){
if(!(*fi)->blocking)
continue;
float ispeedf=1.0f/speedf;
float3 normSpeed=p->speed*ispeedf;
float totalRadius=(*fi)->radius+p->radius;
float3 dif=(*fi)->midPos-p->pos;
float closeTime=dif.dot(normSpeed)/speedf;
if(closeTime<0)
closeTime=0;
if(closeTime>1)
closeTime=1;
float3 closeVect=dif-(p->speed*closeTime);
if(dif.SqLength() < totalRadius*totalRadius){
if((*fi)->isMarkedOnBlockingMap){
float3 closePos(p->pos+p->speed*closeTime);
int square=(int)max(0.0f,min((float)(gs->mapSquares-1),closePos.x*(1.0f/8.0f)+int(closePos.z*(1.0f/8.0f))*gs->mapx));
if(readmap->groundBlockingObjectMap[square]!=(*fi))
continue;
}
p->Collision(*fi);
break;
}
}
}
}
}
}
void CProjectileHandler::AddGroundFlash(CGroundFlash* flash)
{
groundFlashes.push_back(flash);
}
void CProjectileHandler::DrawGroundFlashes(void)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glActiveTextureARB(GL_TEXTURE0_ARB);
// glBindTexture(GL_TEXTURE_2D, CGroundFlash::texture);
groundFXAtlas->BindTexture();
glEnable(GL_TEXTURE_2D);
glDepthMask(0);
glPolygonOffset(-20,-1000);
glEnable(GL_POLYGON_OFFSET_FILL);
glFogfv(GL_FOG_COLOR,FogBlack);
CGroundFlash::va=GetVertexArray();
CGroundFlash::va->Initialize();
std::vector<CGroundFlash*>::iterator gfi;
for(gfi=groundFlashes.begin();gfi!=groundFlashes.end();++gfi){
if ((*gfi)->alwaysVisible || gu->spectatingFullView ||
loshandler->InAirLos((*gfi)->pos,gu->myAllyTeam))
(*gfi)->Draw();
}
CGroundFlash::va->DrawArrayTC(GL_QUADS);
glFogfv(GL_FOG_COLOR,FogLand);
glDepthMask(1);
glDisable(GL_POLYGON_OFFSET_FILL);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_BLEND);
}
void CProjectileHandler::ConvertTex(unsigned char tex[512][512][4], int startx, int starty, int endx, int endy, float absorb)
{
for(int y=starty;y<endy;++y){
for(int x=startx;x<endx;++x){
float alpha=tex[y][x][3];
float mul=alpha/255.0f;
tex[y][x][0]=(unsigned char)(mul * (float)tex[y][x][0]);
tex[y][x][1]=(unsigned char)(mul * (float)tex[y][x][1]);
tex[y][x][2]=(unsigned char)(mul * (float)tex[y][x][2]);
}
}
}
void CProjectileHandler::AddFlyingPiece(float3 pos,float3 speed,S3DO* object,S3DOPrimitive* piece)
{
FlyingPiece* fp=new FlyingPiece;
fp->pos=pos;
fp->speed=speed;
fp->prim=piece;
fp->object=object;
fp->verts=NULL;
fp->rotAxis=gu->usRandVector();
fp->rotAxis.Normalize();
fp->rotSpeed=gu->usRandFloat()*0.1f;
fp->rot=0;
flying3doPieces->push_back(fp);
}
void CProjectileHandler::AddFlyingPiece(int textureType, int team, float3 pos, float3 speed, SS3OVertex * verts){
FlyingPiece_List * pieceList = NULL;
while(flyings3oPieces.size()<=textureType)
flyings3oPieces.push_back(std::vector<FlyingPiece_List*>());
while(flyings3oPieces[textureType].size()<=team){
//logOutput.Print("Creating piece list %d %d.", textureType, flyings3oPieces[textureType].size());
FlyingPiece_List * fpl = SAFE_NEW FlyingPiece_List;
flyings3oPieces[textureType].push_back(fpl);
flyingPieces.push_back(fpl);
}
pieceList=flyings3oPieces[textureType][team];
FlyingPiece* fp=new FlyingPiece;
fp->pos=pos;
fp->speed=speed;
fp->prim=NULL;
fp->object=NULL;
fp->verts=verts;
/* Duplicated with AddFlyingPiece. */
fp->rotAxis=gu->usRandVector();
fp->rotAxis.Normalize();
fp->rotSpeed=gu->usRandFloat()*0.1f;
fp->rot=0;
pieceList->push_back(fp);
}
void CProjectileHandler::UpdateTextures()
{
if(numPerlinProjectiles && drawPerlinTex)
UpdatePerlin();
/*
if(gs->frameNum==300){
logOutput.Print("Saving tex");
perlinFB->select();
unsigned char* buf=SAFE_NEW unsigned char[512*512*4];
glReadPixels(0,0,512,512,GL_RGBA,GL_UNSIGNED_BYTE,buf);
CBitmap b(buf,512,512);
b.ReverseYAxis();
b.Save("proj2.tga");
delete[] buf;
perlinFB->deselect();
}*/
}
void CProjectileHandler::UpdatePerlin()
{
perlinFB->select();
glViewport(perlintex.ixstart,perlintex.iystart,128,128);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0,1,0,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDepthMask(0);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glDisable(GL_FOG);
unsigned char col[4];
float time=gu->lastFrameTime*gs->speedFactor*3;
float speed=1;
float size=1;
for(int a=0;a<4;++a){
perlinBlend[a]+=time*speed;
if(perlinBlend[a]>1){
unsigned int temp=perlinTex[a*2];
perlinTex[a*2]=perlinTex[a*2+1];
perlinTex[a*2+1]=temp;
GenerateNoiseTex(perlinTex[a*2+1],16);
perlinBlend[a]-=1;
}
float tsize=8/size;
if(a==0)
glDisable(GL_BLEND);
CVertexArray* va=GetVertexArray();
va->Initialize();
for(int b=0;b<4;++b)
col[b]=int((1-perlinBlend[a])*16*size);
glBindTexture(GL_TEXTURE_2D, perlinTex[a*2]);
va->AddVertexTC(float3(0,0,0),0,0,col);
va->AddVertexTC(float3(0,1,0),0,tsize,col);
va->AddVertexTC(float3(1,1,0),tsize,tsize,col);
va->AddVertexTC(float3(1,0,0),tsize,0,col);
va->DrawArrayTC(GL_QUADS);
if(a==0)
glEnable(GL_BLEND);
va=GetVertexArray();
va->Initialize();
for(int b=0;b<4;++b)
col[b]=int(perlinBlend[a]*16*size);
glBindTexture(GL_TEXTURE_2D, perlinTex[a*2+1]);
va->AddVertexTC(float3(0,0,0),0,0,col);
va->AddVertexTC(float3(0,1,0),0,tsize,col);
va->AddVertexTC(float3(1,1,0),tsize,tsize,col);
va->AddVertexTC(float3(1,0,0),tsize,0,col);
va->DrawArrayTC(GL_QUADS);
speed*=0.6f;
size*=2;
}
/*
glBindTexture(GL_TEXTURE_2D, CProjectile::textures[0]);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,384,256,0,0,128,128);
*/
perlinFB->deselect();
glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glDepthMask(1);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void CProjectileHandler::GenerateNoiseTex(unsigned int tex,int size)
{
unsigned char* mem=SAFE_NEW unsigned char[4*size*size];
for(int a=0;a<size*size;++a){
unsigned char rnd=int(max(0.f,gu->usRandFloat()*555-300));
mem[a*4+0]=rnd;
mem[a*4+1]=rnd;
mem[a*4+2]=rnd;
mem[a*4+3]=rnd;
}
glBindTexture(GL_TEXTURE_2D, tex);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,size,size,GL_RGBA,GL_UNSIGNED_BYTE,mem);
delete[] mem;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?