diff --git a/bin/conf/gui.conf.default b/bin/conf/gui.conf.default index 54a30d7..fbf51c6 100644 --- a/bin/conf/gui.conf.default +++ b/bin/conf/gui.conf.default @@ -21,4 +21,49 @@ vsync=0 shadows=1 // color depth; 16 or 32 bit -depth=32 \ No newline at end of file +depth=32 + + +//================================================================================================ +// Expert options: Renderer finetuning +// Uncomment/Adjust the following settings if you really know what you do or if you need some extra performance! +// Set a value to 0 or comment it out to use the default setting. +//------------------------------------------------------------------------------------------------ + +// The terrain is split into sectors, here you can specify how many will be used on every axis. +// Each sector is seperately culled if not visible, removing GPU load, but the culling test takes up some CPU. +// If the terrain draw size is very large, it might be better to increase the sector amount. [Default: 5] +//TerrainSectors=5 + +// The higher this value is, the more CPU+GPU power is needed to render the terrain. +// Note that if you set it too low, you will get hard terrin cut-offs in some distance. +// It looks best if this value is larger then . [Default: * 0.33] +//TerrainDrawSize=300 + +// The terrain gets updated after walking some distance over it. Updating needs some CPU, but the more often +// it is updated the smoother it will look like. If the fog starts early enough and covers places where there is no terrain drawn yet +// (depends also on ) there will be no real visual disadvantages. [Default: 1 (min: 1, max: 50)] +//TerrainUpdateStep=3 + +// The distance until the driver will stop drawing. This value has the most impact on the framerate, but setting it too low +// will end up in a very short view distance. If your hardware is good enough, set it as high as possible, but don't forget to +// adjust terrain drawing and fog distances if you do! [Default: 533.33] +//farclip=533.33 + +// The fog gets 100% thickness in the distance specified here. [Default: * 0.7] +//fogfar=380 + +// The fog starts here, getting thicker until reaching . [Default: * 0.75] +//fognear=280 + +// Field of view. The higher the FOV is the more of the scene is visible on the screen, but the more distorted the scene will be! +// Examples: < 0.5 is like looking through a sniper scope +// > 1.0 is the best setting for a "normal" field of view +// > 1.4 is like looking through a fish's eye +// > 2 offers a very high but still playable field of view, but can cause extreme headache after a while +// 2.5 isn't a reasonable value anymore (psychotic) +// at around 3 it starts f***ing up the renderer +// Note that the FOV also has a great impact on the framerate, the higher the value is, the less frames per sec. +// [Default: 1.25] +//FOV=1.1 + diff --git a/src/Client/GUI/CM2MeshFileLoader.cpp b/src/Client/GUI/CM2MeshFileLoader.cpp index 526d09d..3606a3d 100644 --- a/src/Client/GUI/CM2MeshFileLoader.cpp +++ b/src/Client/GUI/CM2MeshFileLoader.cpp @@ -2,12 +2,6 @@ #include "CM2MeshFileLoader.h" #include "common.h" -#ifdef _DEBUG -#define DEBUG(code) code; -#else -#define DEBUG(code) ; -#endif - namespace irr { @@ -204,7 +198,7 @@ for(u32 i=0; iseek(M2MTextureDef[i].texFileOfs); file->read((void*)tempTexFileName.c_str(),M2MTextureDef[i].texFileLen); M2MTextureFiles.push_back(tempTexFileName.c_str()); - std::cout<getTimer(); //... + // disable crappy irrlicht logging + _device->getLogger()->setLogLevel(ELL_NONE); + // register external loaders for not supported filetypes video::CImageLoaderBLP* BLPloader = new video::CImageLoaderBLP(); _driver->addExternalImageLoader(BLPloader); diff --git a/src/Client/GUI/Scene.h b/src/Client/GUI/Scene.h index 73a0cf6..0a395bc 100644 --- a/src/Client/GUI/Scene.h +++ b/src/Client/GUI/Scene.h @@ -108,8 +108,6 @@ private: ZThread::FastMutex mutex; PseuGUI *gui; uint32 map_gridX, map_gridY; - s32 mapsize, meshsize; - f32 tilesize; WorldSession *wsession; World *world; MapMgr *mapmgr; diff --git a/src/Client/GUI/SceneWorld.cpp b/src/Client/GUI/SceneWorld.cpp index e0b5db1..06a1cd0 100644 --- a/src/Client/GUI/SceneWorld.cpp +++ b/src/Client/GUI/SceneWorld.cpp @@ -24,9 +24,6 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g) world = wsession->GetWorld(); mapmgr = world->GetMapMgr(); - // TODO: hardcoded for now, make this adjustable later - float fogdist = 150; - ILightSceneNode* light = smgr->addLightSceneNode(0, core::vector3df(0,0,0), SColorf(255, 255, 255, 255), 1000.0f); SLight ldata = light->getLightData(); ldata.AmbientColor = video::SColorf(0.2f,0.2f,0.2f); @@ -40,7 +37,19 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g) camera = new MCameraFPS(smgr); camera->setNearValue(0.1f); - camera->setFarValue(TILESIZE); // TODO: make this configurable later + + f32 farclip = instance->GetConf()->farclip; + if(farclip < 50) + farclip = TILESIZE; + + f32 fov = instance->GetConf()->fov; + if(!iszero(fov)) + { + logdetail("Camera: Field of view (FOV) = %.3f",fov); + camera->setFOV(fov); + } + + camera->setFarValue(farclip); debugText = guienv->addStaticText(L"< debug text >",rect(0,0,driver->getScreenSize().Width,30),true,true,0,-1,true); @@ -56,8 +65,16 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g) sky->remove(); // thus we grab the sky node while removing it from rendering. */ - f32 fogfar = camera->getFarValue() * 0.7f; - f32 fognear = fogfar * 0.75f; + f32 fogfar = instance->GetConf()->fogfar; + if(fogfar < 30) + fogfar = farclip * 0.7f; + + f32 fognear = instance->GetConf()->fognear; + if(fognear < 10) + fognear = fogfar * 0.75f; + + logdetail("GUI: Using farclip=%.2f fogfar=%.2f fognear=%.2f", farclip, fogfar, fognear); + driver->setFog(envBasicColor, true, fognear, fogfar, 0.02f); // setup cursor @@ -212,6 +229,10 @@ void SceneWorld::OnUpdate(s32 timediff) str += (int)terrain->getSectorsRendered(); str += L" / "; str += (int)terrain->getSectorCount(); + str += L" ("; + str += (u32)(((f32)terrain->getSectorsRendered()/(f32)terrain->getSectorCount())*100.0f); + str += L"%)"; + str += L"\n"; @@ -273,17 +294,28 @@ void SceneWorld::InitTerrain(void) gui->SetSceneState(SCENESTATE_GUISTART); return; } + s32 mapsize = (8 * 16 * 3) - 1; // 9-1 height floats in 16 chunks per tile per axis in 3 MapTiles - mapsize = (8 * 16 * 3) - 1; // 9-1 height floats in 16 chunks per tile per axis in 3 MapTiles - tilesize = UNITSIZE; - meshsize = (s32)TILESIZE/3; + // terrain rendering settings + u32 rendersize = instance->GetConf()->terrainrendersize; + if(!rendersize) + rendersize = camera->getFarValue() / 3.0f; - //camera->setPosition(core::vector3df(mapsize*tilesize/2, 0, mapsize*tilesize/2) + terrainPos); + u32 sectors = instance->GetConf()->terrainsectors; + if(!sectors) + sectors = 5; - terrain = new ShTlTerrainSceneNode(smgr,mapsize,mapsize,tilesize,meshsize); + u32 step = instance->GetConf()->terrainupdatestep; + if(!step || step > 50) + step = 1; + + logdetail("Terrain: Using %ux%u sectors, rendersize=%u, updatestep=%u",sectors,sectors,rendersize,step); + + terrain = new ShTlTerrainSceneNode(smgr,mapsize,mapsize,UNITSIZE,rendersize,sectors); terrain->drop(); + terrain->setStep(step); terrain->follow(camera->getNode()); - terrain->getMaterial(0).setTexture(0, driver->getTexture("data/misc/dirt_test.jpg")); + terrain->getMaterial(0).setTexture(1,driver->getTexture("data/misc/dirt_test.jpg")); terrain->getMaterial(0).setFlag(video::EMF_LIGHTING, true); terrain->getMaterial(0).setFlag(video::EMF_FOG_ENABLE, true); diff --git a/src/Client/GUI/ShTlTerrainSceneNode.cpp b/src/Client/GUI/ShTlTerrainSceneNode.cpp index 4a17c82..76314af 100644 --- a/src/Client/GUI/ShTlTerrainSceneNode.cpp +++ b/src/Client/GUI/ShTlTerrainSceneNode.cpp @@ -1,10 +1,23 @@ +/*-----------------------------------------------------------------------------* +| sourcefile ShTlTerrainSceneNode.cpp | +| | +| version 2.20 | +| date: (17.04.2008) | +| | +| author: Michal Švantner | +| | +| Shifting Tiled Terrain Scene Node | +| | +| Writen for Irrlicht engine version 1.4 | +*-----------------------------------------------------------------------------*/ + #include "ShTlTerrainSceneNode.h" // constructor -ShTlTerrainSceneNode::ShTlTerrainSceneNode(scene::ISceneManager* pSceneManager, - s32 width, s32 height, f32 tilesize, s32 visiblesize, +ShTlTerrainSceneNode::ShTlTerrainSceneNode(scene::ISceneManager* smgr, + s32 width, s32 height, f32 tilesize, s32 visiblesize, s32 sect, scene::ISceneNode* parent, s32 id) - : scene::ISceneNode(pSceneManager->getRootSceneNode(), pSceneManager, id) + : scene::ISceneNode(smgr->getRootSceneNode(), smgr, id) { Size.Width = width; Size.Height = height; @@ -51,12 +64,16 @@ ShTlTerrainSceneNode::ShTlTerrainSceneNode(scene::ISceneManager* pSceneManager, // calculate number of sectors // terrain mesh will be split to 1 or 3 or 5 sectors on each axis depending on size - s32 w = 1; - s32 h = 1; - if(MeshSize.Width >= 30) w = 3; - if(MeshSize.Height >= 30) h = 3; - if(MeshSize.Width >= 50) w = 5; - if(MeshSize.Height >= 50) h = 5; + s32 w,h; + w = h = sect; + if(!(w && h)) + { + w = h = 1; + if(MeshSize.Width >= 30) w = 3; + if(MeshSize.Height >= 30) h = 3; + if(MeshSize.Width >= 50) w = 5; + if(MeshSize.Height >= 50) h = 5; + } // create sectors Sector.reset(w, h); @@ -67,16 +84,16 @@ ShTlTerrainSceneNode::ShTlTerrainSceneNode(scene::ISceneManager* pSceneManager, for(s32 j=0; j(w, h); + Sector(i,j).Size = core::dimension2d(w, h); // find size of center sector in tiles w = MeshSize.Width - Sector(0,0).Size.Width * (Sector.width()-1); h = MeshSize.Height - Sector(0,0).Size.Height * (Sector.height()-1); - {s32 j= Sector.height()/2; + {s32 j=Sector.height()/2; for(s32 i=0; isetTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mmflag); - Material[0].TextureLayer[1].Texture = CTexture; - Material[0].TextureLayer[1].TextureWrap = video::ETC_CLAMP_TO_EDGE; + Material[0].TextureLayer[0].Texture = CTexture; + Material[0].TextureLayer[0].TextureWrap = video::ETC_CLAMP_TO_EDGE; // setup UV coordinates of vertices on 2nd texture layer f32 ax = (f32)MeshSize.Width / CTexture->getSize().Width / MeshSize.Width; f32 ay = (f32)MeshSize.Height/ CTexture->getSize().Height / MeshSize.Height; f32 ry = 1.0f - (f32)MeshSize.Height/ CTexture->getSize().Height; - u32 n = MeshSize.Height-1; + s32 n = MeshSize.Height-1; for(s32 j=0; jTCoords2 = core::vector2d(i*ax, ry+(j+1)*ay); - Tile(i,n).Vertex[1]->TCoords2 = core::vector2d(i*ax, ry+j*ay); - Tile(i,n).Vertex[3]->TCoords2 = core::vector2d((i+1)*ax, ry+(j+1)*ay); - Tile(i,n).Vertex[2]->TCoords2 = core::vector2d((i+1)*ax, ry+j*ay); + Tile(i,n).Vertex[0]->TCoords = core::vector2d(i*ax, ry+(j+1)*ay); + Tile(i,n).Vertex[1]->TCoords = core::vector2d(i*ax, ry+j*ay); + Tile(i,n).Vertex[3]->TCoords = core::vector2d((i+1)*ax, ry+(j+1)*ay); + Tile(i,n).Vertex[2]->TCoords = core::vector2d((i+1)*ax, ry+j*ay); } n--; } @@ -231,7 +248,6 @@ ShTlTerrainSceneNode::ShTlTerrainSceneNode(scene::ISceneManager* pSceneManager, // culling will be done by terrain itself, sector by sector so that sectors // which are not on screen will not be renderd to save time setAutomaticCulling( scene::EAC_OFF ); - } @@ -372,10 +388,11 @@ void ShTlTerrainSceneNode::render() for (u32 n = 0; ndraw3DLine ( v[n].Pos, v[n].Pos + h, c ); + driver->draw3DLine ( v[n].Pos, v[n].Pos + h, c ); } } } + } @@ -425,7 +442,7 @@ void ShTlTerrainSceneNode::recalculateBoundingBox() // returns amount of materials used by terrain -u32 ShTlTerrainSceneNode::getMaterialCount() +u32 ShTlTerrainSceneNode::getMaterialCount() const { return Material.size(); } @@ -451,7 +468,7 @@ s32 ShTlTerrainSceneNode::getStep() // set number of tiles to skip before terrain mesh gets updated // default is 1 // updating slows down rendering and seting step higher will cause terrain to update less ofthen -void ShTlTerrainSceneNode::setStep(u32 newstep) +void ShTlTerrainSceneNode::setStep(s32 newstep) { ShStep = newstep; } @@ -496,7 +513,7 @@ core::dimension2d ShTlTerrainSceneNode::getRenderedSize() // return number of sectors -u32 ShTlTerrainSceneNode::getSectorCount() +s32 ShTlTerrainSceneNode::getSectorCount() { return Sector.width() * Sector.height(); } @@ -504,7 +521,7 @@ u32 ShTlTerrainSceneNode::getSectorCount() // returns numner of sectors rendered last frame -u32 ShTlTerrainSceneNode::getSectorsRendered() +s32 ShTlTerrainSceneNode::getSectorsRendered() { return SectorsRendered; } @@ -512,7 +529,7 @@ u32 ShTlTerrainSceneNode::getSectorsRendered() // return height of terrain spot at terrain coordinates -f32 ShTlTerrainSceneNode::getHeight(u32 w, u32 h) +f32 ShTlTerrainSceneNode::getHeight(s32 w, s32 h) { return Data(w,h).Height; } @@ -565,7 +582,7 @@ f32 ShTlTerrainSceneNode::getHeight(core::vector3df pos) // set relative height of terrain spot at terrain coordinates -void ShTlTerrainSceneNode::setHeight(u32 w, u32 h, f32 newheight) +void ShTlTerrainSceneNode::setHeight(s32 w, s32 h, f32 newheight) { Data(w,h).Height = newheight; @@ -593,7 +610,7 @@ void ShTlTerrainSceneNode::setHeight(u32 w, u32 h, f32 newheight) // return normal of terrain at terrain coordinates -core::vector3df ShTlTerrainSceneNode::getNormal(u32 w, u32 h) +core::vector3df ShTlTerrainSceneNode::getNormal(s32 w, s32 h) { return Data(w,h).Normal; } @@ -601,7 +618,7 @@ core::vector3df ShTlTerrainSceneNode::getNormal(u32 w, u32 h) // set normal of terrain at terrain coordinates void ShTlTerrainSceneNode::setNormal(s32 w, s32 h, core::vector3df newnormal) { - Data(w,h).Normal = newnormal; + Data(w,h).Normal = newnormal; } @@ -697,15 +714,15 @@ void ShTlTerrainSceneNode::smoothNormals() // get texture coordinates of tile corner -core::vector2d ShTlTerrainSceneNode::getTileUV(u32 w, u32 h, TILE_VERTEX corner) +core::vector2d ShTlTerrainSceneNode::getTileUV(s32 w, s32 h, TILE_VERTEX corner) { - return UVdata(w,h).Vertex[corner]; + return UVdata(w,h).Vertex[corner]; } // set texture coordinates of tile -void ShTlTerrainSceneNode::setTileUV(u32 w, u32 h, core::vector2d UVlowerLeft, +void ShTlTerrainSceneNode::setTileUV(s32 w, s32 h, core::vector2d UVlowerLeft, core::vector2d UVupperLeft, core::vector2d UVupperRight, core::vector2d UVlowerRight) { @@ -723,7 +740,7 @@ void ShTlTerrainSceneNode::stretchTexture(core::vector2d scale) f32 ax = scale.X / Size.Width; f32 ay = scale.X / Size.Height; - u32 n = Size.Height-1; + s32 n = Size.Height-1; for(s32 j=0; j scale) // rotate texture of tile 90 degrees -void ShTlTerrainSceneNode::rotateTileTexture90(u32 w, u32 h) +void ShTlTerrainSceneNode::rotateTileTexture90(s32 w, s32 h) { core::vector2d tmp = UVdata(w,h).Vertex[3]; @@ -768,7 +785,7 @@ void ShTlTerrainSceneNode::rotateTileTexture90(u32 w, u32 h) // rotate texture of tile 180 degrees -void ShTlTerrainSceneNode::rotateTileTexture180(u32 w, u32 h) +void ShTlTerrainSceneNode::rotateTileTexture180(s32 w, s32 h) { core::vector2d tmp = UVdata(w,h).Vertex[3]; @@ -784,7 +801,7 @@ void ShTlTerrainSceneNode::rotateTileTexture180(u32 w, u32 h) // rotate texture of tile 270 degrees -void ShTlTerrainSceneNode::rotateTileTexture270(u32 w, u32 h) +void ShTlTerrainSceneNode::rotateTileTexture270(s32 w, s32 h) { core::vector2d tmp = UVdata(w,h).Vertex[3]; @@ -797,7 +814,7 @@ void ShTlTerrainSceneNode::rotateTileTexture270(u32 w, u32 h) // flip (mirror) texture of tile horizontaly -void ShTlTerrainSceneNode::flipTileTextureHorizontal(u32 w, u32 h) +void ShTlTerrainSceneNode::flipTileTextureHorizontal(s32 w, s32 h) { core::vector2d tmp = UVdata(w,h).Vertex[3]; @@ -813,7 +830,7 @@ void ShTlTerrainSceneNode::flipTileTextureHorizontal(u32 w, u32 h) // flip (mirror) texture of tile verticaly -void ShTlTerrainSceneNode::flipTileTextureVertical(u32 w, u32 h) +void ShTlTerrainSceneNode::flipTileTextureVertical(s32 w, s32 h) { core::vector2d tmp = UVdata(w,h).Vertex[3]; @@ -829,7 +846,7 @@ void ShTlTerrainSceneNode::flipTileTextureVertical(u32 w, u32 h) // get color of tile at terrain coordinates -video::SColor ShTlTerrainSceneNode::getColor(u32 w, u32 h) +video::SColor ShTlTerrainSceneNode::getColor(s32 w, s32 h) { return Data(w,h).Color; } @@ -837,7 +854,7 @@ video::SColor ShTlTerrainSceneNode::getColor(u32 w, u32 h) // set color of tile at terrain coordinates -void ShTlTerrainSceneNode::setColor(u32 w, u32 h, video::SColor newcolor) +void ShTlTerrainSceneNode::setColor(s32 w, s32 h, video::SColor newcolor) { Data(w,h).Color = newcolor; } @@ -1052,7 +1069,7 @@ bool ShTlTerrainSceneNode::getIntersectionWithLine( core::line3d line, core // load height data from texture -void ShTlTerrainSceneNode::loadHeightMap(const c8 *filename, f32 scale, u32 w, u32 h) +void ShTlTerrainSceneNode::loadHeightMap(const c8 *filename, f32 scale, s32 w, s32 h) { video::IVideoDriver* driver = SceneManager->getVideoDriver(); if(!driver) return; @@ -1095,7 +1112,7 @@ void ShTlTerrainSceneNode::loadHeightMap(const c8 *filename, f32 scale, u32 w, u // load color data from texture -void ShTlTerrainSceneNode::loadColorMap(const c8 *filename, u32 w, u32 h) +void ShTlTerrainSceneNode::loadColorMap(const c8 *filename, s32 w, s32 h) { video::IVideoDriver* driver = SceneManager->getVideoDriver(); if(!driver) return; @@ -1103,8 +1120,8 @@ void ShTlTerrainSceneNode::loadColorMap(const c8 *filename, u32 w, u32 h) video::IImage *image = driver->createImageFromFile(filename); if(!image) return; - s32 tw = (u32)image->getDimension().Width; - s32 th = (u32)image->getDimension().Height; + s32 tw = image->getDimension().Width; + s32 th = image->getDimension().Height; s32 we = w + tw; if(we > Size.Width+1) we = Size.Width+1; @@ -1120,7 +1137,7 @@ void ShTlTerrainSceneNode::loadColorMap(const c8 *filename, u32 w, u32 h) { video::SColor color = image->getPixel(tw, th); - Data(i,j).Color = color; + setColor(i,j, color); tw++; } @@ -1145,32 +1162,32 @@ bool ShTlTerrainSceneNode::isSectorOnScreen(TlTSector* sctr) // get camera frustrum planes const scene::SViewFrustum* frustrum = SceneManager->getActiveCamera()->getViewFrustum(); - core::plane3d Left = frustrum->planes[scene::SViewFrustum::VF_LEFT_PLANE]; - core::plane3d Right = frustrum->planes[scene::SViewFrustum::VF_RIGHT_PLANE]; - core::plane3d Top = frustrum->planes[scene::SViewFrustum::VF_TOP_PLANE]; - core::plane3d Bottom = frustrum->planes[scene::SViewFrustum::VF_BOTTOM_PLANE]; - core::plane3d Near = frustrum->planes[scene::SViewFrustum::VF_NEAR_PLANE]; - core::plane3d Far = frustrum->planes[scene::SViewFrustum::VF_FAR_PLANE]; + core::plane3d left = frustrum->planes[scene::SViewFrustum::VF_LEFT_PLANE]; + core::plane3d right = frustrum->planes[scene::SViewFrustum::VF_RIGHT_PLANE]; + core::plane3d top = frustrum->planes[scene::SViewFrustum::VF_TOP_PLANE]; + core::plane3d bottom = frustrum->planes[scene::SViewFrustum::VF_BOTTOM_PLANE]; + core::plane3d near = frustrum->planes[scene::SViewFrustum::VF_NEAR_PLANE]; + core::plane3d far = frustrum->planes[scene::SViewFrustum::VF_FAR_PLANE]; // test sector bounding box against planes s32 leftRel, rightRel, topRel, bottomRel, nearRel, farRel; - nearRel = box.classifyPlaneRelation(Near); + nearRel = box.classifyPlaneRelation(near); if(nearRel == core::ISREL3D_FRONT) return false; - leftRel = box.classifyPlaneRelation(Left); + leftRel = box.classifyPlaneRelation(left); if(leftRel == core::ISREL3D_FRONT) return false; - rightRel = box.classifyPlaneRelation(Right); + rightRel = box.classifyPlaneRelation(right); if(rightRel == core::ISREL3D_FRONT) return false; - bottomRel = box.classifyPlaneRelation(Bottom); + bottomRel = box.classifyPlaneRelation(bottom); if(bottomRel == core::ISREL3D_FRONT) return false; - farRel = box.classifyPlaneRelation(Far); + farRel = box.classifyPlaneRelation(far); if(farRel == core::ISREL3D_FRONT) return false; - topRel = box.classifyPlaneRelation(Top); + topRel = box.classifyPlaneRelation(top); if(topRel == core::ISREL3D_FRONT) return false; return true; @@ -1181,15 +1198,12 @@ bool ShTlTerrainSceneNode::isSectorOnScreen(TlTSector* sctr) // update vertices of sector void ShTlTerrainSceneNode::updateVertices(TlTSector §or) { - scene::SMeshBuffer* MeshBuffer=new scene::SMeshBuffer(); - scene::SMesh* Mesh=new scene::SMesh(); - - for(u32 j=sector.Offset.Y; jPos = core::vector3df(x*TileSize, Data(x,y).Height, y*TileSize); @@ -1198,33 +1212,17 @@ void ShTlTerrainSceneNode::updateVertices(TlTSector §or) Tile(i,j).Vertex[3]->Pos = core::vector3df( (x+1)*TileSize, Data(x+1,y).Height, y*TileSize); // update normals - Tile(i,j).Vertex[0]->Normal = Data(x,y).Normal; - Tile(i,j).Vertex[1]->Normal = Data(x,y+1).Normal; - Tile(i,j).Vertex[2]->Normal = Data(x+1,y+1).Normal; - Tile(i,j).Vertex[3]->Normal = Data(x+1,y).Normal; + Tile(i,j).Vertex[0]->Normal = getNormal(x,y); + Tile(i,j).Vertex[1]->Normal = getNormal(x,y+1); + Tile(i,j).Vertex[2]->Normal = getNormal(x+1,y+1); + Tile(i,j).Vertex[3]->Normal = getNormal(x+1,y); // update texture coordinates - Tile(i,j).Vertex[0]->TCoords = UVdata(x,y).Vertex[0]; - Tile(i,j).Vertex[1]->TCoords = UVdata(x,y).Vertex[1]; - Tile(i,j).Vertex[2]->TCoords = UVdata(x,y).Vertex[2]; - Tile(i,j).Vertex[3]->TCoords = UVdata(x,y).Vertex[3]; - - for (int z=0;z<4;z++) - MeshBuffer->Vertices.push_back(video::S3DVertex( - Tile(i,j).Vertex[z]->Pos, - core::vector3df(0,0,0), video::SColor(0,0,0,0), core::vector2df(0,0))); + Tile(i,j).Vertex[0]->TCoords2 = getTileUV(x,y,LOWER_LEFT); + Tile(i,j).Vertex[1]->TCoords2 = getTileUV(x,y,UPPER_LEFT); + Tile(i,j).Vertex[2]->TCoords2 = getTileUV(x,y,UPPER_RIGHT); + Tile(i,j).Vertex[3]->TCoords2 = getTileUV(x,y,LOWER_RIGHT); } - - for (u32 z=0;zIndices.push_back( - sector.Index[z]); - } - - Mesh->addMeshBuffer(MeshBuffer); - MeshBuffer->drop(); - - Mesh->drop(); } @@ -1232,24 +1230,24 @@ void ShTlTerrainSceneNode::updateVertices(TlTSector §or) // update 2nd texture layer void ShTlTerrainSceneNode::updateTexture(u32* p, TlTSector §or) { - u32 x, y; + s32 x, y; // in case created texure is larger than terrain mesh, update one more pixel // on each axis to get rid of unused pixels at the border blended in to used ones - u32 w = 0; + s32 w = 0; if(MeshSize.Width < CTexture->getSize().Width) w = 1; - u32 h = 0; + s32 h = 0; if(MeshSize.Height < CTexture->getSize().Height) h = 1; - for(u32 j=sector.Offset.Y; jgetSize().Height-1 - j; - for(u32 i=sector.Offset.X; igetSize().Height-1 - j; + for(s32 i=sector.Offset.X; igetSize().Width + i] = Data(x,y).Color.color; + p[n*CTexture->getSize().Width + i] = getColor(x,y).color; } } } diff --git a/src/Client/GUI/ShTlTerrainSceneNode.h b/src/Client/GUI/ShTlTerrainSceneNode.h index beb2ae9..6cacacc 100644 --- a/src/Client/GUI/ShTlTerrainSceneNode.h +++ b/src/Client/GUI/ShTlTerrainSceneNode.h @@ -1,8 +1,8 @@ /*-----------------------------------------------------------------------------* | headerfile ShTlTerrainSceneNode.h | | | -| version 2.00 | -| date: (29.04.2007) | +| version 2.20 | +| date: (17.04.2008) | | | | author: Michal Švantner | | | @@ -43,7 +43,7 @@ | Rendered mesh is split in to seweral sectors which are culled individualy. | | This exclude around 60% of polygoons from rendering. | | | -| Writen for Irrlicht engine version 1.3 | +| Writen for Irrlicht engine version 1.4 | *-----------------------------------------------------------------------------*/ #ifndef SHTLTERRAINSCENENODE_H @@ -59,61 +59,61 @@ class ShTlTerrainSceneNode : public scene::ISceneNode { // dimensions of whole terrain core::dimension2d Size; - + // bounding box of terrain mesh core::aabbox3d BoundingBox; - + // terrain vertex data array2d Data; - + // terrain tile UV data for 1th texture layer array2d UVdata; - + // terrain mesh sectors array2d Sector; - + // array of pointers to vertices of tiles array2d Tile; - + // size of vissible terrain mesh core::dimension2d MeshSize; - + // position of vissible terrain mesh relative to whole terrain in tiles core::vector2d MeshPosition; - + // material core::array Material; - + // size of terrain tiles f32 TileSize; - + // node terrain mesh should be rendered around scene::ISceneNode* Fnode; - + // color texture set as 2nd texture layer video::ITexture* CTexture; - + // number of sectors rendered last frame - u32 SectorsRendered; - + s32 SectorsRendered; + // howe many tiles should be skiped before terrain mesh gets updated s32 ShStep; - + // return true if sector is on screen virtual bool isSectorOnScreen(TlTSector* sctr); - + // update vertices of sector virtual void updateVertices(TlTSector §or); - + // update 2nd texture layer virtual void updateTexture(u32* p, TlTSector §or); - + // return true if 3d line colide with tile - virtual bool getIntersectionWithTile(s32 w, s32 h, core::line3d line, + virtual bool getIntersectionWithTile(s32 w, s32 h, core::line3d line, core::vector3df &outIntersection); public: - + // constructor // \param smgr -pointer to scene manager // \param width - width of terrain in tiles @@ -122,99 +122,99 @@ public: // \param rendersize -size of rendered terrain mesh in tiles // \param parent -parent scene node // \param id -ID number - ShTlTerrainSceneNode(scene::ISceneManager* pSceneManager, s32 width, s32 height, - f32 tilesize, s32 rendersize, scene::ISceneNode* parent = 0, s32 id = -1); - + ShTlTerrainSceneNode(scene::ISceneManager* smgr, s32 width, s32 height, + f32 tilesize, s32 rendersize, s32 sect = 0, scene::ISceneNode* parent = 0, s32 id = -1); + // destructor ~ShTlTerrainSceneNode(); - + // frame virtual void OnRegisterSceneNode(); - + // renders terrain virtual void render(); - + // returns the axis aligned bounding box of terrain virtual const core::aabbox3d& getBoundingBox() const; - + // recalculate terrain bounding box virtual void recalculateBoundingBox(); - + // returns amount of materials used by terrain // this terrain uses only one material - virtual u32 getMaterialCount(); - + virtual u32 getMaterialCount() const; + // returns the material of terrain based on the zero based index // \param i -index of material to return virtual video::SMaterial& getMaterial(u32 i); - + // return number of tiles to skip before terrain mesh gets updated virtual s32 getStep(); - + // set number of tiles to skip before terrain mesh gets updated, default is 1 // updating slows down rendering and seting step higher will cause terrain to update less ofthen // \param newstep -amount of tiles to skip before updating - virtual void setStep(u32 newstep); - + virtual void setStep(s32 newstep); + // return dimensions of whole terrain in tiles virtual core::dimension2d getSize(); - + // return dimension of terrain tile virtual f32 getTileSize(); - + // set new dimensions of terrain tile // \param newsize -new size of tile virtual void setTileSize(f32 newsize); - + // returns dimension of rendered mesh in tiles virtual core::dimension2d getRenderedSize(); - + // return number of sectors into which terrain mesh is divided - virtual u32 getSectorCount(); - + virtual s32 getSectorCount(); + // returns sectors rendered last frame - virtual u32 getSectorsRendered(); - + virtual s32 getSectorsRendered(); + // return relative height of terrain spot at terrain coordinates // \param w -width coordinate of spot in tiles // \param h -height coordinate of spot in tiles - virtual f32 getHeight(u32 w, u32 h); - + virtual f32 getHeight(s32 w, s32 h); + // return height of terrain at any position // \param pos -3d coordinates at which to get height of terrain virtual f32 getHeight(core::vector3df pos); - + // set relative height of terrain spot at terrain coordinates // \param w -width coordinate of spot in tiles // \param h -height coordinate of spot in tiles // \param newheight -new height of spot - virtual void setHeight(u32 w, u32 h, f32 newheight); - + virtual void setHeight(s32 w, s32 h, f32 newheight); + // return normal of terrain at terrain coordinates // \param w -width coordinate of spot in tiles // \param h -height coordinate of spot in tiles - virtual core::vector3df getNormal(u32 w, u32 h); - + virtual core::vector3df getNormal(s32 w, s32 h); + // set normal of terrain at terrain coordinates // \param w -width coordinate of spot in tiles // \param h -height coordinate of spot in tiles // \param newnormal -new normal vector terrain spot virtual void setNormal(s32 w, s32 h, core::vector3df newnormal); - + // recalculate normal at terrain coordinates // \param w -width coordinate of spot in tiles // \param h -height coordinate of spot in tiles virtual void recalculateNormal(s32 w, s32 h); - + // recalculare normals of whole terrain making it look smooth under light virtual void smoothNormals(); - + // get texture coordinates of tile corner // \param w -width coordinate of tile // \param h -height coordinate of tile // \param corner -tile corner, can be LOWER_LEFT, UPPER_LEFT, UPPER_RIGHT, LOWER_RIGHT - virtual core::vector2d getTileUV(u32 w, u32 h, TILE_VERTEX corner); - + virtual core::vector2d getTileUV(s32 w, s32 h, TILE_VERTEX corner); + // set texture coordinates of tile // \param w -width coordinate of tile // \param h -height coordinate of tile @@ -222,81 +222,81 @@ public: // \param UVUpperLeft -UV coordinates of upper left corner // \param UVUpperRight -UV coordinates of upper right corner // \param UVLowerRight -UV coordinates of lower right corner - virtual void setTileUV(u32 w, u32 h, core::vector2d UVLowerLeft, + virtual void setTileUV(s32 w, s32 h, core::vector2d UVLowerLeft, core::vector2d UVUpperLeft, core::vector2d UVUpperRight, core::vector2d UVLowerRight); - + // stretch texture over whole terrain // \param scale -scale of the texture stretched, 2,2 would stretch it twice virtual void stretchTexture(core::vector2d scale = core::vector2d(1,1)); - + // stretch texture over every tile individualy // \param scale -scale of the texture stretched, 0.5,0.5 would display half of texture over each tile virtual void stretchTextureOverTile(core::vector2d scale = core::vector2d(1,1)); - + // rotate texture of tile 90 degrees // \param w -width coordinate of tile // \param h -height coordinate of tile - virtual void rotateTileTexture90(u32 w, u32 h); - + virtual void rotateTileTexture90(s32 w, s32 h); + // rotate texture of tile 180 degrees // \param w -width coordinate of tile // \param h -height coordinate of tile - virtual void rotateTileTexture180(u32 w, u32 h); - + virtual void rotateTileTexture180(s32 w, s32 h); + // rotate texture of tile 270 degrees // \param w -width coordinate of tile // \param h -height coordinate of tile - virtual void rotateTileTexture270(u32 w, u32 h); - + virtual void rotateTileTexture270(s32 w, s32 h); + // flip (mirror) texture of tile horizontaly // \param w -width coordinate of tile // \param h -height coordinate of tile - virtual void flipTileTextureHorizontal(u32 w, u32 h); - + virtual void flipTileTextureHorizontal(s32 w, s32 h); + // flip (mirror) texture of tile verticaly // \param w -width coordinate of tile // \param h -height coordinate of tile - virtual void flipTileTextureVertical(u32 w, u32 h); - + virtual void flipTileTextureVertical(s32 w, s32 h); + // get color of tile at terrain coordinates // \param w -width coordinate of tile // \param h -height coordinate of tile - virtual video::SColor getColor(u32 w, u32 h); - + virtual video::SColor getColor(s32 w, s32 h); + // set color of tile at terrain coordinates // \param w -width coordinate of tile // \param h -height coordinate of tile // \param newcolor -new color of tile - virtual void setColor(u32 w, u32 h, video::SColor newcolor); - + virtual void setColor(s32 w, s32 h, video::SColor newcolor); + // set rendered mesh position relative to terrain // note that origin of mesh is in its lower left corner // \param pos -new position of mesh relative to terrain in tiles virtual void setMeshPosition(core::vector2d pos); - + // center rendered mesh at 3d coordinates // \param pos -new position mesh should be rendered around virtual void centerAt(core::vector3d pos); - + // update rendered mesh virtual void update(); - + // set scene node terrain mesh should be automaticly rendered arround // can be camera or player node for example // \param node -scene node to automaticaly follow virtual void follow(scene::ISceneNode* node); - + // cancel pervious function // stop following scene node if any virtual void stop(); - + // test if 3d line colide with terrain // returns true if yes, false if not and store intersection in "outIntersection" vector // \param line -3d line // \param outIntersection -vector to store intersection point if any virtual bool getIntersectionWithLine( core::line3d line, core::vector3df &outIntersection); - + // load height data from texture // parameters allow to specify place where to load data, which makes possible // to load terrain from seweral smaller textures @@ -304,14 +304,14 @@ public: // \param scale -scale to apply at height data, if you want white color to be height of 10.5 set scale to 10.5 // \param w -width coordinate of tile were to start loading // \param h -height coordinate of tile were to start loading - virtual void loadHeightMap(const c8 *filename, f32 scale, u32 w = 0, u32 h = 0); - + virtual void loadHeightMap(const c8 *filename, f32 scale, s32 w = 0, s32 h = 0); + // load color data from texture // parameters allow to specify place where to load data, which makes possible // to load terrain from seweral smaller textures // \param filename -filename of texture // \param w -width coordinate of tile were to start loading // \param h -height coordinate of tile were to start loading - virtual void loadColorMap(const c8 *filename, u32 w = 0, u32 h = 0); + virtual void loadColorMap(const c8 *filename, s32 w = 0, s32 h = 0); }; #endif diff --git a/src/Client/GUI/TlTMesh.h b/src/Client/GUI/TlTMesh.h index 66d0424..4979d59 100644 --- a/src/Client/GUI/TlTMesh.h +++ b/src/Client/GUI/TlTMesh.h @@ -1,19 +1,19 @@ /*-----------------------------------------------------------------------------* | headerfile TLTMesh.h | | | -| version 1.00 | -| date: (17.04.2007) | +| version 1.10 | +| date: (07.04.2008) | | | | author: Michal Švantner | | | | Some structures used for Tiled Terrain | -| Writen for Irrlicht engine version 1.3 | +| Writen for Irrlicht engine version 1.4 | *-----------------------------------------------------------------------------*/ #ifndef TLTMESH_H #define TLTMESH_H -#include +#include "irrlicht/irrlicht.h" using namespace irr; @@ -21,58 +21,58 @@ using namespace irr; // dynamic 2d array template class array2d { - T** data; - s32 w, h; - + T** data; + s32 w, h; + public: - array2d() : w(0), h(0) {} - - array2d(int width, int height) : w(width), h(height) - { - data = new T*[w]; - for(int i=0; i Offset; - + // dimension of sector in tiles - core::dimension2d Size; - + core::dimension2d Size; + // array of vertices core::array Vertex; - + // array of indices core::array Index; - + // axis aligned bounding box core::aabbox3d BoundingBox; - + // update texture flag bool UpdateTexture; - + // update vertices flag bool UpdateVertices; - + // vissibility flag bool isVissible; }; diff --git a/src/Client/GUI/TlTSector.h b/src/Client/GUI/TlTSector.h new file mode 100644 index 0000000..a8f73a0 --- /dev/null +++ b/src/Client/GUI/TlTSector.h @@ -0,0 +1,130 @@ +#ifndef TLMESH_H +#define TLMESH_H + +#include +using namespace irr; + +template class array2d +{ + T** data; + u32 w, h; + +public: + array2d() : w(0), h(0) {} + + array2d(int width, int height) : w(width), h(height) + { + data = new T*[w]; + for(int i=0; i Vertex[4]; +}; + +struct TlTData +{ + f32 Height; + core::vector3df Normal; + video::SColor Color; +}; + +struct TlTSector +{ + core::vector2d Offset; + core::dimension2d Size; + core::array Vertex; + core::array Index; + core::aabbox3d BoundingBox; + + array2d Tile; + + virtual void addTile() + { + u32 n = Vertex.size(); + + video::S3DVertex2TCoords v; + + Vertex.push_back(v); + Vertex.push_back(v); + Vertex.push_back(v); + Vertex.push_back(v); + + Index.push_back(n); + Index.push_back(n+1); + Index.push_back(n+2); + + Index.push_back(n); + Index.push_back(n+2); + Index.push_back(n+3); + } + + virtual void recalculateBoundingBox() + { + if(Vertex.empty()) + BoundingBox.reset(0,0,0); + else + { + BoundingBox.reset(Vertex[0].Pos); + for(u32 i=1; i + +