Example #1
0
ProfileDrawer::ProfileDrawer()
: CEventClient("[ProfileDrawer]", 199991, false)
{
	autoLinkEvents = true;
	RegisterLinkedEvents(this);
	eventHandler.AddClient(this);
}
Example #2
0
CGrassDrawer::CGrassDrawer()
: CEventClient("[GrassDrawer]", 199992, false)
, grassOff(false)
, blocksX(mapDims.mapx / grassSquareSize / grassBlockSize)
, blocksY(mapDims.mapy / grassSquareSize / grassBlockSize)
, grassDL(0)
, grassBladeTex(0)
, farTex(0)
, farnearVA(nullptr)
, updateBillboards(false)
, grassMap(nullptr)
{
	blockDrawer.ResetState();
	rng.Seed(15);

	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;
	}

	// needed to create the far tex
	if (!GLEW_EXT_framebuffer_blit) {
		grassOff = true;
		return;
	}

	// load grass density from map
	{
		MapBitmapInfo grassbm;
		unsigned char* grassdata = readMap->GetInfoMap("grass", &grassbm);
		if (!grassdata) {
			grassOff = true;
			return;
		}

		if (grassbm.width != mapDims.mapx / grassSquareSize || grassbm.height != mapDims.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, mapDims.mapx / 4, mapDims.mapy / 4);
			throw std::runtime_error(b);
		}
		const int grassMapSize = mapDims.mapx * mapDims.mapy / (grassSquareSize * grassSquareSize);
		grassMap = new unsigned char[grassMapSize];
		memcpy(grassMap, grassdata, grassMapSize);
		readMap->FreeInfoMap("grass", grassdata);
	}

	// create/load blade texture
	{
		CBitmap grassBladeTexBM;
		if (!grassBladeTexBM.Load(mapInfo->grass.bladeTexName)) {
			// 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]);
			}
		}
		//grassBladeTexBM.Save("blade.png", false);
		grassBladeTex = grassBladeTexBM.CreateTexture(true);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}

	// create shaders * finalize
	grass.resize(blocksX * blocksY);
	farnearVA = new CVertexArray;
	grassDL = glGenLists(1);

	ChangeDetail(detail);
	LoadGrassShaders();
	configHandler->NotifyOnChange(this);

	// eventclient
	autoLinkEvents = true;
	RegisterLinkedEvents(this);
	eventHandler.AddClient(this);
}