projectilehandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 881 行 · 第 1/2 页
CPP
881 行
#include "StdAfx.h"
// ProjectileHandler.cpp: implementation of the CProjectileHandler class.
//
//////////////////////////////////////////////////////////////////////
#include "ProjectileHandler.h"
#include "Rendering/GL/myGL.h"
#include <GL/glu.h> // Header File For The GLu32 Library
#include "Projectile.h"
#include "Game/Camera.h"
#include "Rendering/GL/VertexArray.h"
#include "Sim/Misc/QuadField.h"
#include "Sim/Units/Unit.h"
#include "Sim/Units/UnitDef.h"
#include "TimeProfiler.h"
#include "Rendering/Textures/Bitmap.h"
#include "Rendering/GroundFlash.h"
#include "Sim/Misc/LosHandler.h"
#include "Map/Ground.h"
#include "Rendering/Textures/TextureHandler.h"
#include "Sim/Misc/Feature.h"
#include "Platform/ConfigHandler.h"
#include "Rendering/ShadowHandler.h"
#include "Rendering/UnitModels/UnitDrawer.h"
#include "Rendering/UnitModels/3DOParser.h"
#include "Rendering/UnitModels/s3oParser.h"
#include "LogOutput.h"
#include <algorithm>
#include "Rendering/GL/IFramebuffer.h"
#include "System/FileSystem/FileHandler.h"
#include "mmgr.h"
#include "creg/STL_List.h"
CProjectileHandler* ph;
using namespace std;
extern GLfloat FogBlack[];
extern GLfloat FogLand[];
CR_BIND(CProjectileHandler,);
CR_REG_METADATA(CProjectileHandler,(
//CR_MEMBER(ps),
CR_MEMBER(groundFlashes),
CR_RESERVED(32),
CR_SERIALIZER(Serialize),
CR_POSTLOAD(PostLoad)
));
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CProjectileHandler::CProjectileHandler()
{
PrintLoadMsg("Creating projectile texture");
maxParticles=configHandler.GetInt("MaxParticles",4000);
currentParticles=0;
particleSaturation=0;
numPerlinProjectiles=0;
textureAtlas = SAFE_NEW CTextureAtlas(2048, 2048);
// used to block resources_map.tdf from loading textures
std::set<std::string> blockMapTexNames;
TdfParser resources("gamedata/resources.tdf");
//add all textures in projectiletextures section
std::map<std::string,std::string> ptex = resources.GetAllValues("resources\\graphics\\projectiletextures");
for(std::map<std::string,std::string>::iterator pi=ptex.begin(); pi!=ptex.end(); ++pi)
{
textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second);
blockMapTexNames.insert(pi->first);
}
//add all texture from sections within projectiletextures section
std::vector<std::string> seclist = resources.GetSectionList("resources\\graphics\\projectiletextures");
for(int i=0; i<seclist.size(); i++)
{
std::map<std::string,std::string> ptex2 = resources.GetAllValues("resources\\graphics\\projectiletextures\\" + seclist[i]);
for(std::map<std::string,std::string>::iterator pi=ptex2.begin(); pi!=ptex2.end(); ++pi)
{
textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second);
blockMapTexNames.insert(pi->first);
}
}
for (int i = 0; i < 12; i++) {
char num[10];
sprintf(num, "%02i", i);
textureAtlas->AddTexFromFile(std::string("ismoke") + num, std::string("bitmaps/")+resources.SGetValueDef(std::string("smoke/smoke") + num +".tga",std::string("resources\\graphics\\smoke\\smoke")+num+"alpha"));
blockMapTexNames.insert(std::string("ismoke") + num);
}
char tex[128][128][4];
for (int y = 0; y < 128; y++) { // shield
for (int x = 0; x < 128; x++) {
tex[y][x][0] = 70;
tex[y][x][1] = 70;
tex[y][x][2] = 70;
tex[y][x][3] = 70;
}
}
textureAtlas->AddTexFromMem("perlintex", 128, 128, CTextureAtlas::RGBA32, tex);
blockMapTexNames.insert("perlintex");
blockMapTexNames.insert("flare");
blockMapTexNames.insert("explo");
blockMapTexNames.insert("explofade");
blockMapTexNames.insert("heatcloud");
blockMapTexNames.insert("laserend");
blockMapTexNames.insert("laserfalloff");
blockMapTexNames.insert("randdots");
blockMapTexNames.insert("smoketrail");
blockMapTexNames.insert("wake");
blockMapTexNames.insert("perlintex");
blockMapTexNames.insert("flame");
blockMapTexNames.insert("sbtrailtexture");
blockMapTexNames.insert("missiletrailtexture");
blockMapTexNames.insert("muzzleflametexture");
blockMapTexNames.insert("repulsetexture");
blockMapTexNames.insert("dguntexture");
blockMapTexNames.insert("flareprojectiletexture");
blockMapTexNames.insert("sbflaretexture");
blockMapTexNames.insert("missileflaretexture");
blockMapTexNames.insert("beamlaserflaretexture");
blockMapTexNames.insert("bubbletexture");
blockMapTexNames.insert("geosquaretexture");
blockMapTexNames.insert("gfxtexture");
blockMapTexNames.insert("projectiletexture");
blockMapTexNames.insert("repulsegfxtexture");
blockMapTexNames.insert("sphereparttexture");
blockMapTexNames.insert("torpedotexture");
blockMapTexNames.insert("wrecktexture");
blockMapTexNames.insert("plasmatexture");
// allow map specified atlas textures for gaia unit projectiles
CFileHandler fh("gamedata/resources_map.tdf");
if (fh.FileExists()) {
TdfParser resources_map("gamedata/resources_map.tdf");
//add all textures in projectiletextures section
std::map<std::string,std::string> mptex =
resources_map.GetAllValues("resources\\graphics\\projectiletextures");
std::map<std::string,std::string>::iterator pi;
for (pi = mptex.begin(); pi != mptex.end(); ++pi) {
if (blockMapTexNames.find(pi->first) == blockMapTexNames.end()) {
textureAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second);
}
}
}
if (!textureAtlas->Finalize()) {
logOutput.Print("Could not finalize projectile texture atlas. Use less/smaller textures.");
}
flaretex = textureAtlas->GetTexture("flare");
explotex = textureAtlas->GetTexture("explo");
explofadetex = textureAtlas->GetTexture("explofade");
heatcloudtex = textureAtlas->GetTexture("heatcloud");
laserendtex = textureAtlas->GetTexture("laserend");
laserfallofftex = textureAtlas->GetTexture("laserfalloff");
randdotstex = textureAtlas->GetTexture("randdots");
smoketrailtex = textureAtlas->GetTexture("smoketrail");
waketex = textureAtlas->GetTexture("wake");
perlintex = textureAtlas->GetTexture("perlintex");
flametex = textureAtlas->GetTexture("flame");
for (int i = 0; i < 12; i++) {
char num[10];
sprintf(num, "%02i", i);
smoketex[i] = textureAtlas->GetTexture(std::string("ismoke") + num);
}
sbtrailtex = textureAtlas->GetTextureWithBackup("sbtrailtexture", "smoketrail" );
missiletrailtex = textureAtlas->GetTextureWithBackup("missiletrailtexture", "smoketrail" );
muzzleflametex = textureAtlas->GetTextureWithBackup("muzzleflametexture", "explo" );
repulsetex = textureAtlas->GetTextureWithBackup("repulsetexture", "explo" );
dguntex = textureAtlas->GetTextureWithBackup("dguntexture", "flare" );
flareprojectiletex= textureAtlas->GetTextureWithBackup("flareprojectiletexture", "flare" );
sbflaretex = textureAtlas->GetTextureWithBackup("sbflaretexture", "flare" );
missileflaretex = textureAtlas->GetTextureWithBackup("missileflaretexture", "flare" );
beamlaserflaretex = textureAtlas->GetTextureWithBackup("beamlaserflaretexture", "flare" );
bubbletex = textureAtlas->GetTextureWithBackup("bubbletexture", "circularthingy");
geosquaretex = textureAtlas->GetTextureWithBackup("geosquaretexture", "circularthingy");
gfxtex = textureAtlas->GetTextureWithBackup("gfxtexture", "circularthingy");
projectiletex = textureAtlas->GetTextureWithBackup("projectiletexture", "circularthingy");
repulsegfxtex = textureAtlas->GetTextureWithBackup("repulsegfxtexture", "circularthingy");
sphereparttex = textureAtlas->GetTextureWithBackup("sphereparttexture", "circularthingy");
torpedotex = textureAtlas->GetTextureWithBackup("torpedotexture", "circularthingy");
wrecktex = textureAtlas->GetTextureWithBackup("wrecktexture", "circularthingy");
plasmatex = textureAtlas->GetTextureWithBackup("plasmatexture", "circularthingy");
groundFXAtlas = SAFE_NEW CTextureAtlas(2048, 2048);
//add all textures in groundfx section
ptex = resources.GetAllValues("resources\\graphics\\groundfx");
for(std::map<std::string,std::string>::iterator pi=ptex.begin(); pi!=ptex.end(); ++pi)
{
groundFXAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second);
}
//add all texture from sections within groundfx section
seclist = resources.GetSectionList("resources\\graphics\\groundfx");
for(int i=0; i<seclist.size(); i++)
{
std::map<std::string,std::string> ptex2 = resources.GetAllValues("resources\\graphics\\groundfx\\" + seclist[i]);
for(std::map<std::string,std::string>::iterator pi=ptex2.begin(); pi!=ptex2.end(); ++pi)
{
groundFXAtlas->AddTexFromFile(pi->first, "bitmaps/" + pi->second);
}
}
if (!groundFXAtlas->Finalize())
logOutput.Print("Could not finalize groundFX texture atlas. Use less/smaller textures.");
groundflashtex = groundFXAtlas->GetTexture("groundflash");
groundringtex = groundFXAtlas->GetTexture("groundring");
seismictex = groundFXAtlas->GetTexture("seismic");
if(shadowHandler->canUseShadows){
projectileShadowVP=LoadVertexProgram("projectileshadow.vp");
}
flying3doPieces = SAFE_NEW FlyingPiece_List;
flyingPieces.push_back(flying3doPieces);
for(int a=0;a<4;++a){
perlinBlend[a]=0;
}
unsigned char tempmem[4*16*16];
for(int a=0;a<4*16*16;++a)
tempmem[a]=0;
for(int a=0;a<8;++a){
glGenTextures(1, &perlinTex[a]);
glBindTexture(GL_TEXTURE_2D, perlinTex[a]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8,16, 16, GL_RGBA, GL_UNSIGNED_BYTE, tempmem);
}
drawPerlinTex=false;
if(shadowHandler && shadowHandler->drawShadows && GLEW_EXT_framebuffer_object && !GLEW_ATI_envmap_bumpmap){ //this seems to bug on ati cards so disable it on those (just some random ati extension to detect ati cards), should be fixed by someone that actually has a ati card
perlinFB = instantiate_fb(512, 512, FBO_NEED_COLOR);
if (perlinFB && perlinFB->valid()){
drawPerlinTex=true;
perlinFB->attachTexture(textureAtlas->gltex, GL_TEXTURE_2D, FBO_ATTACH_COLOR);
perlinFB->checkFBOStatus();
}
}
else
perlinFB = 0;
}
CProjectileHandler::~CProjectileHandler()
{
for(int a=0;a<8;++a)
glDeleteTextures (1, &perlinTex[a]);
Projectile_List::iterator psi;
for(psi=ps.begin();psi!=ps.end();++psi)
delete *psi;
std::vector<CGroundFlash*>::iterator gfi;
for(gfi=groundFlashes.begin();gfi!=groundFlashes.end();++gfi)
delete *gfi;
distlist.clear();
if(shadowHandler->canUseShadows){
glSafeDeleteProgram(projectileShadowVP);
}
/* Also invalidates flying3doPieces and flyings3oPieces. */
for(std::list<FlyingPiece_List*>::iterator pti=flyingPieces.begin();pti!=flyingPieces.end();++pti){
FlyingPiece_List * fpl = *pti;
for(std::list<FlyingPiece*>::iterator pi=fpl->begin();pi!=fpl->end();++pi){
if ((*pi)->verts != NULL){
delete[] ((*pi)->verts);
}
delete *pi;
}
delete fpl;
}
ph=0;
delete perlinFB;
delete textureAtlas;
delete groundFXAtlas;
}
void CProjectileHandler::Serialize(creg::ISerializer *s)
{
if (s->IsWriting ()) {
int size = (int)ps.size();
s->Serialize (&size,sizeof(int));
for (Projectile_List::iterator it = ps.begin(); it!=ps.end(); ++it) {
void **ptr = (void**)&*it;
s->SerializeObjectPtr(ptr,(*it)->GetClass());
}
} else {
int size;
s->Serialize (&size, sizeof(int));
ps.resize (size);
for (Projectile_List::iterator it = ps.begin(); it!=ps.end(); ++it) {
void **ptr = (void**)&*it;
s->SerializeObjectPtr(ptr,0/*FIXME*/);
}
}
}
void CProjectileHandler::PostLoad()
{
}
void CProjectileHandler::SetMaxParticles(int value)
{
maxParticles = value;
}
void CProjectileHandler::Update()
{
SCOPED_TIMER("Projectile handler");
Projectile_List::iterator psi=ps.begin();
while(psi!= ps.end()){
CProjectile *p = *psi;
if(p->deleteMe){
Projectile_List::iterator prev=psi++;
ps.erase(prev);
delete p;
} else {
(*psi)->Update();
++psi;
}
}
for(unsigned int i = 0; i < groundFlashes.size();)
{
CGroundFlash *gf = groundFlashes[i];
if (!gf->Update ())
{
// swap gf with the groundflash at the end of the list, so pop_back() can be used to erase it
if ( i < groundFlashes.size()-1 )
std::swap (groundFlashes.back(), groundFlashes[i]);
groundFlashes.pop_back();
delete gf;
} else i++;
}
for(std::list<FlyingPiece_List*>::iterator pti=flyingPieces.begin();pti!=flyingPieces.end();++pti){
FlyingPiece_List * fpl = *pti;
/* Note: nothing in the third clause of this loop. TODO Rewrite it as a while */
for(std::list<FlyingPiece*>::iterator pi=fpl->begin();pi!=fpl->end();){
(*pi)->pos+=(*pi)->speed;
(*pi)->speed*=0.996f;
(*pi)->speed.y+=gs->gravity;
(*pi)->rot+=(*pi)->rotSpeed;
if((*pi)->pos.y<ground->GetApproximateHeight((*pi)->pos.x,(*pi)->pos.z)-10){
delete *pi;
pi=fpl->erase(pi);
} else {
++pi;
}
}
}
}
int CompareProjDist(CProjectileHandler::projdist const &arg1, CProjectileHandler::projdist const &arg2){
if (arg1.dist <= arg2.dist)
return 0;
return 1;
}
void CProjectileHandler::Draw(bool drawReflection,bool drawRefraction)
{
glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glDepthMask(1);
CVertexArray* va=GetVertexArray();
int numFlyingPieces = 0;
int drawnPieces = 0;
/* Putting in, say, viewport culling will deserve refactoring. */
/* 3DO */
unitDrawer->SetupForUnitDrawing();
va->Initialize();
numFlyingPieces += flying3doPieces->size();
for(std::list<FlyingPiece*>::iterator pi=flying3doPieces->begin();pi!=flying3doPieces->end();++pi){
CMatrix44f m;
m.Rotate((*pi)->rot,(*pi)->rotAxis);
float3 interPos=(*pi)->pos+(*pi)->speed*gu->timeOffset;
CTextureHandler::UnitTexture* tex=(*pi)->prim->texture;
S3DOVertex* v=&(*pi)->object->vertices[(*pi)->prim->vertices[0]];
float3 tp=m.Mul(v->pos);
float3 tn=m.Mul(v->normal);
tp+=interPos;
va->AddVertexTN(tp,tex->xstart,tex->ystart,tn);
v=&(*pi)->object->vertices[(*pi)->prim->vertices[1]];
tp=m.Mul(v->pos);
tn=m.Mul(v->normal);
tp+=interPos;
va->AddVertexTN(tp,tex->xend,tex->ystart,tn);
v=&(*pi)->object->vertices[(*pi)->prim->vertices[2]];
tp=m.Mul(v->pos);
tn=m.Mul(v->normal);
tp+=interPos;
va->AddVertexTN(tp,tex->xend,tex->yend,tn);
v=&(*pi)->object->vertices[(*pi)->prim->vertices[3]];
tp=m.Mul(v->pos);
tn=m.Mul(v->normal);
tp+=interPos;
va->AddVertexTN(tp,tex->xstart,tex->yend,tn);
}
drawnPieces+=va->drawIndex/32;
va->DrawArrayTN(GL_QUADS);
unitDrawer->CleanUpUnitDrawing();
/* S3O */
unitDrawer->SetupForS3ODrawing();
for (int textureType = 1; textureType < flyings3oPieces.size(); textureType++){
/* TODO Skip this if there's no FlyingPieces. */
texturehandler->SetS3oTexture(textureType);
for (int team = 0; team < flyings3oPieces[textureType].size(); team++){
FlyingPiece_List * fpl = flyings3oPieces[textureType][team];
unitDrawer->SetS3OTeamColour(team);
va->Initialize();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?