All pastes #907373 Raw Edit

Something

public cpp v1 · immutable
·published 2008-02-17 15:32 UTC
rendered paste body
/*	textureBlender - Used for blending textures together for the terrain *////////////////////////////////////////////////////////////////////#include <Base.h>#include "textureBlender.h"#include "Terrain.h"// Static Initialization//////////////////////////////////////////////////ShaderRef	textureBlender::m_blendShader;	//loadAssets - Loads all the external assets needed for this classvoid textureBlender::loadAssets(){	//Load our blending shader	m_blendShader = G3D::Shader::fromFiles("shaders/terrainblend.vert", "shaders/terrainblend.frag");	assert(m_blendShader->ok(), "Terrain texture blending shader failed to load."); }// Con/De-struction//////////////////////////////////////////////////textureBlender::textureBlender(){}textureBlender::~textureBlender(){}// Texture functions////////////////////////////////////////////////////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;	if (oldSurface.isNull())		renderSurface = Texture::createEmpty(TEXTURE_SIZE, TEXTURE_SIZE, "terrainTexture", TextureFormat::RGBA8, Texture::TILE, Texture::NO_INTERPOLATION, Texture::DIM_2D);	else		renderSurface = oldSurface;	//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->pushState();	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();	rd->popState();	fb->set(Framebuffer::COLOR_ATTACHMENT0, NULL);	// 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)		{	//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];			// Move to next chunk of data...			tmpBits += 4;		}		// Make a texture and store it...		m_opacity[rangeStart / 4] = Texture::fromGImage("terrainAlphaMap", tempMap);		//NOTE: Does having a constant name for all alpha textures mean that		//		it'll just always default for the first one commited?	}}