示例#1
0
void CGrassDrawer::ChangeDetail(int detail) {
	// TODO: get rid of the magic constants
	const int detail_lim = std::min(3, detail);
	maxGrassDist = 800 + std::sqrt((float) detail) * 240;
	maxDetailedDist = 146 + detail * 24;
	detailedBlocks = int((maxDetailedDist + 128.f * 1.5f) / bMSsq) + 1;
	numTurfs = 3 + int(detail_lim * 0.5f);
	strawPerTurf = std::min(50 + int(std::sqrt((float)detail_lim) * 10), mapInfo->grass.maxStrawsPerTurf);

	// recreate textures & XBOs
	CreateGrassDispList(grassDL);
	CreateFarTex();

	// reset  all cached blocks
	for (GrassStruct& pGS: grass) {
		ResetPos(pGS.posX, pGS.posZ);
	}
}
示例#2
0
CGrassDrawer::CGrassDrawer()
: grassOff(false)
, grassDL(0)
, grassBladeTex(0)
, farTex(0)
, grassMap(nullptr)
{
	const int detail = configHandler->GetInt("GrassDetail");

	// some ATI drivers crash with grass enabled, default to disabled
	if ((detail == 0) || ((detail == 7) && globalRendering->haveATI)) {
		grassOff = true;
		return;
	}

	if (!GLEW_EXT_framebuffer_blit) {
		grassOff = true;
		return;
	}

	{
		MapBitmapInfo grassbm;
		unsigned char* grassdata = readMap->GetInfoMap("grass", &grassbm);

		if (!grassdata) {
			grassOff = true;
			return;
		}

		if (grassbm.width != gs->mapx / grassSquareSize || grassbm.height != gs->mapy / grassSquareSize) {
			char b[128];
			SNPRINTF(b, sizeof(b), "grass-map has wrong size (%dx%d, should be %dx%d)\n",
				grassbm.width, grassbm.height, gs->mapx / 4, gs->mapy / 4);
			throw std::runtime_error(b);
		}
		const int grassMapSize = gs->mapx * gs->mapy / (grassSquareSize * grassSquareSize);
		grassMap = new unsigned char[grassMapSize];
		memcpy(grassMap, grassdata, grassMapSize);
		readMap->FreeInfoMap("grass", grassdata);
	}

	ChangeDetail(detail);

	blocksX = gs->mapx / grassSquareSize / grassBlockSize;
	blocksY = gs->mapy / grassSquareSize / grassBlockSize;

	rng.Seed(15);
	grassDL = glGenLists(1);
	CreateGrassDispList(grassDL);

	{
		CBitmap grassBladeTexBM;
		if (!grassBladeTexBM.Load(mapInfo->grass.grassBladeTexName)) {
			//! map didn't define a grasstex, so generate one
			grassBladeTexBM.channels = 4;
			grassBladeTexBM.Alloc(256,64);

			for (int a = 0; a < 16; ++a) {
				CreateGrassBladeTex(&grassBladeTexBM.mem[a * 16 * 4]);
			}
		}

		glGenTextures(1, &grassBladeTex);
		glBindTexture(GL_TEXTURE_2D, grassBladeTex);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
		glBuildMipmaps(GL_TEXTURE_2D, GL_RGBA8, grassBladeTexBM.xsize, grassBladeTexBM.ysize, GL_RGBA, GL_UNSIGNED_BYTE, &grassBladeTexBM.mem[0]);
	}

	CreateFarTex();
	LoadGrassShaders();
	configHandler->NotifyOnChange(this);
}