Ejemplo n.º 1
0
void GLMeshRenderer::DrawLightModel(int arraySize, float deltaSecond, Matrix4x4 perspectiveMatrix, Matrix4x4 viewMatrix, Matrix4x4 modelMatrix, Vector3 lPosition, Vector3 cameraPosition)
{
	//////////////////////////////////////////////////////////////////////////
	arraySize;
	static float totalTime = 0;
	totalTime += deltaSecond;
	glUseProgram(m_material.m_program.m_gProgram);
	GLCheckError(__FILE__, __LINE__);
	glBindVertexArray(m_VAO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_mesh.m_iboID);
	Vector3 cam_position = cameraPosition;
	Vector3 lightPosition = lPosition;
	float light_power = 10000.1f;
	Vector4 ambient_light(1.0f, 1.0f, 1.0f, 0.05f);
	Vector4 light_color(1.0f, 1.0f, 1.0f, light_power);
	GLint textureIndex = 0;
	GLuint m_gBuffer = m_material.m_program.m_gProgram;
	ProgramBindSamplerIndex(m_gBuffer, "gTexDiffuse", textureIndex);
	ProgramBindSamplerIndex(m_gBuffer, "gTexNormal", textureIndex + 1);
	ProgramBindSamplerIndex(m_gBuffer, "gTexSpecGlossEmit", textureIndex + 2);
	ProgramBindMatrix(m_gBuffer, "gProj", perspectiveMatrix);
	ProgramBindMatrix(m_gBuffer, "gView", viewMatrix);
	ProgramBindMatrix(m_gBuffer, "gModel", modelMatrix);
	ProgramBindVector4(m_gBuffer, "gAmbientLight", ambient_light);
	ProgramBindVector4(m_gBuffer, "gLightColor", light_color);
	ProgramBindVector3(m_gBuffer, "gLightPosition", lightPosition);
	ProgramBindVector3(m_gBuffer, "gCameraPosition", cam_position);

	if (m_material.m_sampler.gTexDiffuse == nullptr)
	{
		unsigned char defaultWhiteTexel[3] = { 255, 255, 255 };
		m_material.m_sampler.gTexDiffuse = Texture::CreateMissingTexture("DefaultDiffuse", defaultWhiteTexel, Vector2(1.0f, 1.0f), 3);
	}
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexDiffuse->GetPlatformHandle());
	textureIndex++;

	if (m_material.m_sampler.gTexNormal == nullptr)
	{
		unsigned char defaultBlueTexel[3] = { 127, 127, 255 };
		m_material.m_sampler.gTexNormal = Texture::CreateMissingTexture("DefaultNormal", defaultBlueTexel, Vector2(1.0f, 1.0f), 3);
	}
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexNormal->GetPlatformHandle());
	textureIndex++;

	if (m_material.m_sampler.gTexSpecGlossEmit == nullptr)
	{
		unsigned char defaultYellowTexel[3] = { 127, 127, 0 };
		m_material.m_sampler.gTexSpecGlossEmit = Texture::CreateMissingTexture("DefaultSpecGlossEmit", defaultYellowTexel, Vector2(1.0f, 1.0f), 3);
	}
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexSpecGlossEmit->GetPlatformHandle());

	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	//glDrawArrays(GL_TRIANGLES, 0, m_mesh.m_vboNumBytes);
	glDrawElements(GL_TRIANGLES,m_mesh.m_iboNumIndexes , GL_UNSIGNED_INT,(void*)0 );
	glBindVertexArray(NULL);
	glUseProgram(NULL);
	GLCheckError(__FILE__, __LINE__);

}
Ejemplo n.º 2
0
void GLMeshRenderer::DrawLightShader(int arraySize, float deltaSecond, Matrix4x4 perspectiveMatrix, Matrix4x4 viewMatrix,Matrix4x4 modelMatrix,Vector3 lPosition,Vector3 cameraPosition)
{
	//////////////////////////////////////////////////////////////////////////
	arraySize;
	static float totalTime = 0;
	totalTime += deltaSecond;
	glUseProgram(m_material.m_program.m_gProgram);
	GLCheckError(__FILE__, __LINE__);
	glBindVertexArray(m_VAO);
	Vector3 cam_position = cameraPosition;
	Vector3 lightPosition = lPosition;
	float light_power = 2.1f;
	Vector4 ambient_light(1.0f, 1.0f, 1.0f, 0.05f);
	Vector4 light_color(1.0f, 1.0f, 1.0f, light_power);
	GLint textureIndex = 0;
	GLuint m_gBuffer = m_material.m_program.m_gProgram;
	ProgramBindSamplerIndex(m_gBuffer, "gTexDiffuse", textureIndex);
	ProgramBindSamplerIndex(m_gBuffer, "gTexNormal", textureIndex+1);
	ProgramBindSamplerIndex(m_gBuffer, "gTexSpecular", textureIndex + 2);
	ProgramBindSamplerIndex(m_gBuffer, "gTexEmissive", textureIndex + 3);
	ProgramBindMatrix(m_gBuffer, "gProj", perspectiveMatrix);
	ProgramBindMatrix(m_gBuffer, "gView", viewMatrix);
	ProgramBindMatrix(m_gBuffer, "gModel", modelMatrix);
	ProgramBindVector4(m_gBuffer, "gAmbientLight", ambient_light);
	ProgramBindVector4(m_gBuffer, "gLightColor", light_color);
	ProgramBindVector3(m_gBuffer, "gLightPosition", lightPosition);
	ProgramBindVector3(m_gBuffer, "gCameraPosition", cam_position);
	
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexDiffuse->GetPlatformHandle());
	textureIndex++;
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexNormal->GetPlatformHandle());
	textureIndex++;
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexSpecular->GetPlatformHandle());
	textureIndex++;
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexEmissive->GetPlatformHandle());
	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glDrawArrays(GL_TRIANGLES, 0, m_mesh.m_vboNumBytes);
	glBindVertexArray(NULL);
	glUseProgram(NULL);
	GLCheckError(__FILE__, __LINE__);

}
Ejemplo n.º 3
0
void GLMeshRenderer::DrawMultLightsShader(float deltaSecond, Matrix4x4 perspectiveMatrix, Matrix4x4 viewMatrix, Matrix4x4 modelMatrix, const std::vector<Light> &lights, Vector3 cameraPosition, float discardValue)
{
	std::vector<Light> tempLights = lights;
	if (tempLights.size()>16)
	{
		return;
	}
	////////////////////////////////////////////////////////////////////
	Vector3 lightPositions[16];
	Vector3 lightDirections[16];
	Vector4 lightColors[16];
	float lVWeights[16];
	float lightAngles[16];
	float spotPowers[16];
	float minSfs[16];
	float minIntensitys[16];
	float maxIntensitys[16];
	for (unsigned int i = 0; i < tempLights.size(); i++)
	{
		lightPositions[i] = tempLights[i].m_lightPosition;
		lightDirections[i] = tempLights[i].m_lightDirection;
		lightColors[i] = tempLights[i].m_lightColor;
		lVWeights[i] = tempLights[i].m_lVWeight;
		lightAngles[i] = tempLights[i].m_lightAngle;
		spotPowers[i] = tempLights[i].m_spotPower;
		minSfs[i] = tempLights[i].m_minSf;
		minIntensitys[i] = tempLights[i].m_minIntensity;
		maxIntensitys[i] = tempLights[i].m_maxIntensity;
	}
	////////////////////////////////////////////////////////////////////
	static float totalTime = 0;
	totalTime += deltaSecond;
	discardValue = 1.5f*cos(totalTime*0.1f);
	glUseProgram(m_material.m_program.m_gProgram);
	GLCheckError(__FILE__, __LINE__);
	glBindVertexArray(m_VAO);
	Vector3 cam_position = cameraPosition;
	Vector4 ambient_light(1.0f, 1.0f, 1.0f, 0.05f);
	GLint textureIndex = 0;
	GLuint m_gBuffer = m_material.m_program.m_gProgram;
	//////////////////////////////////////////////////////////////////////////
	ProgramBindSamplerIndex(m_gBuffer, "gTexDiffuse", textureIndex);
	ProgramBindSamplerIndex(m_gBuffer, "gTexNormal", textureIndex + 1);
	ProgramBindSamplerIndex(m_gBuffer, "gTexSpecular", textureIndex + 2);
	ProgramBindSamplerIndex(m_gBuffer, "gTexEmissive", textureIndex + 3);
	ProgramBindMatrix(m_gBuffer, "gProj", perspectiveMatrix);
	ProgramBindMatrix(m_gBuffer, "gView", viewMatrix);
	ProgramBindMatrix(m_gBuffer, "gModel", modelMatrix);
	ProgramBindVector4(m_gBuffer, "gAmbientLight", ambient_light);
	ProgramBindVector4Array(m_gBuffer, "gLightColors[0]", lightColors, (int)tempLights.size());
	ProgramBindVector3Array(m_gBuffer, "gLightPositions[0]", lightPositions, (int)tempLights.size());
	ProgramBindVector3Array(m_gBuffer, "gLightDirections[0]", lightDirections, (int)tempLights.size());
	ProgramBindVector3(m_gBuffer, "gCameraPosition", cam_position);
	ProgramBindFloatArray(m_gBuffer, "gLVWeights[0]", lVWeights, (int)tempLights.size());
	ProgramBindFloatArray(m_gBuffer, "gLightAngles[0]", lightAngles, (int)tempLights.size());
	ProgramBindFloatArray(m_gBuffer, "gSpotPowers[0]", spotPowers, (int)tempLights.size());
	ProgramBindFloatArray(m_gBuffer, "gMinSfs[0]", minSfs, (int)tempLights.size());
	ProgramBindFloatArray(m_gBuffer, "gMinIntensitys[0]", minIntensitys, (int)tempLights.size());
	ProgramBindFloatArray(m_gBuffer, "gMaxIntensitys[0]", maxIntensitys, (int)tempLights.size());
	ProgramBindInt(m_gBuffer, "gLightNumber", (int)tempLights.size());
	ProgramBindFloat(m_gBuffer, "gDiscardValue", discardValue);
	
	
	//////////////////////////////////////////////////////////////////////////
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexDiffuse->GetPlatformHandle());
	textureIndex++;
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexNormal->GetPlatformHandle());
	textureIndex++;
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexSpecular->GetPlatformHandle());
	textureIndex++;
	ProgramBindTexture(textureIndex, m_material.m_sampler.gTexEmissive->GetPlatformHandle());
	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glDrawArrays(GL_TRIANGLES, 0, m_mesh.m_vboNumBytes);
	glBindVertexArray(NULL);
	glUseProgram(NULL);
	GLCheckError(__FILE__, __LINE__);
}
Ejemplo n.º 4
0
	virtual void updateTexturesAndMeshes(IGameDef *gamedef)
	{
#ifndef SERVER
		infostream<<"ItemDefManager::updateTexturesAndMeshes(): Updating "
				<<"textures and meshes in item definitions"<<std::endl;

		ITextureSource *tsrc = gamedef->getTextureSource();
		INodeDefManager *nodedef = gamedef->getNodeDefManager();
		IrrlichtDevice *device = tsrc->getDevice();
		video::IVideoDriver *driver = device->getVideoDriver();

		for(std::map<std::string, ItemDefinition*>::iterator
				i = m_item_definitions.begin();
				i != m_item_definitions.end(); i++)
		{
			ItemDefinition *def = i->second;

			bool need_node_mesh = false;

			// Create an inventory texture
			def->inventory_texture = NULL;
			if(def->inventory_image != "")
			{
				def->inventory_texture = tsrc->getTextureRaw(def->inventory_image);
			}
			else if(def->type == ITEM_NODE)
			{
				need_node_mesh = true;
			}

			// Create a wield mesh
			if(def->wield_mesh != NULL)
			{
				def->wield_mesh->drop();
				def->wield_mesh = NULL;
			}
			if(def->type == ITEM_NODE && def->wield_image == "")
			{
				need_node_mesh = true;
			}
			else if(def->wield_image != "" || def->inventory_image != "")
			{
				// Extrude the wield image into a mesh

				std::string imagename;
				if(def->wield_image != "")
					imagename = def->wield_image;
				else
					imagename = def->inventory_image;

				def->wield_mesh = createExtrudedMesh(
						tsrc->getTextureRaw(imagename),
						driver,
						def->wield_scale * v3f(40.0, 40.0, 4.0));
				if(def->wield_mesh == NULL)
				{
					infostream<<"ItemDefManager: WARNING: "
						<<"updateTexturesAndMeshes(): "
						<<"Unable to create extruded mesh for item "
						<<def->name<<std::endl;
				}
			}

			if(need_node_mesh)
			{
				/*
					Get node properties
				*/
				content_t id = nodedef->getId(def->name);
				const ContentFeatures &f = nodedef->get(id);

				u8 param1 = 0;
				if(f.param_type == CPT_LIGHT)
					param1 = 0xee;

				/*
				 	Make a mesh from the node
				*/
				MeshMakeData mesh_make_data(gamedef);
				MapNode mesh_make_node(id, param1, 0);
				mesh_make_data.fillSingleNode(&mesh_make_node);
				MapBlockMesh mapblock_mesh(&mesh_make_data);

				scene::IMesh *node_mesh = mapblock_mesh.getMesh();
				assert(node_mesh);
				setMeshColor(node_mesh, video::SColor(255, 255, 255, 255));

				/*
					Scale and translate the mesh so it's a unit cube
					centered on the origin
				*/
				scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS));
				translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0));

				/*
					Draw node mesh into a render target texture
				*/
				if(def->inventory_texture == NULL)
				{
					core::dimension2d<u32> dim(64,64);
					std::string rtt_texture_name = "INVENTORY_"
						+ def->name + "_RTT";
					v3f camera_position(0, 1.0, -1.5);
					camera_position.rotateXZBy(45);
					v3f camera_lookat(0, 0, 0);
					core::CMatrix4<f32> camera_projection_matrix;
					// Set orthogonal projection
					camera_projection_matrix.buildProjectionMatrixOrthoLH(
							1.65, 1.65, 0, 100);

					video::SColorf ambient_light(0.2,0.2,0.2);
					v3f light_position(10, 100, -50);
					video::SColorf light_color(0.5,0.5,0.5);
					f32 light_radius = 1000;

					def->inventory_texture = generateTextureFromMesh(
						node_mesh, device, dim, rtt_texture_name,
						camera_position,
						camera_lookat,
						camera_projection_matrix,
						ambient_light,
						light_position,
						light_color,
						light_radius);

					// render-to-target didn't work
					if(def->inventory_texture == NULL)
					{
						def->inventory_texture =
							tsrc->getTextureRaw(f.tname_tiles[0]);
					}
				}

				/*
					Use the node mesh as the wield mesh
				*/
				if(def->wield_mesh == NULL)
				{
					// Scale to proper wield mesh proportions
					scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0)
							* def->wield_scale);
					def->wield_mesh = node_mesh;
					def->wield_mesh->grab();
				}

				// falling outside of here deletes node_mesh
			}
		}
#endif
	}
Ejemplo n.º 5
0
void			phong_shade(t_ray *ray, t_env *e)
{
	ambient_light(ray);
	phong_light(ray, e);
}
Ejemplo n.º 6
0
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
		IrrlichtDevice *device, SourceImageCache *sourcecache)
{
	video::IVideoDriver* driver = device->getVideoDriver();
	assert(driver);

	// Stuff starting with [ are special commands
	if(part_of_name.size() == 0 || part_of_name[0] != '[')
	{
		video::IImage *image = sourcecache->getOrLoad(part_of_name, device);

		if(image == NULL)
		{
			if(part_of_name != ""){
				errorstream<<"generate_image(): Could not load image \""
						<<part_of_name<<"\""<<" while building texture"<<std::endl;
				errorstream<<"generate_image(): Creating a dummy"
						<<" image for \""<<part_of_name<<"\""<<std::endl;
			}

			// Just create a dummy image
			//core::dimension2d<u32> dim(2,2);
			core::dimension2d<u32> dim(1,1);
			image = driver->createImage(video::ECF_A8R8G8B8, dim);
			assert(image);
			/*image->setPixel(0,0, video::SColor(255,255,0,0));
			image->setPixel(1,0, video::SColor(255,0,255,0));
			image->setPixel(0,1, video::SColor(255,0,0,255));
			image->setPixel(1,1, video::SColor(255,255,0,255));*/
			image->setPixel(0,0, video::SColor(255,myrand()%256,
					myrand()%256,myrand()%256));
			/*image->setPixel(1,0, video::SColor(255,myrand()%256,
					myrand()%256,myrand()%256));
			image->setPixel(0,1, video::SColor(255,myrand()%256,
					myrand()%256,myrand()%256));
			image->setPixel(1,1, video::SColor(255,myrand()%256,
					myrand()%256,myrand()%256));*/
		}

		// If base image is NULL, load as base.
		if(baseimg == NULL)
		{
			//infostream<<"Setting "<<part_of_name<<" as base"<<std::endl;
			/*
				Copy it this way to get an alpha channel.
				Otherwise images with alpha cannot be blitted on 
				images that don't have alpha in the original file.
			*/
			core::dimension2d<u32> dim = image->getDimension();
			baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
			image->copyTo(baseimg);
			image->drop();
		}
		// Else blit on base.
		else
		{
			//infostream<<"Blitting "<<part_of_name<<" on base"<<std::endl;
			// Size of the copied area
			core::dimension2d<u32> dim = image->getDimension();
			//core::dimension2d<u32> dim(16,16);
			// Position to copy the blitted to in the base image
			core::position2d<s32> pos_to(0,0);
			// Position to copy the blitted from in the blitted image
			core::position2d<s32> pos_from(0,0);
			// Blit
			image->copyToWithAlpha(baseimg, pos_to,
					core::rect<s32>(pos_from, dim),
					video::SColor(255,255,255,255),
					NULL);
			// Drop image
			image->drop();
		}
	}
	else
	{
		// A special texture modification

		/*infostream<<"generate_image(): generating special "
				<<"modification \""<<part_of_name<<"\""
				<<std::endl;*/
		
		/*
			This is the simplest of all; it just adds stuff to the
			name so that a separate texture is created.

			It is used to make textures for stuff that doesn't want
			to implement getting the texture from a bigger texture
			atlas.
		*/
		if(part_of_name == "[forcesingle")
		{
			// If base image is NULL, create a random color
			if(baseimg == NULL)
			{
				core::dimension2d<u32> dim(1,1);
				baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
				assert(baseimg);
				baseimg->setPixel(0,0, video::SColor(255,myrand()%256,
						myrand()%256,myrand()%256));
			}
		}
		/*
			[crackN
			Adds a cracking texture
		*/
		else if(part_of_name.substr(0,6) == "[crack")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generate_image(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}
			
			// Crack image number and overlay option
			s32 progression = 0;
			bool use_overlay = false;
			if(part_of_name.substr(6,1) == "o")
			{
				progression = stoi(part_of_name.substr(7));
				use_overlay = true;
			}
			else
			{
				progression = stoi(part_of_name.substr(6));
				use_overlay = false;
			}

			// Size of the base image
			core::dimension2d<u32> dim_base = baseimg->getDimension();
			
			/*
				Load crack image.

				It is an image with a number of cracking stages
				horizontally tiled.
			*/
			video::IImage *img_crack = sourcecache->getOrLoad("crack.png", device);
		
			if(img_crack && progression >= 0)
			{
				// Dimension of original image
				core::dimension2d<u32> dim_crack
						= img_crack->getDimension();
				// Count of crack stages
				s32 crack_count = dim_crack.Height / dim_crack.Width;
				// Limit progression
				if(progression > crack_count-1)
					progression = crack_count-1;
				// Dimension of a single crack stage
				core::dimension2d<u32> dim_crack_cropped(
					dim_crack.Width,
					dim_crack.Width
				);
				// Create cropped and scaled crack images
				video::IImage *img_crack_cropped = driver->createImage(
						video::ECF_A8R8G8B8, dim_crack_cropped);
				video::IImage *img_crack_scaled = driver->createImage(
						video::ECF_A8R8G8B8, dim_base);

				if(img_crack_cropped && img_crack_scaled)
				{
					// Crop crack image
					v2s32 pos_crack(0, progression*dim_crack.Width);
					img_crack->copyTo(img_crack_cropped,
							v2s32(0,0),
							core::rect<s32>(pos_crack, dim_crack_cropped));
					// Scale crack image by copying
					img_crack_cropped->copyToScaling(img_crack_scaled);
					// Copy or overlay crack image
					if(use_overlay)
					{
						overlay(baseimg, img_crack_scaled);
					}
					else
					{
						img_crack_scaled->copyToWithAlpha(
								baseimg,
								v2s32(0,0),
								core::rect<s32>(v2s32(0,0), dim_base),
								video::SColor(255,255,255,255));
					}
				}

				if(img_crack_scaled)
					img_crack_scaled->drop();

				if(img_crack_cropped)
					img_crack_cropped->drop();
				
				img_crack->drop();
			}
		}
		/*
			[combine:WxH:X,Y=filename:X,Y=filename2
			Creates a bigger texture from an amount of smaller ones
		*/
		else if(part_of_name.substr(0,8) == "[combine")
		{
			Strfnd sf(part_of_name);
			sf.next(":");
			u32 w0 = stoi(sf.next("x"));
			u32 h0 = stoi(sf.next(":"));
			infostream<<"combined w="<<w0<<" h="<<h0<<std::endl;
			core::dimension2d<u32> dim(w0,h0);
			baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
			while(sf.atend() == false)
			{
				u32 x = stoi(sf.next(","));
				u32 y = stoi(sf.next("="));
				std::string filename = sf.next(":");
				infostream<<"Adding \""<<filename
						<<"\" to combined ("<<x<<","<<y<<")"
						<<std::endl;
				video::IImage *img = sourcecache->getOrLoad(filename, device);
				if(img)
				{
					core::dimension2d<u32> dim = img->getDimension();
					infostream<<"Size "<<dim.Width
							<<"x"<<dim.Height<<std::endl;
					core::position2d<s32> pos_base(x, y);
					video::IImage *img2 =
							driver->createImage(video::ECF_A8R8G8B8, dim);
					img->copyTo(img2);
					img->drop();
					img2->copyToWithAlpha(baseimg, pos_base,
							core::rect<s32>(v2s32(0,0), dim),
							video::SColor(255,255,255,255),
							NULL);
					img2->drop();
				}
				else
				{
					infostream<<"img==NULL"<<std::endl;
				}
			}
		}
		/*
			"[brighten"
		*/
		else if(part_of_name.substr(0,9) == "[brighten")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generate_image(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			brighten(baseimg);
		}
		/*
			"[noalpha"
			Make image completely opaque.
			Used for the leaves texture when in old leaves mode, so
			that the transparent parts don't look completely black 
			when simple alpha channel is used for rendering.
		*/
		else if(part_of_name.substr(0,8) == "[noalpha")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generate_image(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			core::dimension2d<u32> dim = baseimg->getDimension();
			
			// Set alpha to full
			for(u32 y=0; y<dim.Height; y++)
			for(u32 x=0; x<dim.Width; x++)
			{
				video::SColor c = baseimg->getPixel(x,y);
				c.setAlpha(255);
				baseimg->setPixel(x,y,c);
			}
		}
		/*
			"[makealpha:R,G,B"
			Convert one color to transparent.
		*/
		else if(part_of_name.substr(0,11) == "[makealpha:")
		{
			if(baseimg == NULL)
			{
				errorstream<<"generate_image(): baseimg==NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			Strfnd sf(part_of_name.substr(11));
			u32 r1 = stoi(sf.next(","));
			u32 g1 = stoi(sf.next(","));
			u32 b1 = stoi(sf.next(""));
			std::string filename = sf.next("");

			core::dimension2d<u32> dim = baseimg->getDimension();
			
			/*video::IImage *oldbaseimg = baseimg;
			baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
			oldbaseimg->copyTo(baseimg);
			oldbaseimg->drop();*/

			// Set alpha to full
			for(u32 y=0; y<dim.Height; y++)
			for(u32 x=0; x<dim.Width; x++)
			{
				video::SColor c = baseimg->getPixel(x,y);
				u32 r = c.getRed();
				u32 g = c.getGreen();
				u32 b = c.getBlue();
				if(!(r == r1 && g == g1 && b == b1))
					continue;
				c.setAlpha(0);
				baseimg->setPixel(x,y,c);
			}
		}
		/*
			[inventorycube{topimage{leftimage{rightimage
			In every subimage, replace ^ with &.
			Create an "inventory cube".
			NOTE: This should be used only on its own.
			Example (a grass block (not actually used in game):
			"[inventorycube{grass.png{mud.png&grass_side.png{mud.png&grass_side.png"
		*/
		else if(part_of_name.substr(0,14) == "[inventorycube")
		{
			if(baseimg != NULL)
			{
				errorstream<<"generate_image(): baseimg!=NULL "
						<<"for part_of_name=\""<<part_of_name
						<<"\", cancelling."<<std::endl;
				return false;
			}

			str_replace_char(part_of_name, '&', '^');
			Strfnd sf(part_of_name);
			sf.next("{");
			std::string imagename_top = sf.next("{");
			std::string imagename_left = sf.next("{");
			std::string imagename_right = sf.next("{");

			// Generate images for the faces of the cube
			video::IImage *img_top = generate_image_from_scratch(
					imagename_top, device, sourcecache);
			video::IImage *img_left = generate_image_from_scratch(
					imagename_left, device, sourcecache);
			video::IImage *img_right = generate_image_from_scratch(
					imagename_right, device, sourcecache);
			assert(img_top && img_left && img_right);

			// Create textures from images
			video::ITexture *texture_top = driver->addTexture(
					(imagename_top + "__temp__").c_str(), img_top);
			video::ITexture *texture_left = driver->addTexture(
					(imagename_left + "__temp__").c_str(), img_left);
			video::ITexture *texture_right = driver->addTexture(
					(imagename_right + "__temp__").c_str(), img_right);
			assert(texture_top && texture_left && texture_right);

			// Drop images
			img_top->drop();
			img_left->drop();
			img_right->drop();
			
			/*
				Draw a cube mesh into a render target texture
			*/
			scene::IMesh* cube = createCubeMesh(v3f(1, 1, 1));
			setMeshColor(cube, video::SColor(255, 255, 255, 255));
			cube->getMeshBuffer(0)->getMaterial().setTexture(0, texture_top);
			cube->getMeshBuffer(1)->getMaterial().setTexture(0, texture_top);
			cube->getMeshBuffer(2)->getMaterial().setTexture(0, texture_right);
			cube->getMeshBuffer(3)->getMaterial().setTexture(0, texture_right);
			cube->getMeshBuffer(4)->getMaterial().setTexture(0, texture_left);
			cube->getMeshBuffer(5)->getMaterial().setTexture(0, texture_left);

			core::dimension2d<u32> dim(64,64);
			std::string rtt_texture_name = part_of_name + "_RTT";

			v3f camera_position(0, 1.0, -1.5);
			camera_position.rotateXZBy(45);
			v3f camera_lookat(0, 0, 0);
			core::CMatrix4<f32> camera_projection_matrix;
			// Set orthogonal projection
			camera_projection_matrix.buildProjectionMatrixOrthoLH(
					1.65, 1.65, 0, 100);

			video::SColorf ambient_light(0.2,0.2,0.2);
			v3f light_position(10, 100, -50);
			video::SColorf light_color(0.5,0.5,0.5);
			f32 light_radius = 1000;

			video::ITexture *rtt = generateTextureFromMesh(
					cube, device, dim, rtt_texture_name,
					camera_position,
					camera_lookat,
					camera_projection_matrix,
					ambient_light,
					light_position,
					light_color,
					light_radius);
			
			// Drop mesh
			cube->drop();

			// Free textures of images
			driver->removeTexture(texture_top);
			driver->removeTexture(texture_left);
			driver->removeTexture(texture_right);
			
			if(rtt == NULL)
			{
				baseimg = generate_image_from_scratch(
						imagename_top, device, sourcecache);
				return true;
			}

			// Create image of render target
			video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim);
			assert(image);

			baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);

			if(image)
			{
				image->copyTo(baseimg);
				image->drop();
			}
		}
		else
		{
			errorstream<<"generate_image(): Invalid "
					" modification: \""<<part_of_name<<"\""<<std::endl;
		}
	}

	return true;
}
Ejemplo n.º 7
0
    ClientCached* createClientCachedDirect(const std::string &name,
                                           IGameDef *gamedef) const
    {
        infostream<<"Lazily creating item texture and mesh for \""
                  <<name<<"\""<<std::endl;

        // This is not thread-safe
        assert(get_current_thread_id() == m_main_thread);

        // Skip if already in cache
        ClientCached *cc = NULL;
        m_clientcached.get(name, &cc);
        if(cc)
            return cc;

        ITextureSource *tsrc = gamedef->getTextureSource();
        INodeDefManager *nodedef = gamedef->getNodeDefManager();
        IrrlichtDevice *device = tsrc->getDevice();
        video::IVideoDriver *driver = device->getVideoDriver();
        const ItemDefinition *def = &get(name);

        // Create new ClientCached
        cc = new ClientCached();

        bool need_node_mesh = false;

        // Create an inventory texture
        cc->inventory_texture = NULL;
        if(def->inventory_image != "")
        {
            cc->inventory_texture = tsrc->getTextureRaw(def->inventory_image);
        }
        else if(def->type == ITEM_NODE)
        {
            need_node_mesh = true;
        }

        // Create a wield mesh
        assert(cc->wield_mesh == NULL);
        if(def->type == ITEM_NODE && def->wield_image == "")
        {
            need_node_mesh = true;
        }
        else if(def->wield_image != "" || def->inventory_image != "")
        {
            // Extrude the wield image into a mesh

            std::string imagename;
            if(def->wield_image != "")
                imagename = def->wield_image;
            else
                imagename = def->inventory_image;

            cc->wield_mesh = createExtrudedMesh(
                                 tsrc->getTextureRaw(imagename),
                                 driver,
                                 def->wield_scale * v3f(40.0, 40.0, 4.0));
            if(cc->wield_mesh == NULL)
            {
                infostream<<"ItemDefManager: WARNING: "
                          <<"updateTexturesAndMeshes(): "
                          <<"Unable to create extruded mesh for item "
                          <<def->name<<std::endl;
            }
        }

        if(need_node_mesh)
        {
            /*
            	Get node properties
            */
            content_t id = nodedef->getId(def->name);
            const ContentFeatures &f = nodedef->get(id);

            u8 param1 = 0;
            if(f.param_type == CPT_LIGHT)
                param1 = 0xee;

            /*
            	Make a mesh from the node
            */
            MeshMakeData mesh_make_data(gamedef);
            MapNode mesh_make_node(id, param1, 0);
            mesh_make_data.fillSingleNode(&mesh_make_node);
            MapBlockMesh mapblock_mesh(&mesh_make_data);

            scene::IMesh *node_mesh = mapblock_mesh.getMesh();
            assert(node_mesh);
            video::SColor c(255, 255, 255, 255);
            if(g_settings->getS32("enable_shaders") != 0)
                c = MapBlock_LightColor(255, 0xffff, decode_light(f.light_source));
            setMeshColor(node_mesh, c);

            /*
            	Scale and translate the mesh so it's a unit cube
            	centered on the origin
            */
            scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS));
            translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0));

            /*
            	Draw node mesh into a render target texture
            */
            if(cc->inventory_texture == NULL)
            {
                core::dimension2d<u32> dim(64,64);
                std::string rtt_texture_name = "INVENTORY_"
                                               + def->name + "_RTT";
                v3f camera_position(0, 1.0, -1.5);
                camera_position.rotateXZBy(45);
                v3f camera_lookat(0, 0, 0);
                core::CMatrix4<f32> camera_projection_matrix;
                // Set orthogonal projection
                camera_projection_matrix.buildProjectionMatrixOrthoLH(
                    1.65, 1.65, 0, 100);

                video::SColorf ambient_light(0.2,0.2,0.2);
                v3f light_position(10, 100, -50);
                video::SColorf light_color(0.5,0.5,0.5);
                f32 light_radius = 1000;

                cc->inventory_texture = generateTextureFromMesh(
                                            node_mesh, device, dim, rtt_texture_name,
                                            camera_position,
                                            camera_lookat,
                                            camera_projection_matrix,
                                            ambient_light,
                                            light_position,
                                            light_color,
                                            light_radius);

                // render-to-target didn't work
                if(cc->inventory_texture == NULL)
                {
                    cc->inventory_texture =
                        tsrc->getTextureRaw(f.tiledef[0].name);
                }
            }
            else
            {
                if (m_driver == 0)
                    m_driver = driver;

                m_extruded_textures.push_back(cc->inventory_texture);
            }

            /*
            	Use the node mesh as the wield mesh
            */

            // Scale to proper wield mesh proportions
            scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0)
                      * def->wield_scale);

            cc->wield_mesh = node_mesh;
            cc->wield_mesh->grab();

            //no way reference count can be smaller than 2 in this place!
            assert(cc->wield_mesh->getReferenceCount() >= 2);
        }

        // Put in cache
        m_clientcached.set(name, cc);

        return cc;
    }