void multiMatrix(GLfloat *A, GLfloat B[][4], GLfloat C[][4]){
	GLfloat ans[4][4] = {0};
	int n = 4;
	//print_aMVP();
	transMatrix(A);
	
	for(int i = 0; i < n; ++i)
		for(int j = 0; j < n; ++j)
			for(int k = 0; k < n; ++k)
				ans[i][j] += (B[i][k] * C[k][j]);
	copyMatrix(A, ans);
	transMatrix(A);
	//print_aMVP();
}
void multiMatrix(GLfloat A[][4], GLfloat *B){
	GLfloat ans[4][4] = {0};
	int n = 4;
	//print_aMVP();
	transMatrix(B);
	

	for(int i = 0; i < n; ++i)
		for(int j = 0; j < n; ++j)
			for(int k = 0; k < n; ++k)
				ans[i][j] += (A[i][k] * B[k*n+j]);
	copyMatrix(B, ans);
	transMatrix(B);
	//print_aMVP();
}
void multiple_all_matrix(GLfloat M[][4]){
	for(int i = 0; i < current_obj; ++i){
		GLfloat I[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
		multiMatrix(I, geoMatrix[i], I);
		multiMatrix(I, viewMatrix, I);
		multiMatrix(I, projMatrix, I);
		copyMatrix(aMVP[i], I);
		transMatrix(aMVP[i]);
	}
}
示例#4
0
Matrix Matrix::getTranspose()
{
	Matrix transMatrix(mMatrix);
	for(int i = 0; i < mRows; i++)
	{
		for(int j = i; j < mCols; j++)
		{
			std::swap(transMatrix[i][j],transMatrix[j][i]);
		}
	}
	return transMatrix;
}
glm::vec3 localToWorld(glm::vec3 w_s, Intersection isx){
    glm::vec3 bitangentL = isx.bitangent;
    glm::vec3 normalL = isx.normal;
    glm::vec3 tangentL = isx.tangent;

    glm::mat4 transMatrix (
                tangentL.x, tangentL.y, tangentL.z, 0.0f,
                bitangentL.x, bitangentL.y, bitangentL.z, 0.0f,
                normalL.x, normalL.y, normalL.z, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f);
    w_s = glm::vec3(transMatrix * glm::vec4(w_s, 0.0f));
    return w_s;
}
示例#6
0
int similarMatrix(float_j_t work1[][3], float_j_t work2[][3], float_j_t result[][3], int row, int col) {

	float_j_t res[3][3]={0,};
	float_j_t res_t[3][3]={0,};

	transMatrix(work1,res_t,3,3);
//printMatrix(work1,3,3);
//printMatrix(res_t,3,3);

	multiMatrix(work1,work2,res,3,3);
//printMatrix(work2,3,3);
	multiMatrix(res,res_t,result,3,3);
//printMatrix(result,3,3);
return 0;
}
示例#7
0
/**
 * @brief Calculates the transpose of a matrix and returns it.
 * @return The transposed IntMatrix.
 */
const IntMatrix IntMatrix :: trans() const
{

    // create a copy of our matrix and switch indexes so that it is transposed
    IntMatrix transMatrix(*this);
    for (int i = 0; i < _rowNum; i++)
    {
        for( int j = 0; j < _colNum; j++)
        {
            transMatrix.getArr()[(j * _rowNum) + i] = _matrix[(i * _colNum) + j];
        }
    }
    // change column and row values
    transMatrix.setRow(_colNum);
    transMatrix.setCol(_rowNum);
    return transMatrix;
}
示例#8
0
void CStarburstProjectile::DrawUnitPart(void)
{
	glPushMatrix();
	float3 rightdir;
	if(dir.y!=1) {
		rightdir=dir.cross(UpVector);
		rightdir.SafeNormalize();
	}
	else
		rightdir=float3(1,0,0);
	float3 updir=rightdir.cross(dir);

	CMatrix44f transMatrix(drawPos,-rightdir,updir,dir);
	glMultMatrixf(&transMatrix[0]);

	glCallList(s3domodel->rootobject->displist); // dont cache displists because of delayed loading
	glPopMatrix();
}
void CStarburstProjectile::DrawUnitPart(void)
{
	float3 rightdir, updir;

	if (fabs(dir.y) < 0.95f) {
		rightdir = dir.cross(UpVector);
		rightdir.SafeNormalize();
	} else {
		rightdir = float3(1.0f, 0.0f, 0.0f);
	}

	updir = rightdir.cross(dir);

	CMatrix44f transMatrix(drawPos, -rightdir, updir, dir);

	glPushMatrix();
		glMultMatrixf(transMatrix);
		glCallList(s3domodel->rootobject->displist); // dont cache displists because of delayed loading
	glPopMatrix();
}
示例#10
0
void CWeaponProjectile::DrawUnitPart()
{
	float3 dir(speed);
	dir.Normalize();
	glPushMatrix();
	float3 rightdir;

	if (dir.y != 1)
		rightdir = dir.cross(UpVector);
	else
		rightdir = float3(1, 0, 0);

	rightdir.Normalize();
	float3 updir(rightdir.cross(dir));

	CMatrix44f transMatrix(drawPos,-rightdir,updir,dir);

	glMultMatrixf(&transMatrix[0]);
	glCallList(s3domodel->rootobject->displist); // dont cache displists because of delayed loading
	glPopMatrix();
}
void CWeaponProjectile::DrawUnitPart()
{
	float3 interPos = pos + speed * gu->timeOffset;
	float3 dir(speed);
	dir.Normalize();
	glPushMatrix();
	float3 rightdir;

	if (dir.y != 1)
		rightdir = dir.cross(UpVector);
	else
		rightdir = float3(1, 0, 0);

	rightdir.Normalize();
	float3 updir(rightdir.cross(dir));

	CMatrix44f transMatrix(interPos,-rightdir,updir,dir);

	glMultMatrixf(&transMatrix[0]);
	glCallList(modelDispList);
	glPopMatrix();
}
示例#12
0
	// Move Action
	ThymioMoveAction::ThymioMoveAction( QGraphicsItem *parent ) :
		ThymioButton(false, 0.2, false, false, parent)
	{
		setData(0, "action");
		setData(1, "move");

		QTransform transMatrix(2.0,0.0,0.0,0.0,2.3,0.0,0.0,0.0,1.0);
				
		for(int i=0; i<2; i++)
		{
			QSlider *s = new QSlider(Qt::Vertical);
			s->setRange(-500,500);
			s->setStyleSheet("QSlider::groove:vertical { width: 14px; border: 2px solid #000000; "
							  "background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #00FF00, stop:0.25 #FFFF00, stop:0.5 #FF0000, stop:0.75 #FFFF00, stop:1 #00FF00 ); }"
						      "QSlider::handle:vertical { "
						      "background: #FFFFFF; "
						      "border: 2px solid #000000; height: 10px; width: 20px; margin: 0px 0; }");
			s->setSliderPosition(0);

			QGraphicsProxyWidget *w = new QGraphicsProxyWidget(this);
			w->setWidget(s);
			w->setPos(10+i*200, 15);
			w->setTransform(transMatrix);
			
			sliders.push_back(s);
			widgets.push_back(w);
			
			connect(s, SIGNAL(valueChanged(int)), this, SLOT(valueChangeDetected()));
			connect(s, SIGNAL(valueChanged(int)), this, SLOT(updateIRButton()));
		}		

		timer = new QTimeLine(2000);
		timer->setFrameRange(0, 100);
		timer->setCurveShape(QTimeLine::LinearCurve);
		animation = new QGraphicsItemAnimation(this);
		animation->setItem(thymioBody);
		animation->setTimeLine(timer);				
		thymioBody->setTransformOriginPoint(0,-14);//(pt[1]+pt[0]) == 0 ? 0 : (abs(pt[1])-abs(pt[0]))/(abs(pt[1])+abs(pt[0]))*22.2,-25);
	}
示例#13
0
	// Color Action
	ThymioColorAction::ThymioColorAction( QGraphicsItem *parent ) :
		ThymioButton(false, 1.0, true, false, parent)
	{
		setData(0, "action");
		setData(1, "color");

		QTransform transMatrix(1.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,1.0);
		QString sliderColor("FF0000");
		
		for(int i=0; i<3; i++)
		{
			if( i == 1 ) sliderColor="00FF00";
			else if( i == 2 ) sliderColor="0000FF";

			QSlider *s = new QSlider(Qt::Horizontal);
			s->setRange(0,32);
			s->setStyleSheet(QString("QSlider::groove:horizontal { height: 14px; border: 2px solid #000000; "
							  "background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #000000, stop:1 #%0); }"
						      "QSlider::handle:horizontal { "
						      "background: #FFFFFF; "
						      "border: 5px solid #000000; width: 18px; margin: -2px 0; }").arg(sliderColor));
			s->setSliderPosition(0);

			QGraphicsProxyWidget *w = new QGraphicsProxyWidget(this);
			w->setWidget(s);
			w->setPos(27, 70+i*60);
			w->setTransform(transMatrix);
			
			
			sliders.push_back(s);
			widgets.push_back(w);
			
			connect(s, SIGNAL(valueChanged(int)), this, SLOT(valueChangeDetected()));
			connect(s, SIGNAL(valueChanged(int)), this, SLOT(updateIRButton()));
		}

	}
示例#14
0
文件: Park.cpp 项目: amcolash/cs559
PicnicTable::PicnicTable(float x, float y, float z){
	transMatrix(transform, x, y, z);
	add(new Surface(glm::vec3(0, 10, 0), glm::vec3(1.0, 1.0, 1.0), S_UMBRELLA, 10,"ShadedCubeTest.vert", "Umbrella.frag", NULL, 1.0, 1.0, false));
	add(new Surface(glm::vec3(0, 5, 0), glm::vec3(1.0, 1.0, 1.0), S_TABLE, 16, NULL, NULL, "wood.jpg", 1.0, 1.0, false));
}
bool CProjectileDrawer::DrawProjectileModel(const CProjectile* p, bool shadowPass) {
	if (!(p->weapon || p->piece) || (p->model == NULL)) {
		return false;
	}

	if (p->weapon) {
		// weapon-projectile
		const CWeaponProjectile* wp = dynamic_cast<const CWeaponProjectile*>(p);

		#define SET_TRANSFORM_VECTORS(dir)           \
			float3 rightdir, updir;                  \
                                                     \
			if (fabs(dir.y) < 0.95f) {               \
				rightdir = dir.cross(UpVector);      \
				rightdir.SafeANormalize();           \
			} else {                                 \
				rightdir = float3(1.0f, 0.0f, 0.0f); \
			}                                        \
                                                     \
			updir = rightdir.cross(dir);

		#define TRANSFORM_DRAW(mat)                                \
			glPushMatrix();                                        \
				glMultMatrixf(mat);                                \
				glCallList(wp->model->GetRootPiece()->dispListID); \
			glPopMatrix();

		switch (wp->GetProjectileType()) {
			case CWeaponProjectile::WEAPON_BASE_PROJECTILE:
			case CWeaponProjectile::WEAPON_EXPLOSIVE_PROJECTILE: 
			case CWeaponProjectile::WEAPON_LASER_PROJECTILE:
			case CWeaponProjectile::WEAPON_TORPEDO_PROJECTILE: {
				if (!shadowPass) {
					unitDrawer->SetTeamColour(wp->colorTeam);
				}

				float3 dir(wp->speed);
				dir.SafeANormalize();
				SET_TRANSFORM_VECTORS(dir);

				CMatrix44f transMatrix(wp->drawPos, -rightdir, updir, dir);

				TRANSFORM_DRAW(transMatrix);
			} break;

			case CWeaponProjectile::WEAPON_MISSILE_PROJECTILE: {
				if (!shadowPass) {
					unitDrawer->SetTeamColour(wp->colorTeam);
				}

				SET_TRANSFORM_VECTORS(wp->dir);

				CMatrix44f transMatrix(wp->drawPos + wp->dir * wp->radius * 0.9f, -rightdir, updir, wp->dir);

				TRANSFORM_DRAW(transMatrix);
			} break;

			case CWeaponProjectile::WEAPON_STARBURST_PROJECTILE: {
				if (!shadowPass) {
					unitDrawer->SetTeamColour(wp->colorTeam);
				}

				SET_TRANSFORM_VECTORS(wp->dir);

				CMatrix44f transMatrix(wp->drawPos, -rightdir, updir, wp->dir);

				TRANSFORM_DRAW(transMatrix);
			} break;

			default: {
			} break;
		}

		#undef SET_TRANSFORM_VECTORS
		#undef TRANSFORM_DRAW
	} else {
		// piece-projectile
		const CPieceProjectile* pp = dynamic_cast<const CPieceProjectile*>(p);

		if (!shadowPass) {
			unitDrawer->SetTeamColour(pp->colorTeam);
		}

		if (pp->alphaThreshold != 0.1f) {
			glPushAttrib(GL_COLOR_BUFFER_BIT);
			glAlphaFunc(GL_GEQUAL, pp->alphaThreshold);
		}

		glPushMatrix();
			glTranslatef3(pp->pos);
			glRotatef(pp->spinAngle, pp->spinVec.x, pp->spinVec.y, pp->spinVec.z);
			glCallList(pp->dispList);
		glPopMatrix();

		if (pp->alphaThreshold != 0.1f) {
			glPopAttrib();
		}
	}

	return true;
}
示例#16
0
void CAdvTreeDrawer::DrawShadowPass(void)
{
	float treeDistance=oldTreeDistance;

	int activeFarTex=camera->forward.z<0 ? treeGen->farTex[0] : treeGen->farTex[1];

	bool drawDetailed=true;
	if(treeDistance<4)
		drawDetailed=false;

	glBindTexture(GL_TEXTURE_2D, activeFarTex);
	glEnable(GL_TEXTURE_2D);
	glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarShadowVP );
	glEnable( GL_VERTEX_PROGRAM_ARB );
	glEnable(GL_ALPHA_TEST);
	glPolygonOffset(1,1);
	glEnable(GL_POLYGON_OFFSET_FILL);

	CAdvTreeSquareDrawer_SP drawer;
	int cx = drawer.cx=(int)(camera->pos.x/(SQUARE_SIZE*TREE_SQUARE_SIZE));
	int cy = drawer.cy=(int)(camera->pos.z/(SQUARE_SIZE*TREE_SQUARE_SIZE));

	drawer.drawDetailed = drawDetailed;
	drawer.td = this;
	drawer.treeDistance = treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE;

	GML_STDMUTEX_LOCK(tree); // DrawShadowPass

	// draw with extraSize=1
	readmap->GridVisibility (camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer, 1);

	if(drawDetailed){
		int xstart=std::max(0,cx-2);
		int xend=std::min(gs->mapx/TREE_SQUARE_SIZE-1,cx+2);
		int ystart=std::max(0,cy-2);
		int yend=std::min(gs->mapy/TREE_SQUARE_SIZE-1,cy+2);

		glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
		glEnable(GL_TEXTURE_2D);
		glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeShadowVP );
		glEnable( GL_VERTEX_PROGRAM_ARB );
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13,  camera->right.x,camera->right.y,camera->right.z,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9,  camera->up.x,camera->up.y,camera->up.z,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, 1,1,1,0.85f);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 0,0,0,0.20f*(1.0f/MAX_TREE_HEIGHT));	//w=alpha/height modifier
		glAlphaFunc(GL_GREATER,0.5f);
		glEnable(GL_ALPHA_TEST);
		glColor4f(1,1,1,1);
		va=GetVertexArray();
		va->Initialize();

		struct FadeTree{
			float3 pos;
			float relDist;
			float deltaY;
			int type;
		};
		static FadeTree fadeTrees[3000];
		FadeTree *pFT=fadeTrees;

		for(TreeSquareStruct* pTSS=trees+ystart*treesX; pTSS<=trees+yend*treesX; pTSS+=treesX) {
			for(TreeSquareStruct* tss=pTSS+xstart; tss<=pTSS+xend; ++tss) {
				tss->lastSeen=gs->frameNum;
				va->EnlargeArrays(12*tss->trees.size(),0,VA_SIZE_T); //!alloc room for all tree vertexes
				for(std::map<int,TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){
					TreeStruct* ts=&ti->second;
					float3 pos(ts->pos);
					int type=ts->type;
					float dy;
					unsigned int displist;
					if(type<8){
						dy=0.5f;
						displist=treeGen->pineDL+type;
					} else {
						type-=8;
						dy=0;
						displist=treeGen->leafDL+type;
					}
					if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2+150)){
						float camDist=(pos-camera->pos).SqLength();
						if(camDist<SQUARE_SIZE*SQUARE_SIZE*110*110){	//draw detailed tree
							glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
							glCallList(displist);
						} else if(camDist<SQUARE_SIZE*SQUARE_SIZE*125*125){	//draw fading tree
							float relDist=(pos.distance(camera->pos)-SQUARE_SIZE*110)/(SQUARE_SIZE*15);
							glAlphaFunc(GL_GREATER,0.8f+relDist*0.2f);
							glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
							glCallList(displist);
							glAlphaFunc(GL_GREATER,0.5f);
							pFT->pos=pos;
							pFT->deltaY=dy;
							pFT->type=type;
							pFT->relDist=relDist;
							++pFT;
						} else {																//draw undetailed tree
							DrawTreeVertex(pos, type*0.125f, dy, false);
						}
					}
				}
			}
		}
		//draw trees that have been marked as falling
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,0,0,0,0);
		for(std::list<FallingTree>::iterator fti=fallingTrees.begin(); fti!=fallingTrees.end(); ++fti){
			float3 pos=fti->pos-UpVector*(fti->fallPos*20);
			if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){
				float ang=fti->fallPos*PI;
				float3 up(fti->dir.x*sin(ang),cos(ang),fti->dir.z*sin(ang));
				float3 z(up.cross(float3(1,0,0)));
				z.ANormalize();
				float3 x(z.cross(up));
				CMatrix44f transMatrix(pos,x,up,z);

				glPushMatrix();
				glMultMatrixf(&transMatrix[0]);

				int type=fti->type;
				int displist;
				if(type<8){
					displist=treeGen->pineDL+type;
				} else {
					type-=8;
					displist=treeGen->leafDL+type;
				}
				glCallList(displist);

				glPopMatrix();
			}
		}
		glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarShadowVP );
		glBindTexture(GL_TEXTURE_2D, activeFarTex);
		va->DrawArrayT(GL_QUADS);

		for(FadeTree *pFTree=fadeTrees; pFTree<pFT; ++pFTree) { //faded close trees
			va=GetVertexArray();
			va->Initialize();
			va->CheckInitSize(12*VA_SIZE_T);

			DrawTreeVertex(pFTree->pos, pFTree->type*0.125f, pFTree->deltaY, false);

			glAlphaFunc(GL_GREATER,1-pFTree->relDist*0.5f);
			va->DrawArrayT(GL_QUADS);
		}
	}
	glDisable(GL_POLYGON_OFFSET_FILL);
	glDisable( GL_VERTEX_PROGRAM_ARB );
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_ALPHA_TEST);
}
示例#17
0
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(gu->drawFog) {
		glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor);
		glEnable(GL_FOG);
	}

	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, mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,1);
			glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,11, 0,0,0,1-mapInfo->light.groundShadowDensity*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-mapInfo->light.groundShadowDensity*0.5f);

			float texConstant[]={mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.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 * SQUARE_SIZE * TREE_SQUARE_SIZE;
	drawer.drawDetailed = drawDetailed;

	GML_STDMUTEX_LOCK(tree); // Draw

	// draw far away trees using the map dependent grid visibility
	oldTreeDistance=treeDistance;
	readmap->GridVisibility (camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer);

	if(drawDetailed){
		int xstart=std::max(0,cx-2);
		int xend=std::min(gs->mapx/TREE_SQUARE_SIZE-1,cx+2);
		int ystart=std::max(0,cy-2);
		int yend=std::min(gs->mapy/TREE_SQUARE_SIZE-1,cy+2);

		if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
			glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeVP );

			glActiveTextureARB(GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
			glActiveTextureARB(GL_TEXTURE0_ARB);

		} else {
			glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
			glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeNSVP );
			glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,15, 1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),1.0f/(gs->pwr2mapx*SQUARE_SIZE),1);
		}
		glEnable( GL_VERTEX_PROGRAM_ARB );
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13,  camera->right.x,camera->right.y,camera->right.z,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9,  camera->up.x,camera->up.y,camera->up.z,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, mapInfo->light.groundSunColor.x,mapInfo->light.groundSunColor.y,mapInfo->light.groundSunColor.z,0.85f);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,0.85f);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 0,0,0,0.20f*(1.0f/MAX_TREE_HEIGHT));	//w=alpha/height modifier
		glAlphaFunc(GL_GREATER,0.5f);
		glDisable(GL_BLEND);
		glColor4f(1,1,1,1);
		va=GetVertexArray();
		va->Initialize();

		struct FadeTree{
			float3 pos;
			float relDist;
			float deltaY;
			int type;
		};
		static FadeTree fadeTrees[3000];
		FadeTree *pFT=fadeTrees;

		for(TreeSquareStruct* pTSS=trees+ystart*treesX; pTSS<=trees+yend*treesX; pTSS+=treesX) {
			for(TreeSquareStruct* tss=pTSS+xstart; tss<=pTSS+xend; ++tss) {
				tss->lastSeen=gs->frameNum;
				va->EnlargeArrays(12*tss->trees.size(),0,VA_SIZE_T); //!alloc room for all tree vertexes
				for(std::map<int,TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){
					TreeStruct* ts=&ti->second;
					float3 pos(ts->pos);
					int type=ts->type;
					float dy;
					unsigned int displist;
					if(type<8){
						dy=0.5f;
						displist=treeGen->pineDL+type;
					} else {
						type-=8;
						dy=0;
						displist=treeGen->leafDL+type;
					}
					if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){
						float camDist=(pos-camera->pos).SqLength();
						if(camDist<SQUARE_SIZE*SQUARE_SIZE*110*110){	//draw detailed tree
							glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
							glCallList(displist);
						} else if(camDist<SQUARE_SIZE*SQUARE_SIZE*125*125){	//draw fading tree
							float relDist=(pos.distance(camera->pos)-SQUARE_SIZE*110)/(SQUARE_SIZE*15);
							glAlphaFunc(GL_GREATER,0.8f+relDist*0.2f);
							glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
							glCallList(displist);
							glAlphaFunc(GL_GREATER,0.5f);
							pFT->pos=pos;
							pFT->deltaY=dy;
							pFT->type=type;
							pFT->relDist=relDist;
							++pFT;
						} else {																//draw undetailed tree
							DrawTreeVertex(pos, type*0.125f, dy, false);
						}
					}
				}
			}
		}
		//draw trees that has been marked as falling
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,0,0,0,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13,  camera->right.x,camera->right.y,camera->right.z,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9,  camera->up.x,camera->up.y,camera->up.z,0);
		for(std::list<FallingTree>::iterator fti=fallingTrees.begin(); fti!=fallingTrees.end(); ++fti){
			float3 pos=fti->pos-UpVector*(fti->fallPos*20);
			if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){
				float ang=fti->fallPos*PI;
				float3 up(fti->dir.x*sin(ang),cos(ang),fti->dir.z*sin(ang));
				float3 z(up.cross(float3(-1,0,0)));
				z.ANormalize();
				float3 x(up.cross(z));
				CMatrix44f transMatrix(pos,x,up,z);

				glPushMatrix();
				glMultMatrixf(&transMatrix[0]);

				int type=fti->type;
				int displist;
				if(type<8){
					displist=treeGen->pineDL+type;
				} else {
					type-=8;
					displist=treeGen->leafDL+type;
				}
				glCallList(displist);

				glPopMatrix();
			}
		}

		glDisable( GL_VERTEX_PROGRAM_ARB );

		if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
			glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP );
			glEnable(GL_VERTEX_PROGRAM_ARB);

			glActiveTextureARB(GL_TEXTURE1_ARB);
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
			glActiveTextureARB(GL_TEXTURE0_ARB);
		} else {
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
		}
		va->DrawArrayT(GL_QUADS);

		for(FadeTree *pFTree=fadeTrees; pFTree<pFT; ++pFTree) { //faded close trees
			va=GetVertexArray();
			va->Initialize();
			va->CheckInitSize(12*VA_SIZE_T);

			DrawTreeVertex(pFTree->pos, pFTree->type*0.125f, pFTree->deltaY, false);

			glAlphaFunc(GL_GREATER,1-pFTree->relDist*0.5f);
			va->DrawArrayT(GL_QUADS);
		}
	}
	if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
		glDisable( GL_VERTEX_PROGRAM_ARB );
		if(shadowHandler->useFPShadows){
			glDisable(GL_FRAGMENT_PROGRAM_ARB);
		}
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glDisable(GL_TEXTURE_2D);
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
		glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
	}

	glDisable(GL_FOG);

	glDisable(GL_ALPHA_TEST);

	//clean out squares from memory that are no longer visible
	int startClean=lastListClean*20%(nTrees);
	lastListClean=gs->frameNum;
	int endClean=gs->frameNum*20%(nTrees);

	if(startClean>endClean){
		for(TreeSquareStruct *pTSS=trees+startClean; pTSS<trees+nTrees; ++pTSS) {
			if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){
				glDeleteLists(pTSS->displist,1);
				pTSS->displist=0;
			}
			if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){
				glDeleteLists(pTSS->farDisplist,1);
				pTSS->farDisplist=0;
			}
		}
		for(TreeSquareStruct *pTSS=trees; pTSS<trees+endClean; ++pTSS) {
			if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){
				glDeleteLists(pTSS->displist,1);
				pTSS->displist=0;
			}
			if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){
				glDeleteLists(pTSS->farDisplist,1);
				pTSS->farDisplist=0;
			}
		}
	} else {
		for(TreeSquareStruct *pTSS=trees+startClean; pTSS<trees+endClean; ++pTSS) {
			if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){
				glDeleteLists(pTSS->displist,1);
				pTSS->displist=0;
			}
			if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){
				glDeleteLists(pTSS->farDisplist,1);
				pTSS->farDisplist=0;
			}
		}
	}
}
示例#18
0
int main()
{
	char cmd[1000]={},split[5][100]={};
	char *token;
	int cmdSpt=0,i,returnA,returnB,returnTar,returnFunc,row,col,size;
	double mul;
	FILE *fileA=NULL,*fileB=NULL,*fileTar=NULL;
	matrix matA,matB,matTar;
	
	//prints welcome messages
	system("cls");
	printf("\n\n===Matrix manipulation program===\n\n");
	printf("Type <help> for command list and usage\n\n");
	do
	{
		printf("MATRIX> ");					//command prompt
		rewind(stdin);						//rewind everything
		scanf("%[^\n]",cmd);				//get command (with spaces)
		
		cmdSpt=0;							//set sub command count to 0
		token=strtok(cmd," ");				//partition command to subcommand with spaces
		while(token!=NULL&&cmdSpt<=5)
		{
			strcpy(split[cmdSpt],token);	//save subcommands to split[]
			cmdSpt++;						//increase sub command count
			token=strtok(NULL," ");
		}
		
		for(i=0;i<strlen(split[0]);i++)			//set command to lowercase
			split[0][i]=tolower(split[0][i]);	
		
		if(strcmp(split[0],"show")==0&&cmdSpt==2)	//show command
		{
			returnA=openFile(&fileA,split[1],0);	//call openFile() to open file to show
			
			if(returnA==1)							//failed to open
				printf("Error: file %s failed to open.\n\n",split[1]);
			else
			{
				matA=readMatrix(fileA);				//read matrix and save to matA
				showMatrix(matA,split[1]);					//show matrix matA
			}
		}
		else if(strcmp(split[0],"create")==0&&cmdSpt==4)	//create command
		{
			returnA=openFile(&fileA,split[3],1);			//call openFile() to create a new file
			{
				if(returnA==1)								//failed to open
					printf("Error: file %s failed to open.\n\n",split[3]);
				else if(sscanf(split[1],"%d",&row)!=1||sscanf(split[2],"%d",&col)!=1)	//incorrect matrix size entered
					printf("Error: invalid matrix size.\n\n");
				else if(row>50||col>50)						//size too large
					printf("Error: maximum matrix size is 50x50.\n\n");
				else
				{
					createMatrix(row,col,fileA);			//create a new matrix with specified size
					printf("%dx%d matrix was successfully saved to %s.\n\n",row,col,split[3]);
				}
			}
		}
		else if(strcmp(split[0],"copy")==0&&cmdSpt==3)		//copy command
		{
			returnA=openFile(&fileA,split[1],0);			//open source and destination files
			returnB=openFile(&fileTar,split[2],1);
			
			if(returnA==1)		//failed to open source
				printf("Error: file %s failed to open.\n\n",split[1]);
			if(returnB==1)		//failed to open destination
				printf("Error: file %s failed to open.\n\n",split[2]);
			
			if(returnA==0&&returnB==0)		//passed
			{
				matA=readMatrix(fileA);		//read source file
				writeMatrix(matA,fileTar);	//write to destination file
				printf("Matrix from %s is successfully copied to %s.\n\n",split[1],split[2]);
			}
		}
		else if(strcmp(split[0],"add")==0&&cmdSpt==4)		//add command
		{
			returnA=openFile(&fileA,split[1],0);			//open source and destination files
			returnB=openFile(&fileB,split[2],0);
			returnTar=openFile(&fileTar,split[3],1);
			
			if(returnA==1)		//failed to open source A
				printf("Error: file %s failed to open.\n\n",split[1]);
			if(returnB==1)		//failed to open source B
				printf("Error: file %s failed to open.\n\n",split[2]);
			if(returnTar==1)	//failed to open destination
				printf("Error: file %s failed to open.\n\n",split[3]);
			
			if(returnA==0&&returnB==0&&returnTar==0)		//passed
			{
				matA=readMatrix(fileA);						//read both sources files
				matB=readMatrix(fileB);
				returnFunc=addMatrix(matA,matB,fileTar);	//add matrices and save to destination
				if(returnFunc==0)							//success
				{
					printf("New matrix is successfully saved to %s.\n\n",split[3]);
					matTar=readMatrix(fileTar);
					printf("===Base matrix===\n");
					showMatrix(matA,split[1]);
					printf("===Adder matrix===\n");
					showMatrix(matB,split[2]);
					printf("===Result matrix===\n");
					showMatrix(matTar,split[3]);
				}
				else										//dimensions not matched
					printf("Error: matrix dimensions unmatched.\n\n");
			}
		}
		else if((strcmp(split[0],"subtract")==0||strcmp(split[0],"sub")==0)&&cmdSpt==4)		//subtract command
		{
			returnA=openFile(&fileA,split[1],0);			//open source and destination files
			returnB=openFile(&fileB,split[2],0);
			returnTar=openFile(&fileTar,split[3],1);
			
			if(returnA==1)		//failed to open source A
				printf("Error: file %s failed to open.\n\n",split[1]);
			if(returnB==1)		//failed to open source B
				printf("Error: file %s failed to open.\n\n",split[2]);
			if(returnTar==1)	//failed to open destination	
				printf("Error: file %s failed to open.\n\n",split[3]);
			
			if(returnA==0&&returnB==0&&returnTar==0)		//passed
			{
				matA=readMatrix(fileA);						//read both sources files
				matB=readMatrix(fileB);
				returnFunc=subMatrix(matA,matB,fileTar);	//subtract matrices and save to destination
				if(returnFunc==0)							//success
				{
					printf("New matrix is successfully saved to %s.\n\n",split[3]);
					matTar=readMatrix(fileTar);
					printf("===Base matrix===\n");
					showMatrix(matA,split[1]);
					printf("===Subtractor matrix===\n");
					showMatrix(matB,split[2]);
					printf("===Result matrix===\n");
					showMatrix(matTar,split[3]);
				}
				else										//dimensions not matched
					printf("Error: matrix dimensions unmatched.\n\n");
			}			
		}
		else if((strcmp(split[0],"multiply")==0||strcmp(split[0],"mul")==0)&&cmdSpt==4)		//multiply command
		{
			returnA=openFile(&fileA,split[1],0);			//open source and destination files
			returnB=openFile(&fileB,split[2],0);
			returnTar=openFile(&fileTar,split[3],1);
			
			if(returnA==1)		//failed to open source A
				printf("Error: file %s failed to open.\n\n",split[1]);
			if(returnB==1)		//failed to open source B
				printf("Error: file %s failed to open.\n\n",split[2]);
			if(returnTar==1)	//failed to open destination	
				printf("Error: file %s failed to open.\n\n",split[3]);
			
			if(returnA==0&&returnB==0&&returnTar==0)		//passed
			{
				matA=readMatrix(fileA);						//read both sources files
				matB=readMatrix(fileB);
				returnFunc=mulMatrix(matA,matB,fileTar);	//multiply matrices and save to destination
				if(returnFunc==0)							//success
				{
					printf("New matrix is successfully saved to %s.\n\n",split[3]);
					matTar=readMatrix(fileTar);
					printf("===Base matrix===\n");
					showMatrix(matA,split[1]);
					printf("===Multiplier matrix===\n");
					showMatrix(matB,split[2]);
					printf("===Result matrix===\n");
					showMatrix(matTar,split[3]);
				}
				else										//dimensions not matched
					printf("Error: matrix dimensions unmatched.\n\n");
			}			
		}
		else if((strcmp(split[0],"mulscalar")==0||strcmp(split[0],"muls")==0)&&cmdSpt==4)	//multiply scalar command
		{
			returnA=openFile(&fileA,split[2],0);			//open source and destination files
			returnTar=openFile(&fileTar,split[3],1);
			returnFunc=sscanf(split[1],"%lf",&mul);			//convert multiplier to double
			
			if(returnA==1)		//failed to open source A					
				printf("Error: file %s failed to open.\n\n",split[2]);
			if(returnTar==1)	//failed to open destination
				printf("Error: file %s failed to open.\n\n",split[3]);
			if(returnFunc!=1)	//cannot convert multiplier to double (invalid)
				printf("Error: invalid multiplier.\n\n");
			
			if(returnA==0&&returnB==0&&returnFunc==1)		//passed
			{
				matA=readMatrix(fileA);						//read source file
				mulScaMatrix(matA,mul,fileTar);				//multiply with scalar and save to destination
				
				printf("New matrix is successfully saved to %s.\n\n",split[3]);	
				matTar=readMatrix(fileTar);
				printf("===Base matrix===\n");
				showMatrix(matA,split[2]);
				printf("Multiply with %g\n\n",mul);
				printf("===Result matrix===\n");
				showMatrix(matTar,split[3]);				
			}
		}
		else if((strcmp(split[0],"transpose")==0||strcmp(split[0],"trans")==0)&&cmdSpt==3)	//transpose command
		{
			returnA=openFile(&fileA,split[1],0);			//open source and destination files
			returnTar=openFile(&fileTar,split[2],1);	

			if(returnA==1)		//failed to open source A
				printf("Error: file %s failed to open.\n\n",split[1]);
			if(returnTar==1)	//failed to open destination
				printf("Error: file %s failed to open.\n\n",split[2]);	

			if(returnA==0&&returnTar==0)					//passed
			{
				matA=readMatrix(fileA);						//read source file
				transMatrix(matA,fileTar);					//transpose matrix and save to destination
				
				printf("New matrix is successfully saved to %s.\n\n",split[2]);	
			}
		}
		else if((strcmp(split[0],"identity")==0||strcmp(split[0],"iden")==0)&&cmdSpt==3)	//identity matrix command
		{
			returnTar=openFile(&fileTar,split[2],1);		//open destination file
			returnFunc=sscanf(split[1],"%d",&size);			//convert size to integer
			
			if(returnTar==1)			//failed to open destination
				printf("Error: file %s failed to open.\n\n",split[2]);
			else if(returnFunc!=1)		//failed to convert size to integer (invalid)
				printf("Error: invalid matrix size.\n\n");
			else if(size>50)			//size too large
				printf("Error: maximum matrix size is 50x50.\n\n");
			else
			{
				idenMatrix(size,fileTar);		//create identity matrix with specified size and save to destination
				
				printf("Identity matrix of size %d is successfully saved to %s.\n\n",size,split[2]);	
			}
		}
		else if(strcmp(split[0],"help")==0&&cmdSpt==1)		//help command
		{
			displayHelp();		//display help
		}
		else if((strcmp(split[0],"clear")==0||strcmp(split[0],"cls")==0)&&cmdSpt==1)	//clear screen command
		{
			system("cls");		//clear screen
		}
		else if((strcmp(split[0],"exit")==0||strcmp(split[0],"end")==0)&&cmdSpt==1)		//exit command
		{
			printf("Exit\n");	//display exit message
		}
		else					//invalid command
		{
			printf("Invalid command or incorrect command syntax, type <help> for command list and usage.\n\n");
		}
		
		if(fileA!=NULL)			//close all file pointers in case they weren't closed by functions
			fclose(fileA);
		if(fileB!=NULL)
			fclose(fileB);
		if(fileTar!=NULL)
			fclose(fileTar);
		
	} while(strcmp(cmd,"exit")!=0&&strcmp(cmd,"end")!=0);	//loop until exit
	return 0;
}
示例#19
0
void CAdvTreeDrawer::DrawShadowPass(void)
{
	const float treeDistance = oldTreeDistance;
	const int activeFarTex = (camera->forward.z < 0.0f)? treeGen->farTex[0] : treeGen->farTex[1];
	const bool drawDetailed = (treeDistance >= 4.0f);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, activeFarTex);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_ALPHA_TEST);
	glDisable(GL_CULL_FACE);

	glPolygonOffset(1, 1);
	glEnable(GL_POLYGON_OFFSET_FILL);

	CAdvTreeSquareDrawer_SP drawer;
	const int cx = drawer.cx = (int)(camera->pos.x / (SQUARE_SIZE * TREE_SQUARE_SIZE));
	const int cy = drawer.cy = (int)(camera->pos.z / (SQUARE_SIZE * TREE_SQUARE_SIZE));

	drawer.drawDetailed = drawDetailed;
	drawer.td = this;
	drawer.treeDistance = treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE;

	Shader::IProgramObject* po = NULL;

	GML_STDMUTEX_LOCK(tree); // DrawShadowPass

	// draw with extraSize=1
	readmap->GridVisibility(camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer, 1);

	if (drawDetailed) {
		const int xstart = std::max(                              0, cx - 2);
		const int xend   = std::min(gs->mapx / TREE_SQUARE_SIZE - 1, cx + 2);
		const int ystart = std::max(                              0, cy - 2);
		const int yend   = std::min(gs->mapy / TREE_SQUARE_SIZE - 1, cy + 2);

		glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
		glEnable(GL_TEXTURE_2D);

		po = shadowHandler->GetShadowGenProg(CShadowHandler::SHADOWGEN_PROGRAM_TREE_NEAR);
		po->Enable();

		if (globalRendering->haveGLSL) {
			po->SetUniform3fv(1, &camera->right[0]);
			po->SetUniform3fv(2, &camera->up[0]);
		} else {
			po->SetUniformTarget(GL_VERTEX_PROGRAM_ARB);
			po->SetUniform4f(13, camera->right.x, camera->right.y, camera->right.z, 0.0f);
			po->SetUniform4f(9,  camera->up.x,    camera->up.y,    camera->up.z,    0.0f);
			po->SetUniform4f(11, 1.0f, 1.0f, 1.0f, 0.85f                           );
			po->SetUniform4f(12, 0.0f, 0.0f, 0.0f, 0.20f * (1.0f / MAX_TREE_HEIGHT));   // w = alpha/height modifier
		}

		glAlphaFunc(GL_GREATER, 0.5f);
		glEnable(GL_ALPHA_TEST);
		glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

		varr = GetVertexArray();
		varr->Initialize();

		static FadeTree fadeTrees[3000];
		FadeTree* pFT = fadeTrees;

		for (TreeSquareStruct* pTSS = trees + ystart * treesX; pTSS <= trees + yend * treesX; pTSS += treesX) {
			for (TreeSquareStruct* tss = pTSS + xstart; tss <= pTSS + xend; ++tss) {
				tss->lastSeen = gs->frameNum;
				varr->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes

				for (std::map<int, TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) {
					const TreeStruct* ts = &ti->second;
					const float3 pos(ts->pos);

					if (!camera->InView(pos + float3(0, MAX_TREE_HEIGHT / 2, 0), MAX_TREE_HEIGHT / 2 + 150)) {
						continue;
					}

					const float camDist = (pos - camera->pos).SqLength();
					int type = ts->type;
					float dy = 0.0f;
					unsigned int displist;

					if (type < 8) {
						dy = 0.5f;
						displist = treeGen->pineDL + type;
					} else {
						type -= 8;
						dy = 0;
						displist = treeGen->leafDL + type;
					}

					if (camDist < SQUARE_SIZE * SQUARE_SIZE * 110 * 110) {
						po->SetUniform3f((globalRendering->haveGLSL? 3: 10), pos.x, pos.y, pos.z);
						glCallList(displist);
					} else if (camDist < SQUARE_SIZE * SQUARE_SIZE * 125 * 125) {
						const float relDist = (pos.distance(camera->pos) - SQUARE_SIZE * 110) / (SQUARE_SIZE * 15);

						glAlphaFunc(GL_GREATER, 0.8f + relDist * 0.2f);
						po->SetUniform3f((globalRendering->haveGLSL? 3: 10), pos.x, pos.y, pos.z);
						glCallList(displist);
						glAlphaFunc(GL_GREATER, 0.5f);

						pFT->pos = pos;
						pFT->deltaY = dy;
						pFT->type = type;
						pFT->relDist = relDist;
						++pFT;
					} else {
						DrawTreeVertex(varr, pos, type * 0.125f, dy, false);
					}
				}
			}
		}


		po->SetUniform3f((globalRendering->haveGLSL? 3: 10), 0.0f, 0.0f, 0.0f);

		for (std::list<FallingTree>::iterator fti = fallingTrees.begin(); fti != fallingTrees.end(); ++fti) {
			const float3 pos = fti->pos - UpVector * (fti->fallPos * 20);

			if (camera->InView(pos + float3(0, MAX_TREE_HEIGHT / 2, 0), MAX_TREE_HEIGHT / 2)) {
				const float ang = fti->fallPos * PI;

				const float3 yvec(fti->dir.x * sin(ang), cos(ang), fti->dir.z * sin(ang));
				const float3 zvec((yvec.cross(float3(1.0f, 0.0f, 0.0f))).ANormalize());
				const float3 xvec(zvec.cross(yvec));

				CMatrix44f transMatrix(pos, xvec, yvec, zvec);

				glPushMatrix();
				glMultMatrixf(&transMatrix[0]);

				int type = fti->type;
				int displist;

				if (type < 8) {
					displist = treeGen->pineDL + type;
				} else {
					type -= 8;
					displist = treeGen->leafDL + type;
				}

				glCallList(displist);
				glPopMatrix();
			}
		}

		po->Disable();
		po = shadowHandler->GetShadowGenProg(CShadowHandler::SHADOWGEN_PROGRAM_TREE_FAR);
		po->Enable();

		glBindTexture(GL_TEXTURE_2D, activeFarTex);
		varr->DrawArrayT(GL_QUADS);

		for (FadeTree* pFTree = fadeTrees; pFTree < pFT; ++pFTree) {
			// faded close trees
			varr = GetVertexArray();
			varr->Initialize();
			varr->CheckInitSize(12 * VA_SIZE_T);

			DrawTreeVertex(varr, pFTree->pos, pFTree->type * 0.125f, pFTree->deltaY, false);

			glAlphaFunc(GL_GREATER, 1.0f - (pFTree->relDist * 0.5f));
			varr->DrawArrayT(GL_QUADS);
		}

		po->Disable();
	}

	glEnable(GL_CULL_FACE);
	glDisable(GL_POLYGON_OFFSET_FILL);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_ALPHA_TEST);
}
示例#20
0
文件: Park.cpp 项目: amcolash/cs559
Flag::Flag(float x, float y, float z, float r, float g, float b) :
color(r, g, b)
{
	transMatrix(transform, x, 0, z);
}
示例#21
0
int kalman_function(sensor_struct_t* sen,float_j_t dt){

	/*
	 *
	 *	system model 
	 *	omega = [ w_x w_y w_z ]^T
	 *	x = [pi theta psi]^T
	 *	used  x_dot, C_inv, omega, x_k_1, x_k, dt, 
	 *
	 * */
#define Def_x	0
#define Def_y	1
#define Def_z	2
#define Def_pi		0
#define Def_theta	1
#define Def_psi		2
	//float_j_t dt;
	//float_j_t B[3][3]={0,};

	float_j_t res[3][3]={0,};
	float_j_t res2[3][3]={0,};

	float_j_t omega[3][3]={0,};
	omega[0][0] = sen->gyroX*DEG_TO_RAD;
	omega[1][0] = sen->gyroY*DEG_TO_RAD;
	omega[2][0] = sen->gyroZ*DEG_TO_RAD;

	static float_j_t x_k_1[3][3]={0,}; 
	float_j_t x_k_p[3][3]={0,};

	float_j_t pi,theta,psi;
	pi = x_k_1[Def_pi][0];
	theta = x_k_1[Def_theta][0];
	psi = x_k_1[Def_psi][0];

if(cosf(theta)==0.0){ 
		printf("cosf error\n ");
		theta += 0.00001;
}

	float_j_t C_inv[3][3]={0,};
	C_inv[0][0] = 1*dt;
	C_inv[0][1] = sinf(pi)*tanf(theta)*dt; 
	C_inv[0][2] = cosf(pi)*tanf(theta)*dt;
	C_inv[1][0] = 0;
	C_inv[1][1] = cosf(pi)*dt;
	C_inv[1][2] = -sinf(pi)*dt;
	C_inv[2][0] = 0;
	C_inv[2][1] = (sinf(pi)/cosf(theta))*dt;
	C_inv[2][2] = (cosf(pi)/cosf(theta))*dt;

	//x_k = x_k_1 + C_inv * omega * dt
	multiMatrix(C_inv,omega,res,3,3);
	sumMatrix(res,x_k_1,x_k_p,3,3);




	/* A_k*/
	float_j_t A[3][3]={0,};
	A[0][0] = 1 + (sinf(theta)*(omega[1][0]*cosf(pi)-omega[2][0]*sinf(pi)) / cosf(theta))*dt;
	A[0][1] = ((omega[1][0]*sinf(pi)+omega[2][0]*cosf(pi)) / (cosf(theta)*cosf(theta)))*dt;
	A[0][2] = 0;

	A[1][0] = (-omega[1][0]*sinf(pi)-omega[2][0]*cosf(pi))*dt;
	A[1][1] = 1;
	A[1][2] = 0;

	A[2][0] = ((omega[1][0]*cosf(pi)-omega[2][0]*sinf(pi)) / cosf(theta))*dt;
	A[2][1] = (sinf(theta)*(omega[1][0]*sinf(pi)+omega[2][0]*cosf(pi)) / (cosf(theta)*cosf(theta)))*dt;
	A[2][2] = 1;

	float_j_t P_k_p[3][3]={0,};
	static float_j_t P_k_1[3][3]={1,0,0,0,1,0,0,0,1};

	float_j_t Q[3][3]={1,0,0,0,1,0,0,0,1};
	//P_k = A* P_k_1 * A^T + B * Q * B^T
	similarMatrix(A,P_k_1,res,3,3);
	similarMatrix(C_inv,Q,res2,3,3);
	sumMatrix(res,res2,P_k_p,3,3);

	//Correct term 

	float_j_t H[3][3]={1,0,0,0,1,0,0,0,0};

	float_j_t norm_a=9.8;
	norm_a=sqrtf(powf(sen->accX,2)+powf(sen->accY,2)+powf(sen->accZ,2));
//		printf("norm_a = %f\n",norm_a);
	float_j_t R[3][3]={0,};
	if((norm_a<10.8 )&&(norm_a>8.8)){
		R[0][0]=1;
		R[1][1]=1;
	}else{
		R[0][0]=1000;
		R[1][1]=1000;
	}


	float_j_t res3[3][3] = {0,};

	similarMatrix(H,P_k_p,res,3,3);
	

	//printf("similarMatrix res\n");
	//printMatrix(res,3,3);

	sumMatrix(res,R,res2,3,3);
	
	_2by2_inverseMatrix(res2,res,3,3);

	//inverseMatrix(res2,res,3,3);
	//result inverse matrix is res
	//so  kalman gain  K = Pk* H^T* res
	float_j_t K[3][3]={0,};
	
	transMatrix(H,res3,3,3);
	multiMatrix(P_k_p,res3,res2,3,3);
	res2[0][2]=0;
	res2[1][2]=0;
	res2[2][0]=0;
	res2[2][1]=0;
	res2[2][2]=0;

		
//	printf("res2 gain\n");
//	printMatrix(res2,3,3);
//	printf("res gain\n");
//	printMatrix(res,3,3);
	multiMatrix(res2,res,K,3,3);
//	printf("kalman gain\n");
//	printMatrix(K,3,3);


	/* state variable,  covaliance mat  update*/
	float_j_t x_k[3][3]={0,};

	//calculate z_k  roll, ptich,  with gravitational euler angle calc.
	float_j_t z_k[3][3] ={0,};
	
#if 1
	z_k[0][0] = atan2f(sen->accY,sen->accZ);
    z_k[1][0] = atan2f(-sen->accX, sqrtf( powf(sen->accY,2)+powf(sen->accZ,2) ));
#else
    if(sen->accZ>=0){
	    z_k[0][0] = atan2f(sen->accY,sen->accZ);
        z_k[1][0] = atan2f(-sen->accX, sqrtf( powf(sen->accY,2)+powf(sen->accZ,2) ));
    }else if(sen->accZ<0){
        omega[1][0] = -omega[1][0];
	    z_k[1][0] = -atan2f(sen->accX,sen->accZ);
        z_k[0][0] = atan2f(-sen->accY, sqrtf( powf(sen->accX,2)+powf(sen->accZ,2) ));
    }
#endif
    //GravityToEuler(sen->accX, sen->accY, sen->accZ, z_k);
    //printf("r %f p %f ",z_k[0][0]*180/3.14,z_k[1][0]*180/3.14);
	multiMatrix(H,x_k_p,res,3,3);

	subMatrix(z_k,res,res2,3,3);
	multiMatrix(K,res2,res,3,3);
	sumMatrix(x_k_p,res,x_k,3,3);

	float_j_t P_k[3][3]={0,};
	multiMatrix(K,H,res,3,3);
	multiMatrix(res,P_k_p,res2,3,3);
	subMatrix(P_k_p,res2,P_k,3,3);

	/*insert prev value*/
	insertMatrix(x_k, x_k_1,3,3);
	insertMatrix(P_k, P_k_1,3,3);
	/*Debug print*/
	//printf("roll = %f , pitch = %f \n",x_k[0][0]*180.0/3.14,x_k[1][0]*180.0/3.14);
    sen->roll=x_k[0][0]*RAD_TO_DEG;
    sen->pitch=x_k[1][0]*RAD_TO_DEG;
    return 0;
}
示例#22
0
void CUnit::Draw()
{
    glPushMatrix();
    float3 interPos=pos+speed*gu->timeOffset;

    if (physicalState == Flying && unitDef->canmove) {
        //aircraft or skidding ground unit
        CMatrix44f transMatrix(interPos,-rightdir,updir,frontdir);

        glMultMatrixf(&transMatrix[0]);
    } else if(upright || !unitDef->canmove) {
        glTranslatef3(interPos);
        if(heading!=0)
            glRotatef(heading*(180.0/32768.0),0,1,0);
    } else {
        float3 frontDir=GetVectorFromHeading(heading);		//making local copies of vectors
        float3 upDir=ground->GetSmoothNormal(pos.x,pos.z);
        float3 rightDir=frontDir.cross(upDir);
        rightDir.Normalize();
        frontDir=upDir.cross(rightDir);

        CMatrix44f transMatrix(interPos,-rightDir,upDir,frontDir);

        glMultMatrixf(&transMatrix[0]);
    }

    if(beingBuilt && unitDef->showNanoFrame) {
        if(shadowHandler->inShadowPass) {
            if(buildProgress>0.66)
                localmodel->Draw();
        } else {
            float height=model->height;
            float start=model->miny;
            glEnable(GL_CLIP_PLANE0);
            glEnable(GL_CLIP_PLANE1);
            //float col=fabs(128.0-((gs->frameNum*4)&255))/255.0+0.5f;
            float3 fc;// fc frame color
            if(gu->teamNanospray) {
                unsigned char* tcol=gs->Team(team)->color;
                fc = float3(tcol[0]*(1./255.),tcol[1]*(1./255.),tcol[2]*(1./255.));
            } else {
                fc = unitDef->nanoColor;
            }
            glColorf3(fc);

            unitDrawer->UnitDrawingTexturesOff(model);

            double plane[4]= {0,-1,0,start+height*buildProgress*3};
            glClipPlane(GL_CLIP_PLANE0 ,plane);
            double plane2[4]= {0,1,0,-start-height*(buildProgress*10-9)};
            glClipPlane(GL_CLIP_PLANE1 ,plane2);
            glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
            localmodel->Draw();
            glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

            if(buildProgress>0.33) {
                glColorf3(fc*1.4f);
                double plane[4]= {0,-1,0,start+height*(buildProgress*3-1)};
                glClipPlane(GL_CLIP_PLANE0 ,plane);
                double plane2[4]= {0,1,0,-start-height*(buildProgress*3-2)};
                glClipPlane(GL_CLIP_PLANE1 ,plane2);

                localmodel->Draw();
            }
            glDisable(GL_CLIP_PLANE1);
            unitDrawer->UnitDrawingTexturesOn(model);

            if(buildProgress>0.66) {
                double plane[4]= {0,-1,0,start+height*(buildProgress*3-2)};
                glClipPlane(GL_CLIP_PLANE0 ,plane);
                if(shadowHandler->drawShadows && !water->drawReflection) {
                    glPolygonOffset(1,1);
                    glEnable(GL_POLYGON_OFFSET_FILL);
                }
                localmodel->Draw();
                if(shadowHandler->drawShadows && !water->drawReflection) {
                    glDisable(GL_POLYGON_OFFSET_FILL);
                }
            }
            glDisable(GL_CLIP_PLANE0);
        }
    } else {
        localmodel->Draw();
    }
    if(gu->drawdebug) {
        glPushMatrix();
        glTranslatef3(frontdir*relMidPos.z + updir*relMidPos.y + rightdir*relMidPos.x);
        GLUquadricObj* q=gluNewQuadric();
        gluQuadricDrawStyle(q,GLU_LINE);
        gluSphere(q,radius,10,10);
        gluDeleteQuadric(q);
        glPopMatrix();
    }/**/
    glPopMatrix();
}
示例#23
0
Point3d Viewpoint::point3DinView(const Point3d& p3d){
	double posi[] = {p3d.x, p3d.y, p3d.z, 1};
	Matrix posiVector(1, 4, posi);
	//fill in the matrix
	//fit the position	
	double trans[] = {
		1,0,0,-position.x,
		0,1,0,-position.y,
		0,0,1,-position.z,
		0,0,0,1
	};
	Matrix transMatrix(4,4,trans);
	//spin x axis , base on direction
	/*	double xspin[] = {
		1,0,0,0,
		0,cos(theta),-sin(theta),0,
		0,sin(theta),cos(theta),0,
		0,0,0,1
		};
	 */

	double xspin[] = {
		1,0,0,0,
		0,direction.z/sqrt(pow(direction.z,2)+ pow(direction.y, 2)),-direction.y/sqrt(pow(direction.z,2)+ pow(direction.y, 2)),0,
		0,direction.y/sqrt(pow(direction.z,2)+ pow(direction.y, 2)),direction.z/sqrt(pow(direction.z,2)+ pow(direction.y, 2)),0,
		0,0,0,1
	};
	Matrix xspinMatrix(4,4,xspin);

	//spin y axis , base on direction
	/*double yspin[] = {
	  cos(theta),0,sin(theta),0,
	  0,1,0,0,
	  -sin(theta),0,cos(theta),0,
	  0,0,0,1
	  };*/

	double yspin[] = {
		direction.z/sqrt(pow(direction.z,2)+ pow(direction.x, 2)),0,direction.x/sqrt(pow(direction.z,2)+ pow(direction.x, 2)),0,
		0,1,0,0,
		-direction.x/sqrt(pow(direction.z,2)+ pow(direction.x, 2)),0,direction.z/sqrt(pow(direction.z,2)+ pow(direction.x, 2)),0,
		0,0,0,1
	};
	Matrix yspinMatrix(4,4,yspin);

	//spin z axis , base on direction , dont use it here
	/*double zspin[] = {
	  cos(theta),sin(theta),0,0,
	  sin(theta),cos(theta),0,0,
	  0,0,1,0,
	  0,0,0,1
	  };*/

	double zspin[] = {
		direction.x/sqrt(pow(direction.x,2)+ pow(direction.y, 2)),-direction.y/sqrt(pow(direction.x,2)+ pow(direction.y, 2)),0,0,
		direction.y/sqrt(pow(direction.x,2)+ pow(direction.y, 2)),direction.x/sqrt(pow(direction.x,2)+ pow(direction.y, 2)),0,0,
		0,0,1,0,
		0,0,0,1
	};

	Matrix zspinMatrix(4,4,zspin);

	posiVector= transMatrix*posiVector;
	posiVector= xspinMatrix*posiVector;
	posiVector= yspinMatrix*posiVector;
	return Point3d(posiVector.dataAt(0,0), posiVector.dataAt(0,1), posiVector.dataAt(0,2));

}
示例#24
0
int RenderMain ( void )
{
	int 			tmrLast = 0;
	int 			currFps = 0,
					lastFps = 0;
	int 			frameIndex = 0;
	float 			frameInterp = 0;
	float			rotRadY = 0.0f,
					rotRadX = 0.0f;
	char			textBuffer[128];
	bool 			keyTable[4] = { false };
	bool focus = true;

	Matrix4fi		transMatrix( false );
	MAExtent		size = maGetScrSize( );
	MDLFixed 		model( RES_MODEL_OGRE );
	TransformPipe	pipe( EXTENT_X( size ), EXTENT_Y( size ) );


	// Center model
	model.centerModel( );

	tmrLast = maGetMilliSecondCount( );

	//
	// Rendering loop
	//
	while ( true )
	{
		//
		// Handle input
		//
		MAEvent e;
		while ( maGetEvent( &e ) )
		{
			if ( e.type == EVENT_TYPE_CLOSE ||
				 e.type == EVENT_TYPE_KEY_PRESSED ||
				 e.type == EVENT_TYPE_POINTER_PRESSED )
				maExit(0);
			else if(e.type == EVENT_TYPE_FOCUS_LOST)
				focus = false;
			else if(e.type == EVENT_TYPE_FOCUS_GAINED)
				focus = true;

			else if ( e.type == EVENT_TYPE_KEY_PRESSED )
			{
				if ( e.key == MAK_LEFT )
					keyTable[MAK_LEFT-MAK_UP] = true;
				else if ( e.key == MAK_RIGHT )
					keyTable[MAK_RIGHT-MAK_UP] = true;
				else if ( e.key == MAK_UP )
					keyTable[MAK_UP-MAK_UP] = true;
				else if ( e.key == MAK_DOWN )
					keyTable[MAK_DOWN-MAK_UP] = true;
			}
			else if ( e.type == EVENT_TYPE_KEY_RELEASED )
			{
				if ( e.key == MAK_LEFT )
					keyTable[MAK_LEFT-MAK_UP] = false;
				else if ( e.key == MAK_RIGHT )
					keyTable[MAK_RIGHT-MAK_UP] = false;
				else if ( e.key == MAK_UP )
					keyTable[MAK_UP-MAK_UP] = false;
				else if ( e.key == MAK_DOWN )
					keyTable[MAK_DOWN-MAK_UP] = false;
			}
		}

		if(focus) {
			if ( keyTable[MAK_LEFT-MAK_UP] )
				rotRadY -= (float)M_PI / 60;
			else if ( keyTable[MAK_RIGHT-MAK_UP] )
				rotRadY += (float)M_PI / 60;
			else if ( keyTable[MAK_UP-MAK_UP] )
				rotRadX -= (float)M_PI / 60;
			else if ( keyTable[MAK_DOWN-MAK_UP] )
				rotRadX += (float)M_PI / 60;

			rotRadX = (rotRadX >= 2*(float)M_PI) ? rotRadX-2*(float)M_PI : rotRadX;
			rotRadY = (rotRadY >= 2*(float)M_PI) ? rotRadY-2*(float)M_PI : rotRadY;

			//
			// Construct transformation pipe
			//
			pipe.resetPipe( );

			transMatrix.rotateX( (float)-M_PI/2 );
			pipe.addTransform( transMatrix );
			transMatrix.rotateY( (float)M_PI/4 );
			pipe.addTransform( transMatrix );

			transMatrix.rotateX( rotRadX );
			pipe.addTransform( transMatrix );
			transMatrix.rotateY( rotRadY );
			pipe.addTransform( transMatrix );
			transMatrix.translate( 0, 0, 130 );
			pipe.addTransform( transMatrix );


			// Clear screen
			maSetColor( 0 );
			maFillRect( 0, 0, EXTENT_X( size ), EXTENT_Y( size ) );

			//
			// Animate and render model
			//
			maSetColor( 0xffffff );
			model.drawFrameLerp( frameIndex, FLT2FIX( frameInterp ), pipe );
			frameInterp += 0.25f;
			if ( frameInterp >= 1.0f )
			{
				frameIndex  = (frameIndex+1) % model.getFrameCount( );
				frameInterp = 0.0f;
			}

			// Draw fps to screen
			sprintf( textBuffer, "fps: %d", lastFps );
			maDrawText( 0, 0, textBuffer );

			// Update screen and keep backlight on
			maUpdateScreen( );
			maResetBacklight( );

			// FPS counter
			currFps++;
			if ( tmrLast+1000 <= maGetMilliSecondCount( ) )
			{
				lastFps = currFps;
				currFps = 0;
				tmrLast = maGetMilliSecondCount( );
				lprintfln( "fps: %d", lastFps );
			}
		} else {	// no focus
			maWait(0);
		}
	}
}
示例#25
0
void CAdvTreeDrawer::Draw(float treeDistance, bool drawReflection)
{
	const int activeFarTex = (camera->forward.z < 0.0f)? treeGen->farTex[0]: treeGen->farTex[1];
	const bool drawDetailed = ((treeDistance >= 4.0f) || drawReflection);

	CBaseGroundDrawer* gd = readmap->GetGroundDrawer();
	Shader::IProgramObject* treeShader = NULL;

	#define L mapInfo->light

	glEnable(GL_ALPHA_TEST);
	glEnable(GL_TEXTURE_2D);

	if (globalRendering->drawFog) {
		glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor);
		glEnable(GL_FOG);
	}


	if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) {
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, activeFarTex);
		glActiveTexture(GL_TEXTURE0);
		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);

		treeShader = treeShaders[TREE_PROGRAM_DIST_SHADOW];
		treeShader->Enable();

		if (globalRendering->haveGLSL) {
			treeShader->SetUniformMatrix4fv(7, false, &shadowHandler->shadowMatrix.m[0]);
			treeShader->SetUniform4fv(8, &(shadowHandler->GetShadowParams().x));
		} else {
			treeShader->SetUniformTarget(GL_FRAGMENT_PROGRAM_ARB);
			treeShader->SetUniform4f(10, L.groundAmbientColor.x, L.groundAmbientColor.y, L.groundAmbientColor.z, 1.0f);
			treeShader->SetUniform4f(11, 0.0f, 0.0f, 0.0f, 1.0f - (sky->GetLight()->GetGroundShadowDensity() * 0.5f));
			treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB);

			glMatrixMode(GL_MATRIX0_ARB);
			glLoadMatrixf(shadowHandler->shadowMatrix.m);
			glMatrixMode(GL_MODELVIEW);
		}
	} else {
		glBindTexture(GL_TEXTURE_2D, activeFarTex);
	}


	const int cx = int(camera->pos.x / (SQUARE_SIZE * TREE_SQUARE_SIZE));
	const int cy = int(camera->pos.z / (SQUARE_SIZE * TREE_SQUARE_SIZE));

	CAdvTreeSquareDrawer drawer(this, cx, cy, treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE, drawDetailed);

	GML_STDMUTEX_LOCK(tree); // Draw

	oldTreeDistance = treeDistance;

	// draw far-trees using map-dependent grid-visibility
	readmap->GridVisibility(camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer);


	if (drawDetailed) {
		// draw near-trees
		const int xstart = std::max(                              0, cx - 2);
		const int xend   = std::min(gs->mapx / TREE_SQUARE_SIZE - 1, cx + 2);
		const int ystart = std::max(                              0, cy - 2);
		const int yend   = std::min(gs->mapy / TREE_SQUARE_SIZE - 1, cy + 2);

		if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) {
			treeShader->Disable();
			treeShader = treeShaders[TREE_PROGRAM_NEAR_SHADOW];
			treeShader->Enable();

			if (globalRendering->haveGLSL) {
				treeShader->SetUniformMatrix4fv(7, false, &shadowHandler->shadowMatrix.m[0]);
				treeShader->SetUniform4fv(8, &(shadowHandler->GetShadowParams().x));
			}

			glActiveTexture(GL_TEXTURE1);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
			glActiveTexture(GL_TEXTURE0);
		} else {
			glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);

			treeShader = treeShaders[TREE_PROGRAM_NEAR_BASIC];
			treeShader->Enable();

			if (!globalRendering->haveGLSL) {
				#define MX (gs->pwr2mapx * SQUARE_SIZE)
				#define MY (gs->pwr2mapy * SQUARE_SIZE)
				treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB);
				treeShader->SetUniform4f(15, 1.0f / MX, 1.0f / MY, 1.0f / MX, 1.0f);
				#undef MX
				#undef MY
			}
		}


		if (globalRendering->haveGLSL) {
			treeShader->SetUniform3fv(0, &camera->right[0]);
			treeShader->SetUniform3fv(1, &camera->up[0]);
			treeShader->SetUniform2f(5, 0.20f * (1.0f / MAX_TREE_HEIGHT), 0.85f);
		} else {
			treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB);
			treeShader->SetUniform3f(13, camera->right.x, camera->right.y, camera->right.z);
			treeShader->SetUniform3f( 9, camera->up.x,    camera->up.y,    camera->up.z   );
			treeShader->SetUniform4f(11, L.groundSunColor.x,     L.groundSunColor.y,     L.groundSunColor.z,     0.85f);
			treeShader->SetUniform4f(14, L.groundAmbientColor.x, L.groundAmbientColor.y, L.groundAmbientColor.z, 0.85f);
			treeShader->SetUniform4f(12, 0.0f, 0.0f, 0.0f, 0.20f * (1.0f / MAX_TREE_HEIGHT)); // w = alpha/height modifier
		}


		glAlphaFunc(GL_GREATER, 0.5f);
		glDisable(GL_BLEND);
		glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

		varr = GetVertexArray();
		varr->Initialize();

		static FadeTree fadeTrees[3000];
		FadeTree* pFT = fadeTrees;


		for (TreeSquareStruct* pTSS = trees + ystart * treesX; pTSS <= trees + yend * treesX; pTSS += treesX) {
			for (TreeSquareStruct* tss = pTSS + xstart; tss <= pTSS + xend; ++tss) {
				tss->lastSeen = gs->frameNum;
				varr->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes

				for (std::map<int, TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) {
					const TreeStruct* ts = &ti->second;
					const float3 pos(ts->pos);

					if (!camera->InView(pos + float3(0.0f, MAX_TREE_HEIGHT / 2.0f, 0.0f), MAX_TREE_HEIGHT / 2.0f)) {
						continue;
					}

					const float camDist = (pos - camera->pos).SqLength();
					int type = ts->type;
					float dy = 0.0f;
					unsigned int displist;

					if (type < 8) {
						dy = 0.5f;
						displist = treeGen->pineDL + type;
					} else {
						type -= 8;
						dy = 0.0f;
						displist = treeGen->leafDL + type;
					}

					if (camDist < (SQUARE_SIZE * SQUARE_SIZE * 110 * 110)) {
						// draw detailed near-distance tree (same as mid-distance trees without alpha)
						treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), pos.x, pos.y, pos.z);
						glCallList(displist);
					} else if (camDist < (SQUARE_SIZE * SQUARE_SIZE * 125 * 125)) {
						// draw mid-distance tree
						const float relDist = (pos.distance(camera->pos) - SQUARE_SIZE * 110) / (SQUARE_SIZE * 15);

						treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), pos.x, pos.y, pos.z);

						glAlphaFunc(GL_GREATER, 0.8f + relDist * 0.2f);
						glCallList(displist);
						glAlphaFunc(GL_GREATER, 0.5f);

						// save for second pass
						pFT->pos = pos;
						pFT->deltaY = dy;
						pFT->type = type;
						pFT->relDist = relDist;
						++pFT;
					} else {
						// draw far-distance tree
						DrawTreeVertex(varr, pos, type * 0.125f, dy, false);
					}
				}
			}
		}


		// reset the world-offset
		treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), 0.0f, 0.0f, 0.0f);

		// draw trees that have been marked as falling
		for (std::list<FallingTree>::iterator fti = fallingTrees.begin(); fti != fallingTrees.end(); ++fti) {
			const float3 pos = fti->pos - UpVector * (fti->fallPos * 20);

			if (camera->InView(pos + float3(0.0f, MAX_TREE_HEIGHT / 2, 0.0f), MAX_TREE_HEIGHT / 2.0f)) {
				const float ang = fti->fallPos * PI;

				const float3 yvec(fti->dir.x * sin(ang), cos(ang), fti->dir.z * sin(ang));
				const float3 zvec((yvec.cross(float3(-1.0f, 0.0f, 0.0f))).ANormalize());
				const float3 xvec(yvec.cross(zvec));

				CMatrix44f transMatrix(pos, xvec, yvec, zvec);

				glPushMatrix();
				glMultMatrixf(&transMatrix[0]);

				int type = fti->type;
				int displist = 0;

				if (type < 8) {
					displist = treeGen->pineDL + type;
				} else {
					type -= 8;
					displist = treeGen->leafDL + type;
				}

				glCallList(displist);
				glPopMatrix();
			}
		}


		if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) {
			treeShader->Disable();
			treeShader = treeShaders[TREE_PROGRAM_DIST_SHADOW];
			treeShader->Enable();

			glActiveTexture(GL_TEXTURE1);
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
			glActiveTexture(GL_TEXTURE0);
		} else {
			treeShader->Disable();
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
		}


		// draw far-distance trees
		varr->DrawArrayT(GL_QUADS);

		// draw faded mid-distance trees
		for (FadeTree* pFTree = fadeTrees; pFTree < pFT; ++pFTree) {
			varr = GetVertexArray();
			varr->Initialize();
			varr->CheckInitSize(12 * VA_SIZE_T);

			DrawTreeVertex(varr, pFTree->pos, pFTree->type * 0.125f, pFTree->deltaY, false);

			glAlphaFunc(GL_GREATER, 1.0f - (pFTree->relDist * 0.5f));
			varr->DrawArrayT(GL_QUADS);
		}
	}

	if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) {
		treeShader->Disable();

		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, 0);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, 0);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
		glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
	} else {
		glBindTexture(GL_TEXTURE_2D, 0);
	}

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_FOG);
	glDisable(GL_ALPHA_TEST);



	// clean out squares from memory that are no longer visible
	const int startClean = lastListClean * 20 % (nTrees);
	const int endClean = gs->frameNum * 20 % (nTrees);

	lastListClean = gs->frameNum;

	if (startClean > endClean) {
		for (TreeSquareStruct* pTSS = trees + startClean; pTSS < trees + nTrees; ++pTSS) {
			if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) {
				glDeleteLists(pTSS->displist, 1);
				pTSS->displist = 0;
			}
			if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) {
				glDeleteLists(pTSS->farDisplist, 1);
				pTSS->farDisplist = 0;
			}
		}
		for (TreeSquareStruct* pTSS = trees; pTSS < trees + endClean; ++pTSS) {
			if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) {
				glDeleteLists(pTSS->displist, 1);
				pTSS->displist = 0;
			}
			if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) {
				glDeleteLists(pTSS->farDisplist, 1);
				pTSS->farDisplist = 0;
			}
		}
	} else {
		for (TreeSquareStruct* pTSS = trees + startClean; pTSS < trees + endClean; ++pTSS) {
			if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) {
				glDeleteLists(pTSS->displist, 1);
				pTSS->displist = 0;
			}
			if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) {
				glDeleteLists(pTSS->farDisplist, 1);
				pTSS->farDisplist = 0;
			}
		}
	}

	#undef L
}