All pastes #917129 Raw Edit

Miscellany

public cpp v1 · immutable
#917129 ·published 2008-02-25 03:47 UTC
rendered paste body
////////////////////////// Terrain.cpp//CompileZone - Compiles a zone into a renderable formvoid Terrain::CompileZone(zone &z, u32 zoneidx){	//Calculate zone offset	u32 zone_ofs_x = (zoneidx % ZONE_GRID) * m_zonearea;	u32 zone_ofs_y = (zoneidx / ZONE_GRID) * m_zonearea;	//Allocate a block of memory for the verticies, normals and texture coordinates	if (!z.verts)		z.verts = (Vector3*)malloc(sizeof(Vector3) * m_zonesizesq);	if (!z.normals)		z.normals = (Vector3*)malloc(sizeof(Vector3) * m_zonesizesq);	if (!z.texcoords)		z.texcoords = (Vector2*)malloc(sizeof(Vector2) * m_zonesizesq);	//Create the verticies based on our cell data	for (u32 y = 0; y < m_zonesize; ++y) 	{		for (u32 x = 0; x < m_zonesize; ++x)		{	//Convert into a vertex			u32 ofs = x + (y * m_zonesize);			z.verts[ofs].x = (zone_ofs_x + x);			z.verts[ofs].y = z.cells[x + (y * m_zonesize)].height;			z.verts[ofs].z = (zone_ofs_y + y);			//Bring over the normal data			z.normals[ofs] = z.cells[x + (y * m_zonesize)].normal;			//Set the texture coordinates			z.texcoords[ofs].x = (f32(x) / (m_zonesize - 1));			z.texcoords[ofs].y = (f32(y) / (m_zonesize - 1));		}	}	//If we don't have initialized vertex arrays yet, then	if (!z.var_vertex)	{	//create them and shove in all the vertex data		z.var_vertex = new VAR(z.verts, m_zonesizesq, m_vaarea);		z.var_normal = new VAR(z.normals, m_zonesizesq, m_vaarea);		z.var_tex = new VAR(z.texcoords, m_zonesizesq, m_vaarea);	}	else	{	//Are they valid?		if (!z.var_vertex->valid() || !z.var_normal->valid() || !z.var_tex->valid())		{	//Delete and create new arrays			delete z.var_vertex;			delete z.var_tex;			delete z.var_normal;			z.var_vertex = new VAR(z.verts, m_zonesizesq, m_vaarea);			z.var_normal = new VAR(z.normals, m_zonesizesq, m_vaarea);			z.var_tex = new VAR(z.texcoords, m_zonesizesq, m_vaarea);		}		else		{	//Otherwise, update the existing ones			z.var_vertex->update(z.verts, m_zonesizesq);			z.var_normal->update(z.normals, m_zonesizesq);			z.var_tex->update(z.texcoords, m_zonesizesq);		}	}	// Construct the zone texture	/////////////////////////////////////////////	textureBlender tB;	Array<u8> alphaMaps[LAYER_COUNT];	//add all our source layer textures	for (u32 i=0; i < LAYER_COUNT; ++i)	{	//Construct the alphamap		alphaMaps[i].resize(m_zonesizesq);		u8 *mapPtr = alphaMaps[i].getCArray();				//Convert the celldata into an alphamap		for (s32 y=0; y < s32(m_zonesize); ++y)			for (s32 x=0; x < s32(m_zonesize); ++x)				mapPtr[x + (y * m_zonesize)] = z.cells[x + (y * m_zonesize)].layeralphas[i];		tB.addTexture(i, m_layers[i], mapPtr);	}		//Blend everything to form a texture	tB.updateOpacity(m_zonesize);	z.zonetex = tB.blend(rd, z.zonetex);}//////////////////////////// textureBlender.cpp//blend - Blends the given textures together using the specified alpha mapsTextureRef textureBlender::blend(RenderDevice *rd, TextureRef oldSurface){	//Allocate a new texture to render to, if we don't have an old one to use	TextureRef renderSurface;	Texture::Settings settings = Texture::Settings::defaults();	settings.wrapMode = WrapMode::CLAMP;	settings.interpolateMode = Texture::BILINEAR_NO_MIPMAP;	if (oldSurface.isNull())		renderSurface = Texture::createEmpty(	"terrainTexture", TEXTURE_SIZE, TEXTURE_SIZE,												TextureFormat::RGBA8(), Texture::DIM_2D, settings);	else		renderSurface = oldSurface;		rd->pushState();	//Setup a framebuffer	FramebufferRef fb = Framebuffer::create("terrainTexturer");	fb->set(Framebuffer::COLOR_ATTACHMENT0, renderSurface);	//Set the rendering device up for rendering to our framebuffer/texture	rd->push2D(fb);	//First, clear the scene	rd->setColorClearValue(Color3(0, 1, 0));    rd->clear();	//Render the opacity map stuff	for(s32 i=0; i < m_sources.size(); i += 4)	{	//Break if there's nothing to draw		if (m_sources[i + 0].source.isNull() &&			m_sources[i + 1].source.isNull() &&			m_sources[i + 2].source.isNull() &&			m_sources[i + 3].source.isNull()	)			break;		bool source2 = (m_sources.size() > i + 1);		bool source3 = (m_sources.size() > i + 2);		bool source4 = (m_sources.size() > i + 3);		//Load up the blending shader		rd->setShader(m_blendShader);	//Maybe move this call outside? faster?		m_blendShader->args.set("opacityMap",   m_opacity[i / 4]);		m_blendShader->args.set("source0",		m_sources[i + 0].source);			//Replace textures that don't exist with the first texture to keep glsl happy.		//The opacity map should ignore them regardless.		m_blendShader->args.set("source1",		m_sources[i + (source2 ? 1:0)].source);		m_blendShader->args.set("source2",		m_sources[i + (source3 ? 2:0)].source);		m_blendShader->args.set("source3",		m_sources[i + (source4 ? 3:0)].source);				//Render the texture		Draw::rect2D(Rect2D::xywh(0,0,TEXTURE_SIZE,TEXTURE_SIZE), rd, Color3::white());		break;	}	//Reset the render mode	rd->setPixelProgram(NULL);	rd->pop2D();		fb->set(Framebuffer::COLOR_ATTACHMENT0, NULL);	rd->popState();	// Return the surface	debugAssertGLOk();	return renderSurface;}//addTexture - Adds a texture to be blended using the specified alpha mapvoid textureBlender::addTexture(u32 materialIdx, TextureRef tex, u8 *alphas){	//Make a new sourcetexture and jam it into the array	SourceTexture s;	s.alpha = alphas;	s.source = tex;	//Resize the array if necessary	if (m_sources.size() <= (s32)materialIdx)		m_sources.resize(materialIdx + 1);	m_sources[materialIdx] = s;}//updateOpacity - Merges all the alpha maps into a single texturevoid textureBlender::updateOpacity(u32 alphamapsize){	//Ready the opacity texture array	u32 alphamapsizesq = (alphamapsize*alphamapsize);	m_opacity.clear();	m_opacity.resize((m_sources.size() / 4) + 1);		//4 Textures for each opacity map	//Build new maps	for(s32 rangeStart=0; rangeStart < m_sources.size(); rangeStart +=4)	{	//If we have a null on source #rangeStart, we are done.		if (!m_sources[rangeStart + 0].alpha) 			break;				bool source2 = (m_sources.size() > rangeStart + 1);		bool source3 = (m_sources.size() > rangeStart + 2);		bool source4 = (m_sources.size() > rangeStart + 3);		//Ready an image		GImage tempMap(alphamapsize, alphamapsize, 4);		u8 *tmpBits = tempMap.byte();		ZeroMemory(tmpBits, sizeof(u32) * alphamapsizesq);		// Copy everything relevant into the texture...		for(u32 x=0; x < alphamapsizesq; ++x, tmpBits += 4)		{	//Always assume that the first alpha exists, but don't rely on the others			tmpBits[0] = m_sources[rangeStart + 0].alpha[x];			if (source2)				tmpBits[1] = m_sources[rangeStart + 1].alpha[x];							if (source3)				tmpBits[2] = m_sources[rangeStart + 2].alpha[x];			if (source4)				tmpBits[3] = m_sources[rangeStart + 3].alpha[x];		}		//Adjust our settings		Texture::Settings settings = Texture::Settings::defaults();		settings.wrapMode = WrapMode::CLAMP;				//Make a texture and store it...		m_opacity[rangeStart / 4] = Texture::fromGImage("terrainAlphaMap", tempMap,														TextureFormat::AUTO(), Texture::DIM_2D,														settings );	}}