advtreedrawer.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 893 行 · 第 1/3 页
CPP
893 行
// TreeDrawer.cpp: implementation of the CAdvTreeDrawer class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "AdvTreeDrawer.h"
#include "Map/BaseGroundDrawer.h"
#include "Map/Ground.h"
#include "Game/Camera.h"
#include "Rendering/GL/VertexArray.h"
#include "Map/ReadMap.h"
#include "Rendering/GL/myGL.h"
#include "AdvTreeGenerator.h"
#include "Rendering/Textures/Bitmap.h"
#include "LogOutput.h"
#include "GrassDrawer.h"
#include "Matrix44f.h"
#include "Rendering/ShadowHandler.h"
#include "mmgr.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static const float TEX_LEAF_START_Y1=0.001f;
static const float TEX_LEAF_END_Y1=0.124f;
static const float TEX_LEAF_START_Y2=0.126f;
static const float TEX_LEAF_END_Y2=0.249f;
static const float TEX_LEAF_START_Y3=0.251f;
static const float TEX_LEAF_END_Y3=0.374f;
static const float TEX_LEAF_START_Y4=0.376f;
static const float TEX_LEAF_END_Y4=0.499f;
static const float TEX_LEAF_START_X1=0.0f;
static const float TEX_LEAF_END_X1=0.125f;
static const float TEX_LEAF_START_X2=0.0f;
static const float TEX_LEAF_END_X2=0.125f;
static const float TEX_LEAF_START_X3=0.0f;
static const float TEX_LEAF_END_X3=0.125f;
CAdvTreeDrawer::CAdvTreeDrawer()
{
oldTreeDistance=4;
treeGen=SAFE_NEW CAdvTreeGenerator;
grassDrawer=SAFE_NEW CGrassDrawer();
lastListClean=0;
treesX=gs->mapx/TREE_SQUARE_SIZE;
treesY=gs->mapy/TREE_SQUARE_SIZE;
trees=SAFE_NEW TreeSquareStruct[treesX*treesY];
for(int y=0;y<treesY;y++){
for(int x=0;x<treesX;x++){
trees[y*treesX+x].lastSeen=0;
trees[y*treesX+x].lastSeenFar=0;
trees[y*treesX+x].viewVector=UpVector;
trees[y*treesX+x].displist=0;
trees[y*treesX+x].farDisplist=0;
}
}
}
CAdvTreeDrawer::~CAdvTreeDrawer()
{
for(int y=0;y<treesY;y++){
for(int x=0;x<treesX;x++){
if(trees[y*treesX+x].displist)
glDeleteLists(trees[y*treesX+x].displist,1);
if(trees[y*treesX+x].farDisplist)
glDeleteLists(trees[y*treesX+x].farDisplist,1);
}
}
delete[] trees;
delete treeGen;
delete grassDrawer;
}
void CAdvTreeDrawer::Update()
{
for(std::list<FallingTree>::iterator fti=fallingTrees.begin();fti!=fallingTrees.end();){
fti->fallPos+=fti->speed*0.1f;
if(fti->fallPos>1){ //remove the tree
std::list<FallingTree>::iterator prev=fti++;
fallingTrees.erase(prev);
} else {
fti->speed+=sin(fti->fallPos)*0.04f;
++fti;
}
}
}
static CVertexArray *va;
static void inline SetArray(float t1,float t2,float3 v)
{
va->AddVertexT(v,t1,t2);
}
struct CAdvTreeSquareDrawer : CReadMap::IQuadDrawer
{
CAdvTreeSquareDrawer() {td=0;}
void DrawQuad (int x,int y);
CAdvTreeDrawer *td;
int cx,cy;
float treeDistance;
bool drawDetailed;
};
void CAdvTreeSquareDrawer::DrawQuad (int x,int y)
{
int treesX = td->treesX;
CAdvTreeDrawer::TreeSquareStruct* tss=&td->trees[y*treesX+x];
if(abs(cy-y)<=2 && abs(cx-x)<=2) //skip the closest squares
return;
float3 dif;
dif.x=camera->pos.x-(x*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2);
dif.y=0;
dif.z=camera->pos.z-(y*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2);
float dist=dif.Length();
dif/=dist;
if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2 && dist>SQUARE_SIZE*TREE_SQUARE_SIZE*(treeDistance)){//far trees
tss->lastSeenFar=gs->frameNum;
if(!tss->farDisplist || dif.dot(tss->viewVector)<0.97f){
va=GetVertexArray();
va->Initialize();
tss->viewVector=dif;
if(!tss->farDisplist)
tss->farDisplist=glGenLists(1);
float3 up(0,1,0);
float3 side=up.cross(dif);
for(std::map<int,CAdvTreeDrawer::TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){
CAdvTreeDrawer::TreeStruct* ts=&ti->second;
float3 base(ts->pos);
int type=ts->type;
float height=MAX_TREE_HEIGHT;
float width=MAX_TREE_HEIGHT*0.5f;
float xdif;
float ydif;
if(ts->type<8){
xdif=type*0.125f;
ydif=0.5f;
} else {
xdif=(type-8)*0.125f;
ydif=0;
}
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_START_Y4+ydif,base+side*width);
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_END_Y4+ydif ,base+side*width+float3(0,height,0));
SetArray(TEX_LEAF_END_X1+xdif ,TEX_LEAF_END_Y4+ydif ,base-side*width+float3(0,height,0));
SetArray(TEX_LEAF_END_X1+xdif ,TEX_LEAF_START_Y4+ydif,base-side*width);
}
glNewList(td->trees[y*treesX+x].farDisplist,GL_COMPILE);
va->DrawArrayT(GL_QUADS);
glEndList();
}
if(dist>SQUARE_SIZE*TREE_SQUARE_SIZE*(treeDistance*2-1)){
float trans=(SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2-dist)/(SQUARE_SIZE*TREE_SQUARE_SIZE);
glEnable(GL_BLEND);
glColor4f(1,1,1,trans);
glAlphaFunc(GL_GREATER,(SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2-dist)/(SQUARE_SIZE*TREE_SQUARE_SIZE*2));
} else {
glColor4f(1,1,1,1);
glDisable(GL_BLEND);
glAlphaFunc(GL_GREATER,0.5f);
}
glCallList(tss->farDisplist);
}
if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance){ //midle distance trees
tss->lastSeen=gs->frameNum;
if(!tss->displist){
va=GetVertexArray();
va->Initialize();
tss->displist=glGenLists(1);
for(std::map<int,CAdvTreeDrawer::TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){
CAdvTreeDrawer::TreeStruct* ts=&ti->second;
float3 pos(ts->pos);
int type=ts->type;
float height=MAX_TREE_HEIGHT;
float width=MAX_TREE_HEIGHT*0.5f;
float xdif;
float ydif;
if(ts->type<8){
xdif=type*0.125f;
ydif=0.5f;
} else {
xdif=(type-8)*0.125f;
ydif=0;
}
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_START_Y1+ydif,pos+float3(width,0,0));
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_END_Y1+ydif,pos+float3(width,height,0));
SetArray(TEX_LEAF_END_X1+xdif,TEX_LEAF_END_Y1+ydif,pos+float3(-width,height,0));
SetArray(TEX_LEAF_END_X1+xdif,TEX_LEAF_START_Y1+ydif,pos+float3(-width,0,0));
SetArray(TEX_LEAF_START_X2+xdif,TEX_LEAF_START_Y2+ydif,pos+float3(0,0,width));
SetArray(TEX_LEAF_START_X2+xdif,TEX_LEAF_END_Y2+ydif,pos+float3(0,height,width));
SetArray(TEX_LEAF_END_X2+xdif,TEX_LEAF_END_Y2+ydif,pos+float3(0,height,-width));
SetArray(TEX_LEAF_END_X2+xdif,TEX_LEAF_START_Y2+ydif,pos+float3(0,0,-width));
//width*=1.41f;
SetArray(TEX_LEAF_START_X3+xdif,TEX_LEAF_START_Y3+ydif,pos+float3(width,height*0.4f,0));
SetArray(TEX_LEAF_START_X3+xdif,TEX_LEAF_END_Y3+ydif,pos+float3(0,height*0.4f,-width));
SetArray(TEX_LEAF_END_X3+xdif,TEX_LEAF_END_Y3+ydif,pos+float3(-width,height*0.4f,0));
SetArray(TEX_LEAF_END_X3+xdif,TEX_LEAF_START_Y3+ydif,pos+float3(0,height*0.4f,width));
}
glNewList(tss->displist,GL_COMPILE);
va->DrawArrayT(GL_QUADS);
glEndList();
}
glColor4f(1,1,1,1);
glDisable(GL_BLEND);
glAlphaFunc(GL_GREATER,0.5f);
glCallList(tss->displist);
}
}
void CAdvTreeDrawer::Draw(float treeDistance,bool drawReflection)
{
int activeFarTex=camera->forward.z<0 ? treeGen->farTex[0] : treeGen->farTex[1];
bool drawDetailed=true;
if(treeDistance<4)
drawDetailed=false;
if(drawReflection)
drawDetailed=false;
CBaseGroundDrawer *gd = readmap->GetGroundDrawer ();
glEnable(GL_ALPHA_TEST);
if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP );
glEnable(GL_VERTEX_PROGRAM_ARB);
glBindTexture(GL_TEXTURE_2D,shadowHandler->shadowTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);
if(shadowHandler->useFPShadows){
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, treeGen->treeFPShadow );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,10, readmap->ambientColor.x,readmap->ambientColor.y,readmap->ambientColor.z,1);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,11, 0,0,0,1-readmap->shadowDensity*0.5f);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, activeFarTex);
} else {
glEnable(GL_TEXTURE_2D);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 1-readmap->shadowDensity*0.5f);
float texConstant[]={readmap->ambientColor.x,readmap->ambientColor.y,readmap->ambientColor.z,0.0f};
glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,texConstant);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB,GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB,GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_ADD);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, activeFarTex);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
glMatrixMode(GL_MATRIX0_ARB);
glLoadMatrixf(shadowHandler->shadowMatrix.m);
glMatrixMode(GL_MODELVIEW);
} else {
glBindTexture(GL_TEXTURE_2D, activeFarTex);
}
glEnable(GL_TEXTURE_2D);
int cx=(int)(camera->pos.x/(SQUARE_SIZE*TREE_SQUARE_SIZE));
int cy=(int)(camera->pos.z/(SQUARE_SIZE*TREE_SQUARE_SIZE));
CAdvTreeSquareDrawer drawer;
drawer.td = this;
drawer.cx = cx;
drawer.cy = cy;
drawer.treeDistance = treeDistance;
drawer.drawDetailed = drawDetailed;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?