TSTerrainSceneNode [Download Links Posted 30/7/08]

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
seno
Posts: 34
Joined: Thu Nov 17, 2005 2:50 am
Location: Seoul Korea

Post by seno »

Well, since Geocities data transfer limit is so low, i decided to post the source code.

//////////////////////////////////////////////////////////////////////////////////
080605_HowToUseTSHeightTerrainSceneNode.txt

Code: Select all

Documented By:		Do-young Chung

Documented Date:	080605

Title:				How to use TSTerrainSceneNode


0.	Please note. 

	@ TSTerrainSceneNode was developed in Irrlicht 1.3.1.
	
	@ TSTerrainSceneNode's actual goal is importing the height map created by Earthsculptor( http://www.earthsculptor.com/ ).
	  and it has only been tested with the height maps that were genereted by Earthsculptor. Thus, to get the best result,
	  please use the height map generated by Earthsculptor.
	  
	@ Only for DirectX 9.
	

1.	To use the TSTerrainSceneNode, Irrlicht must be modified to support 7 textures.
	The unmodified Irrlicht only supports 4  textures, however TSTerrainSceneNode requires
	4 detail textures, 1 detail map texture, 1 light map texture and 1 color map texture. I think about combining 4 detail
	textures to 1, therefore make Irrlicht not be necessary to modify. However I decided to not go that far for the current version.
	
	
	
	
// Modifying Irrlicht To Make Enable Using 8 Textures ------------------------------------------------------------------ //

At SMaterial.h (Line: 310) ===============================================

From -------->

	//! Maximum number of texture an SMaterial can have.
	
	const u32 MATERIAL_MAX_TEXTURES = 4;

To <----------

	//! Maximum number of texture an SMaterial can have.
	/*
	const u32 MATERIAL_MAX_TEXTURES = 4;
	*/

	// Modified By DC
	const u32 MATERIAL_MAX_TEXTURES = 7;
	
==========================================================================

NOTE:	This change enables to set more than 4 textures to the scene::ISceneNode's inherited SceneNode classes

		by calling scene::ISceneNode::void setMaterialTexture(u32 textureLayer, video::ITexture* texture) method.
		


		
At S3DVertex.h(Line: 127) ================================================

From--------->

	//! First set of texture coordinates
	core::vector2d<f32> TCoords;		// Use for detail alpha

	//! Second set of texture coordinates
	core::vector2d<f32> TCoords2;		// Use for 1st texture

Add From Next Line <----

	// Added By DC
	core::vector2d<f32> TCoords3;		// Use for 2nd texture

	core::vector2d<f32> TCoords4;		// Use for 3rd texture

	core::vector2d<f32> TCoords5;		// Use for 4th texture

	core::vector2d<f32> TCoords6;		// Use for light map

	core::vector2d<f32> TCoords7;		// Use for color map

==========================================================================

NOTE:	This change enables to store more than 2 texture coordinates in S3DVertex2TCoords structure, which
		
		is the template type of SMeshBufferLightMap(CMeshBuffer.h). By storing more texture coordinates,
		
		the each detail texture's color can be blended in the Pixel Shader according to the texture coordinates.




CD3D9Driver.cpp(Line 1159) ===============================================

From--------->

case EVT_2TCOORDS:
	hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2);
	break;

To <----------

case EVT_2TCOORDS:	// Modified By DC
	hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX7/*D3DFVF_TEX2*/);
	break;

==========================================================================

NOTE:	This change makes to set vertex type from the vertex with 2 textures to the vertex with 7 textures

		in the DirectX 9.


// End Modifying Irrlicht To Make Enable Using 8 Textures --------------------------------------------------------------- //




2. Now, Irrlicht needs to be modified for being able to create video::IImage from video::ITexture.

NOTE: This modification is posted by tonic( http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=26986&highlight=virtual+iimage%2A+createimage+iimage%2A+imagetocopy )




// Modifying Irrlicht To Make Enable To Create video::IImage From video::ITexture --------------------------------------- //

IImage.h(Line 8) =========================================================

From---------->

#include "IUnknown.h"

#include "position2d.h"
	
To <----------

#include "IUnknown.h"

// Modified By DC: For using TSTerrainSceneNode
//#include "position2d.h"
#include "rect.h"




IImage.h(Line 103) =======================================================

From--------->

virtual u32 getPitch() const = 0;

Add From Next Line <----

// Modified By DC: For using TSHeightTerrainSceneNode

//! fills the surface with given color
virtual void fill(const SColor &color) = 0;

//! copies this surface into another
virtual void copyTo(IImage* target, const core::position2d<s32>& pos, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect=0) = 0;




IVideoDriver.h(Line 714) =================================================

From--------->

	virtual IImage* createImageFromData(ECOLOR_FORMAT format,
		const core::dimension2d<s32>& size, void *data,
		bool ownForeignMemory=false,
		bool deleteMemory = true) = 0;
		
Add From Next Line <----

	// Modified By DC: For using TSHeightTerrainSceneNode

    //! Creates an empty software image.
    /**
    \param format: Desired color format of the image.
    \param size: Size of the image to create.
    \return Returns the created image.
    If you no longer need the image, you should call IImage::drop().
    See IReferenceCounted::drop() for more information. */    
    virtual IImage* createImage(ECOLOR_FORMAT format, const core::dimension2d<s32>& size) = 0;

    //! Creates a software image by converting it to given format from another image.
    /**
    \param format: Desired color format of the image.
    \param imageToCopy: image to copy to the new image.
    \return Returns the created image.
    If you no longer need the image, you should call IImage::drop().
    See IReferenceCounted::drop() for more information. */
    virtual IImage* createImage(ECOLOR_FORMAT format, IImage *imageToCopy) = 0;

    //! Creates a software image from a part of another image.
    /**
    \param imageToCopy: image to copy the the new image in part.
    \param pos: position of rectangle to copy.
    \param size: extents of rectangle to copy.
    \return Returns the created image.
    If you no longer need the image, you should call IImage::drop().
    See IReferenceCounted::drop() for more information. */
    virtual IImage* createImage(IImage* imageToCopy,
            const core::position2d<s32>& pos, const core::dimension2d<s32>& size) = 0; 


    
CNullDriver.h(Line 286) ==================================================

--From------->

	virtual IImage* createImageFromData(ECOLOR_FORMAT format, 
		const core::dimension2d<s32>& size, void *data,
		bool ownForeignMemory=true, bool deleteForeignMemory = true);
	
Add From Next Line <----

	// Modified By DC: For using TSTerrainSceneNode

	virtual IImage* createImage(ECOLOR_FORMAT format, const core::dimension2d<s32>& size);

    virtual IImage* createImage(ECOLOR_FORMAT format, IImage *imageToCopy);

    virtual IImage* createImage(IImage* imageToCopy,
        const core::position2d<s32>& pos, const core::dimension2d<s32>& size);
        
        
        
        
CNullDriver.cpp(Line 1213) ===============================================

From--------->

	//! Creates a software image from a byte array.
	IImage* CNullDriver::createImageFromData(ECOLOR_FORMAT format,
											const core::dimension2d<s32>& size, void *data,
											bool ownForeignMemory,
											bool deleteMemory)
	{
		return new CImage(format, size, data, ownForeignMemory, deleteMemory);
	}
	
Add From Next Line <----

	// Modified By DC: For using TSTerrainSceneNode

	IImage* CNullDriver::createImage(ECOLOR_FORMAT format, const core::dimension2d<s32>& size)
	{
		return new CImage(format, size);
	}


	IImage* CNullDriver::createImage(ECOLOR_FORMAT format, IImage *imageToCopy)
	{
		return new CImage(format, imageToCopy);
	}


	IImage* CNullDriver::createImage(IImage* imageToCopy, const core::position2d<s32>& pos, const core::dimension2d<s32>& size)
	{
		return new CImage(imageToCopy, pos, size);
	}
	

// End Modifying Irrlicht To Make Enable To Create video::IImage From video::ITexture ----------------------------------- //




3. Now, modifying Irrlicht is completed and it is ready to use TSTerrainSceneNode. Thus BUILD IT.




4. To Use the TSTerrainSceneNode

	<1> Before main
	
		#include "TSTerrainSceneNode.h"
		
	<2> In main
	
		IrrlichtDevice			*irrDevice			= createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(1024, 768));
		video::IVideoDriver		*videoDriver		= irrDevice->getVideoDriver();
		scene::ISceneManager	*sceneManager		= irrDevice->getSceneManager();
	
		.............
	
		// Create TSTerrainSceneNode
		TSTerrainSceneNode *terrain = new TSTerrainSceneNode(
			irrDevice->getLogger(), 
			sceneManager, 
			irrDevice->getTimer(), 
			"test03",							// Mesh Name
			"test03.png",						// HeightMap Image File Name
			core::dimension2d<f32>(1.0, 1.0),	// Stretch Size				:Same with ISceneManager::addTerrainMesh's parameter
			250.0f,								// Max Height				:Same with ISceneManager::addTerrainMesh's parameter
			core::dimension2d<s32>(32, 32),		// Default Vertex Block Size:Same with ISceneManager::addTerrainMesh's parameter
			9.39f, 12.85f, 7.947f, 11.478f);	// 1 ~ 4 textures scale		:Same With scene::ITerrainSceneNode::ScaleTexture
			
		// Set Material Textures In SPECIFIC ORDER
		
		terrain->setMaterialTexture(0, videoDriver->getTexture("test03_d.png"));	// Detail Map
		terrain->setMaterialTexture(1, videoDriver->getTexture("grayRock.png"));	// 1st Detail Texture
		terrain->setMaterialTexture(2, videoDriver->getTexture("hardDirt.png"));	// 2nd Detail Texture
		terrain->setMaterialTexture(3, videoDriver->getTexture("bigRockFace.png"));	// 3rd Detail Texture
		terrain->setMaterialTexture(4, videoDriver->getTexture("shortGrass.png"));	// 4th Detail Texture
		terrain->setMaterialTexture(5, videoDriver->getTexture("test03_l.png"));	// Light Map
		terrain->setMaterialTexture(6, videoDriver->getTexture("test03_c.png"));	// Color Map
		
		.............
		
		terrain->drop();
		
		.............
		
		// Usual main loop
		if(irrDevice)
		{
			while(irrDevice->run())
			{
				if (irrDevice->isWindowActive())
				{

					videoDriver->beginScene(true, true, video::SColor(0, 255, 255, 255));
					
					sceneManager->drawAll();
					
					videoDriver->endScene();
				}

			}	
			
			irrDevice->drop();
		}				



5. That's it~.

//////////////////////////////////////////////////////////////////////////////////
TSTerrainSceneNode.h

Code: Select all

/*
	Programmed by Do-young Chung

	Programmed Date 080526

	For:

	TSTerrain(Texture Splatting Height Terrain) Mesh and SceneNode

*/

#pragma once

#include <iostream>
#include <tchar.h>

#include <string>
#include <irrlicht.h>


#pragma comment(lib, "Irrlicht.lib")


using namespace irr;


class TSTerrainSceneNode: public scene::ISceneNode, video::IShaderConstantSetCallBack
{

public:

	// Constructor and Deconstructor ------------------------------------------------//

	TSTerrainSceneNode(
		ILogger					*logger,
		scene::ISceneManager	*sceneManager,
		ITimer					*timer,
		const c8*				name,
		const c8*				heightMapFileName,
		const core::dimension2d<f32>&	stretchSize,
		f32								maxHeight,
		const core::dimension2d<s32>&	defaultVertexBlockSize,
		f32 text1Scale, f32 text2Scale, f32 text3Scale, f32 text4Scale,
		scene::ISceneNode* parent = 0, s32 id = -1);

	virtual ~TSTerrainSceneNode();


	// Inherited From scene::ISceneNode ---------------------------------------------//

	virtual video::SMaterial& getMaterial(u32 i);

	virtual u32 getMaterialCount();

	virtual void OnRegisterSceneNode();

	virtual void OnAnimate(u32 timeMs);

	virtual void render();

	virtual const core::aabbox3d<f32>& getBoundingBox() const;


	// Inherited From video::IShaderConstantSetCallBack -----------------------------//

	virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData);


private:

	// Helper Methods ---------------------------------------------------------------//

	bool loadHeightMap(
		const c8* name,
		video::IImage* heightmap, 
		const core::dimension2d<f32>& stretchSize,
		f32 maxHeight, const core::dimension2d<s32> maxVtxBlockSize,
		bool debugBorders);	

	// Copied From CTerrainSceneNode
	void calculateNormals(scene::SMeshBufferLightMap* pMeshBuffer, core::dimension2d<s32> terrainData);

	
	// Attributes -------------------------------------------------------------------//
	ILogger					*my_logger;

	video::IVideoDriver		*my_videoDriver;

	scene::ISceneManager	*my_sceneManager;

	s32						my_shaderMaterial;

	ITimer					*my_timer;

	core::array<video::SMaterial>	my_materials;

	scene::SMesh					*my_mesh;

	scene::SMeshBufferLightMap		my_RenderBuffer;

	core::dimension2d<f32>	my_size;

	f32						my_detailTextScale;		// Initial value 1.0
	f32						my_lightMapTextScale;	// Initial value 1.0
	f32						my_colorMapTextScale;	// Initial value 1.0
	f32						my_text1Scale;		
	f32						my_text2Scale;
	f32						my_text3Scale;
	f32						my_text4Scale;

};

//////////////////////////////////////////////////////////////////////////////////
TSTerrainSceneNode.cpp

Code: Select all

/*
	Programmed by Do-young Chung

	Programmed Date 080526

	For:

	TSTerrain(Texture Splatting Terrain) SceneNode

*/

#define _USING_SMOOTH_FACTOR


#include "TSTerrainSceneNode.h"


// Constructor and Deconstructor ------------------------------------------------//

TSTerrainSceneNode::TSTerrainSceneNode(
	ILogger					*logger,
	scene::ISceneManager	*sceneManager,
	ITimer					*timer,
	const c8*				name,
	const c8*				heightMapFileName,
	const core::dimension2d<f32>&	stretchSize,
	f32								maxHeight,
	const core::dimension2d<s32>&	defaultVertexBlockSize,
	f32 text1Scale, f32 text2Scale, f32 text3Scale, f32 text4Scale,
	scene::ISceneNode* parent/* = 0*/, s32 id/* = -1*/):
		scene::ISceneNode( parent?parent:sceneManager->getRootSceneNode(), sceneManager, id),
		my_sceneManager(sceneManager), my_timer(timer),
		my_detailTextScale(1.0f), my_lightMapTextScale(1.0f), my_colorMapTextScale(1.0f),
		my_text1Scale(text1Scale), my_text2Scale(text2Scale), my_text3Scale(text3Scale), my_text4Scale(text4Scale)
{
	#ifdef _DEBUG
	setDebugName("TSTerrainSceneNode");
	#endif

	my_logger		= logger;

	my_videoDriver	= my_sceneManager->getVideoDriver();

	my_mesh			= NULL;

	my_size;

	video::IImage *heightMapImage = this->my_videoDriver->createImageFromFile(heightMapFileName);	

	if(this->loadHeightMap(name, heightMapImage, stretchSize, maxHeight, defaultVertexBlockSize, false))
	{
		video::IGPUProgrammingServices* GPUProgrammingServices = my_videoDriver->getGPUProgrammingServices();

		std::string textureSplattingPixelShader		= "";
		std::string textureSplattingVertexShader	= "";

		if (my_videoDriver->getDriverType()		== video::EDT_DIRECT3D9)
		{
			textureSplattingPixelShader		= "textureSplatting_ps.hlsl";
			textureSplattingVertexShader	= "textureSplatting_vs.hlsl";
		}
		/*
		DC NOTE: For now, it's not working for OpenGL

		else if(my_videoDriver->getDriverType()	== video::EDT_OPENGL)
		{
			textureSplattingPixelShader		= "textureSplatting_ps.glsl";
			textureSplattingVertexShader	= "textureSplatting_vs.glsl";
		}
		*/

		my_shaderMaterial = GPUProgrammingServices->addHighLevelShaderMaterialFromFiles(
			textureSplattingVertexShader.c_str(),	"main", video::EVST_VS_2_0,
			textureSplattingPixelShader.c_str(),	"main", video::EPST_PS_2_0,
			this,
			video::EMT_LIGHTMAP);

		this->setMaterialType((video::E_MATERIAL_TYPE)my_shaderMaterial);
	}
	else
	{
		my_shaderMaterial = -1;
	}

	if(heightMapImage != NULL)
		heightMapImage->drop();
}

TSTerrainSceneNode::~TSTerrainSceneNode()
{
	if(my_mesh != NULL)
		my_mesh->drop();
}


// Inherited From scene::ISceneNode ---------------------------------------------//

video::SMaterial& TSTerrainSceneNode::getMaterial(u32 i) 
{ 
	if (i >= this->my_materials.size())
		return ISceneNode::getMaterial(i);

	return this->my_materials[i];
}

u32 TSTerrainSceneNode::getMaterialCount()
{
	return this->my_materials.size();
}

void TSTerrainSceneNode::OnRegisterSceneNode()
{
	if(this->IsVisible)
		this->my_sceneManager->registerNodeForRendering(this);
	
	ISceneNode::OnRegisterSceneNode();
}

void TSTerrainSceneNode::OnAnimate(u32 timeMs)
{
	if(this->IsVisible)
	{

	}

	ISceneNode::OnAnimate(timeMs);
}

void TSTerrainSceneNode::render()
{
	/*
		DC NOTE: Code is partially borrowed from CAnimatedMeshSceneNode(.cpp)
	*/
	if(this->IsVisible && this->my_mesh != NULL)
	{
		this->my_videoDriver->setTransform(video::ETS_WORLD, AbsoluteTransformation);

		bool isTransparentPass =
			this->my_sceneManager->getSceneNodeRenderPass() == scene::ESNRP_TRANSPARENT;

		u32 i = 0;

		for(i = 0; i < this->my_mesh->getMeshBufferCount(); ++i)
		{
			video::IMaterialRenderer* rnd = this->my_videoDriver->getMaterialRenderer(my_materials[i].MaterialType);
			bool transparent = (rnd && rnd->isTransparent());

			// only render transparent buffer if this is the transparent render pass
			// and solid only in solid pass
			if (transparent == isTransparentPass)
			{
				scene::IMeshBuffer* mb = this->my_mesh->getMeshBuffer(i);
				this->my_videoDriver->setMaterial(my_materials[i]);
				this->my_videoDriver->drawMeshBuffer(mb);
			}
		}
	}
}

const core::aabbox3d<f32>& TSTerrainSceneNode::getBoundingBox() const
{
	return this->my_mesh->getBoundingBox();
}


// Inherited From video::IShaderConstantSetCallBack -----------------------------//

void TSTerrainSceneNode::OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
	video::IVideoDriver* driver	= services->getVideoDriver();

	core::matrix4 projection	= driver->getTransform(video::ETS_PROJECTION);
	core::matrix4 view			= driver->getTransform(video::ETS_VIEW);
	core::matrix4 world			= driver->getTransform(video::ETS_WORLD);

	core::matrix4 worldViewProj	=	projection;			
	worldViewProj				*=	view;
	worldViewProj				*=	world;
	services->setVertexShaderConstant("WorldViewProj", worldViewProj.pointer(), 16);
}


// Helper Methods ---------------------------------------------------------------//

bool TSTerrainSceneNode::loadHeightMap(
	const c8* name,
	video::IImage* heightmap, 
	const core::dimension2d<f32>& stretchSize,
	f32 maxHeight, const core::dimension2d<s32> maxVtxBlockSize,
	bool debugBorders)
{
	bool result = false;

	if(name != NULL && strlen(name) > 0 && 
	   heightmap != NULL && this->my_timer != NULL && this->my_videoDriver != NULL)
	{
		u32 startTime = my_timer->getRealTime();

		video::SMaterial material;

		c8 stringBuffer[256];
		c8 textureName[64];

		s32 borderSkip = debugBorders ? 0 : 1;

		video::S3DVertex2TCoords vtx;
		vtx.Color.set(255,255,255,255);

		scene::SMesh* mesh	= new scene::SMesh();

		u32 tm							= this->my_timer->getRealTime() / 1000;
		core::dimension2d<s32> hMapSize	= heightmap->getDimension();
		core::dimension2d<s32> tMapSize = heightmap->getDimension();
		core::position2d<f32> thRel((f32)tMapSize.Width / hMapSize.Width, (f32)tMapSize.Height / hMapSize.Height);
		core::position2d<s32> processed(0,0);


#ifdef _USING_SMOOTH_FACTOR

		s32 widthInBlock			= 0;
		s32 heightInBlock			= 0;
		bool noMoreWidthCounting	= false;

		scene::SMeshBufferLightMap *wholeTerrain	= new scene::SMeshBufferLightMap();
		wholeTerrain->Vertices.set_used(hMapSize.Height * hMapSize.Width);
		u32 wholeTerrainIndex						= 0;

#endif

		while(processed.Y < hMapSize.Height)
		{
#ifdef _USING_SMOOTH_FACTOR
			heightInBlock++;
#endif

			while(processed.X < hMapSize.Width)
			{
#ifdef _USING_SMOOTH_FACTOR
				if(!noMoreWidthCounting)
					widthInBlock++;
#endif

				// 1. Calculate the block size
				core::dimension2d<s32> blockSize = maxVtxBlockSize;

				if (processed.X + blockSize.Width	> hMapSize.Width)
					blockSize.Width		= hMapSize.Width - processed.X;
				if (processed.Y + blockSize.Height	> hMapSize.Height)
					blockSize.Height	= hMapSize.Height - processed.Y;

				// DC NOTE: For Applying Texture Splatting. 
				//			typedef CMeshBuffer<video::S3DVertex2TCoords> SMeshBufferLightMap
				scene::SMeshBufferLightMap* buffer = new scene::SMeshBufferLightMap();

				// 2. Add vertices of vertex block
				s32 y;

				const f32 resDTBySize	= this->my_detailTextScale	/	(f32)(hMapSize.Width - 1);
				const f32 resLMBySize	= this->my_lightMapTextScale/	(f32)(hMapSize.Width - 1);
				const f32 resCMBySize	= this->my_colorMapTextScale/	(f32)(hMapSize.Width - 1);
				const f32 res1BySize	= this->my_text1Scale		/	(f32)(hMapSize.Width - 1);
				const f32 res2BySize	= this->my_text2Scale		/	(f32)(hMapSize.Width - 1);
				const f32 res3BySize	= this->my_text3Scale		/	(f32)(hMapSize.Width - 1);
				const f32 res4BySize	= this->my_text4Scale		/	(f32)(hMapSize.Width - 1);

				f32 xDTval	= 0, zDTval	= 0;
				f32 xLMval	= 0, zLMval = 0;
				f32 xCMval	= 0, zCMval	= 0;
				f32 x1val	= 0, z1val	= 0;
				f32 x2val	= 0, z2val	= 0;
				f32 x3val	= 0, z3val	= 0;
				f32 x4val	= 0, z4val	= 0;


				for (y=0; y < blockSize.Height; ++y)
				{
					if(zDTval == 0)
					{
						zDTval	=	resDTBySize	* (y + processed.Y);
						zLMval	=	resLMBySize	* (y + processed.Y);
						zCMval	=	resCMBySize	* (y + processed.Y);
						z1val	=	res1BySize	* (y + processed.Y);
						z2val	=	res2BySize	* (y + processed.Y);
						z3val	=	res3BySize	* (y + processed.Y);
						z4val	=	res4BySize	* (y + processed.Y);
					}

					for (s32 x=0; x < blockSize.Width; ++x)
					{
						if(xDTval == 0)
						{
							xDTval	+=	resDTBySize	* (x + processed.X);
							xLMval	+=	resLMBySize	* (x + processed.X);
							xCMval	+=	resCMBySize	* (x + processed.X);
							x1val	+=	res1BySize	* (x + processed.X);
							x2val	+=	res2BySize	* (x + processed.X);
							x3val	+=	res3BySize	* (x + processed.X);
							x4val	+=	res4BySize	* (x + processed.X);
						}

						video::SColor clr = heightmap->getPixel(x + processed.X, y + processed.Y);
						f32 height = ((clr.getRed() + clr.getGreen() + clr.getBlue()) / 3.0f) / 255.0f * maxHeight;

						vtx.Pos.set((f32)(x + processed.X) * stretchSize.Width,
							height, (f32)(y + processed.Y) * stretchSize.Height);

						vtx.TCoords.set((x + 0.5f) / blockSize.Width,
							(y + 0.5f) / blockSize.Height);

						vtx.TCoords.X	= xDTval;
						vtx.TCoords6.X	= xLMval;
						vtx.TCoords7.X	= xCMval;
						vtx.TCoords.Y	= zDTval;
						vtx.TCoords6.Y	= zLMval;
						vtx.TCoords7.Y	= zCMval;

						if(this->my_text1Scale == 0)
							vtx.TCoords2	= vtx.TCoords;
						else
						{
							vtx.TCoords2.X	= x1val;
							vtx.TCoords2.Y	= z1val;
						}

						if(this->my_text2Scale == 0)
							vtx.TCoords3	= vtx.TCoords;
						else
						{
							vtx.TCoords3.X	= x2val;
							vtx.TCoords3.Y	= z2val;
						}

						if(this->my_text3Scale == 0)
							vtx.TCoords4	= vtx.TCoords;
						else
						{
							vtx.TCoords4.X	= x3val;
							vtx.TCoords4.Y	= z3val;
						}

						if(this->my_text4Scale == 0)
							vtx.TCoords5	= vtx.TCoords;
						else
						{
							vtx.TCoords5.X	= x4val;
							vtx.TCoords5.Y	= z4val;
						}

						buffer->Vertices.push_back(vtx);

#ifdef _USING_SMOOTH_FACTOR
						wholeTerrainIndex = (x + processed.X) * hMapSize.Width + (y + processed.Y);

						wholeTerrain->Vertices[wholeTerrainIndex] = vtx;
#endif


						xDTval	+=	resDTBySize;
						xLMval	+=	resLMBySize;
						xCMval	+=	resCMBySize;
						x1val	+=	res1BySize;
						x2val	+=	res2BySize;
						x3val	+=	res3BySize;
						x4val	+=	res4BySize;
					}

					xDTval = xLMval = xCMval = x1val = x2val = x3val = x4val = 0;

					zDTval	+=	resDTBySize;
					zLMval	+=	resLMBySize;
					zCMval	+=	resCMBySize;
					z1val	+=	res1BySize;
					z2val	+=	res2BySize;
					z3val	+=	res3BySize;
					z4val	+=	res4BySize;
				}

				// 3. Add indices of vertex block
				for(y = 0; y < blockSize.Height - 1; ++y)
				{
					for (s32 x = 0; x < blockSize.Width - 1; ++x)
					{
						s32 c = (y * blockSize.Width) + x;

						buffer->Indices.push_back(c);
						buffer->Indices.push_back(c + blockSize.Width);
						buffer->Indices.push_back(c + 1);

						buffer->Indices.push_back(c + 1);
						buffer->Indices.push_back(c + blockSize.Width);
						buffer->Indices.push_back(c + 1 + blockSize.Width);
					}
				}

				// 4. Recalculate normals
				for(s32 i = 0; i < (s32)buffer->Indices.size(); i += 3)
				{
					core::plane3d<f32> p(
						buffer->Vertices[buffer->Indices[i + 0]].Pos,
						buffer->Vertices[buffer->Indices[i + 1]].Pos,
						buffer->Vertices[buffer->Indices[i + 2]].Pos);
					p.Normal.normalize();

					buffer->Vertices[buffer->Indices[i + 0]].Normal = p.Normal;
					buffer->Vertices[buffer->Indices[i + 1]].Normal = p.Normal;
					buffer->Vertices[buffer->Indices[i + 2]].Normal = p.Normal;
				}

				if (buffer->Vertices.size())
				{
					// create texture for this block
					video::IImage* img = this->my_videoDriver->createImage(heightmap,
						core::position2d<s32>((s32)(processed.X * thRel.X), (s32)(processed.Y * thRel.Y)),
						core::dimension2d<s32>((s32)(blockSize.Width * thRel.X), (s32)(blockSize.Height * thRel.Y)));

					sprintf_s(textureName, 64, "terrain%u_%d", tm, mesh->getMeshBufferCount());

					material.Textures[0] = this->my_videoDriver->addTexture(textureName, img);

					if (material.Textures[0])
					{
						sprintf_s(stringBuffer, 256, "Generated terrain texture (%dx%d): %s\n",
							material.Textures[0]->getSize().Width,
							material.Textures[0]->getSize().Height,
							textureName);
						this->my_logger->log(stringBuffer);
					}
					else
						printf("Could not create terrain texture.", textureName);

					buffer->Material = material;
					img->drop();
				}

				buffer->recalculateBoundingBox();
				mesh->addMeshBuffer(buffer);
				buffer->drop();

				processed.X += maxVtxBlockSize.Width - borderSkip;

			} // while(processed.X<hMapSize.Width)

#ifdef _USING_SMOOTH_FACTOR
			noMoreWidthCounting = true;
#endif

			// keep on processing
			processed.X = 0;
			processed.Y += maxVtxBlockSize.Height - borderSkip;
		} // while (processed.Y<hMapSize.Height)

		scene::SAnimatedMesh* animatedMesh = new scene::SAnimatedMesh();
		mesh->recalculateBoundingBox();
		this->my_mesh = mesh;


#ifdef _USING_SMOOTH_FACTOR

		for( s32 i=0; i < 5 ;i++)
		{
			for( s32 x=0; x < hMapSize.Width ; x++)
			{
				for( s32 z=0; z < hMapSize.Height ; z++)
				{
				   int counter=1;

				   if( x>0 && z > 0){
					  wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y += wholeTerrain->Vertices[(x-1) + (z-1) * hMapSize.Height].Pos.Y;
					  counter++;
				   }
				   if( x>0 ){
					  wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y += wholeTerrain->Vertices[(x-1) + (z) * hMapSize.Height].Pos.Y;
					  counter++;
				   }
				   if( x>0 && z < hMapSize.Height-1){
					  wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y += wholeTerrain->Vertices[(x-1) + (z+1) * hMapSize.Height].Pos.Y;
					  counter++;
				   }
				   if( x < hMapSize.Width-1 && z > 0){
					  wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y += wholeTerrain->Vertices[(x+1) + (z-1) * hMapSize.Height].Pos.Y;
					  counter++;
				   }
				   if( x < hMapSize.Width-1 ){
					  wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y += wholeTerrain->Vertices[(x+1) + (z) * hMapSize.Height].Pos.Y;
					  counter++;
				   }
				   if( x < hMapSize.Width-1 && z < hMapSize.Height-1){
					  wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y += wholeTerrain->Vertices[(x+1) + (z+1) * hMapSize.Height].Pos.Y;
					  counter++;
				   }
				   if( z > 0 ){
					  wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y += wholeTerrain->Vertices[(x) + (z-1) * hMapSize.Height].Pos.Y;
					  counter++;
				   }
				   if( z < hMapSize.Height-1 ){
					  wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y += wholeTerrain->Vertices[(x) + (z+1) * hMapSize.Height].Pos.Y;
					  counter++;
				   }
				   wholeTerrain->Vertices[x + z * hMapSize.Height].Pos.Y /= (float)counter;
				}
			}
		}

		this->calculateNormals(wholeTerrain, core::dimension2d<s32>(hMapSize.Width, hMapSize.Height));

		// Convert to the Blocks
		s32 curBlockIndex			= 0;
		s32 vertexIndex				= 0;

		processed.X = processed.Y	= 0;

		while(processed.Y < hMapSize.Height)
		{
			while(processed.X < hMapSize.Width)
			{

				// 1. Calculate the block size
				core::dimension2d<s32> blockSize = maxVtxBlockSize;

				if (processed.X + blockSize.Width	> hMapSize.Width)
					blockSize.Width		= hMapSize.Width - processed.X;
				if (processed.Y + blockSize.Height	> hMapSize.Height)
					blockSize.Height	= hMapSize.Height - processed.Y;

				vertexIndex = 0;

				s32 y;

				for (y=0; y < blockSize.Height; ++y)
				{
					for (s32 x=0; x < blockSize.Width; ++x)
					{
						wholeTerrainIndex = (x + processed.X) * hMapSize.Width + (y + processed.Y);

						((scene::SMeshBufferLightMap *)my_mesh->getMeshBuffer(curBlockIndex))->Vertices[vertexIndex].Pos
							= wholeTerrain->Vertices[wholeTerrainIndex].Pos;

						vertexIndex++;
					}
				}

/*
				// 4. Recalculate normals
				for(s32 i = 0; i < (s32)buffer->Indices.size(); i += 3)
				{
					core::plane3d<f32> p(
						buffer->Vertices[buffer->Indices[i + 0]].Pos,
						buffer->Vertices[buffer->Indices[i + 1]].Pos,
						buffer->Vertices[buffer->Indices[i + 2]].Pos);
					p.Normal.normalize();

					buffer->Vertices[buffer->Indices[i + 0]].Normal = p.Normal;
					buffer->Vertices[buffer->Indices[i + 1]].Normal = p.Normal;
					buffer->Vertices[buffer->Indices[i + 2]].Normal = p.Normal;
				}
*/
				curBlockIndex++;
					
				processed.X += maxVtxBlockSize.Width - borderSkip;

			} // while(processed.X<hMapSize.Width)

			// keep on processing
			processed.X = 0;
			processed.Y += maxVtxBlockSize.Height - borderSkip;
		} // while (processed.Y<hMapSize.Height)

		wholeTerrain->drop();
		wholeTerrain = NULL;

#endif


		video::SMaterial mat;
		for (u32 i = 0; i < this->my_mesh->getMeshBufferCount(); ++i)
		{
			scene::IMeshBuffer* mb = this->my_mesh->getMeshBuffer(i);
			if (mb)
				mat = mb->getMaterial();

			this->my_materials.push_back(mat);
		}

		u32 endTime = this->my_timer->getRealTime();

		sprintf_s(stringBuffer, 256, "Generated terrain data (%dx%d) in %.4f seconds\n",
			hMapSize.Width, hMapSize.Height, (endTime - startTime) / 1000.0f);

		this->my_logger->log(stringBuffer);

		if(this->my_mesh != NULL)
		{
			this->my_mesh->grab();
			result = true;
		}
	}

	return result;
}

// calculate smooth normals
void TSTerrainSceneNode::calculateNormals(scene::SMeshBufferLightMap* pMeshBuffer, core::dimension2d<s32> terrainData)
{
	s32 count;
	core::vector3df a, b, c, t;

	for (s32 x=0; x<terrainData.Width; ++x)
		for (s32 z=0; z<terrainData.Height; ++z)
		{
			count = 0;
			core::vector3df normal;

			// top left
			if (x>0 && z>0)
			{
				a = pMeshBuffer->Vertices[(x-1)*terrainData.Width+z-1].Pos;
				b = pMeshBuffer->Vertices[(x-1)*terrainData.Width+z].Pos;
				c = pMeshBuffer->Vertices[x*terrainData.Width+z].Pos;
				b -= a;
				c -= a;
				t = b.crossProduct ( c );
				t.normalize ( );
				normal += t;

				a = pMeshBuffer->Vertices[(x-1)*terrainData.Width+z-1].Pos;
				b = pMeshBuffer->Vertices[x*terrainData.Width+z-1].Pos;
				c = pMeshBuffer->Vertices[x*terrainData.Width+z].Pos;
				b -= a;
				c -= a;
				t = b.crossProduct ( c );
				t.normalize ( );
				normal += t;

				count += 2;
			}

			// top right
			if (x>0 && z<terrainData.Height-1)
			{
				a = pMeshBuffer->Vertices[(x-1)*terrainData.Width+z].Pos;
				b = pMeshBuffer->Vertices[(x-1)*terrainData.Width+z+1].Pos;
				c = pMeshBuffer->Vertices[x*terrainData.Width+z+1].Pos;
				b -= a;
				c -= a;
				t = b.crossProduct ( c );
				t.normalize ( );
				normal += t;

				a = pMeshBuffer->Vertices[(x-1)*terrainData.Width+z].Pos;
				b = pMeshBuffer->Vertices[x*terrainData.Width+z+1].Pos;
				c = pMeshBuffer->Vertices[x*terrainData.Width+z].Pos;
				b -= a;
				c -= a;
				t = b.crossProduct ( c );
				t.normalize ( );
				normal += t;

				count += 2;
			}

			// bottom right
			if (x<terrainData.Width-1 && z<terrainData.Width-1)
			{
				a = pMeshBuffer->Vertices[x*terrainData.Width+z+1].Pos;
				b = pMeshBuffer->Vertices[x*terrainData.Width+z].Pos;
				c = pMeshBuffer->Vertices[(x+1)*terrainData.Width+z+1].Pos;
				b -= a;
				c -= a;
				t = b.crossProduct ( c );
				t.normalize ( );
				normal += t;

				a = pMeshBuffer->Vertices[x*terrainData.Width+z+1].Pos;
				b = pMeshBuffer->Vertices[(x+1)*terrainData.Width+z+1].Pos;
				c = pMeshBuffer->Vertices[(x+1)*terrainData.Width+z].Pos;
				b -= a;
				c -= a;
				t = b.crossProduct ( c );
				t.normalize ( );
				normal += t;

				count += 2;
			}

			// bottom left
			if (x<terrainData.Width-1 && z>0)
			{
				a = pMeshBuffer->Vertices[x*terrainData.Width+z-1].Pos;
				b = pMeshBuffer->Vertices[x*terrainData.Width+z].Pos;
				c = pMeshBuffer->Vertices[(x+1)*terrainData.Width+z].Pos;
				b -= a;
				c -= a;
				t = b.crossProduct ( c );
				t.normalize ( );
				normal += t;

				a = pMeshBuffer->Vertices[x*terrainData.Width+z-1].Pos;
				b = pMeshBuffer->Vertices[(x+1)*terrainData.Width+z].Pos;
				c = pMeshBuffer->Vertices[(x+1)*terrainData.Width+z-1].Pos;
				b -= a;
				c -= a;
				t = b.crossProduct ( c );
				t.normalize ( );
				normal += t;

				count += 2;
			}

			if ( count != 0 )
			{
				normal.normalize ( );
			}
			else
			{
				normal.set( 0.0f, 1.0f, 0.0f );
			}

			pMeshBuffer->Vertices[x * terrainData.Width + z].Normal = normal;
		}
}

//////////////////////////////////////////////////////////////////////////////////
textureSplatting_vs.hlsl

Code: Select all

float4x4 WorldViewProj;  // World * View * Projection transformation

struct VS_INPUT
{
	float4 Position   : POSITION;   // vertex position 
	
	float2 DetailMapCoord			: TEXCOORD0;
	float2 TextureOneCoord			: TEXCOORD1;
	float2 TextureTwoCoord			: TEXCOORD2;
	float2 TextureThreeCoord		: TEXCOORD3;
	float2 TextureFourCoord			: TEXCOORD4;
	float2 LightMapCoord			: TEXCOORD5;
	float2 ColorMapCoord			: TEXCOORD6;
	
};

// Vertex shader output structure
struct VS_OUTPUT
{
	float4 Position   : POSITION;   // vertex position 
	
	float2 DetailMapCoord			: TEXCOORD0;
	float2 TextureOneCoord			: TEXCOORD1;
	float2 TextureTwoCoord			: TEXCOORD2;
	float2 TextureThreeCoord		: TEXCOORD3;
	float2 TextureFourCoord			: TEXCOORD4;
	float2 LightMapCoord			: TEXCOORD5;
	float2 ColorMapCoord			: TEXCOORD6;
};


VS_OUTPUT main( VS_INPUT Input )
{
	VS_OUTPUT Output;

	// transform position to clip space 
	Output.Position = mul(Input.Position, WorldViewProj);

	Output.DetailMapCoord		= Input.DetailMapCoord;
	Output.TextureOneCoord		= Input.TextureOneCoord;
	Output.TextureTwoCoord		= Input.TextureTwoCoord;
	Output.TextureThreeCoord	= Input.TextureThreeCoord;
	Output.TextureFourCoord		= Input.TextureFourCoord;
	Output.LightMapCoord		= Input.LightMapCoord;
	Output.ColorMapCoord		= Input.ColorMapCoord;
	
	return Output;
}

//////////////////////////////////////////////////////////////////////////////////
textureSplatting_ps.hlsl

Code: Select all

sampler2D	DetailMap;
sampler2D	TextureOne;
sampler2D	TextureTwo;
sampler2D	TextureThree;
sampler2D	TextureFour;
sampler2D	LightMap;
sampler2D	ColorMap;

// Pixel shader output structure
struct PS_OUTPUT
{
    float4 Color : COLOR0;  // Pixel color    
};

struct PS_INPUT
{
	float3 Position					: POSITION;   // vertex position
	float3 Normal					: NORMAL;

	float4 Color					: COLOR;
	float2 DetailMapCoord			: TEXCOORD0;
	float2 TextureOneCoord			: TEXCOORD1;
	float2 TextureTwoCoord			: TEXCOORD2;
	float2 TextureThreeCoord		: TEXCOORD3;
	float2 TextureFourCoord			: TEXCOORD4;
	float2 LightMapCoord			: TEXCOORD5;
	float2 ColorMapCoord			: TEXCOORD6;
};

PS_OUTPUT main( PS_INPUT Input ) 
{ 
	PS_OUTPUT Output;

	float4 detailMapColor	= tex2D(DetailMap, Input.DetailMapCoord);
	
	float4 textOneColor		= tex2D(TextureOne,		Input.TextureOneCoord);
	float4 textTwoColor		= tex2D(TextureTwo,		Input.TextureTwoCoord);
	float4 textThreeColor	= tex2D(TextureThree,	Input.TextureThreeCoord);
	float4 textFourColor	= tex2D(TextureFour,	Input.TextureFourCoord);
	
	float4 lightMapColor	= tex2D(LightMap,		Input.LightMapCoord);
	float4 colorMapColor	= tex2D(ColorMap,		Input.ColorMapCoord);
	
	textOneColor	= textOneColor		* detailMapColor.x;
	textTwoColor	= textOneColor		+ detailMapColor.y * (textTwoColor		- textOneColor);
	textThreeColor	= textTwoColor		+ detailMapColor.z * (textThreeColor	- textTwoColor);
	textFourColor	= textThreeColor	+ detailMapColor.w * (textFourColor		- textThreeColor);
	
	colorMapColor	= colorMapColor * 1.6;
	lightMapColor	= lightMapColor + 0.2;
	
	//Output.Color	= textFourColor * lightMapColor - colorMapColor;
	Output.Color	= textFourColor * lightMapColor * colorMapColor;

	return Output;
}

That's it~ First text file is pretty important. Most of them are about

modifying Irrlicht 1.3.1. Once you read, i am pretty sure even you

are using Irrlicht 1.4+, you could get the idea how to modify that.


Ok~ That's it for now. If i implement LOD or Using more detailed textures

(EarthSculptor's license version support 8 detailed textures), then

i will update the project.
Last edited by seno on Tue Jul 15, 2008 1:27 am, edited 2 times in total.
Let's Take Over the World ~!!
Xplod
Posts: 32
Joined: Sat Mar 29, 2008 5:48 pm
Contact:

Post by Xplod »

This looks really amazing.
Any chance to get it working with irr 1.4 ?
seno
Posts: 34
Joined: Thu Nov 17, 2005 2:50 am
Location: Seoul Korea

Post by seno »

well, my project is based on Irrlicht 1.3.1. It might be changed to

Irrlicht 1.4.1 or over, but not soon.

However, i think if you look the code, it wouldn't be that hard to convert

the TSTerrainSceneNode to be able to use with Irrlicht 1.4.1.


Sorry for now.
Let's Take Over the World ~!!
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Well with a glancing look at your code it appears you are modifying the standard S3DVertex to include 7 textures. Instead of doing this why don't you create your own special material/vertex for the usage of 7 textures or, as BlindSide said, make texture arrays so as to keep it within the limit of 4 textures, and fully compatible with existing versions.
TheQuestion = 2B || !2B
seno
Posts: 34
Joined: Thu Nov 17, 2005 2:50 am
Location: Seoul Korea

Post by seno »

Halifax. You are right. I did this way because i hadn't had much idea about

how to implement external material and vertex. Actually, TSTerrainSceneNode.h

was used to contain prototype format of its own vertex, but i erased that

before i posted TSTerrainSceneNode.

My Irrlicht has been pretty much modified, and that's why i didn't bother to

program to fully compatible with existing versions.

However, i HAVE a plan to change this. Until then, please use this as

clumsy reference. :roll:
Let's Take Over the World ~!!
Halifax
Posts: 1424
Joined: Sun Apr 29, 2007 10:40 pm
Location: $9D95

Post by Halifax »

Ah, okay, I was just wondering. Modified or not, your work is great!
TheQuestion = 2B || !2B
doqkhanh
Posts: 158
Joined: Sat Mar 01, 2008 3:14 am
Location: Tokyo, Japan
Contact:

Post by doqkhanh »

Oh, no, there is a stranger error in my project when I try to use this terrain scene node.

I can hack and rebuild Irrlicht 1.4.1 successful. I using right lib and include folder in Visual Studio.net 2005 Express.

Please help me.

Code: Select all

2>TSTerrainSceneNode.cpp
2>d:\engine\demod4\simple game framework\d3(with sgf)\tsterrainscenenode.cpp(416) : error C2660: 'irr::video::IVideoDriver::createImage' : function does not take 3 arguments
The error at video::IImage* img = this->my_videoDriver->createImage in:

Code: Select all


   if (buffer->Vertices.size())
            {
               // create texture for this block
               video::IImage* img = this->my_videoDriver->createImage(
				  heightmap,
                  core::position2d<s32>((s32)(processed.X * thRel.X), (s32)(processed.Y * thRel.Y)),
                  core::dimension2d<s32>((s32)(blockSize.Width * thRel.X), (s32)(blockSize.Height * thRel.Y)));

               sprintf_s(textureName, 64, "terrain%u_%d", tm, mesh->getMeshBufferCount());
			   
			   material.setTexture(0, this->my_videoDriver->addTexture(textureName, img));

               if (material.getTexture(0))
               {
                  sprintf_s(stringBuffer, 256, "Generated terrain texture (%dx%d): %s\n",
                     material.getTexture(0)->getSize().Width,
                     material.getTexture(0)->getSize().Height,
                     textureName);
Edit:

This problem may be from we have only 1 method header in IVideoDriver.h. I don't known what is changed from Irrlicht 1.3 to 1.4, but this look like a error.

Code: Select all


IVideoDriver.h(Line 714) =================================================

From--------->

   virtual IImage* createImageFromData(ECOLOR_FORMAT format,
      const core::dimension2d<s32>& size, void *data,
      bool ownForeignMemory=false,
      bool deleteMemory = true) = 0;
      
Add From Next Line <----

   // Modified By DC: For using TSHeightTerrainSceneNode

    //! Creates an empty software image.
    /**
    \param format: Desired color format of the image.
    \param size: Size of the image to create.
    \return Returns the created image.
    If you no longer need the image, you should call IImage::drop().
    See IReferenceCounted::drop() for more information. */   
    virtual IImage* createImage(ECOLOR_FORMAT format, const core::dimension2d<s32>& size) = 0;


seno
Posts: 34
Joined: Thu Nov 17, 2005 2:50 am
Location: Seoul Korea

Post by seno »

Sorry about late reply.

doqkhanh, you are right. My mistake when i wrote the document about modifying Irrlicht. It's same as NullDriver's last two createImage methods. I attached the code below.

Code: Select all


        //! Creates a software image by converting it to given format from another image.
        /**
        \param format: Desired color format of the image.
        \param imageToCopy: image to copy to the new image.
        \return Returns the created image.
        If you no longer need the image, you should call IImage::drop().
        See IReferenceCounted::drop() for more information. */
        virtual IImage* createImage(ECOLOR_FORMAT format, IImage *imageToCopy) = 0;

        //! Creates a software image from a part of another image.
        /**
        \param imageToCopy: image to copy the the new image in part.
        \param pos: position of rectangle to copy.
        \param size: extents of rectangle to copy.
        \return Returns the created image.
        If you no longer need the image, you should call IImage::drop().
        See IReferenceCounted::drop() for more information. */
        virtual IImage* createImage(IImage* imageToCopy,
            const core::position2d<s32>& pos, const core::dimension2d<s32>& size) = 0; 

The last method is the one that is used in TSTerrainSceneNode.


Thanks about the bug report.
Let's Take Over the World ~!!
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Wow! That's very nice! Terrains looking as good as in Neverwinter night II!

I'll wait to see if you can get a version that you don't need to modify the engine.
Last edited by christianclavet on Thu Jul 17, 2008 5:32 pm, edited 1 time in total.
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

i must be missing something simple here, the error i'm getting (version 1.4.1 ) is...


tsterrainscenenode.cpp(418) : error C2039: 'Textures' : is not a member of 'irr::video::SMaterial'

Code: Select all

material.Textures[0] = this->my_videoDriver->addTexture(textureName, img); 
Image
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

whoa!

that code update messed-up (toasted black) my entire solution file. i had to restore from my last backup to get back my demo programs working again.

blasphemy!
Image
irruser
Posts: 34
Joined: Thu Jul 26, 2007 10:18 am
Location: Scotland

Post by irruser »

the download link inst working :( . try hosting it on another server.
looks awesome though!
B@z
Posts: 876
Joined: Thu Jan 31, 2008 5:05 pm
Location: Hungary

Post by B@z »

hi

i'm using irrlicht 1.4, and it isn't working.
i could do that it doesn't have any compiler error, but when i wanna launch, it dies out:

Code: Select all

            scene::IMeshBuffer* mb = this->my_mesh->getMeshBuffer(i);
			this->my_videoDriver->setMaterial(my_materials[i]);
            this->my_videoDriver->drawMeshBuffer(mb);
here.
says Access violation reading location 0x00000000.

what should i do?
could somebody give me a sample map? maybe my map is wrong (my earth sculptor is a little strange xD)
seno
Posts: 34
Joined: Thu Nov 17, 2005 2:50 am
Location: Seoul Korea

Post by seno »

irruser, sorry about that. i mentioned that the download file is placed at geocities and they don't allow that much transfer limit. You should try to download after a day.

B@z, hmm.. seems like it failed generating meshes from heightmap. missing texture doesn't create null pointer error. Do you have proper messages about generating meshes like below in the console?

Code: Select all

Loaded texture: ./TSTerrainSN_Data/irrlicht2_up.jpg
Loaded texture: ./TSTerrainSN_Data/irrlicht2_dn.jpg
Loaded texture: ./TSTerrainSN_Data/irrlicht2_lf.jpg
Loaded texture: ./TSTerrainSN_Data/irrlicht2_rt.jpg
Loaded texture: ./TSTerrainSN_Data/irrlicht2_ft.jpg
Loaded texture: ./TSTerrainSN_Data/irrlicht2_bk.jpg
Generated terrain texture (32x32): terrain7064_0

Generated terrain texture (32x32): terrain7064_1

Generated terrain texture (32x32): terrain7064_2

Generated terrain texture (32x32): terrain7064_3

Generated terrain texture (32x32): terrain7064_4

Generated terrain texture (32x32): terrain7064_5

Generated terrain texture (32x32): terrain7064_6

Generated terrain texture (32x32): terrain7064_7

Generated terrain texture (16x32): terrain7064_8

Generated terrain texture (32x32): terrain7064_9

Generated terrain texture (32x32): terrain7064_10

Generated terrain texture (32x32): terrain7064_11

Generated terrain texture (32x32): terrain7064_12

Generated terrain texture (32x32): terrain7064_13

Generated terrain texture (32x32): terrain7064_14

Generated terrain texture (32x32): terrain7064_15

Generated terrain texture (32x32): terrain7064_16

Generated terrain texture (16x32): terrain7064_17

Generated terrain texture (32x32): terrain7064_18

Generated terrain texture (32x32): terrain7064_19

Generated terrain texture (32x32): terrain7064_20

Generated terrain texture (32x32): terrain7064_21

Generated terrain texture (32x32): terrain7064_22

Generated terrain texture (32x32): terrain7064_23

Generated terrain texture (32x32): terrain7064_24

Generated terrain texture (32x32): terrain7064_25

Generated terrain texture (16x32): terrain7064_26

Generated terrain texture (32x32): terrain7064_27

Generated terrain texture (32x32): terrain7064_28

Generated terrain texture (32x32): terrain7064_29

Generated terrain texture (32x32): terrain7064_30

Generated terrain texture (32x32): terrain7064_31

Generated terrain texture (32x32): terrain7064_32

Generated terrain texture (32x32): terrain7064_33

Generated terrain texture (32x32): terrain7064_34

Generated terrain texture (16x32): terrain7064_35

Generated terrain texture (32x32): terrain7064_36

Generated terrain texture (32x32): terrain7064_37

Generated terrain texture (32x32): terrain7064_38

Generated terrain texture (32x32): terrain7064_39

Generated terrain texture (32x32): terrain7064_40

Generated terrain texture (32x32): terrain7064_41

Generated terrain texture (32x32): terrain7064_42

Generated terrain texture (32x32): terrain7064_43

Generated terrain texture (16x32): terrain7064_44

Generated terrain texture (32x32): terrain7064_45

Generated terrain texture (32x32): terrain7064_46

Generated terrain texture (32x32): terrain7064_47

Generated terrain texture (32x32): terrain7064_48

Generated terrain texture (32x32): terrain7064_49

Generated terrain texture (32x32): terrain7064_50

Generated terrain texture (32x32): terrain7064_51

Generated terrain texture (32x32): terrain7064_52

Generated terrain texture (16x32): terrain7064_53

Generated terrain texture (32x32): terrain7064_54

Generated terrain texture (32x32): terrain7064_55

Generated terrain texture (32x32): terrain7064_56

Generated terrain texture (32x32): terrain7064_57

Generated terrain texture (32x32): terrain7064_58

Generated terrain texture (32x32): terrain7064_59

Generated terrain texture (32x32): terrain7064_60

Generated terrain texture (32x32): terrain7064_61

Generated terrain texture (16x32): terrain7064_62

Generated terrain texture (32x32): terrain7064_63

Generated terrain texture (32x32): terrain7064_64

Generated terrain texture (32x32): terrain7064_65

Generated terrain texture (32x32): terrain7064_66

Generated terrain texture (32x32): terrain7064_67

Generated terrain texture (32x32): terrain7064_68

Generated terrain texture (32x32): terrain7064_69

Generated terrain texture (32x32): terrain7064_70

Generated terrain texture (16x32): terrain7064_71

Generated terrain texture (32x16): terrain7064_72

Generated terrain texture (32x16): terrain7064_73

Generated terrain texture (32x16): terrain7064_74

Generated terrain texture (32x16): terrain7064_75

Generated terrain texture (32x16): terrain7064_76

Generated terrain texture (32x16): terrain7064_77

Generated terrain texture (32x16): terrain7064_78

Generated terrain texture (32x16): terrain7064_79

Generated terrain texture (16x16): terrain7064_80

Generated terrain data (257x257) in 1.8310 seconds

Loaded texture: ./TSTerrainSN_Data/test03_d.png
Loaded texture: ./TSTerrainSN_Data/grayRock.png
Loaded texture: ./TSTerrainSN_Data/hardDirt.png
Loaded texture: ./TSTerrainSN_Data/bigRockFace.png
Loaded texture: ./TSTerrainSN_Data/shortGrass.png
Loaded texture: ./TSTerrainSN_Data/test03_l.png
Loaded texture: ./TSTerrainSN_Data/test03_c.png
Also, you should check the index of i, the value of my_mesh->getMeshBufferCount() must be equal to the generated mesh buffer number which displayed at the above console. In above console messages, there are 81(0~80) generated mesh buffers.

I hope it is helpful.
Let's Take Over the World ~!!
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Irrlicht 1.4 had a problem with IAnimatedMeshes which are actually only IMeshes. So apply the bugfix, use the workaround to query the IMesh from the scene node first, or update to Irrlicht 1.4.1
Post Reply