Esempio n. 1
0
	void CSMFile::clear()
	{
		header.clear();
		cameraData.clear();

		u32 x =0;
		for( x= 0; x < groups.size(); x++)
			delete groups[x];

		groups.clear();

		for(x= 0; x < visgroups.size(); x++)
			delete visgroups[x];

		visgroups.clear();

		for(x= 0; x < lightmaps.size(); x++)
			delete lightmaps[x];

		lightmaps.clear();

		for(x= 0; x < meshes.size(); x++)
			delete meshes[x];

		meshes.clear();

		for(x= 0; x < entities.size(); x++)
			delete entities[x];

		entities.clear();
	}
Esempio n. 2
0
		//! Writes an xml element with any number of attributes
		void CXMLWriter::writeElement(const c8* name, bool empty,
				core::array<core::stringc> &names, core::array<core::stringc> &values)
		{
			IRR_ASSERT(sizeof(name) > 0);

			if (Tabs > 0)
			{
				for (int i = 0; i < Tabs; ++i)
					File->write("\t", sizeof(c8));
			}

			// write name

			File->write("<", sizeof(c8));
			File->write(name, strlen(name) * sizeof(c8));

			// write attributes
			u32 i = 0;
			for (; i < names.size() && i < values.size(); ++i)
				writeAttribute(names[i].cStr(), values[i].cStr());

			// write closing tag
			if (empty)
				File->write(" />", 3 * sizeof(c8));
			else
			{
				File->write(">", sizeof(c8));
				++Tabs;
			}

			TextWrittenLast = false;
		}
Esempio n. 3
0
//! Writes an xml element with any number of attributes
void CXMLWriter::writeElement(const wchar_t* name, bool empty,
				  core::array<core::stringw> &names,
				  core::array<core::stringw> &values)
{
	if (!File || !name)
		return;

	if (Tabs > 0)
	{
		for (int i=0; i<Tabs; ++i)
			File->write(L"\t", sizeof(wchar_t));
	}
	
	// write name

	File->write(L"<", sizeof(wchar_t));
	File->write(name, wcslen(name)*sizeof(wchar_t));

	// write attributes
	u32 i=0;
	for (; i < names.size() && i < values.size(); ++i)
		writeAttribute(names[i].c_str(), values[i].c_str());

	// write closing tag
	if (empty)
		File->write(L" />", 3*sizeof(wchar_t));
	else
	{
		File->write(L">", sizeof(wchar_t));
		++Tabs;
	}
	
	TextWrittenLast = false;
}
//! Moves a mesh
core::array<bool> CBatchingMesh::moveMesh(const core::array<s32>& bufferIDs, const core::matrix4 &newMatrix)
{
	core::array<bool> result;
	result.reallocate(bufferIDs.size());
	for (u32 i=0; i<bufferIDs.size(); ++i)
		result.push_back(moveMeshBuffer(bufferIDs[i], newMatrix));

	return result;
}
	// this function is for 32bit indices
	void drawElements(
		IVideoDriver* driver,
		const core::array<video::S3DVertex>& vertices,
		const core::array<s32>& indices,
		scene::E_PRIMITIVE_TYPE primType)
	{
		if (!driver)
			return;

		u32 primCount = 0;

		const u32& indexCount = indices.size();

		switch (primType)
		{
			case scene::EPT_POINTS:
					primCount = indexCount;
					break;
			case scene::EPT_LINE_STRIP:
					primCount = indexCount-1;
					break;
			case scene::EPT_LINE_LOOP:
					primCount = indexCount-1;
					break;
			case scene::EPT_LINES:
					primCount = indexCount/2;
					break;
			case scene::EPT_TRIANGLE_STRIP:
					primCount = (indexCount-2)/3;
					break;
			case scene::EPT_TRIANGLE_FAN:
					primCount = (indexCount-2)/3;
					break;
			case scene::EPT_TRIANGLES:
					primCount = indexCount/3;
					break;
			case scene::EPT_QUAD_STRIP:
					primCount = (indexCount-2)/4;
					break;
			case scene::EPT_QUADS:
					primCount = indexCount/4;
					break;
			case scene::EPT_POLYGON:
					primCount = indexCount-1;
					break;
			case scene::EPT_POINT_SPRITES:
					primCount = indexCount;
					break;
			default:
					break;
		}

		driver->drawVertexPrimitiveList( vertices.const_pointer(),
				vertices.size(), indices.const_pointer(),
				primCount, video::EVT_STANDARD,
				primType, video::EIT_32BIT);
	}
Esempio n. 6
0
std::string TextureSource::getTextureName(u32 id)
{
	JMutexAutoLock lock(m_atlaspointer_cache_mutex);

	if(id >= m_atlaspointer_cache.size())
	{
		errorstream<<"TextureSource::getTextureName(): id="<<id
				<<" >= m_atlaspointer_cache.size()="
				<<m_atlaspointer_cache.size()<<std::endl;
		return "";
	}
	
	return m_atlaspointer_cache[id].name;
}
Esempio n. 7
0
void CSoftwareRenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{
	if (Texture != texture)
	{
		if (Texture[0])
			Texture[0]->drop();

		bool textureDetected = false;

		for (u32 i = 0; i < texture.size(); ++i)
		{
			if (texture[i] && texture[i]->getDriverType() == EDT_SOFTWARE)
			{
				Texture[0] = texture[i];
				Texture[0]->grab();
				textureDetected = true;

				break;
			}
		}

		if (!textureDetected)
			Texture[0] = 0;
	}
}
Esempio n. 8
0
//! Adds the slots in the array to the usable slots
void CGUIIcon::addUsableSlotArray(const core::array<IGUIElement*>& slotArray)
{
    s32 arraySize = slotArray.size();
    for(s32 i = 0; i < arraySize; i++)
    {
        UsableSlots->push_back(slotArray[i]);
    }

}
Esempio n. 9
0
	virtual void OnRenderPassPostRender(scene::E_SCENE_NODE_RENDER_PASS renderPass)
	{
		// I only want solid nodes to be lit, so after the solid pass, turn all lights off.
		if(scene::ESNRP_SOLID == renderPass)
		{
			for(u32 i = 0; i < SceneLightList->size(); ++i)
				(*SceneLightList)[i]->setVisible(false);
		}
	}
Esempio n. 10
0
	// Called after the last scene node is rendered.
	virtual void OnPostRender()
	{
		// Since light management might be switched off in the event handler, we'll turn all
		// lights on to ensure that they are in a consistent state. You wouldn't normally have
		// to do this when using a light manager, since you'd continue to do light management
		// yourself.
		for(u32 i = 0; i < SceneLightList->size(); i++)
			(*SceneLightList)[i]->setVisible(true);
	}
Esempio n. 11
0
AtlasPointer TextureSource::getTexture(u32 id)
{
	JMutexAutoLock lock(m_atlaspointer_cache_mutex);

	if(id >= m_atlaspointer_cache.size())
		return AtlasPointer(0, NULL);
	
	return m_atlaspointer_cache[id].a;
}
Esempio n. 12
0
bool CIrrDeviceWin32::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
{
#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
	joystickInfo.clear();
	ActiveJoysticks.clear();

	const u32 numberOfJoysticks = ::joyGetNumDevs();
	JOYINFOEX info;
	info.dwSize = sizeof(info);
	info.dwFlags = JOY_RETURNALL;

	JoystickInfo activeJoystick;
	SJoystickInfo returnInfo;

	joystickInfo.reallocate(numberOfJoysticks);
	ActiveJoysticks.reallocate(numberOfJoysticks);

	u32 joystick = 0;
	for(; joystick < numberOfJoysticks; ++joystick)
	{
		if(JOYERR_NOERROR == joyGetPosEx(joystick, &info)
			&&
			JOYERR_NOERROR == joyGetDevCaps(joystick, 
											&activeJoystick.Caps,
											sizeof(activeJoystick.Caps)))
		{
			activeJoystick.Index = joystick;
			ActiveJoysticks.push_back(activeJoystick);

			returnInfo.Joystick = (u8)joystick;
			returnInfo.Axes = activeJoystick.Caps.wNumAxes;
			returnInfo.Buttons = activeJoystick.Caps.wNumButtons;
			returnInfo.Name = activeJoystick.Caps.szPname;
			returnInfo.PovHat = ((activeJoystick.Caps.wCaps & JOYCAPS_HASPOV) == JOYCAPS_HASPOV)
								? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT;

			joystickInfo.push_back(returnInfo);
		}
	}

	for(joystick = 0; joystick < joystickInfo.size(); ++joystick)
	{
		char logString[256];
		(void)sprintf(logString, "Found joystick %d, %d axes, %d buttons '%s'",
			joystick, joystickInfo[joystick].Axes, 
			joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str());
		os::Printer::log(logString, ELL_INFORMATION);
	}

	return true;
#else
	return false;
#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
}
Esempio n. 13
0
	void Mesh::clear()
	{
		flags = 0;
		groupId = 0;
		visgroupId = 0;
		props = "";
		color.clear();
		position.set(0,0,0);

		for(u32 s = 0; s < surfaces.size(); s++)
		{
			delete surfaces[s];
		}
		surfaces.clear();
	}
void CSceneNodeAnimatorTexture::setFramesDirectionSet(
	u32 direction_idx, const core::array<SAnimationFrame> &frames)
{
	if (direction_idx >= m_DirectionSets.size())
		for (u32 d = m_DirectionSets.size(); d <= direction_idx; d++)
			m_DirectionSets.push_back(core::array<SAnimationFrame>());
	u32 i=0;
	for (i=0; i < m_DirectionSets[direction_idx].size(); ++i)
        SAFE_DROP(m_DirectionSets[direction_idx][i].Texture);
	m_DirectionSets[direction_idx].set_used(0);
	for (i = 0; i < frames.size(); ++i)
    {
        m_DirectionSets[direction_idx].push_back(frames[i]);
		SAFE_GRAB(frames[i].Texture);
    }
}
Esempio n. 15
0
	void Surface::clear()
	{
		flags = 0;
		lightMapId = 0;
		textureName = "";
		uvOffset.set(0.0f,0.0f);
		uvScale.set(0.0f,0.0f);
		uvRotation = 0.0f;
		triangles.clear();
		lines.clear();

		for(u32 v = 0; v < vertices.size(); v++)
			delete vertices[v];

		vertices.clear();
	}
Esempio n. 16
0
void CFontTextTag::create( IExtendedText* text, const core::stringw& tag, const core::array<core::stringw>& params )
{
    if ( params.size() == 0 )
    {
        text->setCurrentFont( text->getDefaultFont() );
    }
    else
    {
        core::map<core::stringw,IGUIFont*>::Node* node = FontMap.find( params[0] );
        
        if ( node != NULL )
        {
            text->setCurrentFont( node->getValue() );
        }
    }
}
//! constructor
CSceneNodeAnimatorTexture::CSceneNodeAnimatorTexture(const core::array<video::ITexture*>& textures,
                                                     s32 timePerFrame, bool loop, u32 now)
	: Loop(loop), StartTime(now), TimePerFrame(timePerFrame)
{
	#ifdef _DEBUG
	setDebugName("CSceneNodeAnimatorTexture");
	#endif

	for (u32 i=0; i<textures.size(); ++i)
	{
		if (textures[i])
			textures[i]->grab();

		Textures.push_back(textures[i]);
	}

	EndTime = now + (timePerFrame * Textures.size());
}
Esempio n. 18
0
//! Activate any joysticks, and generate events for them.
bool CIrrDeviceSDL::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
{
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
	joystickInfo.clear();

	// we can name up to 256 different joysticks
	const int numJoysticks = core::min_(SDL_NumJoysticks(), 256);
	Joysticks.reallocate(numJoysticks);
	joystickInfo.reallocate(numJoysticks);

	int joystick = 0;
	for (; joystick<numJoysticks; ++joystick)
	{
		Joysticks.push_back(SDL_JoystickOpen(joystick));
		SJoystickInfo info;

		info.Joystick = joystick;
		info.Axes = SDL_JoystickNumAxes(Joysticks[joystick]);
		info.Buttons = SDL_JoystickNumButtons(Joysticks[joystick]);
		info.Name = SDL_JoystickName(joystick);
		info.PovHat = (SDL_JoystickNumHats(Joysticks[joystick]) > 0)
						? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT;

		joystickInfo.push_back(info);
	}

	for(joystick = 0; joystick < (int)joystickInfo.size(); ++joystick)
	{
		char logString[256];
		(void)sprintf(logString, "Found joystick %d, %d axes, %d buttons '%s'",
		 joystick, joystickInfo[joystick].Axes,
   joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str());
		os::Printer::log(logString, ELL_INFORMATION);
	}

	return true;

#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_

	return false;
}
Esempio n. 19
0
void TextureSource::rebuildImagesAndTextures()
{
	JMutexAutoLock lock(m_atlaspointer_cache_mutex);

	/*// Oh well... just clear everything, they'll load sometime.
	m_atlaspointer_cache.clear();
	m_name_to_id.clear();*/

	video::IVideoDriver* driver = m_device->getVideoDriver();
	
	// Remove source images from textures to disable inheriting textures
	// from existing textures
	/*for(u32 i=0; i<m_atlaspointer_cache.size(); i++){
		SourceAtlasPointer *sap = &m_atlaspointer_cache[i];
		sap->atlas_img->drop();
		sap->atlas_img = NULL;
	}*/
	
	// Recreate textures
	for(u32 i=0; i<m_atlaspointer_cache.size(); i++){
		SourceAtlasPointer *sap = &m_atlaspointer_cache[i];
		video::IImage *img =
			generate_image_from_scratch(sap->name, m_device, &m_sourcecache);
		// Create texture from resulting image
		video::ITexture *t = NULL;
		if(img)
			t = driver->addTexture(sap->name.c_str(), img);
		
		// Replace texture
		sap->a.atlas = t;
		sap->a.pos = v2f(0,0);
		sap->a.size = v2f(1,1);
		sap->a.tiled = 0;
		sap->atlas_img = img;
		sap->intpos = v2s32(0,0);
		sap->intsize = img->getDimension();
	}
}
void CGUISpriteBank::draw2DSpriteBatch(	const core::array<u32>& indices,
										const core::array<core::position2di>& pos,
										const core::rect<s32>* clip,
										const video::SColor& color,
										u32 starttime, u32 currenttime,
										bool loop, bool center)
{
	const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());

	if (!getTextureCount())
		return;
	core::array<SDrawBatch> drawBatches(getTextureCount());
	for (u32 i=0; i < Textures.size(); ++i)
	{
		drawBatches.push_back(SDrawBatch());
		drawBatches[i].positions.reallocate(drawCount);
		drawBatches[i].sourceRects.reallocate(drawCount);
	}

	for (u32 i = 0; i < drawCount; ++i)
	{
		const u32 index = indices[i];

		if (index >= Sprites.size() || Sprites[index].Frames.empty() )
			continue;

		// work out frame number
		u32 frame = 0;
		if (Sprites[index].frameTime)
		{
			u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
			if (loop)
				frame = f % Sprites[index].Frames.size();
			else
				frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
		}

		const u32 texNum = Sprites[index].Frames[frame].textureNumber;
		SDrawBatch& currentBatch = drawBatches[texNum];

		const u32 rn = Sprites[index].Frames[frame].rectNumber;
		if (rn >= Rectangles.size())
			return;

		const core::rect<s32>& r = Rectangles[rn];

		if (center)
		{
			core::position2di p = pos[i];
			p -= r.getSize() / 2;

			currentBatch.positions.push_back(p);
			currentBatch.sourceRects.push_back(r);
		}
		else
		{
			currentBatch.positions.push_back(pos[i]);
			currentBatch.sourceRects.push_back(r);
		}
	}

	for(u32 i = 0;i < drawBatches.size();i++)
	{
		if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty())
			Driver->draw2DImageBatch(getTexture(i), drawBatches[i].positions,
				drawBatches[i].sourceRects, clip, color, true);
	}
}
Esempio n. 21
0
void HWSkinningCallback::OnSetConstants(video::IMaterialRendererServices *services, s32 userData)
{
/*    static const float colors[] = {
        1.0, 0.0, 0.0, 1.0,
        0.0, 1.0, 0.0, 1.0,
        0.0, 0.0, 1.0, 1.0,
        1.0, 1.0, 0.0, 1.0,
        0.0, 1.0, 1.0, 1.0,
        1.0, 0.0, 1.0, 1.0,
        0.0, 0.0, 0.0, 1.0,
        1.0, 1.0, 1.0, 1.0,
    };
    static const int nb_colors = 8;
    //int index = m_used_material

    int index = 4;
    //int index = *reinterpret_cast<const int*>(&m_used_material->MaterialTypeParam);
    //printf("OnSetConstants: index: %d\n", index);
    //index = 4 * (index % nb_colors);

    services->setPixelShaderConstant("debug_color", &colors[index], 4);
*/
    //! Sets a constant for the pixel shader based on a name.
 /** This can be used if you used a high level shader language like GLSL
 or HLSL to create a shader. See setVertexShaderConstant() for an
 example on how to use this.
 \param name Name of the variable
 \param floats Pointer to array of floats
 \param count Amount of floats in array.
 \return True if successful. */
 /*virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count) = 0;*/

    // TODO: cleanup
    // - joints
    scene::ISkinnedMesh* mesh = (scene::ISkinnedMesh*)m_node->getMesh();
    f32 joints_data[55 * 16];
    int copyIncrement = 0;

    const core::array<scene::ISkinnedMesh::SJoint*> joints = mesh->getAllJoints();
    for(u32 i = 0;i < joints.size();++i)
    {
        core::matrix4 joint_vertex_pull(core::matrix4::EM4CONST_NOTHING);
        joint_vertex_pull.setbyproduct(joints[i]->GlobalAnimatedMatrix, joints[i]->GlobalInversedMatrix);

        f32* pointer = joints_data + copyIncrement;
        for(int i = 0;i < 16;++i)
            *pointer++ = joint_vertex_pull[i];

        copyIncrement += 16;
    }

    services->setVertexShaderConstant("JointTransform", joints_data, mesh->getAllJoints().size() * 16);

    // - mWorldViewProj
    // set clip matrix at register 4
/*    core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
    worldViewProj *= driver->getTransform(video::ETS_VIEW);
    worldViewProj *= driver->getTransform(video::ETS_WORLD);
    services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4);
*/    // for high level shading languages, this would be another solution:
    //services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16);

    // -
}
Esempio n. 22
0
	// This is called before the specified scene node is rendered
	virtual void OnNodePreRender(scene::ISceneNode* node)
	{
		CurrentSceneNode = node;

		// This light manager only considers solid objects, but you are free to manipulate
		// lights during any phase, depending on your requirements.
		if (scene::ESNRP_SOLID != CurrentRenderPass)
			return;

		// And in fact for this example, I only want to consider lighting for cube scene
		// nodes.  You will probably want to deal with lighting for (at least) mesh /
		// animated mesh scene nodes as well.
		if (node->getType() != scene::ESNT_CUBE)
			return;

		if (LIGHTS_NEAREST_NODE == Mode)
		{
			// This is a naive implementation that prioritises every light in the scene
			// by its proximity to the node being rendered.  This produces some flickering
			// when lights orbit closer to a cube than its 'zone' lights.
			const vector3df nodePosition = node->getAbsolutePosition();

			// Sort the light list by prioritising them based on their distance from the node
			// that's about to be rendered.
			array<LightDistanceElement> sortingArray;
			sortingArray.reallocate(SceneLightList->size());

			u32 i;
			for(i = 0; i < SceneLightList->size(); ++i)
			{
				scene::ILightSceneNode* lightNode = (*SceneLightList)[i];
				f64 distance = lightNode->getAbsolutePosition().getDistanceFromSQ(nodePosition);
				sortingArray.push_back(LightDistanceElement(lightNode, distance));
			}

			sortingArray.sort();

			// The list is now sorted by proximity to the node.
			// Turn on the three nearest lights, and turn the others off.
			for(i = 0; i < sortingArray.size(); ++i)
				sortingArray[i].node->setVisible(i < 3);

		}
		else if(LIGHTS_IN_ZONE == Mode)
		{
			// Empty scene nodes are used to represent 'zones'.  For each solid mesh that
			// is being rendered, turn off all lights, then find its 'zone' parent, and turn
			// on all lights that are found under that node in the scene graph.
			// This is a general purpose algorithm that doesn't use any special
			// knowledge of how this particular scene graph is organised.
			for (u32 i = 0; i < SceneLightList->size(); ++i)
			{
				scene::ILightSceneNode* lightNode = (*SceneLightList)[i];
				video::SLight & lightData = lightNode->getLightData();

				if (video::ELT_DIRECTIONAL != lightData.Type)
					lightNode->setVisible(false);
			}

			scene::ISceneNode * parentZone = findZone(node);
			if (parentZone)
				turnOnZoneLights(parentZone);
		}
	}
		void CD3D9RenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
		{
			bool textureUpdate = (Texture != texture) ? true : false;
			bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false;

			if (textureUpdate || depthStencilUpdate)
			{
				// Set color attachments.

				if (textureUpdate)
				{
					if (texture.size() > Driver->ActiveRenderTarget.size())
					{
						core::stringc message = "This GPU supports up to ";
						message += Driver->ActiveRenderTarget.size();
						message += " textures per render target.";

						os::Printer::log(message.c_str(), ELL_WARNING);
					}

					const u32 size = core::min_(texture.size(), static_cast<u32>(Driver->ActiveRenderTarget.size()));

					for (u32 i = 0; i < Surface.size(); ++i)
					{
						if (Surface[i])
							Surface[i]->Release();
					}

					Surface.set_used(size);

					for (u32 i = 0; i < Texture.size(); ++i)
					{
						if (Texture[i])
							Texture[i]->drop();
					}

					Texture.set_used(size);

					for (u32 i = 0; i < size; ++i)
					{
						CD3D9Texture* currentTexture = (texture[i] && texture[i]->getDriverType() == DriverType) ? static_cast<CD3D9Texture*>(texture[i]) : 0;

						IDirect3DTexture9* textureID = 0;

						if (currentTexture)
						{
							if (currentTexture->getType() == ETT_2D)
								textureID = currentTexture->getDX9Texture();
							else
								os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING);
						}

						if (textureID)
						{
							Texture[i] = texture[i];
							Texture[i]->grab();

							IDirect3DSurface9* currentSurface = 0;
							textureID->GetSurfaceLevel(0, &currentSurface);

							Surface[i] = currentSurface;
						}
						else
						{
							Surface[i] = 0;
							Texture[i] = 0;
						}
					}
				}

				// Set depth and stencil attachments.

				if (depthStencilUpdate)
				{
					if (DepthStencilSurface)
					{
						DepthStencilSurface->Release();
						DepthStencilSurface = 0;
					}

					if (DepthStencil)
					{
						DepthStencil->drop();
						DepthStencil = 0;

						DepthStencilSurface = 0;
					}

					CD3D9Texture* currentTexture = (depthStencil && depthStencil->getDriverType() == DriverType) ? static_cast<CD3D9Texture*>(depthStencil) : 0;

					IDirect3DTexture9* textureID = 0;

					if (currentTexture)
					{
						if (currentTexture->getType() == ETT_2D)
							textureID = currentTexture->getDX9Texture();
						else
							os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING);
					}

					if (textureID)
					{
						const ECOLOR_FORMAT textureFormat = (depthStencil) ? depthStencil->getColorFormat() : ECF_UNKNOWN;

						if (IImage::isDepthFormat(textureFormat))
						{
							DepthStencil = depthStencil;
							DepthStencil->grab();

							IDirect3DSurface9* currentSurface = 0;
							textureID->GetSurfaceLevel(0, &currentSurface);

							DepthStencilSurface = currentSurface;
						}
					}
				}

				// Set size required for a viewport.

				bool sizeDetected = false;

				for (u32 i = 0; i < Texture.size(); ++i)
				{
					if (Texture[i])
					{
						Size = Texture[i]->getSize();
						sizeDetected = true;

						break;
					}
				}

				if (!sizeDetected)
				{
					if (DepthStencil)
						Size = DepthStencil->getSize();
					else
						Size = Driver->getScreenSize();
				}
			}
		}
Esempio n. 24
0
void BuildCylinder(   
        core::array<video::S3DVertex>& vertexArray,
        core::array<u16>& indexArray,
        core::aabbox3d<f32>& boundingBox,
        
        f32 height,
        f32 startRadius,
        f32 endRadius,
        s32 radialSegments,
        
        const core::matrix4& transform,
        
        f32 startTCoordY = 0.0f,
        f32 endTCoordY = 1.0f,
        video::SColor startColor = video::SColor(255,255,255,255),
        video::SColor endColor = video::SColor(255,255,255,255) )
{
    u16 vertexIndex = vertexArray.size();
    
    s32 radialVertices = radialSegments + 1; // We want one additional vertex to make the texture wraps correctly
    
    // Place bottom cap
    for ( s32 i=0; i<radialVertices; i++ )
    {
        f32 angle = 2.0f * core::PI * i / (f32)( radialSegments );
        
        core::vector3df dir;
        dir.X = cos(angle);
        dir.Z = sin(angle);
        
        core::vector3df pos;
        core::vector3df normal = dir;

        pos = dir * startRadius;
        
        // Place bottom vertex
        transform.transformVect( pos );
        transform.rotateVect( normal );
        
        core::vector2df tcoord;
        tcoord.X = (f32)( i ) / (f32)( radialSegments );
        tcoord.Y = startTCoordY;
        
        vertexArray.push_back( video::S3DVertex(
            pos,
            normal,
            startColor,
            tcoord  ) );
        
        boundingBox.addInternalPoint( pos );
    }
    
    // Place top cap and indices
    for ( s32 i=0; i<radialVertices; i++ )
    {
        f32 angle = 2.0f * core::PI * i / (f32)( radialSegments );
        
        core::vector3df dir;
        dir.X = cos(angle);
        dir.Z = sin(angle);
        
        core::vector3df normal = dir;
        core::vector3df pos = dir * endRadius;
        pos.Y = height;
        
        transform.transformVect( pos ); 
        transform.rotateVect( normal );
        
        core::vector2df tcoord;
        tcoord.X = (f32)( i ) / (f32)( radialSegments );
        tcoord.Y = endTCoordY;
        
        vertexArray.push_back( video::S3DVertex(
            pos,
            normal,
            endColor,
            tcoord  ) );
        
        boundingBox.addInternalPoint(pos);
        
        // Add indices
        if ( i != radialVertices-1 )
        {
            s32 i2 = (i+1)%radialVertices;
            // Place the indices
            indexArray.push_back ( vertexIndex + i );
            indexArray.push_back ( vertexIndex + radialVertices + i );
            indexArray.push_back ( vertexIndex + i2 );
            
            indexArray.push_back ( vertexIndex + radialVertices + i );
            indexArray.push_back ( vertexIndex + radialVertices + i2 );
            indexArray.push_back ( vertexIndex + i2 );
        }
    }
}
Esempio n. 25
0
void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{
	bool textureUpdate = (Texture != texture) ? true : false;
	bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false;

	if (textureUpdate || depthStencilUpdate)
	{
		// Set color attachments.

		if (textureUpdate)
		{
			for (u32 i = 0; i < Texture.size(); ++i)
			{
				if (Texture[i])
					Texture[i]->drop();
			}

			if (texture.size() > static_cast<u32>(Driver->MaxColorAttachments))
			{
				core::stringc message = "This GPU supports up to ";
				message += static_cast<u32>(Driver->MaxColorAttachments);
				message += " textures per render target.";

				os::Printer::log(message.c_str(), ELL_WARNING);
			}

			Texture.set_used(core::min_(texture.size(), static_cast<u32>(Driver->MaxColorAttachments)));

			for (u32 i = 0; i < Texture.size(); ++i)
			{
				GLuint textureID = (texture[i] && texture[i]->getDriverType() == EDT_OPENGL) ? static_cast<COpenGLTexture*>(texture[i])->getOpenGLTextureName() : 0;

				if (textureID != 0)
				{
					Texture[i] = texture[i];
					Texture[i]->grab();
				}
				else
				{
					Texture[i] = 0;
				}
			}

			RequestTextureUpdate = true;
		}

		// Set depth and stencil attachments.

		if (depthStencilUpdate)
		{
			GLuint textureID = (depthStencil && depthStencil->getDriverType() == EDT_OPENGL) ? static_cast<COpenGLTexture*>(depthStencil)->getOpenGLTextureName() : 0;
			const ECOLOR_FORMAT textureFormat = (textureID != 0) ? depthStencil->getColorFormat() : ECF_UNKNOWN;

			if (IImage::isDepthFormat(textureFormat))
			{
				DepthStencil = depthStencil;
				DepthStencil->grab();
			}
			else
			{
				if (DepthStencil)
					DepthStencil->drop();

				DepthStencil = 0;
			}

			RequestDepthStencilUpdate = true;
		}

		// Set size required for a viewport.

		ITexture* firstTexture = getTexture();

		if (firstTexture)
			Size = firstTexture->getSize();
		else
		{
			if (DepthStencil)
				Size = DepthStencil->getSize();
			else
				Size = Driver->getScreenSize();
		}
	}
}
Esempio n. 26
0
/*
	This method generates all the textures
*/
u32 TextureSource::getTextureIdDirect(const std::string &name)
{
	//infostream<<"getTextureIdDirect(): name=\""<<name<<"\""<<std::endl;

	// Empty name means texture 0
	if(name == "")
	{
		infostream<<"getTextureIdDirect(): name is empty"<<std::endl;
		return 0;
	}
	
	/*
		Calling only allowed from main thread
	*/
	if(get_current_thread_id() != m_main_thread)
	{
		errorstream<<"TextureSource::getTextureIdDirect() "
				"called not from main thread"<<std::endl;
		return 0;
	}

	/*
		See if texture already exists
	*/
	{
		JMutexAutoLock lock(m_atlaspointer_cache_mutex);

		core::map<std::string, u32>::Node *n;
		n = m_name_to_id.find(name);
		if(n != NULL)
		{
			/*infostream<<"getTextureIdDirect(): \""<<name
					<<"\" found in cache"<<std::endl;*/
			return n->getValue();
		}
	}

	/*infostream<<"getTextureIdDirect(): \""<<name
			<<"\" NOT found in cache. Creating it."<<std::endl;*/
	
	/*
		Get the base image
	*/

	char separator = '^';

	/*
		This is set to the id of the base image.
		If left 0, there is no base image and a completely new image
		is made.
	*/
	u32 base_image_id = 0;
	
	// Find last meta separator in name
	s32 last_separator_position = -1;
	for(s32 i=name.size()-1; i>=0; i--)
	{
		if(name[i] == separator)
		{
			last_separator_position = i;
			break;
		}
	}
	/*
		If separator was found, construct the base name and make the
		base image using a recursive call
	*/
	std::string base_image_name;
	if(last_separator_position != -1)
	{
		// Construct base name
		base_image_name = name.substr(0, last_separator_position);
		/*infostream<<"getTextureIdDirect(): Calling itself recursively"
				" to get base image of \""<<name<<"\" = \""
                <<base_image_name<<"\""<<std::endl;*/
		base_image_id = getTextureIdDirect(base_image_name);
	}
	
	//infostream<<"base_image_id="<<base_image_id<<std::endl;
	
	video::IVideoDriver* driver = m_device->getVideoDriver();
	assert(driver);

	video::ITexture *t = NULL;

	/*
		An image will be built from files and then converted into a texture.
	*/
	video::IImage *baseimg = NULL;
	
	// If a base image was found, copy it to baseimg
	if(base_image_id != 0)
	{
		JMutexAutoLock lock(m_atlaspointer_cache_mutex);

		SourceAtlasPointer ap = m_atlaspointer_cache[base_image_id];

		video::IImage *image = ap.atlas_img;
		
		if(image == NULL)
		{
			infostream<<"getTextureIdDirect(): WARNING: NULL image in "
					<<"cache: \""<<base_image_name<<"\""
					<<std::endl;
		}
		else
		{
			core::dimension2d<u32> dim = ap.intsize;

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

			core::position2d<s32> pos_to(0,0);
			core::position2d<s32> pos_from = ap.intpos;
			
			image->copyTo(
					baseimg, // target
					v2s32(0,0), // position in target
					core::rect<s32>(pos_from, dim) // from
			);

			/*infostream<<"getTextureIdDirect(): Loaded \""
					<<base_image_name<<"\" from image cache"
					<<std::endl;*/
		}
	}
	
	/*
		Parse out the last part of the name of the image and act
		according to it
	*/

	std::string last_part_of_name = name.substr(last_separator_position+1);
	//infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;

	// Generate image according to part of name
	if(!generate_image(last_part_of_name, baseimg, m_device, &m_sourcecache))
	{
		errorstream<<"getTextureIdDirect(): "
				"failed to generate \""<<last_part_of_name<<"\""
				<<std::endl;
	}

	// If no resulting image, print a warning
	if(baseimg == NULL)
	{
		errorstream<<"getTextureIdDirect(): baseimg is NULL (attempted to"
				" create texture \""<<name<<"\""<<std::endl;
	}
	
	if(baseimg != NULL)
	{
		// Create texture from resulting image
		t = driver->addTexture(name.c_str(), baseimg);
	}
	
	/*
		Add texture to caches (add NULL textures too)
	*/

	JMutexAutoLock lock(m_atlaspointer_cache_mutex);
	
	u32 id = m_atlaspointer_cache.size();
	AtlasPointer ap(id);
	ap.atlas = t;
	ap.pos = v2f(0,0);
	ap.size = v2f(1,1);
	ap.tiled = 0;
	core::dimension2d<u32> baseimg_dim(0,0);
	if(baseimg)
		baseimg_dim = baseimg->getDimension();
	SourceAtlasPointer nap(name, ap, baseimg, v2s32(0,0), baseimg_dim);
	m_atlaspointer_cache.push_back(nap);
	m_name_to_id.insert(name, id);

	/*infostream<<"getTextureIdDirect(): "
			<<"Returning id="<<id<<" for name \""<<name<<"\""<<std::endl;*/
	
	return id;
}
Esempio n. 27
0
void TextureSource::buildMainAtlas(class IGameDef *gamedef) 
{
	assert(gamedef->tsrc() == this);
	INodeDefManager *ndef = gamedef->ndef();

	infostream<<"TextureSource::buildMainAtlas()"<<std::endl;

	//return; // Disable (for testing)
	
	video::IVideoDriver* driver = m_device->getVideoDriver();
	assert(driver);

	JMutexAutoLock lock(m_atlaspointer_cache_mutex);

	// Create an image of the right size
	core::dimension2d<u32> atlas_dim(1024,1024);
	video::IImage *atlas_img =
			driver->createImage(video::ECF_A8R8G8B8, atlas_dim);
	//assert(atlas_img);
	if(atlas_img == NULL)
	{
		errorstream<<"TextureSource::buildMainAtlas(): Failed to create atlas "
				"image; not building texture atlas."<<std::endl;
		return;
	}

	/*
		Grab list of stuff to include in the texture atlas from the
		main content features
	*/

	core::map<std::string, bool> sourcelist;

	for(u16 j=0; j<MAX_CONTENT+1; j++)
	{
		if(j == CONTENT_IGNORE || j == CONTENT_AIR)
			continue;
		const ContentFeatures &f = ndef->get(j);
		for(u32 i=0; i<6; i++)
		{
			std::string name = f.tname_tiles[i];
			sourcelist[name] = true;
		}
	}
	
	infostream<<"Creating texture atlas out of textures: ";
	for(core::map<std::string, bool>::Iterator
			i = sourcelist.getIterator();
			i.atEnd() == false; i++)
	{
		std::string name = i.getNode()->getKey();
		infostream<<"\""<<name<<"\" ";
	}
	infostream<<std::endl;

	// Padding to disallow texture bleeding
	s32 padding = 16;

	s32 column_width = 256;
	s32 column_padding = 16;

	/*
		First pass: generate almost everything
	*/
	core::position2d<s32> pos_in_atlas(0,0);
	
	pos_in_atlas.Y = padding;

	for(core::map<std::string, bool>::Iterator
			i = sourcelist.getIterator();
			i.atEnd() == false; i++)
	{
		std::string name = i.getNode()->getKey();

		// Generate image by name
		video::IImage *img2 = generate_image_from_scratch(name, m_device,
				&m_sourcecache);
		if(img2 == NULL)
		{
			errorstream<<"TextureSource::buildMainAtlas(): "
					<<"Couldn't generate image \""<<name<<"\""<<std::endl;
			continue;
		}

		core::dimension2d<u32> dim = img2->getDimension();

		// Don't add to atlas if image is large
		core::dimension2d<u32> max_size_in_atlas(32,32);
		if(dim.Width > max_size_in_atlas.Width
		|| dim.Height > max_size_in_atlas.Height)
		{
			infostream<<"TextureSource::buildMainAtlas(): Not adding "
					<<"\""<<name<<"\" because image is large"<<std::endl;
			continue;
		}

		// Wrap columns and stop making atlas if atlas is full
		if(pos_in_atlas.Y + dim.Height > atlas_dim.Height)
		{
			if(pos_in_atlas.X > (s32)atlas_dim.Width - 256 - padding){
				errorstream<<"TextureSource::buildMainAtlas(): "
						<<"Atlas is full, not adding more textures."
						<<std::endl;
				break;
			}
			pos_in_atlas.Y = padding;
			pos_in_atlas.X += column_width + column_padding;
		}
		
		/*infostream<<"TextureSource::buildMainAtlas(): Adding \""<<name
				<<"\" to texture atlas"<<std::endl;*/

		// Tile it a few times in the X direction
		u16 xwise_tiling = column_width / dim.Width;
		if(xwise_tiling > 16) // Limit to 16 (more gives no benefit)
			xwise_tiling = 16;
		for(u32 j=0; j<xwise_tiling; j++)
		{
			// Copy the copy to the atlas
			/*img2->copyToWithAlpha(atlas_img,
					pos_in_atlas + v2s32(j*dim.Width,0),
					core::rect<s32>(v2s32(0,0), dim),
					video::SColor(255,255,255,255),
					NULL);*/
			img2->copyTo(atlas_img,
					pos_in_atlas + v2s32(j*dim.Width,0),
					core::rect<s32>(v2s32(0,0), dim),
					NULL);
		}

		// Copy the borders a few times to disallow texture bleeding
		for(u32 side=0; side<2; side++) // top and bottom
		for(s32 y0=0; y0<padding; y0++)
		for(s32 x0=0; x0<(s32)xwise_tiling*(s32)dim.Width; x0++)
		{
			s32 dst_y;
			s32 src_y;
			if(side==0)
			{
				dst_y = y0 + pos_in_atlas.Y + dim.Height;
				src_y = pos_in_atlas.Y + dim.Height - 1;
			}
			else
			{
				dst_y = -y0 + pos_in_atlas.Y-1;
				src_y = pos_in_atlas.Y;
			}
			s32 x = x0 + pos_in_atlas.X;
			video::SColor c = atlas_img->getPixel(x, src_y);
			atlas_img->setPixel(x,dst_y,c);
		}

		img2->drop();

		/*
			Add texture to caches
		*/
		
		bool reuse_old_id = false;
		u32 id = m_atlaspointer_cache.size();
		// Check old id without fetching a texture
		core::map<std::string, u32>::Node *n;
		n = m_name_to_id.find(name);
		// If it exists, we will replace the old definition
		if(n){
			id = n->getValue();
			reuse_old_id = true;
			/*infostream<<"TextureSource::buildMainAtlas(): "
					<<"Replacing old AtlasPointer"<<std::endl;*/
		}

		// Create AtlasPointer
		AtlasPointer ap(id);
		ap.atlas = NULL; // Set on the second pass
		ap.pos = v2f((float)pos_in_atlas.X/(float)atlas_dim.Width,
				(float)pos_in_atlas.Y/(float)atlas_dim.Height);
		ap.size = v2f((float)dim.Width/(float)atlas_dim.Width,
				(float)dim.Width/(float)atlas_dim.Height);
		ap.tiled = xwise_tiling;

		// Create SourceAtlasPointer and add to containers
		SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim);
		if(reuse_old_id)
			m_atlaspointer_cache[id] = nap;
		else
			m_atlaspointer_cache.push_back(nap);
		m_name_to_id[name] = id;
			
		// Increment position
		pos_in_atlas.Y += dim.Height + padding * 2;
	}

	/*
		Make texture
	*/
	video::ITexture *t = driver->addTexture("__main_atlas__", atlas_img);
	assert(t);

	/*
		Second pass: set texture pointer in generated AtlasPointers
	*/
	for(core::map<std::string, bool>::Iterator
			i = sourcelist.getIterator();
			i.atEnd() == false; i++)
	{
		std::string name = i.getNode()->getKey();
		if(m_name_to_id.find(name) == NULL)
			continue;
		u32 id = m_name_to_id[name];
		//infostream<<"id of name "<<name<<" is "<<id<<std::endl;
		m_atlaspointer_cache[id].a.atlas = t;
	}

	/*
		Write image to file so that it can be inspected
	*/
	/*std::string atlaspath = porting::path_user
			+ DIR_DELIM + "generated_texture_atlas.png";
	infostream<<"Removing and writing texture atlas for inspection to "
			<<atlaspath<<std::endl;
	fs::RecursiveDelete(atlaspath);
	driver->writeImageToFile(atlas_img, atlaspath.c_str());*/
}