Example #1
0
void CAdvWater::UpdateWater(CGame* game)
{
	if (!mapInfo->water.forceRendering && !readMap->HasVisibleWater())
		return;

	glPushAttrib(GL_FOG_BIT);
	glPushAttrib(GL_COLOR_BUFFER_BIT);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE);

	bumpFBO.Bind();
	glViewport(0, 0, 128, 128);

	glClearColor(0.0f, 0.0f, 0.0f, 1);
	glClear(GL_COLOR_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, 1, 0, 1, -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glColor3f(0.2f, 0.2f, 0.2f);

	CVertexArray* va = GetVertexArray();
	va->Initialize();
	va->EnlargeArrays(12, 0, VA_SIZE_T);

	glBindTexture(GL_TEXTURE_2D, rawBumpTexture[0]);

	va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0046f);
	va->AddVertexQT(  UpVector, 0, 2 + gs->frameNum*0.0046f);
	va->AddVertexQT(  XYVector, 2, 2 + gs->frameNum*0.0046f);
	va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0046f);

	va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0026f);
	va->AddVertexQT(  UpVector, 0, 4 + gs->frameNum*0.0026f);
	va->AddVertexQT(  XYVector, 2, 4 + gs->frameNum*0.0026f);
	va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0026f);

	va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0012f);
	va->AddVertexQT(  UpVector, 0, 8 + gs->frameNum*0.0012f);
	va->AddVertexQT(  XYVector, 2, 8 + gs->frameNum*0.0012f);
	va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0012f);

	va->DrawArrayT(GL_QUADS);

	va->Initialize();
	glBindTexture(GL_TEXTURE_2D, rawBumpTexture[1]);

	va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0036f);
	va->AddVertexQT(  UpVector, 0, 1 + gs->frameNum*0.0036f);
	va->AddVertexQT(  XYVector, 1, 1 + gs->frameNum*0.0036f);
	va->AddVertexQT( RgtVector, 1, 0 + gs->frameNum*0.0036f);

	va->DrawArrayT(GL_QUADS);

	va->Initialize();
	glBindTexture(GL_TEXTURE_2D, rawBumpTexture[2]);

	va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0082f);
	va->AddVertexQT(  UpVector, 0, 1 + gs->frameNum*0.0082f);
	va->AddVertexQT(  XYVector, 1, 1 + gs->frameNum*0.0082f);
	va->AddVertexQT( RgtVector, 1, 0 + gs->frameNum*0.0082f);

	va->DrawArrayT(GL_QUADS);

	// this fixes a memory leak on ATI cards
	glBindTexture(GL_TEXTURE_2D, 0);

	glColor3f(1, 1, 1);

//	CCamera* realCam = camera;
//	camera = new CCamera(*realCam);
	char realCam[sizeof(CCamera)];
	new (realCam) CCamera(*camera); // anti-crash workaround for multithreading

	camera->forward.y *= -1.0f;
	camera->SetPos().y *= -1.0f;
	camera->Update();

	reflectFBO.Bind();
	glViewport(0, 0, 512, 512);
	glClear(GL_DEPTH_BUFFER_BIT);

	game->SetDrawMode(CGame::gameReflectionDraw);

	sky->Draw();

	glEnable(GL_CLIP_PLANE2);
	double plane[4] = {0, 1, 0, 0};
	glClipPlane(GL_CLIP_PLANE2, plane);
	drawReflection = true;

	readMap->GetGroundDrawer()->Draw(DrawPass::WaterReflection);
	unitDrawer->Draw(true);
	featureDrawer->Draw();
	unitDrawer->DrawCloakedUnits(true);
	featureDrawer->DrawFadeFeatures(true);
	projectileDrawer->Draw(true);
	eventHandler.DrawWorldReflection();

	game->SetDrawMode(CGame::gameNormalDraw);

	drawReflection = false;
	glDisable(GL_CLIP_PLANE2);

	FBO::Unbind();

	glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY);
	glClearColor(mapInfo->atmosphere.fogColor[0], mapInfo->atmosphere.fogColor[1], mapInfo->atmosphere.fogColor[2], 1);

//	delete camera;
//	camera = realCam;
	camera->~CCamera();
	new (camera) CCamera(*(reinterpret_cast<CCamera*>(realCam)));
	reinterpret_cast<CCamera*>(realCam)->~CCamera();

	camera->Update();
	glPopAttrib();
	glPopAttrib();
}
void CLegacyMeshDrawer::DoDrawGroundRow(const CCamera* cam, int bty)
{
	if (!BigTexSquareRowVisible(cam, bty)) {
		//! skip this entire row of squares if we can't see it
		return;
	}

	CVertexArray* ma = GetVertexArray();

	bool inStrip = false;
	float x0, x1;
	int x,y;
	int sx = 0;
	int ex = smfReadMap->numBigTexX;

	//! only process the necessary big squares in the x direction
	const int bigSquareSizeY = bty * smfReadMap->bigSquareSize;

	const std::vector<CCamera::FrustumLine> negSides = cam->GetNegFrustumSides();
	const std::vector<CCamera::FrustumLine> posSides = cam->GetPosFrustumSides();

	std::vector<CCamera::FrustumLine>::const_iterator fli;

	for (fli = negSides.begin(); fli != negSides.end(); ++fli) {
		x0 = fli->base + fli->dir * bigSquareSizeY;
		x1 = x0 + fli->dir * smfReadMap->bigSquareSize;

		if (x0 > x1)
			x0 = x1;

		x0 /= smfReadMap->bigSquareSize;

		if (x0 > sx)
			sx = (int) x0;
	}
	for (fli = posSides.begin(); fli != posSides.end(); ++fli) {
		x0 = fli->base + fli->dir * bigSquareSizeY + smfReadMap->bigSquareSize;
		x1 = x0 + fli->dir * smfReadMap->bigSquareSize;

		if (x0 < x1)
			x0 = x1;

		x0 /= smfReadMap->bigSquareSize;

		if (x0 < ex)
			ex = (int) x0;
	}

	if (sx > ex)
		return;

	const float cx2 = cam2->GetPos().x / SQUARE_SIZE;
	const float cy2 = cam2->GetPos().z / SQUARE_SIZE;

	for (int btx = sx; btx < ex; ++btx) {
		ma->Initialize();

		for (int lod = 1; lod < neededLod; lod <<= 1) {
			float oldcamxpart = 0.0f;
			float oldcamypart = 0.0f;

			const int hlod = lod >> 1;
			const int dlod = lod << 1;

			int cx = cx2;
			int cy = cy2;

			if (lod > 1) {
				int cxo = (cx / hlod) * hlod;
				int cyo = (cy / hlod) * hlod;
				float cx2o = (cxo / lod) * lod;
				float cy2o = (cyo / lod) * lod;
				oldcamxpart = (cx2 - cx2o) / lod;
				oldcamypart = (cy2 - cy2o) / lod;
			}

			cx = (cx / lod) * lod;
			cy = (cy / lod) * lod;

			const int ysquaremod = (cy % dlod) / lod;
			const int xsquaremod = (cx % dlod) / lod;

			const float camxpart = (cx2 - ((cx / dlod) * dlod)) / dlod;
			const float camypart = (cy2 - ((cy / dlod) * dlod)) / dlod;

			const float mcxp  = 1.0f - camxpart, mcyp  = 1.0f - camypart;
			const float hcxp  = 0.5f * camxpart, hcyp  = 0.5f * camypart;
			const float hmcxp = 0.5f * mcxp,     hmcyp = 0.5f * mcyp;

			const float mocxp  = 1.0f - oldcamxpart, mocyp  = 1.0f - oldcamypart;
			const float hocxp  = 0.5f * oldcamxpart, hocyp  = 0.5f * oldcamypart;
			const float hmocxp = 0.5f * mocxp,       hmocyp = 0.5f * mocyp;

			const int minty = bty * smfReadMap->bigSquareSize, maxty = minty + smfReadMap->bigSquareSize;
			const int mintx = btx * smfReadMap->bigSquareSize, maxtx = mintx + smfReadMap->bigSquareSize;

			const int minly = cy + (-viewRadius + 3 - ysquaremod) * lod;
			const int maxly = cy + ( viewRadius - 1 - ysquaremod) * lod;
			const int minlx = cx + (-viewRadius + 3 - xsquaremod) * lod;
			const int maxlx = cx + ( viewRadius - 1 - xsquaremod) * lod;

			const int xstart = std::max(minlx, mintx), xend = std::min(maxlx, maxtx);
			const int ystart = std::max(minly, minty), yend = std::min(maxly, maxty);

			const int vrhlod = viewRadius * hlod;

			for (y = ystart; y < yend; y += lod) {
				int xs = xstart;
				int xe = xend;

				FindRange(cam2, /*inout*/ xs, /*inout*/ xe, y, lod);

				// If FindRange modifies (xs, xe) to a (less then) empty range,
				// continue to the next row.
				// If we'd continue, nloop (below) would become negative and we'd
				// allocate a vertex array with negative size.  (mantis #1415)
				if (xe < xs) continue;

				int ylod = y + lod;
				int yhlod = y + hlod;
				int nloop = (xe - xs) / lod + 1;

				ma->EnlargeArrays(52 * nloop);

				int yhdx = y * smfReadMap->heightMapSizeX;
				int ylhdx = yhdx + lod * smfReadMap->heightMapSizeX;
				int yhhdx = yhdx + hlod * smfReadMap->heightMapSizeX;

				for (x = xs; x < xe; x += lod) {
					int xlod = x + lod;
					int xhlod = x + hlod;
					//! info: all triangle quads start in the top left corner
					if ((lod == 1) ||
						(x > cx + vrhlod) || (x < cx - vrhlod) ||
						(y > cy + vrhlod) || (y < cy - vrhlod)) {
						//! normal terrain (all vertices in one LOD)
						if (!inStrip) {
							DrawVertexAQ(ma, x, y);
							DrawVertexAQ(ma, x, ylod);
							inStrip = true;
						}

						DrawVertexAQ(ma, xlod, y);
						DrawVertexAQ(ma, xlod, ylod);
					} else {
						//! border between 2 different LODs
						if ((x >= cx + vrhlod)) {
							//! lower LOD to the right
							int idx1 = CLAMP(yhdx + x),  idx1LOD = CLAMP(idx1 + lod), idx1HLOD = CLAMP(idx1 + hlod);
							int idx2 = CLAMP(ylhdx + x), idx2LOD = CLAMP(idx2 + lod), idx2HLOD = CLAMP(idx2 + hlod);
							int idx3 = CLAMP(yhhdx + x),                              idx3HLOD = CLAMP(idx3 + hlod);
							float h1 = (GetVisibleVertexHeight(idx1) + GetVisibleVertexHeight(idx2)) * hmocxp + GetVisibleVertexHeight(idx3) * oldcamxpart;
							float h2 = (GetVisibleVertexHeight(idx1) + GetVisibleVertexHeight(idx1LOD)) * hmocxp + GetVisibleVertexHeight(idx1HLOD) * oldcamxpart;
							float h3 = (GetVisibleVertexHeight(idx2) + GetVisibleVertexHeight(idx1LOD)) * hmocxp + GetVisibleVertexHeight(idx3HLOD) * oldcamxpart;
							float h4 = (GetVisibleVertexHeight(idx2) + GetVisibleVertexHeight(idx2LOD)) * hmocxp + GetVisibleVertexHeight(idx2HLOD) * oldcamxpart;

							if (inStrip) {
								ma->EndStrip();
								inStrip = false;
							}

							DrawVertexAQ(ma, x, y);
							DrawVertexAQ(ma, x, yhlod, h1);
							DrawVertexAQ(ma, xhlod, y, h2);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							ma->EndStrip();
							DrawVertexAQ(ma, x, yhlod, h1);
							DrawVertexAQ(ma, x, ylod);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							DrawVertexAQ(ma, xhlod, ylod, h4);
							ma->EndStrip();
							DrawVertexAQ(ma, xhlod, ylod, h4);
							DrawVertexAQ(ma, xlod, ylod);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							DrawVertexAQ(ma, xlod, y);
							DrawVertexAQ(ma, xhlod, y, h2);
							ma->EndStrip();
						}
						else if ((x <= cx - vrhlod)) {
							//! lower LOD to the left
							int idx1 = CLAMP(yhdx + x),  idx1LOD = CLAMP(idx1 + lod), idx1HLOD = CLAMP(idx1 + hlod);
							int idx2 = CLAMP(ylhdx + x), idx2LOD = CLAMP(idx2 + lod), idx2HLOD = CLAMP(idx2 + hlod);
							int idx3 = CLAMP(yhhdx + x), idx3LOD = CLAMP(idx3 + lod), idx3HLOD = CLAMP(idx3 + hlod);
							float h1 = (GetVisibleVertexHeight(idx1LOD) + GetVisibleVertexHeight(idx2LOD)) * hocxp + GetVisibleVertexHeight(idx3LOD ) * mocxp;
							float h2 = (GetVisibleVertexHeight(idx1   ) + GetVisibleVertexHeight(idx1LOD)) * hocxp + GetVisibleVertexHeight(idx1HLOD) * mocxp;
							float h3 = (GetVisibleVertexHeight(idx2   ) + GetVisibleVertexHeight(idx1LOD)) * hocxp + GetVisibleVertexHeight(idx3HLOD) * mocxp;
							float h4 = (GetVisibleVertexHeight(idx2   ) + GetVisibleVertexHeight(idx2LOD)) * hocxp + GetVisibleVertexHeight(idx2HLOD) * mocxp;

							if (inStrip) {
								ma->EndStrip();
								inStrip = false;
							}

							DrawVertexAQ(ma, xlod, yhlod, h1);
							DrawVertexAQ(ma, xlod, y);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							DrawVertexAQ(ma, xhlod, y, h2);
							ma->EndStrip();
							DrawVertexAQ(ma, xlod, ylod);
							DrawVertexAQ(ma, xlod, yhlod, h1);
							DrawVertexAQ(ma, xhlod, ylod, h4);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							ma->EndStrip();
							DrawVertexAQ(ma, xhlod, y, h2);
							DrawVertexAQ(ma, x, y);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							DrawVertexAQ(ma, x, ylod);
							DrawVertexAQ(ma, xhlod, ylod, h4);
							ma->EndStrip();
						}

						if ((y >= cy + vrhlod)) {
							//! lower LOD above
							int idx1 = yhdx + x,  idx1LOD = CLAMP(idx1 + lod), idx1HLOD = CLAMP(idx1 + hlod);
							int idx2 = ylhdx + x, idx2LOD = CLAMP(idx2 + lod);
							int idx3 = yhhdx + x, idx3LOD = CLAMP(idx3 + lod), idx3HLOD = CLAMP(idx3 + hlod);
							float h1 = (GetVisibleVertexHeight(idx1   ) + GetVisibleVertexHeight(idx1LOD)) * hmocyp + GetVisibleVertexHeight(idx1HLOD) * oldcamypart;
							float h2 = (GetVisibleVertexHeight(idx1   ) + GetVisibleVertexHeight(idx2   )) * hmocyp + GetVisibleVertexHeight(idx3    ) * oldcamypart;
							float h3 = (GetVisibleVertexHeight(idx2   ) + GetVisibleVertexHeight(idx1LOD)) * hmocyp + GetVisibleVertexHeight(idx3HLOD) * oldcamypart;
							float h4 = (GetVisibleVertexHeight(idx2LOD) + GetVisibleVertexHeight(idx1LOD)) * hmocyp + GetVisibleVertexHeight(idx3LOD ) * oldcamypart;

							if (inStrip) {
								ma->EndStrip();
								inStrip = false;
							}

							DrawVertexAQ(ma, x, y);
							DrawVertexAQ(ma, x, yhlod, h2);
							DrawVertexAQ(ma, xhlod, y, h1);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							DrawVertexAQ(ma, xlod, y);
							DrawVertexAQ(ma, xlod, yhlod, h4);
							ma->EndStrip();
							DrawVertexAQ(ma, x, yhlod, h2);
							DrawVertexAQ(ma, x, ylod);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							DrawVertexAQ(ma, xlod, ylod);
							DrawVertexAQ(ma, xlod, yhlod, h4);
							ma->EndStrip();
						}
						else if ((y <= cy - vrhlod)) {
							//! lower LOD beneath
							int idx1 = CLAMP(yhdx + x),  idx1LOD = CLAMP(idx1 + lod);
							int idx2 = CLAMP(ylhdx + x), idx2LOD = CLAMP(idx2 + lod), idx2HLOD = CLAMP(idx2 + hlod);
							int idx3 = CLAMP(yhhdx + x), idx3LOD = CLAMP(idx3 + lod), idx3HLOD = CLAMP(idx3 + hlod);
							float h1 = (GetVisibleVertexHeight(idx2   ) + GetVisibleVertexHeight(idx2LOD)) * hocyp + GetVisibleVertexHeight(idx2HLOD) * mocyp;
							float h2 = (GetVisibleVertexHeight(idx1   ) + GetVisibleVertexHeight(idx2   )) * hocyp + GetVisibleVertexHeight(idx3    ) * mocyp;
							float h3 = (GetVisibleVertexHeight(idx2   ) + GetVisibleVertexHeight(idx1LOD)) * hocyp + GetVisibleVertexHeight(idx3HLOD) * mocyp;
							float h4 = (GetVisibleVertexHeight(idx2LOD) + GetVisibleVertexHeight(idx1LOD)) * hocyp + GetVisibleVertexHeight(idx3LOD ) * mocyp;

							if (inStrip) {
								ma->EndStrip();
								inStrip = false;
							}

							DrawVertexAQ(ma, x, yhlod, h2);
							DrawVertexAQ(ma, x, ylod);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							DrawVertexAQ(ma, xhlod, ylod, h1);
							DrawVertexAQ(ma, xlod, yhlod, h4);
							DrawVertexAQ(ma, xlod, ylod);
							ma->EndStrip();
							DrawVertexAQ(ma, xlod, yhlod, h4);
							DrawVertexAQ(ma, xlod, y);
							DrawVertexAQ(ma, xhlod, yhlod, h3);
							DrawVertexAQ(ma, x, y);
							DrawVertexAQ(ma, x, yhlod, h2);
							ma->EndStrip();
						}
					}
				}

				if (inStrip) {
					ma->EndStrip();
					inStrip = false;
				}
			} //for (y = ystart; y < yend; y += lod)

			const int yst = std::max(ystart - lod, minty);
			const int yed = std::min(yend + lod, maxty);
			int nloop = (yed - yst) / lod + 1;

			if (nloop > 0)
				ma->EnlargeArrays(8 * nloop);

			//! rita yttre begr?snings yta mot n?ta lod
			if (maxlx < maxtx && maxlx >= mintx) {
				x = maxlx;
				int xlod = x + lod;
				for (y = yst; y < yed; y += lod) {
					DrawVertexAQ(ma, x, y);
					DrawVertexAQ(ma, x, y + lod);

					if (y % dlod) {
						const int idx1 = CLAMP((y      ) * smfReadMap->heightMapSizeX + x), idx1LOD = CLAMP(idx1 + lod);
						const int idx2 = CLAMP((y + lod) * smfReadMap->heightMapSizeX + x), idx2LOD = CLAMP(idx2 + lod);
						const int idx3 = CLAMP((y - lod) * smfReadMap->heightMapSizeX + x), idx3LOD = CLAMP(idx3 + lod);
						const float h = (GetVisibleVertexHeight(idx3LOD) + GetVisibleVertexHeight(idx2LOD)) * hmcxp +	GetVisibleVertexHeight(idx1LOD) * camxpart;
						DrawVertexAQ(ma, xlod, y, h);
						DrawVertexAQ(ma, xlod, y + lod);
					} else {
						const int idx1 = CLAMP((y       ) * smfReadMap->heightMapSizeX + x), idx1LOD = CLAMP(idx1 + lod);
						const int idx2 = CLAMP((y +  lod) * smfReadMap->heightMapSizeX + x), idx2LOD = CLAMP(idx2 + lod);
						const int idx3 = CLAMP((y + dlod) * smfReadMap->heightMapSizeX + x), idx3LOD = CLAMP(idx3 + lod);
						const float h = (GetVisibleVertexHeight(idx1LOD) + GetVisibleVertexHeight(idx3LOD)) * hmcxp + GetVisibleVertexHeight(idx2LOD) * camxpart;
						DrawVertexAQ(ma, xlod, y);
						DrawVertexAQ(ma, xlod, y + lod, h);
					}
					ma->EndStrip();
				}
			}

			if (minlx > mintx && minlx < maxtx) {
				x = minlx - lod;
				int xlod = x + lod;
				for (y = yst; y < yed; y += lod) {
					if (y % dlod) {
						int idx1 = CLAMP((y      ) * smfReadMap->heightMapSizeX + x);
						int idx2 = CLAMP((y + lod) * smfReadMap->heightMapSizeX + x);
						int idx3 = CLAMP((y - lod) * smfReadMap->heightMapSizeX + x);
						float h = (GetVisibleVertexHeight(idx3) + GetVisibleVertexHeight(idx2)) * hcxp + GetVisibleVertexHeight(idx1) * mcxp;
						DrawVertexAQ(ma, x, y, h);
						DrawVertexAQ(ma, x, y + lod);
					} else {
						int idx1 = CLAMP((y       ) * smfReadMap->heightMapSizeX + x);
						int idx2 = CLAMP((y +  lod) * smfReadMap->heightMapSizeX + x);
						int idx3 = CLAMP((y + dlod) * smfReadMap->heightMapSizeX + x);
						float h = (GetVisibleVertexHeight(idx1) + GetVisibleVertexHeight(idx3)) * hcxp + GetVisibleVertexHeight(idx2) * mcxp;
						DrawVertexAQ(ma, x, y);
						DrawVertexAQ(ma, x, y + lod, h);
					}
					DrawVertexAQ(ma, xlod, y);
					DrawVertexAQ(ma, xlod, y + lod);
					ma->EndStrip();
				}
			}

			if (maxly < maxty && maxly > minty) {
				y = maxly;
				int xs = std::max(xstart - lod, mintx);
				int xe = std::min(xend + lod,   maxtx);
				FindRange(cam2, xs, xe, y, lod);

				if (xs < xe) {
					x = xs;
					int ylod = y + lod;
					int nloop = (xe - xs) / lod + 2; //! one extra for if statment
					int ylhdx = (y + lod) * smfReadMap->heightMapSizeX;

					ma->EnlargeArrays(2 * nloop);

					if (x % dlod) {
						int idx2 = CLAMP(ylhdx + x), idx2PLOD = CLAMP(idx2 + lod), idx2MLOD = CLAMP(idx2 - lod);
						float h = (GetVisibleVertexHeight(idx2MLOD) + GetVisibleVertexHeight(idx2PLOD)) * hmcyp + GetVisibleVertexHeight(idx2) * camypart;
						DrawVertexAQ(ma, x, y);
						DrawVertexAQ(ma, x, ylod, h);
					} else {
						DrawVertexAQ(ma, x, y);
						DrawVertexAQ(ma, x, ylod);
					}
					for (x = xs; x < xe; x += lod) {
						if (x % dlod) {
							DrawVertexAQ(ma, x + lod, y);
							DrawVertexAQ(ma, x + lod, ylod);
						} else {
							int idx2 = CLAMP(ylhdx + x), idx2PLOD  = CLAMP(idx2 +  lod), idx2PLOD2 = CLAMP(idx2 + dlod);
							float h = (GetVisibleVertexHeight(idx2PLOD2) + GetVisibleVertexHeight(idx2)) * hmcyp + GetVisibleVertexHeight(idx2PLOD) * camypart;
							DrawVertexAQ(ma, x + lod, y);
							DrawVertexAQ(ma, x + lod, ylod, h);
						}
					}
					ma->EndStrip();
				}
			}

			if (minly > minty && minly < maxty) {
				y = minly - lod;
				int xs = std::max(xstart - lod, mintx);
				int xe = std::min(xend + lod,   maxtx);
				FindRange(cam2, xs, xe, y, lod);

				if (xs < xe) {
					x = xs;
					int ylod = y + lod;
					int yhdx = y * smfReadMap->heightMapSizeX;
					int nloop = (xe - xs) / lod + 2; //! one extra for if statment

					ma->EnlargeArrays(2 * nloop);

					if (x % dlod) {
						int idx1 = CLAMP(yhdx + x), idx1PLOD = CLAMP(idx1 + lod), idx1MLOD = CLAMP(idx1 - lod);
						float h = (GetVisibleVertexHeight(idx1MLOD) + GetVisibleVertexHeight(idx1PLOD)) * hcyp + GetVisibleVertexHeight(idx1) * mcyp;
						DrawVertexAQ(ma, x, y, h);
						DrawVertexAQ(ma, x, ylod);
					} else {
						DrawVertexAQ(ma, x, y);
						DrawVertexAQ(ma, x, ylod);
					}

					for (x = xs; x < xe; x+= lod) {
						if (x % dlod) {
							DrawVertexAQ(ma, x + lod, y);
							DrawVertexAQ(ma, x + lod, ylod);
						} else {
							int idx1 = CLAMP(yhdx + x), idx1PLOD  = CLAMP(idx1 +  lod), idx1PLOD2 = CLAMP(idx1 + dlod);
							float h = (GetVisibleVertexHeight(idx1PLOD2) + GetVisibleVertexHeight(idx1)) * hcyp + GetVisibleVertexHeight(idx1PLOD) * mcyp;
							DrawVertexAQ(ma, x + lod, y, h);
							DrawVertexAQ(ma, x + lod, ylod);
						}
					}
					ma->EndStrip();
				}
			}

		} //for (int lod = 1; lod < neededLod; lod <<= 1)

		smfGroundDrawer->SetupBigSquare(btx, bty);
		DrawGroundVertexArrayQ(ma);
	}
}
Example #3
0
void CMiniMap::DrawForReal(bool use_geo)
{
	SCOPED_TIMER("MiniMap::DrawForReal");

	//glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glPushAttrib(GL_DEPTH_BUFFER_BIT);
	glDisable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glDepthMask(GL_FALSE);
	glDisable(GL_TEXTURE_2D);
	glMatrixMode(GL_MODELVIEW);

	if (minimized) {
		if (!slaveDrawMode) {
			DrawMinimizedButton();
		}
		glPopAttrib();
		glEnable(GL_TEXTURE_2D);
		return;
	}

	// draw the frameborder
	if (!slaveDrawMode && !globalRendering->dualScreenMode && !maximized) {
		glEnable(GL_BLEND);
		DrawFrame();
		glDisable(GL_BLEND);
	}


	bool resetTextureMatrix = false;

	if (use_geo) {
		glPushMatrix();

		// switch to normalized minimap coords
		if (globalRendering->dualScreenMode) {
			glViewport(xpos, ypos, width, height);
			glScalef(width * globalRendering->pixelX, height * globalRendering->pixelY, 1.0f);
		} else {
			glTranslatef(xpos * globalRendering->pixelX, ypos * globalRendering->pixelY, 0.0f);
			glScalef(width * globalRendering->pixelX, height * globalRendering->pixelY, 1.0f);
		}

		/* FIXME: fix mouse handling too and make it fully customizable, so Lua can rotate the minimap to any angle
		CCameraController* camController = &camHandler->GetCurrentController();
		COverheadController* taCam = dynamic_cast<COverheadController*>(camController);
		SmoothController* smCam = dynamic_cast<SmoothController*>(camController);

		if ((taCam && taCam->flipped) || (smCam && smCam->flipped)) {
			glTranslatef(1.0f, 1.0f, 0.0f);
			glScalef(-1.0f, -1.0f, 1.0f);

			glMatrixMode(GL_TEXTURE);
			glPushMatrix();
			glTranslatef(1.0f, 1.0f, 0.0f);
			glScalef(-1.0f, -1.0f, 1.0f);
			glMatrixMode(GL_MODELVIEW);

			resetTextureMatrix = true;
		}*/
	}

	setSurfaceCircleFunc(DrawSurfaceCircle);
	setSurfaceSquareFunc(DrawSurfaceSquare);
	cursorIcons.Enable(false);

	glColor4f(0.6f, 0.6f, 0.6f, 1.0f);

	// don't mirror the map texture with flipped cameras
	glMatrixMode(GL_TEXTURE);
	glPushMatrix();
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);

	// draw the map
	glDisable(GL_BLEND);
		readmap->DrawMinimap();
	glEnable(GL_BLEND);

	glMatrixMode(GL_TEXTURE);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);

	// clip everything outside of the minimap box
	{
		const double plane0[4] = {0,-1,0,1};
		const double plane1[4] = {0,1,0,0};
		const double plane2[4] = {-1,0,0,1};
		const double plane3[4] = {1,0,0,0};

		glClipPlane(GL_CLIP_PLANE0, plane0); // clip bottom
		glClipPlane(GL_CLIP_PLANE1, plane1); // clip top
		glClipPlane(GL_CLIP_PLANE2, plane2); // clip right
		glClipPlane(GL_CLIP_PLANE3, plane3); // clip left

		glEnable(GL_CLIP_PLANE0);
		glEnable(GL_CLIP_PLANE1);
		glEnable(GL_CLIP_PLANE2);
		glEnable(GL_CLIP_PLANE3);
	}

	// switch to top-down map/world coords (z is twisted with y compared to the real map/world coords)
	glPushMatrix();
	glTranslatef(0.0f, +1.0f, 0.0f);
	glScalef(+1.0f / (gs->mapx * SQUARE_SIZE), -1.0f / (gs->mapy * SQUARE_SIZE), 1.0f);

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.0f);

	{
		GML_RECMUTEX_LOCK(unit); // DrawForReal
		unitDrawer->DrawUnitMiniMapIcons();
	}

	glDisable(GL_ALPHA_TEST);
	glDisable(GL_TEXTURE_2D);

	glPushMatrix();
	glRotatef(-90.0f, +1.0f, 0.0f, 0.0f); // real 'world' coordinates
	glScalef(1.0f, 0.0f, 1.0f); // skip the y-coord (Lua's DrawScreen is perspective and so any z-coord in it influence the x&y, too)

	// draw the projectiles
	if (drawProjectiles) {
		glPointSize(1.0f);
		WorkaroundATIPointSizeBug();
		projectileDrawer->DrawProjectilesMiniMap();
	}

	// draw the queued commands
	//
	// NOTE: this needlessly adds to the CursorIcons list, but at least
	//       they are not drawn  (because the input receivers are drawn
	//       after the command queues)

	LuaUnsyncedCtrl::DrawUnitCommandQueues();
	if ((drawCommands > 0) && guihandler->GetQueueKeystate()) {
		selectedUnits.DrawCommands();
	}

	lineDrawer.DrawAll();

	// draw the selection shape, and some ranges
	if (drawCommands > 0) {
		guihandler->DrawMapStuff(!!drawCommands);
	}

	{
		GML_RECMUTEX_LOCK(sel); // DrawForReal

		// draw unit ranges
		const float radarSquare = radarhandler->radarDiv;
		CUnitSet& selUnits = selectedUnits.selectedUnits;
		for(CUnitSet::iterator si = selUnits.begin(); si != selUnits.end(); ++si) {
			CUnit* unit = *si;
			if (unit->radarRadius && !unit->beingBuilt && unit->activated) {
				glColor3fv(cmdColors.rangeRadar);
				DrawCircle(unit->pos, (unit->radarRadius * radarSquare));
			}
			if (unit->sonarRadius && !unit->beingBuilt && unit->activated) {
				glColor3fv(cmdColors.rangeSonar);
				DrawCircle(unit->pos, (unit->sonarRadius * radarSquare));
			}
			if (unit->jammerRadius && !unit->beingBuilt && unit->activated) {
				glColor3fv(cmdColors.rangeJammer);
				DrawCircle(unit->pos, (unit->jammerRadius * radarSquare));
			}
			// change if someone someday create a non stockpiled interceptor
			const CWeapon* w = unit->stockpileWeapon;
			if((w != NULL) && w->weaponDef->interceptor) {
				if (w->numStockpiled) {
					glColor3fv(cmdColors.rangeInterceptorOn);
				} else {
					glColor3fv(cmdColors.rangeInterceptorOff);
				}
				DrawCircle(unit->pos, w->weaponDef->coverageRange);
			}
		}
	}

	glPopMatrix(); // revert to the 2d xform

	if (!minimap->maximized) {
		// draw the camera frustum lines
		cam2->GetFrustumSides(0.0f, 0.0f, 1.0f, true);
		cam2->ClipFrustumLines(true, -10000.0f, 400096.0f);

		const std::vector<CCamera::FrustumLine>& negSides = cam2->negFrustumSides;
//		const std::vector<CCamera::FrustumLine>& posSides = cam2->posFrustumSides;
		std::vector<CCamera::FrustumLine>::const_iterator fli;

		CVertexArray* va = GetVertexArray();
		va->Initialize();
		va->EnlargeArrays(negSides.size() * 2, 0, VA_SIZE_2D0);

		for (fli = negSides.begin(); fli != negSides.end(); ++fli) {
			if (fli->minz < fli->maxz) {
				va->AddVertex2dQ0(fli->base + (fli->dir * fli->minz), fli->minz);
				va->AddVertex2dQ0(fli->base + (fli->dir * fli->maxz), fli->maxz);
			}
		}

		glLineWidth(2.5f);
		glColor4f(0, 0, 0, 0.5f);
		va->DrawArray2d0(GL_LINES);

		glLineWidth(1.5f);
		glColor4f(1, 1, 1, 0.75f);
		va->DrawArray2d0(GL_LINES);
		glLineWidth(1.0f);
	}


	// selection box
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	CMouseHandler::ButtonPressEvt& bp = mouse->buttons[SDL_BUTTON_LEFT];
	if (selecting && fullProxy && (bp.movement > 4)) {
		const float3 oldPos = GetMapPosition(bp.x, bp.y);
		const float3 newPos = GetMapPosition(mouse->lastx, mouse->lasty);
		glColor4fv(cmdColors.mouseBox);
		glBlendFunc((GLenum)cmdColors.MouseBoxBlendSrc(),
		            (GLenum)cmdColors.MouseBoxBlendDst());
		glLineWidth(cmdColors.MouseBoxLineWidth());

		float verts[] = {
			oldPos.x, oldPos.z,
			newPos.x, oldPos.z,
			newPos.x, newPos.z,
			oldPos.x, newPos.z,
		};
		glEnableClientState(GL_VERTEX_ARRAY);
		glVertexPointer(2, GL_FLOAT, 0, verts);
		glDrawArrays(GL_LINE_LOOP, 0, 4);
		glDisableClientState(GL_VERTEX_ARRAY);

		glLineWidth(1.0f);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

	DrawNotes();

	// reset 1
	if (resetTextureMatrix) {
		glMatrixMode(GL_TEXTURE_MATRIX);
		glPopMatrix();
	}
	glMatrixMode(GL_MODELVIEW);
	if (use_geo) {
		glPopMatrix();
	}

	// reset 2
	glPopMatrix();
	glPopAttrib();
	glEnable(GL_TEXTURE_2D);

	{
		//! prepare ClipPlanes for Lua's DrawInMinimap Modelview matrix

		//! quote from glClipPlane spec:
		//! "When glClipPlane is called, equation is transformed by the inverse of the modelview matrix and stored in the resulting eye coordinates.
		//!  Subsequent changes to the modelview matrix have no effect on the stored plane-equation components."
		//! -> we have to use the same modelview matrix when calling glClipPlane and later draw calls

		//! set the modelview matrix to the same as used in Lua's DrawInMinimap
		glPushMatrix();
		glLoadIdentity();
		glScalef(1.0f / width, 1.0f / height, 1.0f);

		const double plane0[4] = {0, -1, 0, double(height)};
		const double plane1[4] = {0, 1, 0, 0};
		const double plane2[4] = {-1, 0, 0, double(width)};
		const double plane3[4] = {1, 0, 0, 0};

		glClipPlane(GL_CLIP_PLANE0, plane0); // clip bottom
		glClipPlane(GL_CLIP_PLANE1, plane1); // clip top
		glClipPlane(GL_CLIP_PLANE2, plane2); // clip right
		glClipPlane(GL_CLIP_PLANE3, plane3); // clip left

		glPopMatrix();
	}

	//! allow the LUA scripts to draw into the minimap
	eventHandler.DrawInMiniMap();

	if (use_geo && globalRendering->dualScreenMode)
		glViewport(globalRendering->viewPosX,0,globalRendering->viewSizeX,globalRendering->viewSizeY);

	//FIXME: Lua modifies the matrices w/o reseting it! (quite complexe to fix because ClearMatrixStack() makes it impossible to use glPushMatrix)
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0,1,0,1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	// disable ClipPlanes
	glDisable(GL_CLIP_PLANE0);
	glDisable(GL_CLIP_PLANE1);
	glDisable(GL_CLIP_PLANE2);
	glDisable(GL_CLIP_PLANE3);

	cursorIcons.Enable(true);
	setSurfaceCircleFunc(NULL);
	setSurfaceSquareFunc(NULL);
}
Example #4
0
void CPieceProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points)
{
	points.AddVertexQC(pos, color4::red);
}
void CSelectedUnits::Draw()
{
	glDisable(GL_TEXTURE_2D);
	glDepthMask(false);
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND); // for line smoothing
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glLineWidth(cmdColors.UnitBoxLineWidth());

	GML_RECMUTEX_LOCK(grpsel); // Draw

	if (cmdColors.unitBox[3] > 0.05f) {
		const CUnitSet* unitSet;
		if (selectedGroup != -1) {
			unitSet = &grouphandlers[gu->myTeam]->groups[selectedGroup]->units;
		} else {
			unitSet = &selectedUnits;
		}

		CVertexArray* va = GetVertexArray();
		va->Initialize();
		va->EnlargeArrays(unitSet->size() * 8, 0, VA_SIZE_C);

		for (CUnitSet::const_iterator ui = unitSet->begin(); ui != unitSet->end(); ++ui) {
			const CUnit* unit = *ui;
			if (unit->isIcon) {
				continue;
			}

			const int
				uhxsize = (unit->xsize * SQUARE_SIZE) >> 1,
				uhzsize = (unit->zsize * SQUARE_SIZE) >> 1,
				mhxsize = (unit->mobility == NULL)? uhxsize: ((unit->mobility->xsize * SQUARE_SIZE) >> 1),
				mhzsize = (unit->mobility == NULL)? uhzsize: ((unit->mobility->zsize * SQUARE_SIZE) >> 1);
			const float3 verts[8] = {
				// UnitDef footprint corners
				float3(unit->drawPos.x + uhxsize, unit->drawPos.y, unit->drawPos.z + uhzsize),
				float3(unit->drawPos.x - uhxsize, unit->drawPos.y, unit->drawPos.z + uhzsize),
				float3(unit->drawPos.x - uhxsize, unit->drawPos.y, unit->drawPos.z - uhzsize),
				float3(unit->drawPos.x + uhxsize, unit->drawPos.y, unit->drawPos.z - uhzsize),
				// MoveDef footprint corners
				float3(unit->drawPos.x + mhxsize, unit->drawPos.y, unit->drawPos.z + mhzsize),
				float3(unit->drawPos.x - mhxsize, unit->drawPos.y, unit->drawPos.z + mhzsize),
				float3(unit->drawPos.x - mhxsize, unit->drawPos.y, unit->drawPos.z - mhzsize),
				float3(unit->drawPos.x + mhxsize, unit->drawPos.y, unit->drawPos.z - mhzsize),
			};

			const unsigned char colors[2][4] = {
				{(0.0f + cmdColors.unitBox[0]) * 255, (0.0f + cmdColors.unitBox[1]) * 255, (0.0f + cmdColors.unitBox[2] * 255), cmdColors.unitBox[3] * 255},
				{(1.0f - cmdColors.unitBox[0]) * 255, (1.0f - cmdColors.unitBox[1]) * 255, (1.0f - cmdColors.unitBox[2] * 255), cmdColors.unitBox[3] * 255},
			};

			va->AddVertexQC(verts[0], colors[0]);
			va->AddVertexQC(verts[1], colors[0]);
			va->AddVertexQC(verts[2], colors[0]);
			va->AddVertexQC(verts[3], colors[0]);

			if (globalRendering->drawdebug && (mhxsize != uhxsize || mhzsize != uhzsize)) {
				va->AddVertexQC(verts[4], colors[1]);
				va->AddVertexQC(verts[5], colors[1]);
				va->AddVertexQC(verts[6], colors[1]);
				va->AddVertexQC(verts[7], colors[1]);
			}
		}

		va->DrawArrayC(GL_QUADS);
	}

	// highlight queued build sites if we are about to build something
	// (or old-style, whenever the shift key is being held down)
	if (cmdColors.buildBox[3] > 0.0f) {
		if (!selectedUnits.empty() &&
				((cmdColors.BuildBoxesOnShift() && keyInput->IsKeyPressed(SDLK_LSHIFT)) ||
				 ((guihandler->inCommand >= 0) &&
					(guihandler->inCommand < int(guihandler->commands.size())) &&
					(guihandler->commands[guihandler->inCommand].id < 0)))) {

			GML_STDMUTEX_LOCK(cai); // Draw

			bool myColor = true;
			glColor4fv(cmdColors.buildBox);
			std::list<CBuilderCAI*>::const_iterator bi;
			for (bi = uh->builderCAIs.begin(); bi != uh->builderCAIs.end(); ++bi) {
				CBuilderCAI* builder = *bi;
				if (builder->owner->team == gu->myTeam) {
					if (!myColor) {
						glColor4fv(cmdColors.buildBox);
						myColor = true;
					}
					builder->DrawQuedBuildingSquares();
				}
				else if (teamHandler->AlliedTeams(builder->owner->team, gu->myTeam)) {
					if (myColor) {
						glColor4fv(cmdColors.allyBuildBox);
						myColor = false;
					}
					builder->DrawQuedBuildingSquares();
				}
			}
		}
	}

	glLineWidth(1.0f);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
	glDepthMask(true);
	glEnable(GL_TEXTURE_2D);
}
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;

	const CMapInfo::light_t& light = mapInfo->light;

	glEnable(GL_ALPHA_TEST);
	glEnable(GL_TEXTURE_2D);

	ISky::SetupFog();

	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, light.groundAmbientColor.x, light.groundAmbientColor.y, light.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) {
				const int mx = gs->pwr2mapx * SQUARE_SIZE;
				const int 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);
			}
		}


		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, light.groundSunColor.x,     light.groundSunColor.y,     light.groundSunColor.z,     0.85f);
			treeShader->SetUniform4f(14, light.groundAmbientColor.x, light.groundAmbientColor.y, light.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);

		CVertexArray* va = GetVertexArray();
		va->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;
				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) {
					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
						CAdvTreeDrawer::DrawTreeVertex(va, 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
		va->DrawArrayT(GL_QUADS);

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

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

			glAlphaFunc(GL_GREATER, 1.0f - (pFTree->relDist * 0.5f));
			va->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;
			}
		}
	}
}
void CAdvTreeDrawer::DrawShadowPass()
{
	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);

		CVertexArray* va = GetVertexArray();
		va->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;
				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) {
					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 {
						CAdvTreeDrawer::DrawTreeVertex(va, 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);
		va->DrawArrayT(GL_QUADS);

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

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

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

		po->Disable();
	}

	glEnable(GL_CULL_FACE);
	glDisable(GL_POLYGON_OFFSET_FILL);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_ALPHA_TEST);
}
Example #8
0
static void DrawFrameBarcode()
{
	const float maxHist_f = 0.5f;
	const spring_time curTime = spring_now();
	const spring_time maxHist = spring_secs(maxHist_f);
	float drawArea[4] = {0.01f, 0.2f, start_x - 0.05f, 0.25f};

	// background
	CVertexArray* va = GetVertexArray();
	va->Initialize();
		va->AddVertex0(drawArea[0] - 10 * globalRendering->pixelX, drawArea[1] - 10 * globalRendering->pixelY, 0.0f);
		va->AddVertex0(drawArea[0] - 10 * globalRendering->pixelX, drawArea[3] + 20 * globalRendering->pixelY, 0.0f);
		va->AddVertex0(drawArea[2] + 10 * globalRendering->pixelX, drawArea[3] + 20 * globalRendering->pixelY, 0.0f);
		va->AddVertex0(drawArea[2] + 10 * globalRendering->pixelX, drawArea[1] - 10 * globalRendering->pixelY, 0.0f);
	glColor4f(0.0f,0.0f,0.0f, 0.5f);
	va->DrawArray0(GL_QUADS);

	// title and legend
	font->glFormat(drawArea[0], drawArea[3] + 10 * globalRendering->pixelY, 0.7f, FONT_TOP | DBG_FONT_FLAGS,
			"Frame Grapher (%.2fsec)"
			"\xff\xff\x80\xff  GC"
			"\xff\xff\xff\x01  Unsynced"
			"\xff\x01\x01\xff  Swap"
			"\xff\x01\xff\x01  Video"
			"\xff\xff\x01\x01  Sim"
			, maxHist_f);

	// gc frames
	glColor4f(1.0f,0.5f,1.0f, 0.55f);
	DrawTimeSlice(lgcFrames, curTime, maxHist, drawArea);

	// updateunsynced frames
	glColor4f(1.0f,1.0f,0.0f, 0.9f);
	DrawTimeSlice(uusFrames, curTime, maxHist, drawArea);

	// video swap frames
	glColor4f(0.0f,0.0f,1.0f, 0.55f);
	DrawTimeSlice(swpFrames, curTime, maxHist, drawArea);

	// video frames
	glColor4f(0.0f,1.0f,0.0f, 0.55f);
	DrawTimeSlice(vidFrames, curTime, maxHist, drawArea);

	// sim frames
	glColor4f(1.0f,0.0f,0.0f, 0.55f);
	DrawTimeSlice(simFrames, curTime, maxHist, drawArea);

	// draw `feeder` indicating current time pos
	//CVertexArray* va = GetVertexArray();
	va->Initialize();
		// draw feeder
		const float r = (curTime % maxHist).toSecsf() / maxHist_f;
		const float xf = drawArea[0] + r * (drawArea[2] - drawArea[0]);
		va->AddVertex0(xf, drawArea[1], 0.0f);
		va->AddVertex0(xf, drawArea[3], 0.0f);
		va->AddVertex0(xf + 10 * globalRendering->pixelX, drawArea[3], 0.0f);
		va->AddVertex0(xf + 10 * globalRendering->pixelX, drawArea[1], 0.0f);

		// draw scale (horizontal bar that indicates 30FPS timing length)
		const float xs1 = drawArea[2] - 1.f/(30.f*maxHist_f) * (drawArea[2] - drawArea[0]);
		const float xs2 = drawArea[2] +               0.0f * (drawArea[2] - drawArea[0]);
		va->AddVertex0(xs1, drawArea[3] +  2 * globalRendering->pixelY, 0.0f);
		va->AddVertex0(xs1, drawArea[3] + 10 * globalRendering->pixelY, 0.0f);
		va->AddVertex0(xs2, drawArea[3] + 10 * globalRendering->pixelY, 0.0f);
		va->AddVertex0(xs2, drawArea[3] +  2 * globalRendering->pixelY, 0.0f);
	glColor4f(1.0f,0.0f,0.0f, 1.0f);
	va->DrawArray0(GL_QUADS);
}
Example #9
0
static void DrawProfiler()
{
	font->SetTextColor(1,1,1,1);
	CVertexArray* va  = GetVertexArray();
	CVertexArray* va2 = GetVertexArray();

	// draw the background of the window
	if(!profiler.profile.empty()){
		va->Initialize();
			va->AddVertex0(start_x, end_y,                                      0);
			va->AddVertex0(end_x,   end_y,                                      0);
			va->AddVertex0(start_x, end_y-profiler.profile.size()*0.024f-0.01f, 0);
			va->AddVertex0(end_x,   end_y-profiler.profile.size()*0.024f-0.01f, 0);
		glColor4f(0.0f, 0.0f, 0.5f, 0.5f);
		va->DrawArray0(GL_TRIANGLE_STRIP);
	}

	std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi;

	// draw the textual info (total-time, short-time percentual time, timer-name)
	int y = 0;
	for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) {
		const float fStartY = start_y - y * 0.024f;
		float fStartX = start_x + 0.005f + 0.015f + 0.005f;

		// print total-time running since application start
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2fs", pi->second.total.toSecsf());

		// print percent of CPU time used within the last 500ms
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2f%%", pi->second.percent * 100);
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.2f%%", pi->second.newPeak?1:255, pi->second.newPeak?1:255, pi->second.peak * 100);
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.0fms", pi->second.newLagPeak?1:255, pi->second.newLagPeak?1:255, pi->second.maxLag);

		// print timer name
		fStartX += 0.01f;
		font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM, pi->first);
	}


	// draw the Timer selection boxes
	glPushMatrix();
	glTranslatef(start_x + 0.005f, start_y, 0);
	glScalef(0.015f, 0.02f, 0.02f);
		va->Initialize();
		va2->Initialize();
			int i = 0;
			for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++i){
				auto& fc = pi->second.color;
				SColor c(fc[0], fc[1], fc[2]);
				va->AddVertexC(float3(0, 0 - i * 1.2f, 0), c);
				va->AddVertexC(float3(1, 0 - i * 1.2f, 0), c);
				va->AddVertexC(float3(1, 1 - i * 1.2f, 0), c);
				va->AddVertexC(float3(0, 1 - i * 1.2f, 0), c);

				if (!pi->second.showGraph) {
					va2->AddVertex0(0, 0 - i * 1.2f, 0);
					va2->AddVertex0(1, 1 - i * 1.2f, 0);
					va2->AddVertex0(1, 0 - i * 1.2f, 0);
					va2->AddVertex0(0, 1 - i * 1.2f, 0);
				}
			}
		// draw the boxes
		va->DrawArrayC(GL_QUADS);
		// draw the 'graph view disabled' cross
		glColor3f(1,0,0);
		va2->DrawArray0(GL_LINES);
	glPopMatrix();

	// draw the graph
	glLineWidth(3.0f);
	for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi) {
		if (!pi->second.showGraph) {
			continue;
		}
		va->Initialize();
		const float steps_x = (end_x - start_x) / CTimeProfiler::TimeRecord::frames_size;
		for (size_t a=0; a < CTimeProfiler::TimeRecord::frames_size; ++a) {
			// profile runtime; eg 0.5f means: uses 50% of a CPU (during that frame)
			// This may be more then 1.0f, in case an operation
			// which ran over many frames, ended in this one.
			const float p = pi->second.frames[a].toSecsf() * GAME_SPEED;
			const float x = start_x + (a * steps_x);
			const float y = 0.02f + (p * 0.96f);
			va->AddVertex0(x, y, 0.0f);
		}

		glColorf3((float3)pi->second.color);
		va->DrawArray0(GL_LINE_STRIP);
	}
	glLineWidth(1.0f);
}
Example #10
0
void CFarTextureHandler::Draw()
{
	if (queuedForRender.empty()) {
		return;
	}

	{
		// check if there is enough free space in the atlas, if not try resizing
		// it (as many times as the number of models queued for iconification)
		unsigned int maxNewIcons = 0;

		for (unsigned int n = 0; n < queuedForRender.size(); n++) {
			if (!CheckResizeAtlas(n + 1)) { break; } maxNewIcons++;
		}

		// now create the new far-icons
		// NOTE:
		//    the icons are RTT'ed using a snapshot of the
		//    current state (advModelShading, sunDir, etc)
		//    and will not track later state-changes
		unitDrawer->SetupForUnitDrawing();

		GML_VECTOR<const CSolidObject*>::iterator it;

		for (it = queuedForRender.begin(); it != queuedForRender.end() && maxNewIcons > 0; ++it) {
			maxNewIcons--;

			const CSolidObject* obj = *it;
			const S3DModel* mdl = obj->model;

			unitDrawer->GetOpaqueModelRenderer(mdl->type)->PushRenderState();
			unitDrawer->SetTeamColour(obj->team);

			if (mdl->type != MODELTYPE_3DO) {
				texturehandlerS3O->SetS3oTexture(mdl->textureType);
			}

			if ((int)cache.size() <= obj->team || (int)cache[obj->team].size() <= mdl->id || !cache[obj->team][mdl->id]) {
				CreateFarTexture(obj);
			}

			unitDrawer->GetOpaqueModelRenderer(mdl->type)->PopRenderState();
		}

		unitDrawer->CleanUpUnitDrawing();
	}

	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.5f);
	glActiveTexture(GL_TEXTURE0);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, farTextureID);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x);

	ISky::SetupFog();

	CVertexArray* va = GetVertexArray();
	va->Initialize();
	va->EnlargeArrays(queuedForRender.size() * 4, 0, VA_SIZE_T);
	for (GML_VECTOR<const CSolidObject*>::iterator it = queuedForRender.begin(); it != queuedForRender.end(); ++it) {
		DrawFarTexture(*it, va);
	}

	va->DrawArrayT(GL_QUADS);
	glDisable(GL_ALPHA_TEST);

	queuedForRender.clear();
}
Example #11
0
void CFeatureDrawer::Draw()
{
	drawFar.clear();

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


	GML_RECMUTEX_LOCK(feat); // Draw

	fadeFeatures.clear();
	fadeFeaturesS3O.clear();

	CBaseGroundDrawer *gd = readmap->GetGroundDrawer();
	if (gd->DrawExtraTex()) {
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glEnable(GL_TEXTURE_2D);
		glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB);
		glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);

		SetTexGen(1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,0);

		glBindTexture(GL_TEXTURE_2D, gd->infoTex);
		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	unitDrawer->SetupForUnitDrawing();
		unitDrawer->SetupFor3DO();
			DrawRaw(0, &drawFar);
		unitDrawer->CleanUp3DO();
		unitDrawer->DrawQuedS3O();
	unitDrawer->CleanUpUnitDrawing();

	if (drawFar.size()>0) {
		glAlphaFunc(GL_GREATER, 0.5f);
		glEnable(GL_ALPHA_TEST);
		glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID());
		glColor3f(1.0f, 1.0f, 1.0f);
		glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x);

		CVertexArray* va = GetVertexArray();
		va->Initialize();
		va->EnlargeArrays(drawFar.size() * 4, 0, VA_SIZE_T);
		for (vector<CFeature*>::iterator it = drawFar.begin(); it != drawFar.end(); ++it) {
			fartextureHandler->DrawFarTexture(camera, (*it)->model, (*it)->pos, (*it)->radius, (*it)->heading, va);
		}
		va->DrawArrayT(GL_QUADS);

		glDisable(GL_ALPHA_TEST);
	}

	if (gd->DrawExtraTex()) {
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_FOG);

	if(drawStat.size() > 0) {
		if(!water->drawReflection) {
			for (vector<CFeature *>::iterator fi = drawStat.begin(); fi != drawStat.end(); ++fi)
				DrawFeatureStats(*fi);
		}
		drawStat.clear();
	}
}
Example #12
0
void CProjectileDrawer::UpdatePerlin() {
	perlinFB.Bind();
	glViewport(perlintex->xstart * textureAtlas->xsize, perlintex->ystart * textureAtlas->ysize, 128, 128);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho(0, 1,  0, 1,  -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glDisable(GL_DEPTH_TEST);
	glDepthMask(GL_FALSE);
	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 = globalRendering->lastFrameTime * gs->speedFactor * 3;
	float speed = 1.0f;
	float size = 1.0f;

	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.0f / size;

		if (a == 0)
			glDisable(GL_BLEND);

		CVertexArray* va = GetVertexArray();
		va->Initialize();
		va->CheckInitSize(4 * VA_SIZE_TC, 0);

		for (int b = 0; b < 4; ++b)
			col[b] = int((1.0f - perlinBlend[a]) * 16 * size);

		glBindTexture(GL_TEXTURE_2D, perlinTex[a * 2]);
		va->AddVertexQTC(float3(0, 0, 0), 0,         0, col);
		va->AddVertexQTC(float3(0, 1, 0), 0,     tsize, col);
		va->AddVertexQTC(float3(1, 1, 0), tsize, tsize, col);
		va->AddVertexQTC(float3(1, 0, 0), tsize,     0, col);
		va->DrawArrayTC(GL_QUADS);

		if (a == 0)
			glEnable(GL_BLEND);

		va = GetVertexArray();
		va->Initialize();
		va->CheckInitSize(4 * VA_SIZE_TC, 0);

		for (int b = 0; b < 4; ++b)
			col[b] = int(perlinBlend[a] * 16 * size);

		glBindTexture(GL_TEXTURE_2D, perlinTex[a * 2 + 1]);
		va->AddVertexQTC(float3(0, 0, 0),     0,     0, col);
		va->AddVertexQTC(float3(0, 1, 0),     0, tsize, col);
		va->AddVertexQTC(float3(1, 1, 0), tsize, tsize, col);
		va->AddVertexQTC(float3(1, 0, 0), tsize,     0, col);
		va->DrawArrayTC(GL_QUADS);

		speed *= 0.6f;
		size *= 2;
	}

	perlinFB.Unbind();
	glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY);

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);

	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
}
Example #13
0
void CProjectileDrawer::DrawProjectilesMiniMap()
{
	GML_RECMUTEX_LOCK(proj); // DrawProjectilesMiniMap

	typedef std::set<CProjectile*> ProjectileSet;
	typedef std::set<CProjectile*>::const_iterator ProjectileSetIt;
	typedef std::map<int, ProjectileSet> ProjectileBin;
	typedef std::map<int, ProjectileSet>::const_iterator ProjectileBinIt;

	for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
		const ProjectileBin& projectileBin = modelRenderers[modelType]->GetProjectileBin();

		if (!projectileBin.empty()) {

			for (ProjectileBinIt binIt = projectileBin.begin(); binIt != projectileBin.end(); ++binIt) {
				CVertexArray* lines = GetVertexArray();
				CVertexArray* points = GetVertexArray();

				lines->Initialize();
				lines->EnlargeArrays((binIt->second).size() * 2, 0, VA_SIZE_C);
				points->Initialize();
				points->EnlargeArrays((binIt->second).size(), 0, VA_SIZE_C);

				for (ProjectileSetIt setIt = (binIt->second).begin(); setIt != (binIt->second).end(); ++setIt) {
					CProjectile* p = *setIt;

					CUnit *owner = p->owner();
					if ((owner && (owner->allyteam == gu->myAllyTeam)) ||
						gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) {
							p->DrawOnMinimap(*lines, *points);
					}
				}

				lines->DrawArrayC(GL_LINES);
				points->DrawArrayC(GL_POINTS);
			}

		}
	}

	if (!renderProjectiles.empty()) {
		CVertexArray* lines = GetVertexArray();
		CVertexArray* points = GetVertexArray();

		lines->Initialize();
		lines->EnlargeArrays(renderProjectiles.size() * 2, 0, VA_SIZE_C);

		points->Initialize();
		points->EnlargeArrays(renderProjectiles.size(), 0, VA_SIZE_C);

		for (std::set<CProjectile*>::iterator it = renderProjectiles.begin(); it != renderProjectiles.end(); ++it) {
			CProjectile* p = *it;

			const CUnit* owner = p->owner();
			if ((owner && (owner->allyteam == gu->myAllyTeam)) ||
				gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) {
				p->DrawOnMinimap(*lines, *points);
			}
		}

		lines->DrawArrayC(GL_LINES);
		points->DrawArrayC(GL_POINTS);
	}
}
Example #14
0
static void DrawProfiler()
{
	font->SetTextColor(1,1,1,1);

	// draw the background of the window
	{
		CVertexArray* va  = GetVertexArray();
		va->Initialize();
			va->AddVertex0(start_x, start_y + lineHeight + 0.005f,                          0);
			va->AddVertex0(end_x,   start_y + lineHeight + 0.005f,                          0);
			va->AddVertex0(start_x, start_y - profiler.profile.size() * lineHeight - 0.01f, 0);
			va->AddVertex0(end_x,   start_y - profiler.profile.size() * lineHeight - 0.01f, 0);
		glColor4f(0.0f, 0.0f, 0.5f, 0.5f);
		va->DrawArray0(GL_TRIANGLE_STRIP);
	}

	const float textSize = 0.5f;

	// table header
	{
		const float fStartY = start_y + 0.005f;
		float fStartX = start_x + 0.005f + 0.015f + 0.005f;

		// print total-time running since application start
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "totaltime");

		// print percent of CPU time used within the last 500ms
		fStartX += 0.06f;
		font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "cur-%%usage");
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "max-%%usage");
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "lag");

		// print timer name
		fStartX += 0.01f;
		font->glFormat(fStartX, fStartY, textSize, FONT_SHADOW | FONT_DESCENDER | FONT_SCALE | FONT_NORM, "title");
	}

	// draw the textual info (total-time, short-time percentual time, timer-name)
	int y = 1;
	for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) {
		const auto& profileData = pi->second;

		const float fStartY = start_y - y * lineHeight;
		float fStartX = start_x + 0.005f + 0.015f + 0.005f;

		// print total-time running since application start
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2fs", profileData.total.toSecsf());

		// print percent of CPU time used within the last 500ms
		fStartX += 0.06f;
		font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2f%%", profileData.percent * 100);
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.2f%%", profileData.newPeak?1:255, profileData.newPeak?1:255, profileData.peak * 100);
		fStartX += 0.04f;
		font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM | FONT_RIGHT, "\xff\xff%c%c%.0fms", profileData.newLagPeak?1:255, profileData.newLagPeak?1:255, profileData.maxLag);

		// print timer name
		fStartX += 0.01f;
		font->glFormat(fStartX, fStartY, textSize, FONT_DESCENDER | FONT_SCALE | FONT_NORM, pi->first);
	}


	// draw the Timer selection boxes
	const float boxSize = lineHeight*0.9;
	const float selOffset = boxSize*0.2;
	glPushMatrix();
	glTranslatef(start_x + 0.005f, start_y + boxSize, 0); // we are now at upper left of first box
		CVertexArray* va  = GetVertexArray();
		CVertexArray* va2 = GetVertexArray();
		va->Initialize();
		va2->Initialize();
			int i = 1;
			for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++i){
				auto& fc = pi->second.color;
				SColor c(fc[0], fc[1], fc[2]);
				va->AddVertexC(float3(0, -i*lineHeight, 0), c); // upper left
				va->AddVertexC(float3(0, -i*lineHeight-boxSize, 0), c); // lower left
				va->AddVertexC(float3(boxSize, -i*lineHeight-boxSize, 0), c); // lower right
				va->AddVertexC(float3(boxSize, -i*lineHeight, 0), c); // upper right

				if (pi->second.showGraph) {
					va2->AddVertex0(lineHeight+selOffset, -i*lineHeight-selOffset, 0); // upper left
					va2->AddVertex0(lineHeight+selOffset, -i*lineHeight-boxSize+selOffset, 0); // lower left
					va2->AddVertex0(lineHeight+boxSize-selOffset, -i*lineHeight-boxSize+selOffset, 0); // lower right
					va2->AddVertex0(lineHeight+boxSize-selOffset, -i*lineHeight-selOffset, 0); // upper right
				}
			}
		// draw the boxes
		va->DrawArrayC(GL_QUADS);
		// draw the 'graph view disabled' cross
		glColor3f(1,0,0);
		va2->DrawArray0(GL_QUADS);
	glPopMatrix();

	// draw the graph
	glLineWidth(3.0f);
	for (auto pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi) {
		if (!pi->second.showGraph) {
			continue;
		}
		CVertexArray* va = GetVertexArray();
		va->Initialize();
		const float steps_x = (end_x - start_x) / CTimeProfiler::TimeRecord::frames_size;
		for (size_t a=0; a < CTimeProfiler::TimeRecord::frames_size; ++a) {
			// profile runtime; eg 0.5f means: uses 50% of a CPU (during that frame)
			// This may be more then 1.0f, in case an operation
			// which ran over many frames, ended in this one.
			const float p = pi->second.frames[a].toSecsf() * GAME_SPEED;
			const float x = start_x + (a * steps_x);
			const float y = 0.02f + (p * 0.96f);
			va->AddVertex0(x, y, 0.0f);
		}

		glColorf3((float3)pi->second.color);
		va->DrawArray0(GL_LINE_STRIP);
	}
	glLineWidth(1.0f);
}
void CSelectedUnitsHandler::Draw()
{
	glDisable(GL_TEXTURE_2D);
	glDepthMask(false);
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_BLEND); // for line smoothing
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glLineWidth(cmdColors.UnitBoxLineWidth());

	SColor color1(cmdColors.unitBox);
	SColor color2(cmdColors.unitBox);
	color2.r = 255 - color2.r;
	color2.g = 255 - color2.g;
	color2.b = 255 - color2.b;

	if (color1.a > 0) {
		const CUnitSet* unitSet;
		if (selectedGroup != -1) {
			// note: units in this set are not necessarily all selected themselves, eg.
			// if autoAddBuiltUnitsToSelectedGroup is true, so we check IsUnitSelected
			// for each
			unitSet = &grouphandlers[gu->myTeam]->groups[selectedGroup]->units;
		} else {
			unitSet = &selectedUnits;
		}

		CVertexArray* va = GetVertexArray();
		va->Initialize();
		va->EnlargeArrays(unitSet->size() * 8, 0, VA_SIZE_C);

		for (CUnitSet::const_iterator ui = unitSet->begin(); ui != unitSet->end(); ++ui) {
			const CUnit* unit = *ui;
			const MoveDef* moveDef = unit->moveDef;

			if (unit->isIcon) continue;
			if (!IsUnitSelected(unit)) continue;

			const int
				uhxsize = (unit->xsize * SQUARE_SIZE) >> 1,
				uhzsize = (unit->zsize * SQUARE_SIZE) >> 1,
				mhxsize = (moveDef == NULL)? uhxsize: ((moveDef->xsize * SQUARE_SIZE) >> 1),
				mhzsize = (moveDef == NULL)? uhzsize: ((moveDef->zsize * SQUARE_SIZE) >> 1);
			const float3 verts[8] = {
				// UnitDef footprint corners
				float3(unit->drawPos.x + uhxsize, unit->drawPos.y, unit->drawPos.z + uhzsize),
				float3(unit->drawPos.x - uhxsize, unit->drawPos.y, unit->drawPos.z + uhzsize),
				float3(unit->drawPos.x - uhxsize, unit->drawPos.y, unit->drawPos.z - uhzsize),
				float3(unit->drawPos.x + uhxsize, unit->drawPos.y, unit->drawPos.z - uhzsize),
				// MoveDef footprint corners
				float3(unit->drawPos.x + mhxsize, unit->drawPos.y, unit->drawPos.z + mhzsize),
				float3(unit->drawPos.x - mhxsize, unit->drawPos.y, unit->drawPos.z + mhzsize),
				float3(unit->drawPos.x - mhxsize, unit->drawPos.y, unit->drawPos.z - mhzsize),
				float3(unit->drawPos.x + mhxsize, unit->drawPos.y, unit->drawPos.z - mhzsize),
			};

			va->AddVertexQC(verts[0], color1);
			va->AddVertexQC(verts[1], color1);
			va->AddVertexQC(verts[2], color1);
			va->AddVertexQC(verts[3], color1);

			if (globalRendering->drawdebug && (mhxsize != uhxsize || mhzsize != uhzsize)) {
				va->AddVertexQC(verts[4], color2);
				va->AddVertexQC(verts[5], color2);
				va->AddVertexQC(verts[6], color2);
				va->AddVertexQC(verts[7], color2);
			}
		}

		va->DrawArrayC(GL_QUADS);
	}

	// highlight queued build sites if we are about to build something
	// (or old-style, whenever the shift key is being held down)
	if (cmdColors.buildBox[3] > 0.0f) {
		if (!selectedUnits.empty() &&
				((cmdColors.BuildBoxesOnShift() && KeyInput::GetKeyModState(KMOD_SHIFT)) ||
				 ((guihandler->inCommand >= 0) &&
					(guihandler->inCommand < int(guihandler->commands.size())) &&
					(guihandler->commands[guihandler->inCommand].id < 0)))) {

			bool myColor = true;
			glColor4fv(cmdColors.buildBox);

			for (const auto bi: unitHandler->GetBuilderCAIs()) {
				const CBuilderCAI* builderCAI = bi.second;
				const CUnit* builder = builderCAI->owner;

				if (builder->team == gu->myTeam) {
					if (!myColor) {
						glColor4fv(cmdColors.buildBox);
						myColor = true;
					}
					commandDrawer->DrawQuedBuildingSquares(builderCAI);
				}
				else if (teamHandler->AlliedTeams(builder->team, gu->myTeam)) {
					if (myColor) {
						glColor4fv(cmdColors.allyBuildBox);
						myColor = false;
					}
					commandDrawer->DrawQuedBuildingSquares(builderCAI);
				}
			}
		}
	}

	glLineWidth(1.0f);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
	glDepthMask(true);
	glEnable(GL_TEXTURE_2D);
}
Example #16
0
void CDecalsDrawerGL4::GenerateAtlasTexture()
{
	std::unordered_map<std::string, STex> textures;
	GetBuildingDecals(textures);
	GetGroundScars(textures);
	GetFallbacks(textures);

	CQuadtreeAtlasAlloc atlas;
	atlas.SetNonPowerOfTwo(globalRendering->supportNPOTs);
	atlas.SetMaxSize(globalRendering->maxTextureSize, globalRendering->maxTextureSize);
	for (auto it = textures.begin(); it != textures.end(); ++it) {
		if (it->second.id == 0)
			continue;

		const float maxSize = 1024; //512;
		int2 size = it->second.size;
		if (size.x > maxSize) {
			size.y = size.y * (maxSize / size.x);
			size.x = maxSize;
		}
		if (size.y > maxSize) {
			size.x = size.x * (maxSize / size.y);
			size.y = maxSize;
		}

		atlas.AddEntry(it->first, size);
	}
	/*bool success =*/ atlas.Allocate();



	glGenTextures(1, &atlasTex);
	glBindTexture(GL_TEXTURE_2D, atlasTex);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0f);
	glSpringTexStorage2D(GL_TEXTURE_2D, atlas.GetMaxMipMaps(), GL_RGBA8, atlas.GetAtlasSize().x, atlas.GetAtlasSize().y);

	FBO fb;
	if (!fb.IsValid()) {
		LOG_L(L_ERROR, "[%s] framebuffer not valid", __FUNCTION__);
		return;
	}
	fb.Bind();
	fb.AttachTexture(atlasTex);
	if (!fb.CheckStatus(LOG_SECTION_DECALS_GL4)) {
		LOG_L(L_ERROR, "[%s] Couldn't render to FBO!", __FUNCTION__);
		return;
	}

	glViewport(0, 0, atlas.GetAtlasSize().x, atlas.GetAtlasSize().y);
	glSpringMatrix2dProj(atlas.GetAtlasSize().x, atlas.GetAtlasSize().y);

	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // transparent black
	glClear(GL_COLOR_BUFFER_BIT);

	glActiveTexture(GL_TEXTURE0);
	glEnable(GL_TEXTURE_2D);

	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ZERO);
	glDisable(GL_DEPTH_TEST);

	CVertexArray va;
	for (auto& p: textures) {
		if (p.second.id == 0)
			continue;

		const float4 texCoords = atlas.GetTexCoords(p.first);
		const float4 absCoords = atlas.GetEntry(p.first);
		atlasTexs[p.first] = SAtlasTex(texCoords);

		glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
		glBindTexture(GL_TEXTURE_2D, p.second.id);

		va.Initialize();
		va.AddVertex2dT(absCoords.x,   absCoords.y, 0.0f, 0.0f);
		va.AddVertex2dT(absCoords.z+1, absCoords.y, 1.0f, 0.0f); //FIXME why +1?
		va.AddVertex2dT(absCoords.x,   absCoords.w+1, 0.0f, 1.0f);
		va.AddVertex2dT(absCoords.z+1, absCoords.w+1, 1.0f, 1.0f); //FIXME why +1?
		va.DrawArray2dT(GL_TRIANGLE_STRIP);

		glDeleteTextures(1, &p.second.id);
	}

	fb.Unbind();
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, atlasTex);
	glGenerateMipmap(GL_TEXTURE_2D);

#ifdef DEBUG_SAVE_ATLAS
	glSaveTexture(atlasTex, "x_decal_atlas.png");
#endif
}
Example #17
0
void DebugDrawerAI::Graph::Draw() {
	static unsigned char color[4] = {0.75f * 255, 0.75f * 255, 0.75f * 255, 0.5f * 255};

	CVertexArray* va = GetVertexArray();

	{
		color[0] = 0.25f * 255;
		color[1] = 0.25f * 255;
		color[2] = 0.25f * 255;
		color[3] = 1.00f * 255;

		// label-box
		va->Initialize();
		va->AddVertexC(pos,                                                                               color);
		va->AddVertexC(pos + float3(-(((maxLabelWidth * 1.33f) / globalRendering->viewSizeX) * size.x),   0.0f, 0.0f), color);
		va->AddVertexC(pos + float3(-(((maxLabelWidth * 1.33f) / globalRendering->viewSizeX) * size.x), size.y, 0.0f), color);
		va->AddVertexC(pos + float3(                                                0.0f,  size.y, 0.0f), color);
		va->DrawArrayC(GL_LINE_STRIP);

		if (scale.y > 0.0f && scale.x > 0.0f) {
			font->Begin();
			font->SetTextColor(0.25f, 0.25f, 0.25f, 1.0f);

			// horizontal grid lines
			for (float s = 0.0f; s <= (scale.y + 0.01f); s += (scale.y * 0.1f)) {
				va->Initialize();
				va->AddVertexC(pos + float3(  0.0f, (s / scale.y) * size.y, 0.0f), color);
				va->AddVertexC(pos + float3(size.x, (s / scale.y) * size.y, 0.0f), color);
				va->DrawArrayC(GL_LINES);

				const float tx = (pos.x + size.x) + (size.x * 0.025f);
				const float ty = pos.y + (s / scale.y) * size.y;

				font->glFormat(tx, ty, 1.0f, FONT_SCALE | FONT_NORM, "%2.1e", s + minScale.y);
			}

			// vertical grid lines
			for (float s = 0.0f; s <= (scale.x + 0.01f); s += (scale.x * 0.1f)) {
				va->Initialize();
				va->AddVertexC(pos + float3((s / scale.x) * size.x,   0.0f, 0.0f), color);
				va->AddVertexC(pos + float3((s / scale.x) * size.x, size.y, 0.0f), color);
				va->DrawArrayC(GL_LINES);

				const float tx = (pos.x + (s / scale.x) * size.x) - (size.x * 0.05f);
				const float ty = pos.y - size.y * 0.1f;

				font->glFormat(tx, ty, 1.0f, FONT_SCALE | FONT_NORM, "%2.1e", s + minScale.x);
			}

			font->End();
		}
	}

	{
		typedef std::map<int, Graph::GraphLine>::const_iterator LineIt;
		typedef std::list<float3>::const_iterator ListIt;

		if (!lines.empty()) {
			font->Begin();

			int lineNum = 0;
			float linePad = (1.0f / lines.size()) * 0.5f;

			for (LineIt lit = lines.begin(); lit != lines.end(); ++lit) {
				const Graph::GraphLine& line = lit->second;
				const std::list<float3>& data = line.lineData;

				if (data.empty()) {
					continue;
				}

				// right-outline the labels
				const float sx = (maxLabelWidth / globalRendering->viewSizeX) * size.x;
				const float tx = pos.x - ((line.lineLabelWidth / maxLabelWidth) * 1.33f) * sx;
				const float ty = pos.y + ((lineNum * linePad * 2.0f) + linePad) * size.y;

				font->SetTextColor(line.lineColor.x, line.lineColor.y, line.lineColor.z, 1.0f);
				font->glPrint(tx, ty, 1.0f, FONT_SCALE | FONT_NORM, line.lineLabel);

				color[0] = line.lineColor.x * 255;
				color[1] = line.lineColor.y * 255;
				color[2] = line.lineColor.z * 255;
				color[3] = 255;

				glLineWidth(line.lineWidth);
				va->Initialize();

				for (ListIt pit = data.begin(); pit != data.end(); ++pit) {
					ListIt npit = pit; ++npit;

					const float px1 = ((pit->x - minScale.x) / scale.x) * size.x;
					const float py1 = ((pit->y - minScale.y) / scale.y) * size.y;
					const float px2 = (npit == data.end()) ? px1 : ((npit->x - minScale.x) / scale.x) * size.x;
					const float py2 = (npit == data.end()) ? py1 : ((npit->y - minScale.y) / scale.y) * size.y;

					va->AddVertexC(pos + float3(px1, py1, 0.0f), color);
					va->AddVertexC(pos + float3(px2, py2, 0.0f), color);
				}

				va->DrawArrayC(GL_LINE_STRIP);
				glLineWidth(1.0f);

				lineNum += 1;
			}

			font->End();
		}
	}

	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}
Example #18
0
void ProfileDrawer::Draw()
{
	GML_STDMUTEX_LOCK_NOPROF(time); // Draw

	// draw the background of the window
	glDisable(GL_TEXTURE_2D);
	glColor4f(0.0f, 0.0f, 0.5f, 0.5f);
	if(!profiler.profile.empty()){
		glBegin(GL_TRIANGLE_STRIP);
		glVertex3f(start_x, end_y,                                      0);
		glVertex3f(end_x,   end_y,                                      0);
		glVertex3f(start_x, end_y-profiler.profile.size()*0.024f-0.01f, 0);
		glVertex3f(end_x,   end_y-profiler.profile.size()*0.024f-0.01f, 0);
		glEnd();
	}

	std::map<std::string, CTimeProfiler::TimeRecord>::iterator pi;

	// draw the textual info (total-time, short-time percentual time, timer-name)
	int y = 0;
	font->Begin();
	for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi, ++y) {
#if GML_MUTEX_PROFILER
		if (pi->first.size()<5 || pi->first.substr(pi->first.size()-5,5).compare("Mutex")!=0) { --y; continue; }
		const float fStartY = start_y - y * 0.020f;
#else
		const float fStartY = start_y - y * 0.024f;
#endif
		const float s = ((float)pi->second.total) / 1000.0f;
		const float p = pi->second.percent * 100;
		float fStartX = start_x + 0.005f + 0.015f + 0.005f;

		// print total-time running since application start
		fStartX += 0.09f;
		font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2fs", s);

		// print percent of CPU time used within the last 500ms
		fStartX += 0.08f;
		font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM | FONT_RIGHT, "%.2f%%", p);

		// print timer name
		fStartX += 0.01f;
		font->glFormat(fStartX, fStartY, 0.7f, FONT_BASELINE | FONT_SCALE | FONT_NORM, "%s", pi->first.c_str());
	}
	font->End();

	// draw the Timer selection boxes
	glPushMatrix();
	glTranslatef(start_x + 0.005f, start_y, 0);
	glScalef(0.015f, 0.02f, 0.02f);
	for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi){
		glColorf3((float3)pi->second.color);
		glBegin(GL_QUADS);
		glVertex3f(0,0,0);
		glVertex3f(1,0,0);
		glVertex3f(1,1,0);
		glVertex3f(0,1,0);
		glEnd();
		// draw the 'graph view disabled' cross
		if (!pi->second.showGraph) {
			glColor3f(1,0,0);
			glBegin(GL_LINES);
			glVertex3f(0,0,0);
			glVertex3f(1,1,0);
			glVertex3f(1,0,0);
			glVertex3f(0,1,0);
			glEnd();
		}
		glTranslatef(0,-1.2f,0);
	}
	glPopMatrix();

	// draw the graph
	for (pi = profiler.profile.begin(); pi != profiler.profile.end(); ++pi) {
		if (!pi->second.showGraph) {
			continue;
		}
		CVertexArray* va = GetVertexArray();
		va->Initialize();
		const float steps_x = (end_x - start_x) / CTimeProfiler::TimeRecord::frames_size;
		for (size_t a=0; a < CTimeProfiler::TimeRecord::frames_size; ++a) {
			// profile runtime; eg 0.5f means: uses 50% of a CPU (during that frame)
			// This may be more then 1.0f, in case an operation
			// which ran over many frames, ended in this one.
			const float p = ((float)pi->second.frames[a]) / 1000.0f * GAME_SPEED;
			const float x = start_x + (a * steps_x);
			const float y = 0.02f + (p * 0.4f);
			va->AddVertex0(float3(x, y, 0.0f));
		}
		glColorf3((float3)pi->second.color);
		va->DrawArray0(GL_LINE_STRIP);
	}
	glEnable(GL_TEXTURE_2D);
}
Example #19
0
void CAdvTreeSquareDrawer_SP::DrawQuad(int x, int y)
{
	const int treesX = td->treesX;
	CAdvTreeDrawer::TreeSquareStruct* tss = &td->trees[(y * treesX) + x];

	if ((abs(cy - y) <= 2) && (abs(cx - x) <= 2) && drawDetailed) {
		// 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.0f;
		dif.z = camera->pos.z - ((y * SQUARE_SIZE * TREE_SQUARE_SIZE) + (SQUARE_SIZE * TREE_SQUARE_SIZE / 2));
	const float dist = dif.Length();
	const float distFactor = dist / treeDistance;
	dif.Normalize();

	if (distFactor < MID_TREE_DIST_FACTOR) {
		// midle distance trees
		tss->lastSeen = gs->frameNum;

		if (!tss->dispList) {
			CVertexArray* va = GetVertexArray();
			va->Initialize();
			va->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes
			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;

				if (ts->type < 8) {
					CAdvTreeDrawer::DrawTreeVertexMid(va, ts->pos, (ts->type    ) * 0.125f, 0.5f, false);
				} else {
					CAdvTreeDrawer::DrawTreeVertexMid(va, ts->pos, (ts->type - 8) * 0.125f, 0.0f, false);
				}
			}

			glNewList(tss->dispList, GL_COMPILE);
			va->DrawArrayT(GL_QUADS);
			glEndList();
		}

		glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
		glAlphaFunc(GL_GREATER, 0.5f);
		glCallList(tss->dispList);
	}
	else if (distFactor < FAR_TREE_DIST_FACTOR) {
		// far trees
		tss->lastSeenFar = gs->frameNum;

		if (!tss->farDispList || dif.dot(tss->viewVector) < 0.97f) {
			CVertexArray* va = GetVertexArray();
			va->Initialize();
			va->EnlargeArrays(4 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes
			tss->viewVector = dif;

			if (!tss->farDispList)
				tss->farDispList = glGenLists(1);

			const float3 side = UpVector.cross(dif);

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

				if (ts->type < 8) {
					CAdvTreeDrawer::DrawTreeVertexFar(va, ts->pos, side * HALF_MAX_TREE_HEIGHT, (ts->type    ) * 0.125f, 0.5f, false);
				} else {
					CAdvTreeDrawer::DrawTreeVertexFar(va, ts->pos, side * HALF_MAX_TREE_HEIGHT, (ts->type - 8) * 0.125f, 0.0f, false);
				}
			}

			glNewList(tss->farDispList, GL_COMPILE);
			va->DrawArrayT(GL_QUADS);
			glEndList();
		}
		if (distFactor > FADE_TREE_DIST_FACTOR) {
			// faded far trees
			const float alpha = 1.0f - (distFactor - FADE_TREE_DIST_FACTOR) / (FAR_TREE_DIST_FACTOR - FADE_TREE_DIST_FACTOR);
			glColor4f(1.0f, 1.0f, 1.0f, alpha);
			glAlphaFunc(GL_GREATER, alpha * 0.5f);
		} else {
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			glAlphaFunc(GL_GREATER, 0.5f);
		}
		glCallList(tss->farDispList);
	}
}
Example #20
0
void CAdvWater::Draw(bool useBlending)
{
	if (!waterRendering->forceRendering && !readMap->HasVisibleWater())
		return;

	float3 base = camera->CalcPixelDir(globalRendering->viewPosX, globalRendering->viewSizeY);
	float3 dv   = camera->CalcPixelDir(globalRendering->viewPosX, 0) - camera->CalcPixelDir(globalRendering->viewPosX, globalRendering->viewSizeY);
	float3 dh   = camera->CalcPixelDir(globalRendering->viewPosX + globalRendering->viewSizeX, 0) - camera->CalcPixelDir(globalRendering->viewPosX, 0);

	float3 xbase;
	float3 forward = camera->GetDir();
	float3 dir;
	float3 zpos;

	const int numDivs = 20;

	base *= numDivs;
	float maxY = -0.1f;
	float yInc = 1.0f / numDivs;
	float screenY = 1.0f;

	unsigned char col[4];
	col[0] = (unsigned char)(waterSurfaceColor.x * 255);
	col[1] = (unsigned char)(waterSurfaceColor.y * 255);
	col[2] = (unsigned char)(waterSurfaceColor.z * 255);

	glDisable(GL_ALPHA_TEST);
	if (useBlending) {
		glEnable(GL_BLEND);
	} else {
		glDisable(GL_BLEND);
	}
	glDepthMask(0);
	glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, bumpTexture);
		GLfloat plan[] = {0.02f, 0, 0, 0};
		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
		glTexGenfv(GL_S, GL_EYE_PLANE, plan);
		glEnable(GL_TEXTURE_GEN_S);

		GLfloat plan2[] = {0, 0, 0.02f, 0};
		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
		glTexGenfv(GL_T, GL_EYE_PLANE, plan2);
		glEnable(GL_TEXTURE_GEN_T);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, reflectTexture);

	glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, waterFP);
	glEnable(GL_FRAGMENT_PROGRAM_ARB);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE * wireFrameMode + GL_FILL * (1 - wireFrameMode));

	forward.ANormalize2D();

	glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,  forward.z, forward.x, 0.0f, 0.0f);
	glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, -forward.x, forward.z, 0.0f, 0.0f);

	CVertexArray* va = GetVertexArray();
	va->Initialize();
	va->EnlargeArrays(5 * numDivs * (numDivs + 1) * 2, 5 * numDivs, VA_SIZE_TC); //! alloc room for all vertexes and strips

	for (int a = 0; a < 5; ++a) { //! CAUTION: loop count must match EnlargeArrays above
		bool maxReached = false;

		for (int y = 0; y < numDivs; ++y) {
			dir = base;
			dir.ANormalize();

			if (dir.y >= maxY) {
				maxReached = true;
				break;
			}

			xbase = base;

			for (int x = 0; x < numDivs + 1; ++x) { //! CAUTION: loop count must match EnlargeArrays above
				dir = xbase + dv;
				dir.ANormalize();

				zpos = camera->GetPos() + dir * (camera->GetPos().y / -dir.y);
				zpos.y = fastmath::sin(zpos.z * 0.1f + gs->frameNum * 0.06f) * 0.06f + 0.05f;

				col[3] = (unsigned char)((0.8f + 0.7f * dir.y) * 255);
				va->AddVertexQTC(zpos, x * (1.0f / numDivs), screenY - yInc, col);

				dir = xbase;
				dir.ANormalize();

				zpos = camera->GetPos() + dir * (camera->GetPos().y / -dir.y);
				zpos.y = fastmath::sin(zpos.z * 0.1f + gs->frameNum * 0.06f) * 0.06f + 0.05f;

				col[3] = (unsigned char)((0.8f + 0.7f * dir.y) * 255);
				va->AddVertexQTC(zpos, x * (1.0f / numDivs), screenY, col);

				xbase += dh;
			}
			va->EndStrip();
			base += dv;
			screenY -= yInc;
		}

		if (!maxReached)
			break;

		dv   *= 0.5f;
		maxY *= 0.5f;
		yInc *= 0.5f;
	}
	va->DrawArrayTC(GL_TRIANGLE_STRIP);

	glDepthMask(1);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glDisable(GL_FRAGMENT_PROGRAM_ARB);

	glActiveTexture(GL_TEXTURE1);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
	glActiveTexture(GL_TEXTURE0);

	// for translucent stuff like water, the default mode is blending and alpha testing enabled
	if (!useBlending)
		glEnable(GL_BLEND);
}
Example #21
0
CBumpWater::CBumpWater()
	: CEventClient("[CBumpWater]", 271923, false)
{
	eventHandler.AddClient(this);

	// LOAD USER CONFIGS
	reflTexSize  = next_power_of_2(configHandler->GetInt("BumpWaterTexSizeReflection"));
	reflection   = configHandler->GetInt("BumpWaterReflection");
	refraction   = configHandler->GetInt("BumpWaterRefraction");
	anisotropy   = configHandler->GetFloat("BumpWaterAnisotropy");
	depthCopy    = configHandler->GetBool("BumpWaterUseDepthTexture");
	depthBits    = configHandler->GetInt("BumpWaterDepthBits");
	if ((depthBits == 24) && !globalRendering->support24bitDepthBuffers)
		depthBits = 16;
	blurRefl     = configHandler->GetBool("BumpWaterBlurReflection");
	shoreWaves   = (configHandler->GetBool("BumpWaterShoreWaves")) && mapInfo->water.shoreWaves;
	endlessOcean = (configHandler->GetBool("BumpWaterEndlessOcean")) && mapInfo->water.hasWaterPlane
	               && ((readmap->initMinHeight <= 0.0f) || (mapInfo->water.forceRendering));
	dynWaves     = (configHandler->GetBool("BumpWaterDynamicWaves")) && (mapInfo->water.numTiles>1);
	useUniforms  = (configHandler->GetBool("BumpWaterUseUniforms"));

	refractTexture = 0;
	reflectTexture = 0;

	// CHECK HARDWARE
	if (!globalRendering->haveGLSL) {
		throw content_error("["LOG_SECTION_BUMP_WATER"] your hardware/driver setup does not support GLSL");
	}

	shoreWaves = shoreWaves && (GLEW_EXT_framebuffer_object);
	dynWaves   = dynWaves && (GLEW_EXT_framebuffer_object && GLEW_ARB_imaging);


	// LOAD TEXTURES
	foamTexture   = LoadTexture(mapInfo->water.foamTexture);
	normalTexture = LoadTexture(mapInfo->water.normalTexture , anisotropy , &normalTextureX, &normalTextureY);

	//! caustic textures
	const vector<string>& causticNames = mapInfo->water.causticTextures;
	if (causticNames.size() <= 0) {
		throw content_error("["LOG_SECTION_BUMP_WATER"] no caustic textures");
	}
	for (int i = 0; i < (int)causticNames.size(); ++i) {
		caustTextures.push_back(LoadTexture(causticNames[i]));
	}

	// CHECK SHOREWAVES TEXTURE SIZE
	if (shoreWaves) {
		GLint maxw, maxh;
		glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA16F_ARB, 4096, 4096, 0, GL_RGBA, GL_FLOAT, NULL);
		glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &maxw);
		glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &maxh);
		if (gs->mapx>maxw || gs->mapy>maxh) {
			shoreWaves = false;
			LOG_L(L_WARNING, "Can not display shorewaves (map too large)!");
		}
	}


	// SHOREWAVES
	if (shoreWaves) {
		waveRandTexture = LoadTexture( "bitmaps/shorewaverand.png" );

		glGenTextures(1, &coastTexture);
		glBindTexture(GL_TEXTURE_2D, coastTexture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, gs->mapx, gs->mapy, 0, GL_RGBA, GL_FLOAT, NULL);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, gs->mapx, gs->mapy, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
		//glGenerateMipmapEXT(GL_TEXTURE_2D);


		{
			blurShader = shaderHandler->CreateProgramObject("[BumpWater]", "CoastBlurShader", false);
			blurShader->AttachShaderObject(shaderHandler->CreateShaderObject("GLSL/bumpWaterCoastBlurFS.glsl", "", GL_FRAGMENT_SHADER));
			blurShader->Link();

			if (!blurShader->IsValid()) {
				const char* fmt = "shorewaves-shader compilation error: %s";
				const char* log = (blurShader->GetLog()).c_str();

				LOG_L(L_ERROR, fmt, log);

				//! string size is limited with content_error()
				throw content_error(string("["LOG_SECTION_BUMP_WATER"] shorewaves-shader compilation error!"));
			}

			blurShader->SetUniformLocation("tex0"); // idx 0
			blurShader->SetUniformLocation("tex1"); // idx 1
			blurShader->Enable();
			blurShader->SetUniform1i(0, 0);
			blurShader->SetUniform1i(1, 1);
			blurShader->Disable();
			blurShader->Validate();

			if (!blurShader->IsValid()) {
				const char* fmt = "shorewaves-shader validation error: %s";
				const char* log = (blurShader->GetLog()).c_str();

				LOG_L(L_ERROR, fmt, log);
				throw content_error(string("["LOG_SECTION_BUMP_WATER"] shorewaves-shader validation error!"));
			}
		}


		coastFBO.reloadOnAltTab = true;
		coastFBO.Bind();
		coastFBO.AttachTexture(coastTexture, GL_TEXTURE_2D, GL_COLOR_ATTACHMENT0_EXT);

		if (coastFBO.CheckStatus("BUMPWATER(Coastmap)")) {
			//! initialize texture
			glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			glClear(GL_COLOR_BUFFER_BIT);

			//! fill with current heightmap/coastmap
			UnsyncedHeightMapUpdate(SRectangle(0, 0, gs->mapx, gs->mapy));
			UploadCoastline(true);
			UpdateCoastmap();
		} else
			shoreWaves = false;

		if (shoreWaves)
			eventHandler.InsertEvent(this, "UnsyncedHeightMapUpdate");
		
		//coastFBO.Unbind(); // gets done below
	}


	// CREATE TEXTURES
	if ((refraction > 0) || depthCopy) {
		//! ATIs do not have GLSL support for texrects
		screenTextureX = globalRendering->viewSizeX;
		screenTextureY = globalRendering->viewSizeY;
		if (GLEW_ARB_texture_rectangle && !globalRendering->atiHacks) {
			target = GL_TEXTURE_RECTANGLE_ARB;
		} else {
			target = GL_TEXTURE_2D;
			if (!globalRendering->supportNPOTs) {
				screenTextureX = next_power_of_2(globalRendering->viewSizeX);
				screenTextureY = next_power_of_2(globalRendering->viewSizeY);
			}
		}
	}

	if (refraction > 0) {
		//! CREATE REFRACTION TEXTURE
		glGenTextures(1, &refractTexture);
		glBindTexture(target, refractTexture);
		glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		if (GLEW_EXT_texture_edge_clamp) {
			glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		} else {
			glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP);
			glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP);
		}
		glTexImage2D(target, 0, GL_RGBA8, screenTextureX, screenTextureY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	}

	if (reflection > 0) {
		//! CREATE REFLECTION TEXTURE
		glGenTextures(1, &reflectTexture);
		glBindTexture(GL_TEXTURE_2D, reflectTexture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		if (GLEW_EXT_texture_edge_clamp) {
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		} else {
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		}
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	}

	if (depthCopy) {
		//! CREATE DEPTH TEXTURE
		glGenTextures(1, &depthTexture);
		glBindTexture(target, depthTexture);
		glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		GLuint depthFormat = GL_DEPTH_COMPONENT;
		switch (globalRendering->depthBufferBits) { // use same depth as screen framebuffer
			case 16: depthFormat = GL_DEPTH_COMPONENT16; break;
			case 24: if (!globalRendering->atiHacks) { depthFormat = GL_DEPTH_COMPONENT24; break; } // ATIs fall through and use 32bit!
			default: depthFormat = GL_DEPTH_COMPONENT32; break;
		}
		glTexImage2D(target, 0, depthFormat, screenTextureX, screenTextureY, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
	}

	if (dynWaves) {
		//! SETUP DYNAMIC WAVES
		tileOffsets = new unsigned char[mapInfo->water.numTiles * mapInfo->water.numTiles];

		normalTexture2 = normalTexture;
		glBindTexture(GL_TEXTURE_2D, normalTexture2);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0.0);

		glGenTextures(1, &normalTexture);
		glBindTexture(GL_TEXTURE_2D, normalTexture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		if (anisotropy > 0.0f) {
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
		}
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, normalTextureX, normalTextureY, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
		glGenerateMipmapEXT(GL_TEXTURE_2D);
	}

	// CREATE FBOs
	if (GLEW_EXT_framebuffer_object) {
		GLuint depthRBOFormat = GL_DEPTH_COMPONENT;
		switch (depthBits) {
			case 16: depthRBOFormat = GL_DEPTH_COMPONENT16; break;
			case 24: depthRBOFormat = GL_DEPTH_COMPONENT24; break;
			case 32: depthRBOFormat = GL_DEPTH_COMPONENT32; break;
		}

		if (reflection>0) {
			reflectFBO.Bind();
			reflectFBO.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, depthRBOFormat, reflTexSize, reflTexSize);
			reflectFBO.AttachTexture(reflectTexture);
		}

		if (refraction>0) {
			refractFBO.Bind();
			refractFBO.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, depthRBOFormat, screenTextureX, screenTextureY);
			refractFBO.AttachTexture(refractTexture,target);
		}

		if (!reflectFBO.CheckStatus("BUMPWATER(reflection)")) {
			reflection = 0;
		}
		if (!refractFBO.CheckStatus("BUMPWATER(refraction)")) {
			refraction = 0;
		}

		if (dynWaves) {
			dynWavesFBO.reloadOnAltTab = true;
			dynWavesFBO.Bind();
			dynWavesFBO.AttachTexture(normalTexture);
			if (dynWavesFBO.CheckStatus("BUMPWATER(DynWaves)")) {
				UpdateDynWaves(true); //! initialize
			}
		}
		FBO::Unbind();
	}


	/*
	 * DEFINE SOME SHADER RUNTIME CONSTANTS
	 * (I do not use Uniforms for that, because the GLSL compiler can not
	 * optimize those!)
	 */
	string definitions;
	if (reflection>0) definitions += "#define opt_reflection\n";
	if (refraction>0) definitions += "#define opt_refraction\n";
	if (shoreWaves)   definitions += "#define opt_shorewaves\n";
	if (depthCopy)    definitions += "#define opt_depth\n";
	if (blurRefl)     definitions += "#define opt_blurreflection\n";
	if (endlessOcean) definitions += "#define opt_endlessocean\n";
	if (target == GL_TEXTURE_RECTANGLE_ARB) definitions += "#define opt_texrect\n";

	GLSLDefineConstf3(definitions, "MapMid",                    float3(readmap->width * SQUARE_SIZE * 0.5f, 0.0f, readmap->height * SQUARE_SIZE * 0.5f) );
	GLSLDefineConstf2(definitions, "ScreenInverse",             1.0f / globalRendering->viewSizeX, 1.0f / globalRendering->viewSizeY );
	GLSLDefineConstf2(definitions, "ScreenTextureSizeInverse",  1.0f / screenTextureX, 1.0f / screenTextureY );
	GLSLDefineConstf2(definitions, "ViewPos",                   globalRendering->viewPosX, globalRendering->viewPosY );

	if (useUniforms) {
		SetupUniforms(definitions);
	} else {
		GLSLDefineConstf4(definitions, "SurfaceColor",   mapInfo->water.surfaceColor*0.4, mapInfo->water.surfaceAlpha );
		GLSLDefineConstf4(definitions, "PlaneColor",     mapInfo->water.planeColor*0.4, mapInfo->water.surfaceAlpha );
		GLSLDefineConstf3(definitions, "DiffuseColor",   mapInfo->water.diffuseColor);
		GLSLDefineConstf3(definitions, "SpecularColor",  mapInfo->water.specularColor);
		GLSLDefineConstf1(definitions, "SpecularPower",  mapInfo->water.specularPower);
		GLSLDefineConstf1(definitions, "SpecularFactor", mapInfo->water.specularFactor);
		GLSLDefineConstf1(definitions, "AmbientFactor",  mapInfo->water.ambientFactor);
		GLSLDefineConstf1(definitions, "DiffuseFactor",  mapInfo->water.diffuseFactor * 15.0f);
		GLSLDefineConstf3(definitions, "SunDir",         sky->GetLight()->GetLightDir()); // FIXME: not a constant
		GLSLDefineConstf1(definitions, "FresnelMin",     mapInfo->water.fresnelMin);
		GLSLDefineConstf1(definitions, "FresnelMax",     mapInfo->water.fresnelMax);
		GLSLDefineConstf1(definitions, "FresnelPower",   mapInfo->water.fresnelPower);
		GLSLDefineConstf1(definitions, "ReflDistortion", mapInfo->water.reflDistortion);
		GLSLDefineConstf2(definitions, "BlurBase",       0.0f, mapInfo->water.blurBase / globalRendering->viewSizeY);
		GLSLDefineConstf1(definitions, "BlurExponent",   mapInfo->water.blurExponent);
		GLSLDefineConstf1(definitions, "PerlinStartFreq",  mapInfo->water.perlinStartFreq);
		GLSLDefineConstf1(definitions, "PerlinLacunarity", mapInfo->water.perlinLacunarity);
		GLSLDefineConstf1(definitions, "PerlinAmp",        mapInfo->water.perlinAmplitude);
		GLSLDefineConstf1(definitions, "WindSpeed",        mapInfo->water.windSpeed);
	}

	{
		const int mapX = readmap->width  * SQUARE_SIZE;
		const int mapZ = readmap->height * SQUARE_SIZE;
		const float shadingX = (float)gs->mapx / gs->pwr2mapx;
		const float shadingZ = (float)gs->mapy / gs->pwr2mapy;
		const float scaleX = (mapX > mapZ) ? (readmap->height/64)/16.0f * (float)mapX/mapZ : (readmap->width/64)/16.0f;
		const float scaleZ = (mapX > mapZ) ? (readmap->height/64)/16.0f : (readmap->width/64)/16.0f * (float)mapZ/mapX;
		GLSLDefineConst4f(definitions, "TexGenPlane", 1.0f/mapX, 1.0f/mapZ, scaleX/mapX, scaleZ/mapZ);
		GLSLDefineConst4f(definitions, "ShadingPlane", shadingX/mapX, shadingZ/mapZ, shadingX, shadingZ);
	}



	// LOAD SHADERS
	{
		waterShader = shaderHandler->CreateProgramObject("[BumpWater]", "WaterShader", false);
		waterShader->AttachShaderObject(shaderHandler->CreateShaderObject("GLSL/bumpWaterVS.glsl", definitions, GL_VERTEX_SHADER));
		waterShader->AttachShaderObject(shaderHandler->CreateShaderObject("GLSL/bumpWaterFS.glsl", definitions, GL_FRAGMENT_SHADER));
		waterShader->Link();
		waterShader->SetUniformLocation("eyePos");      // idx  0
		waterShader->SetUniformLocation("frame");       // idx  1
		waterShader->SetUniformLocation("normalmap");   // idx  2
		waterShader->SetUniformLocation("heightmap");   // idx  3
		waterShader->SetUniformLocation("caustic");     // idx  4
		waterShader->SetUniformLocation("foam");        // idx  5
		waterShader->SetUniformLocation("reflection");  // idx  6
		waterShader->SetUniformLocation("refraction");  // idx  7
		waterShader->SetUniformLocation("depthmap");    // idx  8
		waterShader->SetUniformLocation("coastmap");    // idx  9
		waterShader->SetUniformLocation("waverand");    // idx 10

		if (!waterShader->IsValid()) {
			const char* fmt = "water-shader compilation error: %s";
			const char* log = (waterShader->GetLog()).c_str();
			LOG_L(L_ERROR, fmt, log);
			throw content_error(string("["LOG_SECTION_BUMP_WATER"] water-shader compilation error!"));
		}

		if (useUniforms) {
			GetUniformLocations(waterShader);
		}

		// BIND TEXTURE UNIFORMS
		// NOTE: ATI shader validation code is stricter wrt. state,
		// so postpone the call until all texture uniforms are set
		waterShader->Enable();
		waterShader->SetUniform1i( 2, 0);
		waterShader->SetUniform1i( 3, 1);
		waterShader->SetUniform1i( 4, 2);
		waterShader->SetUniform1i( 5, 3);
		waterShader->SetUniform1i( 6, 4);
		waterShader->SetUniform1i( 7, 5);
		waterShader->SetUniform1i( 8, 7);
		waterShader->SetUniform1i( 9, 6);
		waterShader->SetUniform1i(10, 8);
		waterShader->Disable();
		waterShader->Validate();

		if (!waterShader->IsValid()) {
			const char* fmt = "water-shader validation error: %s";
			const char* log = (waterShader->GetLog()).c_str();

			LOG_L(L_ERROR, fmt, log);
			throw content_error(string("["LOG_SECTION_BUMP_WATER"] water-shader validation error!"));
		}
	}


	// CREATE DISPLAYLIST
	displayList = glGenLists(1);
	glNewList(displayList, GL_COMPILE);
	if (endlessOcean) {
		DrawRadialDisc();
	} else {
		const int mapX = readmap->width  * SQUARE_SIZE;
		const int mapZ = readmap->height * SQUARE_SIZE;
		CVertexArray* va = GetVertexArray();
		va->Initialize();
		for (int z = 0; z < 9; z++) {
			for (int x = 0; x < 10; x++) {
				for (int zs = 0; zs <= 1; zs++) {
					va->AddVertex0(float3(x*(mapX/9.0f), 0.0f, (z + zs)*(mapZ/9.0f)));
				}
			}
			va->EndStrip();
		}
		va->DrawArray0(GL_TRIANGLE_STRIP);
	}
	glEndList();

/*
	windndir = wind.GetCurrentDirection();
	windStrength = (smoothstep(0.0f, 12.0f, wind.GetCurrentStrength()) * 0.5f + 4.0f);
	windVec = windndir * windStrength;
*/
	windVec = float3(20.0, 0.0, 20.0);

	occlusionQuery = 0;
	occlusionQueryResult = GL_TRUE;
	wasLastFrameVisible = true;
	bool useOcclQuery  = (configHandler->GetBool("BumpWaterOcclusionQuery"));
	if (useOcclQuery && GLEW_ARB_occlusion_query && (refraction < 2)) { //! in the case of a separate refraction pass, there isn't enough time for a occlusion query
		GLint bitsSupported;
		glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &bitsSupported);
		if (bitsSupported > 0) {
			glGenQueries(1, &occlusionQuery);
		}
	}

	if (refraction > 1) {
		drawSolid = true;
	}
}
Example #22
0
void CAdvWater::UpdateWater(CGame* game)
{
	if (!waterRendering->forceRendering && !readMap->HasVisibleWater())
		return;

	glPushAttrib(GL_FOG_BIT | GL_COLOR_BUFFER_BIT);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE);

	{
		bumpFBO.Bind();
		glViewport(0, 0, 128, 128);

		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		glSpringMatrix2dSetupPV(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);

		glColor3f(0.2f, 0.2f, 0.2f);

		CVertexArray* va = GetVertexArray();
		va->Initialize();
		va->EnlargeArrays(12, 0, VA_SIZE_T);

		glBindTexture(GL_TEXTURE_2D, rawBumpTexture[0]);

		va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0046f);
		va->AddVertexQT(  UpVector, 0, 2 + gs->frameNum*0.0046f);
		va->AddVertexQT(  XYVector, 2, 2 + gs->frameNum*0.0046f);
		va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0046f);

		va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0026f);
		va->AddVertexQT(  UpVector, 0, 4 + gs->frameNum*0.0026f);
		va->AddVertexQT(  XYVector, 2, 4 + gs->frameNum*0.0026f);
		va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0026f);

		va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0012f);
		va->AddVertexQT(  UpVector, 0, 8 + gs->frameNum*0.0012f);
		va->AddVertexQT(  XYVector, 2, 8 + gs->frameNum*0.0012f);
		va->AddVertexQT( RgtVector, 2, 0 + gs->frameNum*0.0012f);

		va->DrawArrayT(GL_QUADS);

		va = GetVertexArray();
		va->Initialize();
		glBindTexture(GL_TEXTURE_2D, rawBumpTexture[1]);

		va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0036f);
		va->AddVertexQT(  UpVector, 0, 1 + gs->frameNum*0.0036f);
		va->AddVertexQT(  XYVector, 1, 1 + gs->frameNum*0.0036f);
		va->AddVertexQT( RgtVector, 1, 0 + gs->frameNum*0.0036f);

		va->DrawArrayT(GL_QUADS);

		va = GetVertexArray();
		va->Initialize();
		glBindTexture(GL_TEXTURE_2D, rawBumpTexture[2]);

		va->AddVertexQT(ZeroVector, 0, 0 + gs->frameNum*0.0082f);
		va->AddVertexQT(  UpVector, 0, 1 + gs->frameNum*0.0082f);
		va->AddVertexQT(  XYVector, 1, 1 + gs->frameNum*0.0082f);
		va->AddVertexQT( RgtVector, 1, 0 + gs->frameNum*0.0082f);

		va->DrawArrayT(GL_QUADS);

		// this fixes a memory leak on ATI cards
		glBindTexture(GL_TEXTURE_2D, 0);
		glColor3f(1.0f, 1.0f, 1.0f);
	}


	reflectFBO.Bind();
	glClearColor(sky->fogColor[0], sky->fogColor[1], sky->fogColor[2], 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	const double clipPlaneEqs[2 * 4] = {
		0.0, 1.0, 0.0, 0.0,
		0.0, 1.0, 0.0, 0.0,
	};

	CCamera* prvCam = CCamera::GetSetActiveCamera(CCamera::CAMTYPE_UWREFL);
	CCamera* curCam = CCamera::GetActiveCamera();

	{
		curCam->CopyStateReflect(prvCam);
		curCam->UpdateLoadViewPort(0, 0, 512, 512);

		DrawReflections(&clipPlaneEqs[0], true, true);
	}

	CCamera::SetActiveCamera(prvCam->GetCamType());
	prvCam->Update();
	prvCam->LoadViewPort();

	FBO::Unbind();

	glPopAttrib();
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void CLargeBeamLaserProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points)
{
	unsigned char color[4] = { kocolstart[0], kocolstart[1], kocolstart[2], 255 };
	lines.AddVertexQC(startPos, color);
	lines.AddVertexQC(endPos,   color);
}
Example #24
0
void CEndGameBox::Draw()
{
	if (!graphTex) {
		graphTex = bm.CreateTexture();
	}

	if (!enabled) {
		return;
	}

	float mx = MouseX(mouse->lastx);
	float my = MouseY(mouse->lasty);

	glDisable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glDisable(GL_ALPHA_TEST);

	// Large Box
	glColor4f(0.2f, 0.2f, 0.2f, guiAlpha);
	DrawBox(box);

	glColor4f(0.2f, 0.2f, 0.7f, guiAlpha);
	if (dispMode == 0) {
		DrawBox(box + playerBox);
	} else if (dispMode == 1) {
		DrawBox(box + sumBox);
	} else {
		DrawBox(box + difBox);
	}

	if (InBox(mx, my, box+exitBox)) {
		glColor4f(0.7f, 0.2f, 0.2f, guiAlpha);
		DrawBox(box + exitBox);
	}
	if (InBox(mx,my,box+playerBox)) {
		glColor4f(0.7f, 0.2f, 0.2f, guiAlpha);
		DrawBox(box + playerBox);
	}
	if (InBox(mx,my,box+sumBox)) {
		glColor4f(0.7f, 0.2f, 0.2f, guiAlpha);
		DrawBox(box + sumBox);
	}
	if (InBox(mx,my,box+difBox)) {
		glColor4f(0.7f, 0.2f, 0.2f, guiAlpha);
		DrawBox(box + difBox);
	}

	glEnable(GL_TEXTURE_2D);
	glColor4f(1, 1, 1, 0.8f);
	font->glPrint(box.x1 + exitBox.x1   + 0.025f, box.y1 + exitBox.y1   + 0.005f, 1.0f, FONT_SCALE | FONT_NORM, "Exit");
	font->glPrint(box.x1 + playerBox.x1 + 0.015f, box.y1 + playerBox.y1 + 0.005f, 0.7f, FONT_SCALE | FONT_NORM, "Player stats");
	font->glPrint(box.x1 + sumBox.x1    + 0.015f, box.y1 + sumBox.y1    + 0.005f, 0.7f, FONT_SCALE | FONT_NORM, "Team stats");
	font->glPrint(box.x1 + difBox.x1    + 0.015f, box.y1 + difBox.y1    + 0.005f, 0.7f, FONT_SCALE | FONT_NORM, "Team delta stats");

	if (winners.empty()) {
		font->glPrint(box.x1 + 0.25f, box.y1 + 0.65f, 1.0f, FONT_SCALE | FONT_NORM, "Game result was undecided");
	} else {
		std::stringstream winnersText;
		std::stringstream winnersList;

		// myPlayingAllyTeam is >= 0 iff we ever joined a team
		const bool neverPlayed = (gu->myPlayingAllyTeam < 0);
		      bool playedAndWon = false;

		for (unsigned int i = 0; i < winners.size(); i++) {
			const int winnerAllyTeam = winners[i];

			if (!neverPlayed && winnerAllyTeam == gu->myPlayingAllyTeam) {
				// we actually played and won!
				playedAndWon = true; break;
			}

			winnersList << (((i > 0)? ((i < (winners.size() - 1))? ", ": " and "): ""));
			winnersList << winnerAllyTeam;
		}

		if (neverPlayed) {
			winnersText << "Game Over! Ally-team(s) ";
			winnersText << winnersList.str() << " won!";

			font->glPrint(box.x1 + 0.25f, box.y1 + 0.65f, 1.0f, FONT_SCALE | FONT_NORM, (winnersText.str()).c_str());
		} else {
			winnersText.str("");
			winnersText << "Game Over! Your ally-team ";
			winnersText << (playedAndWon? "won!": "lost!");
			font->glPrint(box.x1 + 0.25f, box.y1 + 0.65f, 1.0f, FONT_SCALE | FONT_NORM, (winnersText.str()).c_str());
		}
	}

	if (gs->frameNum <= 0) {
		return;
	}

	if (dispMode == 0) {
		float xpos = 0.01f;

		std::string headers[] = {"Name", "MC/m", "MP/m", "KP/m", "Cmds/m", "ACS"};

		for (int a = 0; a < 6; ++a) {
			font->glPrint(box.x1 + xpos, box.y1 + 0.55f, 0.8f, FONT_SCALE | FONT_NORM,headers[a].c_str());
			xpos += 0.1f;
		}

		float ypos = 0.5f;
		for (int a = 0; a < playerHandler->ActivePlayers(); ++a) {
			const CPlayer* p = playerHandler->Player(a);
			const PlayerStatistics& pStats = p->currentStats;
			char values[6][100];

			SNPRINTF(values[0], 100, "%s", p->name.c_str());
			if (game->totalGameTime>0){ //prevent div zero
				SNPRINTF(values[1], 100, "%i", int(pStats.mouseClicks * 60 / game->totalGameTime));
				SNPRINTF(values[2], 100, "%i", int(pStats.mousePixels * 60 / game->totalGameTime));
				SNPRINTF(values[3], 100, "%i", int(pStats.keyPresses  * 60 / game->totalGameTime));
				SNPRINTF(values[4], 100, "%i", int(pStats.numCommands * 60 / game->totalGameTime));
			}else{
				for(int i=1; i<5; i++)
					SNPRINTF(values[i], 100, "%i", 0);
			}
			SNPRINTF(values[5], 100, "%i",
				(pStats.numCommands != 0)?
				(pStats.unitCommands / pStats.numCommands):
				(0));

			float xpos = 0.01f;
			for (int a = 0; a < 6; ++a) {
				font->glPrint(box.x1 + xpos, box.y1 + ypos, 0.8f, FONT_SCALE | FONT_NORM, values[a]);
				xpos += 0.1f;
			}

			ypos -= 0.02f;
		}
	} else {
		if (stats.empty()) {
			FillTeamStats();
		}

		glBindTexture(GL_TEXTURE_2D, graphTex);
		CVertexArray* va=GetVertexArray();
		va->Initialize();

		va->AddVertexT(float3(box.x1+0.15f, box.y1+0.08f, 0), 0, 0);
		va->AddVertexT(float3(box.x1+0.69f, box.y1+0.08f, 0), 4, 0);
		va->AddVertexT(float3(box.x1+0.69f, box.y1+0.62f, 0), 4, 4);
		va->AddVertexT(float3(box.x1+0.15f, box.y1+0.62f, 0), 0, 4);

		va->DrawArrayT(GL_QUADS);

		if ((mx > box.x1 + 0.01f) && (mx < box.x1 + 0.12f) &&
		    (my < box.y1 + 0.57f) && (my > box.y1 + 0.571f - (stats.size() * 0.02f))) {
			const int sel = (int) math::floor(50 * -(my - box.y1 - 0.57f));

			glColor4f(0.7f, 0.2f, 0.2f, guiAlpha);
			glDisable(GL_TEXTURE_2D);
			CVertexArray* va = GetVertexArray();
			va->Initialize();

			va->AddVertex0(float3(box.x1 + 0.01f, box.y1 + 0.55f - (sel * 0.02f)         , 0));
			va->AddVertex0(float3(box.x1 + 0.01f, box.y1 + 0.55f - (sel * 0.02f) + 0.02f , 0));
			va->AddVertex0(float3(box.x1 + 0.12f, box.y1 + 0.55f - (sel * 0.02f) + 0.02f , 0));
			va->AddVertex0(float3(box.x1 + 0.12f, box.y1 + 0.55f - (sel * 0.02f)         , 0));

			va->DrawArray0(GL_QUADS);
			glEnable(GL_TEXTURE_2D);
			glColor4f(1, 1, 1, 0.8f);
		}
		float ypos = 0.55f;
		for (size_t a = 0; a < stats.size(); ++a) {
			font->glPrint(box.x1 + 0.01f, box.y1 + ypos, 0.8f, FONT_SCALE | FONT_NORM, stats[a].name);
			ypos -= 0.02f;
		}
		float maxy = 1;

		if (dispMode == 1) {
			maxy = std::max(stats[stat1].max,    (stat2 != -1) ? stats[stat2].max    : 0);
		} else {
			maxy = std::max(stats[stat1].maxdif, (stat2 != -1) ? stats[stat2].maxdif : 0) / TeamStatistics::statsPeriod;
		}

		int numPoints = stats[0].values[0].size();

		for (int a = 0; a < 5; ++a) {
			font->glPrint(box.x1 + 0.12f, box.y1 + 0.07f + (a * 0.135f), 0.8f, FONT_SCALE | FONT_NORM,
			                FloatToSmallString(maxy * 0.25f * a));
			font->glFormat(box.x1 + 0.135f + (a * 0.135f), box.y1 + 0.057f, 0.8f, FONT_SCALE | FONT_NORM, "%02i:%02i",
			                (int) (a * 0.25f * numPoints * TeamStatistics::statsPeriod / 60),
			                (int) (a * 0.25f * (numPoints - 1) * TeamStatistics::statsPeriod) % 60);
		}

		font->glPrint(box.x1 + 0.55f, box.y1 + 0.65f, 0.8f, FONT_SCALE | FONT_NORM, stats[stat1].name);
		font->glPrint(box.x1 + 0.55f, box.y1 + 0.63f, 0.8f, FONT_SCALE | FONT_NORM, (stat2 != -1) ? stats[stat2].name : "");

		glDisable(GL_TEXTURE_2D);
		glBegin(GL_LINES);
				glVertex3f(box.x1+0.50f, box.y1+0.66f, 0);
				glVertex3f(box.x1+0.55f, box.y1+0.66f, 0);
		glEnd();

		glLineStipple(3, 0x5555);
		glEnable(GL_LINE_STIPPLE);
		glBegin(GL_LINES);
				glVertex3f(box.x1 + 0.50f, box.y1 + 0.64f, 0.0f);
				glVertex3f(box.x1 + 0.55f, box.y1 + 0.64f, 0.0f);
		glEnd();
		glDisable(GL_LINE_STIPPLE);

		const float scalex = 0.54f / std::max(1.0f, numPoints - 1.0f);
		const float scaley = 0.54f / maxy;

		for (int team = 0; team < teamHandler->ActiveTeams(); team++) {
			const CTeam* pteam = teamHandler->Team(team);

			if (pteam->gaia) {
				continue;
			}

			glColor4ubv(pteam->color);

			glBegin(GL_LINE_STRIP);
			for (int a = 0; a < numPoints; ++a) {
				float value = 0.0f;

				if (dispMode == 1) {
					value = stats[stat1].values[team][a];
				} else if (a > 0) {
					value = (stats[stat1].values[team][a] - stats[stat1].values[team][a - 1]) / TeamStatistics::statsPeriod;
				}

				glVertex3f(box.x1 + 0.15f + a * scalex, box.y1 + 0.08f + value * scaley, 0.0f);
			}
			glEnd();

			if (stat2 != -1) {
				glLineStipple(3, 0x5555);
				glEnable(GL_LINE_STIPPLE);

				glBegin(GL_LINE_STRIP);
				for (int a = 0; a < numPoints; ++a) {
					float value = 0;
					if (dispMode == 1) {
						value = stats[stat2].values[team][a];
					} else if (a > 0) {
						value = (stats[stat2].values[team][a]-stats[stat2].values[team][a-1]) / TeamStatistics::statsPeriod;
					}

					glVertex3f(box.x1+0.15f+a*scalex, box.y1+0.08f+value*scaley, 0);
				}
				glEnd();

				glDisable(GL_LINE_STIPPLE);
			}
		}
	}
}
Example #25
0
void CWeaponProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points)
{
	points.AddVertexQC(pos, color4::yellow);
}
void CLightningProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points)
{
	unsigned char lcolor[4] = {(unsigned char)color[0]*255,(unsigned char)color[1]*255,(unsigned char)color[2]*255,255};
	lines.AddVertexQC(pos, lcolor);
	lines.AddVertexQC(endPos, lcolor);
}
void CLegacyMeshDrawer::DoDrawGroundShadowLOD(int nlod) {
	CVertexArray* ma = GetVertexArray();
	ma->Initialize();

	bool inStrip = false;
	int x,y;
	int lod = 1 << nlod;

	float cx2 = camera->GetPos().x / SQUARE_SIZE;
	float cy2 = camera->GetPos().z / SQUARE_SIZE;

	float oldcamxpart = 0.0f;
	float oldcamypart = 0.0f;

	int hlod = lod >> 1;
	int dlod = lod << 1;

	int cx = (int)cx2;
	int cy = (int)cy2;
	if (lod > 1) {
		int cxo = (cx / hlod) * hlod;
		int cyo = (cy / hlod) * hlod;
		float cx2o = (cxo / lod) * lod;
		float cy2o = (cyo / lod) * lod;
		oldcamxpart = (cx2 - cx2o) / lod;
		oldcamypart = (cy2 - cy2o) / lod;
	}

	cx = (cx / lod) * lod;
	cy = (cy / lod) * lod;
	const int ysquaremod = (cy % dlod) / lod;
	const int xsquaremod = (cx % dlod) / lod;

	const float camxpart = (cx2 - (cx / dlod) * dlod) / dlod;
	const float camypart = (cy2 - (cy / dlod) * dlod) / dlod;

	const int minty = 0, maxty = mapDims.mapy;
	const int mintx = 0, maxtx = mapDims.mapx;

	const int minly = cy + (-viewRadius + 3 - ysquaremod) * lod, maxly = cy + ( viewRadius - 1 - ysquaremod) * lod;
	const int minlx = cx + (-viewRadius + 3 - xsquaremod) * lod, maxlx = cx + ( viewRadius - 1 - xsquaremod) * lod;

	const int xstart = std::max(minlx, mintx), xend   = std::min(maxlx, maxtx);
	const int ystart = std::max(minly, minty), yend   = std::min(maxly, maxty);

	const int lhdx = lod * smfReadMap->heightMapSizeX;
	const int hhdx = hlod * smfReadMap->heightMapSizeX;
	const int dhdx = dlod * smfReadMap->heightMapSizeX;

	const float mcxp  = 1.0f - camxpart, mcyp  = 1.0f - camypart;
	const float hcxp  = 0.5f * camxpart, hcyp  = 0.5f * camypart;
	const float hmcxp = 0.5f * mcxp,     hmcyp = 0.5f * mcyp;

	const float mocxp  = 1.0f - oldcamxpart, mocyp  = 1.0f - oldcamypart;
	const float hocxp  = 0.5f * oldcamxpart, hocyp  = 0.5f * oldcamypart;
	const float hmocxp = 0.5f * mocxp,       hmocyp = 0.5f * mocyp;

	const int vrhlod = viewRadius * hlod;

	for (y = ystart; y < yend; y += lod) {
		int xs = xstart;
		int xe = xend;

		if (xe < xs) continue;

		int ylod = y + lod;
		int yhlod = y + hlod;
		int ydx = y * smfReadMap->heightMapSizeX;
		int nloop = (xe - xs) / lod + 1;

		ma->EnlargeArrays(52 * nloop);

		for (x = xs; x < xe; x += lod) {
			int xlod = x + lod;
			int xhlod = x + hlod;
			if ((lod == 1) ||
				(x > cx + vrhlod) || (x < cx - vrhlod) ||
				(y > cy + vrhlod) || (y < cy - vrhlod)) {
					if (!inStrip) {
						DrawVertexAQ(ma, x, y   );
						DrawVertexAQ(ma, x, ylod);
						inStrip = true;
					}
					DrawVertexAQ(ma, xlod, y   );
					DrawVertexAQ(ma, xlod, ylod);
			}
			else {  //! inre begr?sning mot f?eg?nde lod
				int yhdx=ydx+x;
				int ylhdx=yhdx+lhdx;
				int yhhdx=yhdx+hhdx;

				if ( x>= cx + vrhlod) {
					const float h1 = (GetVisibleVertexHeight(yhdx ) + GetVisibleVertexHeight(ylhdx    )) * hmocxp + GetVisibleVertexHeight(yhhdx     ) * oldcamxpart;
					const float h2 = (GetVisibleVertexHeight(yhdx ) + GetVisibleVertexHeight(yhdx+lod )) * hmocxp + GetVisibleVertexHeight(yhdx+hlod ) * oldcamxpart;
					const float h3 = (GetVisibleVertexHeight(ylhdx) + GetVisibleVertexHeight(yhdx+lod )) * hmocxp + GetVisibleVertexHeight(yhhdx+hlod) * oldcamxpart;
					const float h4 = (GetVisibleVertexHeight(ylhdx) + GetVisibleVertexHeight(ylhdx+lod)) * hmocxp + GetVisibleVertexHeight(ylhdx+hlod) * oldcamxpart;

					if(inStrip){
						ma->EndStrip();
						inStrip=false;
					}
					DrawVertexAQ(ma, x,y);
					DrawVertexAQ(ma, x,yhlod,h1);
					DrawVertexAQ(ma, xhlod,y,h2);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					ma->EndStrip();
					DrawVertexAQ(ma, x,yhlod,h1);
					DrawVertexAQ(ma, x,ylod);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					DrawVertexAQ(ma, xhlod,ylod,h4);
					ma->EndStrip();
					DrawVertexAQ(ma, xhlod,ylod,h4);
					DrawVertexAQ(ma, xlod,ylod);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					DrawVertexAQ(ma, xlod,y);
					DrawVertexAQ(ma, xhlod,y,h2);
					ma->EndStrip();
				}
				if (x <= cx - vrhlod) {
					const float h1 = (GetVisibleVertexHeight(yhdx+lod) + GetVisibleVertexHeight(ylhdx+lod)) * hocxp + GetVisibleVertexHeight(yhhdx+lod ) * mocxp;
					const float h2 = (GetVisibleVertexHeight(yhdx    ) + GetVisibleVertexHeight(yhdx+lod )) * hocxp + GetVisibleVertexHeight(yhdx+hlod ) * mocxp;
					const float h3 = (GetVisibleVertexHeight(ylhdx   ) + GetVisibleVertexHeight(yhdx+lod )) * hocxp + GetVisibleVertexHeight(yhhdx+hlod) * mocxp;
					const float h4 = (GetVisibleVertexHeight(ylhdx   ) + GetVisibleVertexHeight(ylhdx+lod)) * hocxp + GetVisibleVertexHeight(ylhdx+hlod) * mocxp;

					if(inStrip){
						ma->EndStrip();
						inStrip=false;
					}
					DrawVertexAQ(ma, xlod,yhlod,h1);
					DrawVertexAQ(ma, xlod,y);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					DrawVertexAQ(ma, xhlod,y,h2);
					ma->EndStrip();
					DrawVertexAQ(ma, xlod,ylod);
					DrawVertexAQ(ma, xlod,yhlod,h1);
					DrawVertexAQ(ma, xhlod,ylod,h4);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					ma->EndStrip();
					DrawVertexAQ(ma, xhlod,y,h2);
					DrawVertexAQ(ma, x,y);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					DrawVertexAQ(ma, x,ylod);
					DrawVertexAQ(ma, xhlod,ylod,h4);
					ma->EndStrip();
				}
				if (y >= cy + vrhlod) {
					const float h1 = (GetVisibleVertexHeight(yhdx     ) + GetVisibleVertexHeight(yhdx+lod)) * hmocyp + GetVisibleVertexHeight(yhdx+hlod ) * oldcamypart;
					const float h2 = (GetVisibleVertexHeight(yhdx     ) + GetVisibleVertexHeight(ylhdx   )) * hmocyp + GetVisibleVertexHeight(yhhdx     ) * oldcamypart;
					const float h3 = (GetVisibleVertexHeight(ylhdx    ) + GetVisibleVertexHeight(yhdx+lod)) * hmocyp + GetVisibleVertexHeight(yhhdx+hlod) * oldcamypart;
					const float h4 = (GetVisibleVertexHeight(ylhdx+lod) + GetVisibleVertexHeight(yhdx+lod)) * hmocyp + GetVisibleVertexHeight(yhhdx+lod ) * oldcamypart;

					if(inStrip){
						ma->EndStrip();
						inStrip=false;
					}
					DrawVertexAQ(ma, x,y);
					DrawVertexAQ(ma, x,yhlod,h2);
					DrawVertexAQ(ma, xhlod,y,h1);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					DrawVertexAQ(ma, xlod,y);
					DrawVertexAQ(ma, xlod,yhlod,h4);
					ma->EndStrip();
					DrawVertexAQ(ma, x,yhlod,h2);
					DrawVertexAQ(ma, x,ylod);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					DrawVertexAQ(ma, xlod,ylod);
					DrawVertexAQ(ma, xlod,yhlod,h4);
					ma->EndStrip();
				}
				if (y <= cy - vrhlod) {
					const float h1 = (GetVisibleVertexHeight(ylhdx    ) + GetVisibleVertexHeight(ylhdx+lod)) * hocyp + GetVisibleVertexHeight(ylhdx+hlod) * mocyp;
					const float h2 = (GetVisibleVertexHeight(yhdx     ) + GetVisibleVertexHeight(ylhdx    )) * hocyp + GetVisibleVertexHeight(yhhdx     ) * mocyp;
					const float h3 = (GetVisibleVertexHeight(ylhdx    ) + GetVisibleVertexHeight(yhdx+lod )) * hocyp + GetVisibleVertexHeight(yhhdx+hlod) * mocyp;
					const float h4 = (GetVisibleVertexHeight(ylhdx+lod) + GetVisibleVertexHeight(yhdx+lod )) * hocyp + GetVisibleVertexHeight(yhhdx+lod ) * mocyp;

					if (inStrip) {
						ma->EndStrip();
						inStrip = false;
					}
					DrawVertexAQ(ma, x,yhlod,h2);
					DrawVertexAQ(ma, x,ylod);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					DrawVertexAQ(ma, xhlod,ylod,h1);
					DrawVertexAQ(ma, xlod,yhlod,h4);
					DrawVertexAQ(ma, xlod,ylod);
					ma->EndStrip();
					DrawVertexAQ(ma, xlod,yhlod,h4);
					DrawVertexAQ(ma, xlod,y);
					DrawVertexAQ(ma, xhlod,yhlod,h3);
					DrawVertexAQ(ma, x,y);
					DrawVertexAQ(ma, x,yhlod,h2);
					ma->EndStrip();
				}
			}
		}
		if (inStrip) {
			ma->EndStrip();
			inStrip=false;
		}
	}

	int yst = std::max(ystart - lod, minty);
	int yed = std::min(yend + lod, maxty);
	int nloop = (yed - yst) / lod + 1;
	ma->EnlargeArrays(8 * nloop);

	//!rita yttre begr?snings yta mot n?ta lod
	if (maxlx < maxtx && maxlx >= mintx) {
		x = maxlx;
		const int xlod = x + lod;

		for (y = yst; y < yed; y += lod) {
			DrawVertexAQ(ma, x, y      );
			DrawVertexAQ(ma, x, y + lod);
			const int yhdx = y * smfReadMap->heightMapSizeX + x;

			if (y % dlod) {
				const float h = (GetVisibleVertexHeight(yhdx - lhdx + lod) + GetVisibleVertexHeight(yhdx + lhdx + lod)) * hmcxp + GetVisibleVertexHeight(yhdx+lod) * camxpart;
				DrawVertexAQ(ma, xlod, y, h);
				DrawVertexAQ(ma, xlod, y + lod);
			} else {
				const float h = (GetVisibleVertexHeight(yhdx+lod) + GetVisibleVertexHeight(yhdx+dhdx+lod)) * hmcxp + GetVisibleVertexHeight(yhdx+lhdx+lod) * camxpart;
				DrawVertexAQ(ma, xlod,y);
				DrawVertexAQ(ma, xlod,y+lod,h);
			}
			ma->EndStrip();
		}
	}

	if (minlx > mintx && minlx < maxtx) {
		x = minlx - lod;
		const int xlod = x + lod;

		for(y = yst; y < yed; y += lod) {
			int yhdx = y * smfReadMap->heightMapSizeX + x;
			if(y%dlod){
				const float h = (GetVisibleVertexHeight(yhdx-lhdx) + GetVisibleVertexHeight(yhdx+lhdx)) * hcxp + GetVisibleVertexHeight(yhdx) * mcxp;
				DrawVertexAQ(ma, x,y,h);
				DrawVertexAQ(ma, x,y+lod);
			} else {
				const float h = (GetVisibleVertexHeight(yhdx) + GetVisibleVertexHeight(yhdx+dhdx)) * hcxp + GetVisibleVertexHeight(yhdx+lhdx) * mcxp;
				DrawVertexAQ(ma, x,y);
				DrawVertexAQ(ma, x,y+lod,h);
			}
			DrawVertexAQ(ma, xlod,y);
			DrawVertexAQ(ma, xlod,y+lod);
			ma->EndStrip();
		}
	}
	if (maxly < maxty && maxly > minty) {
		y = maxly;
		const int xs = std::max(xstart -lod, mintx);
		const int xe = std::min(xend + lod, maxtx);

		if (xs < xe) {
			x = xs;
			const int ylod = y + lod;
			const int ydx = y * smfReadMap->heightMapSizeX;
			const int nloop = (xe - xs) / lod + 2; //! two extra for if statment

			ma->EnlargeArrays(2 * nloop);

			if (x % dlod) {
				const int ylhdx = ydx + x + lhdx;
				const float h = (GetVisibleVertexHeight(ylhdx-lod) + GetVisibleVertexHeight(ylhdx+lod)) * hmcyp + GetVisibleVertexHeight(ylhdx) * camypart;
				DrawVertexAQ(ma, x, y);
				DrawVertexAQ(ma, x, ylod, h);
			} else {
				DrawVertexAQ(ma, x, y);
				DrawVertexAQ(ma, x, ylod);
			}

			for (x = xs; x < xe; x += lod) {
				if (x % dlod) {
					DrawVertexAQ(ma, x + lod, y);
					DrawVertexAQ(ma, x + lod, ylod);
				} else {
					DrawVertexAQ(ma, x+lod,y);
					const int ylhdx = ydx + x + lhdx;
					const float h = (GetVisibleVertexHeight(ylhdx+dlod) + GetVisibleVertexHeight(ylhdx)) * hmcyp + GetVisibleVertexHeight(ylhdx+lod) * camypart;
					DrawVertexAQ(ma, x+lod,ylod,h);
				}
			}
			ma->EndStrip();
		}
	}
	if (minly > minty && minly < maxty) {
		y = minly - lod;
		const int xs = std::max(xstart - lod, mintx);
		const int xe = std::min(xend + lod, maxtx);

		if (xs < xe) {
			x = xs;
			const int ylod = y + lod;
			const int ydx = y * smfReadMap->heightMapSizeX;
			const int nloop = (xe - xs) / lod + 2; //! two extra for if statment

			ma->EnlargeArrays(2 * nloop);

			if (x % dlod) {
				const int yhdx = ydx + x;
				const float h = (GetVisibleVertexHeight(yhdx-lod) + GetVisibleVertexHeight(yhdx + lod)) * hcyp + GetVisibleVertexHeight(yhdx) * mcyp;
				DrawVertexAQ(ma, x, y, h);
				DrawVertexAQ(ma, x, ylod);
			} else {
				DrawVertexAQ(ma, x, y);
				DrawVertexAQ(ma, x, ylod);
			}

			for (x = xs; x < xe; x += lod) {
				if (x % dlod) {
					DrawVertexAQ(ma, x + lod, y);
					DrawVertexAQ(ma, x + lod, ylod);
				} else {
					const int yhdx = ydx + x;
					const float h = (GetVisibleVertexHeight(yhdx+dlod) + GetVisibleVertexHeight(yhdx)) * hcyp + GetVisibleVertexHeight(yhdx+lod) * mcyp;
					DrawVertexAQ(ma, x + lod, y, h);
					DrawVertexAQ(ma, x + lod, ylod);
				}
			}
			ma->EndStrip();
		}
	}
	DrawGroundVertexArrayQ(ma);
}
Example #28
0
void CGrassDrawer::CreateFarTex()
{
	//TODO create normalmap, too?
	const int sizeMod = 2;
	const int billboardSize = 256;
	const int numAngles = 16;
	const int texSizeX = billboardSize * numAngles;
	const int texSizeY = billboardSize;

	if (farTex == 0) {
		glGenTextures(1, &farTex);
		glBindTexture(GL_TEXTURE_2D, farTex);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glSpringTexStorage2D(GL_TEXTURE_2D, -1, GL_RGBA8, texSizeX, texSizeY);
	}

	FBO fboTex;
	fboTex.Bind();
	fboTex.AttachTexture(farTex);
	fboTex.CheckStatus("GRASSDRAWER1");

	FBO fbo;
	fbo.Bind();
	fbo.CreateRenderBuffer(GL_DEPTH_ATTACHMENT_EXT, GL_DEPTH_COMPONENT16, texSizeX * sizeMod, texSizeY * sizeMod);
	fbo.CreateRenderBuffer(GL_COLOR_ATTACHMENT0_EXT, GL_RGBA8, texSizeX * sizeMod, texSizeY * sizeMod);
	fbo.CheckStatus("GRASSDRAWER2");

	if (!fboTex.IsValid() || !fbo.IsValid()) {
		grassOff = true;
		return;
	}

	glPushMatrix();
	glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();

	glDisable(GL_FOG);
	glDisable(GL_BLEND);
	glDisable(GL_ALPHA_TEST);
	glBindTexture(GL_TEXTURE_2D, grassBladeTex);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_CLIP_PLANE0);
	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);
	glColor4f(1,1,1,1);

	glViewport(0,0,texSizeX*sizeMod, texSizeY*sizeMod);
	glClearColor(mapInfo->grass.color.r,mapInfo->grass.color.g,mapInfo->grass.color.b,0.f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0.f,0.f,0.f,0.f);

	static const GLdouble eq[4] = {0.f, 1.f, 0.f, 0.f};

	// render turf from different vertical angles
	for (int a=0;a<numAngles;++a) {
		glViewport(a*billboardSize*sizeMod, 0, billboardSize*sizeMod, billboardSize*sizeMod);
		glMatrixMode(GL_MODELVIEW);
			glLoadIdentity();
			glRotatef(a*90.f/(numAngles-1),1,0,0);
			//glTranslatef(0,-0.5f,0);
		glMatrixMode(GL_PROJECTION);
			glLoadIdentity();
			glOrtho(-partTurfSize, partTurfSize, partTurfSize, -partTurfSize, -turfSize, turfSize);

		// has to be applied after the matrix transformations,
		// cause it uses those an `compiles` them into the clip plane
		glClipPlane(GL_CLIP_PLANE0, &eq[0]);

		glCallList(grassDL);
	}

	glDisable(GL_CLIP_PLANE0);

	// scale down the rendered fartextures (MSAA) and write to the final texture
	glBindFramebufferEXT(GL_READ_FRAMEBUFFER, fbo.fboId);
	glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, fboTex.fboId);
	glBlitFramebufferEXT(0, 0, texSizeX*sizeMod, texSizeY*sizeMod,
		0, 0, texSizeX, texSizeY,
		GL_COLOR_BUFFER_BIT, GL_LINEAR);

	// compute mipmaps
	glBindTexture(GL_TEXTURE_2D, farTex);
	glGenerateMipmap(GL_TEXTURE_2D);

	// blur non-rendered areas, so in mipmaps color data isn't blurred with background color
	{
		const int mipLevels = std::ceil(std::log(std::max(texSizeX, texSizeY) + 1));

		glMatrixMode(GL_MODELVIEW);
			glLoadIdentity();
		glMatrixMode(GL_PROJECTION);
			glLoadIdentity();

		glEnable(GL_BLEND);
		glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ZERO, GL_DST_ALPHA);

		// copy each mipmap to its predecessor background
		// -> fill background with blurred color data
		fboTex.Bind();
		for (int mipLevel = mipLevels - 2; mipLevel >= 0; --mipLevel) {
			fboTex.AttachTexture(farTex, GL_TEXTURE_2D, GL_COLOR_ATTACHMENT0_EXT, mipLevel);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, mipLevel + 1.f);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, mipLevel + 1.f);
			glViewport(0, 0, texSizeX>>mipLevel, texSizeY>>mipLevel);

			CVertexArray* va = GetVertexArray();
			va->Initialize();
				va->AddVertexT(float3(-1.0f,  1.0f, 0.0f), 0.0f, 1.0f);
				va->AddVertexT(float3( 1.0f,  1.0f, 0.0f), 1.0f, 1.0f);
				va->AddVertexT(float3( 1.0f, -1.0f, 0.0f), 1.0f, 0.0f);
				va->AddVertexT(float3(-1.0f, -1.0f, 0.0f), 0.0f, 0.0f);
			va->DrawArrayT(GL_QUADS);
		}

		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

		// recreate mipmaps from now blurred base level
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, -1000.f);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD,  1000.f);
		glGenerateMipmap(GL_TEXTURE_2D);
	}

	glViewport(globalRendering->viewPosX, 0, globalRendering->viewSizeX, globalRendering->viewSizeY);
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	FBO::Unbind();
	//glSaveTexture(farTex, "grassfar.png");
}
void CProjectileHandler::Draw(bool drawReflection, bool drawRefraction) {
	glDisable(GL_BLEND);
	glEnable(GL_TEXTURE_2D);
	glDepthMask(1);

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

	CVertexArray* va = GetVertexArray();

	/* Putting in, say, viewport culling will deserve refactoring. */

	unitDrawer->SetupForUnitDrawing();

	{
		GML_STDMUTEX_LOCK(rpiece); // Draw

		flyingPieces.delete_delayed();
		flyingPieces.add_delayed();
	}

	size_t lasttex = 0xFFFFFFFF;
	size_t lastteam = 0xFFFFFFFF;
	va->Initialize();

	int numFlyingPieces = flyingPieces.render_size();
	int drawnPieces = numFlyingPieces;
	va->EnlargeArrays(numFlyingPieces * 4, 0, VA_SIZE_TN);

	FlyingPieceContainer::render_iterator fpi = flyingPieces.render_begin();

	// S3O flying pieces
	for( ; fpi != flyingPieces.render_end(); ++fpi) {
		FlyingPiece *fp = *fpi;
		if (fp->texture != lasttex) {
			lasttex = fp->texture;
			if (lasttex == 0)
				break;
			va->DrawArrayTN(GL_QUADS);
			va->Initialize();
			texturehandlerS3O->SetS3oTexture(lasttex);
		}
		if (fp->team != lastteam) {
			lastteam = fp->team;
			va->DrawArrayTN(GL_QUADS);
			va->Initialize();
			unitDrawer->SetTeamColour(lastteam);
		}
		CMatrix44f m;
		m.Rotate(fp->rot, fp->rotAxis);
		float3 interPos = fp->pos + fp->speed * gu->timeOffset;
		SS3OVertex* verts = fp->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->AddVertexQTN(tp, verts[i].textureX, verts[i].textureY, tn);
		}
	}

	va->DrawArrayTN(GL_QUADS);
	va->Initialize();

	unitDrawer->SetupFor3DO();

	// 3DO flying pieces
	for ( ; fpi != flyingPieces.render_end(); ++fpi) {
		FlyingPiece* fp = *fpi;
		CMatrix44f m;
		m.Rotate(fp->rot, fp->rotAxis);
		float3 interPos = fp->pos + fp->speed * gu->timeOffset;
		C3DOTextureHandler::UnitTexture* tex = fp->prim->texture;

		const std::vector<S3DOVertex>& vertices    = fp->object->vertices;
		const std::vector<int>&        verticesIdx = fp->prim->vertices;

		const S3DOVertex* v = &vertices[verticesIdx[0]];
		float3 tp = m.Mul(v->pos);
		float3 tn = m.Mul(v->normal);
		tp += interPos;
		va->AddVertexQTN(tp, tex->xstart, tex->ystart, tn);

		v = &vertices[verticesIdx[1]];
		tp = m.Mul(v->pos);
		tn = m.Mul(v->normal);
		tp += interPos;
		va->AddVertexQTN(tp, tex->xend, tex->ystart, tn);

		v = &vertices[verticesIdx[2]];
		tp = m.Mul(v->pos);
		tn = m.Mul(v->normal);
		tp += interPos;
		va->AddVertexQTN(tp, tex->xend, tex->yend, tn);

		v = &vertices[verticesIdx[3]];
		tp = m.Mul(v->pos);
		tn = m.Mul(v->normal);
		tp += interPos;
		va->AddVertexQTN(tp, tex->xstart, tex->yend, tn);
	}

	va->DrawArrayTN(GL_QUADS);

	distset.clear();

	{
		GML_STDMUTEX_LOCK(rproj); // Draw

		//! batch-insert projectiles into render queue
		syncedProjectiles.add_delayed();

		unsyncedProjectiles.delete_delayed();
		unsyncedProjectiles.add_delayed();
	}

	{
		GML_STDMUTEX_LOCK(proj); // Draw

		//! 3DO projectiles get rendered immediately here, S3O's are queued
		DrawProjectiles(syncedProjectiles, drawReflection, drawRefraction);
		DrawProjectiles(unsyncedProjectiles, drawReflection, drawRefraction);

		unitDrawer->CleanUp3DO();
		unitDrawer->DrawQuedS3O(); //! draw qued S3O projectiles
		unitDrawer->CleanUpUnitDrawing();

		currentParticles = 0;
		CProjectile::inArray = false;
		CProjectile::va = GetVertexArray();
		CProjectile::va->Initialize();

		for (std::set<CProjectile*, distcmp>::iterator i = distset.begin(); i != distset.end(); ++i) {
			(*i)->Draw();
		}
	}

	glEnable(GL_BLEND);
	glDisable(GL_FOG);

	if (CProjectile::inArray) {
		// Alpha transculent particles
		glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_TEXTURE_2D);
		textureAtlas->BindTexture();
		glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
		glAlphaFunc(GL_GREATER, 0.0f);
		glEnable(GL_ALPHA_TEST);
		glDepthMask(0);

		// note: nano-particles (CGfxProjectile instances) also
		// contribute to the count, but have their own creation
		// cutoff
		currentParticles += CProjectile::DrawArray();
	}

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	//glDisable(GL_TEXTURE_2D);
	glDisable(GL_ALPHA_TEST);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glDepthMask(1);

	currentParticles  = int(currentParticles * 0.2f);
	currentParticles += int((syncedProjectiles.render_size() + unsyncedProjectiles.render_size()) * 0.8f);
	currentParticles += (int) (0.2f * drawnPieces + 0.3f * numFlyingPieces);

	particleSaturation     = currentParticles     / float(maxParticles);
	nanoParticleSaturation = currentNanoParticles / float(maxNanoParticles);
}
void InMapDraw_QuadDrawer::DrawQuad(int x, int y)
{
	int drawQuadsX = imd->drawQuadsX;
	CInMapDraw::DrawQuad* dq = &imd->drawQuads[y * drawQuadsX + x];

	va->EnlargeArrays(dq->points.size()*12,0,VA_SIZE_TC);
	// draw point markers
	for (std::list<CInMapDraw::MapPoint>::iterator pi = dq->points.begin(); pi != dq->points.end(); ++pi) {
		const int allyteam = pi->senderAllyTeam;
		const bool spec = pi->senderSpectator;
		const bool allied = (gs->Ally(gu->myAllyTeam, allyteam) && gs->Ally(allyteam, gu->myAllyTeam));
		const bool maySee = (gu->spectating || (!spec && allied) || imd->drawAll);

		if (maySee) {
			float3 pos = pi->pos;
			float3 dif(pos - camera->pos);
			float camDist = dif.Length();
			dif /= camDist;
			float3 dir1(dif.cross(UpVector));
			dir1.Normalize();
			float3 dir2(dif.cross(dir1));

			unsigned char col[4];
			col[0] = pi->color[0];
			col[1] = pi->color[1];
			col[2] = pi->color[2];
			col[3] = 200;

			float size = 6;
			float3 pos1 = pos;
			float3 pos2 = pos1;
			pos2.y += 100;

			va->AddVertexQTC(pos1 - dir1 * size,               0.25f, 0, col);
			va->AddVertexQTC(pos1 + dir1 * size,               0.25f, 1, col);
			va->AddVertexQTC(pos1 + dir1 * size + dir2 * size, 0.00f, 1, col);
			va->AddVertexQTC(pos1 - dir1 * size + dir2 * size, 0.00f, 0, col);

			va->AddVertexQTC(pos1 - dir1 * size,               0.75f, 0, col);
			va->AddVertexQTC(pos1 + dir1 * size,               0.75f, 1, col);
			va->AddVertexQTC(pos2 + dir1 * size,               0.75f, 1, col);
			va->AddVertexQTC(pos2 - dir1 * size,               0.75f, 0, col);

			va->AddVertexQTC(pos2 - dir1 * size,               0.25f, 0, col);
			va->AddVertexQTC(pos2 + dir1 * size,               0.25f, 1, col);
			va->AddVertexQTC(pos2 + dir1 * size - dir2 * size, 0.00f, 1, col);
			va->AddVertexQTC(pos2 - dir1 * size - dir2 * size, 0.00f, 0, col);

			if (pi->label.size() > 0) {
				glPushMatrix();
				glTranslatef3(pi->pos + UpVector * 105);
				glScalef(1200, 1200, 1200);
				glColor4ub(pi->color[0], pi->color[1], pi->color[2], 250);
				font->glWorldPrint(pi->label.c_str());
				glPopMatrix();
			}
		}
	}

	va->EnlargeArrays(dq->lines.size()*2,0,VA_SIZE_C);
	// draw line markers
	for (std::list<CInMapDraw::MapLine>::iterator li = dq->lines.begin(); li != dq->lines.end(); ++li) {
		const int allyteam = li->senderAllyTeam;
		const bool spec = li->senderSpectator;
		const bool allied = (gs->Ally(gu->myAllyTeam, allyteam) && gs->Ally(allyteam, gu->myAllyTeam));
		const bool maySee = (gu->spectating || (!spec && allied) || imd->drawAll);

		if (maySee) {
			lineva->AddVertexQC(li->pos - (li->pos - camera->pos).ANormalize() * 26, li->color);
			lineva->AddVertexQC(li->pos2 - (li->pos2 - camera->pos).ANormalize() * 26, li->color);
		}
	}
}