Project D3D11Client Development

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Thanks for the detailed replies Glider :tiphat:

So I was able to remove the TextureGenerator class for now. Till I get to terrains in the future.

I ll throw another quick question. So the client is setup for HDR rendering currently. I am trying to remove the HDR rendering and post processing effects temporarily till I get a better understanding of how they are implemented. I was able to remove the class CSPostProcessingPipeline. But It seems some minimal level of post processing has to be there for getting textures drawn on planets.

I am trying to remove the post processing pipeline and trying to get simple textured sphere planets like in Dx7/Dx9. There is a member of the class Scene which I would like to remove so that the PP pipeline is not used for now : m_ppPipeline

https://bitbucket.org/asmi/ovp/src/...lient/Scene.h?at=D3D11Client - Terrain#cl-250
https://bitbucket.org/asmi/ovp/src/a32935c8d6b3/Orbitersdk/D3D11Client/Scene.cpp#cl-1678

Is it possible to convert it back now to normal non-hdr rendering or are the changes needed too elaborate ? Maybe I can try carefully rolling back to one of the previous versions of Scene.
 

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
Thanks for the detailed replies Glider :tiphat:

So I was able to remove the TextureGenerator class for now. Till I get to terrains in the future.

I ll throw another quick question. So the client is setup for HDR rendering currently. I am trying to remove the HDR rendering and post processing effects temporarily till I get a better understanding of how they are implemented. I was able to remove the class CSPostProcessingPipeline. But It seems some minimal level of post processing has to be there for getting textures drawn on planets.
You can try to render directly into a swap chain buffer (a texture in BGRA8 format that PP pipeline renders into) instead of HDRTarget. Should work because HDR in this client didn't have actually range more than 0-1.0 for most objects (thats why it looks so similar to blurred low range render). I think nothing except those runway lights used actually high range values...

Is it possible to convert it back now to normal non-hdr rendering or are the changes needed too elaborate ? Maybe I can try carefully rolling back to one of the previous versions of Scene.
HDR should be easily removable if u want to do so.
 

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
What is the process of rendering the celestial background ? I am guessing a sphere patch mesh is generated and textures are attached to the inside of the sphere ? Is there one large background textures thats mapped to the celestial background mesh ?

How far away is this mesh rendered from the camera (though I am guessing that's not very important as its rendered first and so the illusion of it being far away and in the background would be always present at any distance)
 
Last edited:

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
What is the process of rendering the celestial background ? I am guessing a sphere patch mesh is generated and textures are attached to the inside of the sphere ? Is there one large background textures thats mapped to the celestial background mesh ?
background mesh is level 8 planet tiles that form a L8 sphere (camera is in center of that sphere). texture file has 367 tiles arranged in the same way L8 planet textures are.

How far away is this mesh rendered from the camera (though I am guessing that's not very important as its rendered first and so the illusion of it being far away and in the background would be always present at any distance)
1 or 1000 units away I think, but better to check code. but it doesn't matter because it doesn't use depth for background so background will look same way from any distance between near and far frames of perspective projection.
 

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Thanks for the reply. A question about configs.

I see in Resources.h there is a
struct D3D11CONFIG
and a class D3D11Config

There is also a
D3D11Config *cfg = NULL;

this cfg is set in D3D11Config::D3D11Config() :
Code:
D3D11Config::D3D11Config() {
...
	CfgFILE = NULL;
	cfg = this;
}

Then again there are 2 config pointers in class VideoTab:
D3D11Config *cfg;
D3D11CONFIG Cfg;

class VideoTab gets the config passed to it in its ctor. So I guess whereever its instantiated, the config is passed to it. Why cant it simply access the global config variable declared in Resources.h ?

class D3D11Client has a function for returning a config pointer :
D3D11Config *Cfg() { return cfg; };

Since it does not have any member variable called cfg I guess it returns the global variable thats also called cfg ?

I also see that D3D11Client::D3D11Client sets the global cfg variable :
cfg = new D3D11Config();

But so does the D3D11Config ctor as mentioned before. So whats the point here ?


Why do we need so many config variables created all over the place ? I can see only 2 places where config may be needed :
1. By the VideoTab object
2. By the D3D11Client object

When the VideoTab is created then the D3D11Client object does not exist and vice versa. So we need to create separate D3D11Config objects for each.

-------------

Or maybe the D3D11Client object does exist when the VideoTab object is created, as I see in :

Code:
//LAUNCHPAD.
BOOL D3D11Client::LaunchpadVideoWndProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) {
	if( !bVideoTab ) {
		if( !bEnumerate ) {
			cfg->EnumerateAll( GetVideoData() );
			cfg->LoadConfig();
			cfg->ApplyConfig();
			bEnumerate = true;
		}
		bVideoTab = true;
		VTab = new VideoTab( this, cfg, oapi::GraphicsClient::LaunchpadVideoTab(), hDLL );
		VTab->InitTextBoxes();
	}
	if (VTab)
	{
		return VTab->LaunchpadVideoWndProc( hwnd, msg, wp, lp );
	}
	else
	{
		return oapi::GraphicsClient::LaunchpadVideoWndProc(hwnd, msg, wp, lp);
	}
}

In that case, we do not need a global D3D11Config object. We just create one and store in class D3D11Client. When needed gc->GetCfg() is called by anyone who needs it.
 
Last edited:

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
So whats the point here ?
I don't remember it now but probably theres no point - just another piece of bad and old code. Looks like there was a global config variable at first which was replaced imcompletely later with something else. Better to remove global config variable completely and use D3D11Client::GetConfig() or add static method like D3D11Config *D3D11Config::GetInstance() with a static D3D11Config * variable, since there can be only one instance of config class, and then replace every cfg-> with GetConfig() or whatever.

Why do we need so many config variables created all over the place ? I can see only 2 places where config may be needed :
1. By the VideoTab object
2. By the D3D11Client object
thats correct.

When the VideoTab is created then the D3D11Client object does not exist and vice versa. So we need to create separate D3D11Config objects for each.

...

Or maybe the D3D11Client object does exist when the VideoTab object is created, as I see in :

In that case, we do not need a global D3D11Config object. We just create one and store in class D3D11Client. When needed gc->GetCfg() is called by anyone who needs it.
IIRC, D3D11client is created first whenever simulation is started or user goes to video settings tab in the launchpad window so its better to create config when D3D11Client is created and use D3D11Config::GetConfig() later everywhere.
 

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Thanks. A few more questions :

1. Does the D3D11Client object exist when VideoTab is created ? I noticed that VideoTab is created from within D3D11Client so it probably does but I wanted to confirm.

2. I see the word microtextures used in TileRenderMgr ? What are microtextures exactly ? Are they parts of textures or cover lesser u/v ranges or longitude/latitude ranges than textures ?

3. Why are there 2 graphics client pointers gc and _gcl ? I see gcl is used in InitModule()/ExitModule ? But do we need to use this ?

4. What does the boolean flag bBBRender in D3D11Client stand for ?
 
Last edited:

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
1. Does the D3D11Client object exist when VideoTab is created ? I noticed that VideoTab is created from within D3D11Client so it probably does but I wanted to confirm.
you can find that out in 5 second (if u have code that compiles) if u place 2 breakpoints in videotab and client's constructors, but client is created first.

2. I see the word microtextures used in TileRenderMgr ? What are microtextures exactly ? Are they parts of textures or cover lesser u/v ranges or longitude/latitude ranges than textures ?
microtextures are small tileable textures for blending with main texture at low altitudes for more details. It wasn't completed in any of code there so its just another useless code which u can delete if u want;

3. Why are there 2 graphics client pointers gc and _gcl ? I see gcl is used in InitModule()/ExitModule ? But do we need to use this ?
One of them can be deleted, 2 pointers for same object.

4. What does the boolean flag bBBRender in D3D11Client stand for ?
It was used in multithreading code, so u can delete it along with all of this multithreading related stuff beacuse its useless like probably 30% of all code there.
 

HoldYourFire

New member
Joined
Feb 7, 2014
Messages
2
Reaction score
0
Points
0
Hello Devs and Fellow Orbinauts,

Kudos for the great work on the dx11 client thus far. The hdr features among others adds a whole other level of immersion to orbiter.

A am having a few issues with blank mfd text and dim virtual cockpit indicators (see attached) that's a game killer. I've searched the thread for similar issues with no luck so excuse me if I'm repeating something previously addressed. I'm running win7 with latest drivers and dx11.

View attachment 12403

View attachment 12404

And here's the latest log;

View attachment 12405

Any ideas what might be causing this? Thanks.

I just want to flag up that I'm having the same issue.

Edit: I want to add that my report is an exact facsimile of Zamolxis's one.
 
Last edited:

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
I see there are 2 classes for loading tiles. There is TileLoader which seems to be used by TerrainManager. TileLoader has a lot of texture loading functions for different types of textures.

Then there is TileManager and TileBuffer. TileBuffer can also load textures.

Why are there 2 different classes to load textures ? Did you want to use TileLoader only for terrain tiles and TileBuffer for all other tiles like for the planet surface tiles, celestial sphere tiles etc ?

SurfaceManager seems to inherit from TileManager. Is it supposed to be for loading only planetary surface tiles ?

All these classes seem to have the ability to render tiles. Then where does TileRenderMgr fit in ?
 
Last edited:

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
I see there are 2 classes for loading tiles. There is TileLoader which seems to be used by TerrainManager. TileLoader has a lot of texture loading functions for different types of textures.

Then there is TileManager and TileBuffer. TileBuffer can also load textures.

Why are there 2 different classes to load textures ? Did you want to use TileLoader only for terrain tiles and TileBuffer for all other tiles like for the planet surface tiles, celestial sphere tiles etc ?
I'm not sure, but I think Tilebuffer was there only for cloud/celestial background textures since they cloud/celbackground classes inherit from TileManager, while TileLoader was for terrain textures, so it can load more texture types. Though clouds/celbackground didn't use levels higher than 8 so TileBuffer looks useless...

SurfaceManager seems to inherit from TileManager. Is it supposed to be for loading only planetary surface tiles ?
This class looks like the earliest version of planet surface object which is very similar to DX7/9 one... its probably another useless class - another thing to delete, like almost everything else there :lol:. Try to place some breakpoints and see if it is used anywhere at all.

All these classes seem to have the ability to render tiles. Then where does TileRenderMgr fit in ?
I think it was supposed to receive an array of visible tiles from TerrainManager class and render them.
 

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Thanks.

I was looking at TileManager::LoadTileData()

Code:
void TileManager::LoadTileData() {
	FILE *file;
	char fname[256], cpath[256];

	int compare_idx( const void *el1, const void *el2 );

	if( maxlvl <= 8 )
		return;

	strcpy_s( fname, 256, objname );
	strcat_s( fname, 256, "_tile.bin" );
	if( !gGraphicsClient->TexturePath( fname, cpath ) || !(file = fopen( cpath, "rb" )) ) {
//		LogWrn("Surface Tile TOC not found for %s",fname);
		return;
	}
//	LogAlw("Reading Tile Data for %s",fname);

	char idstr[9] = "        ";
	fread( idstr, 1, 8, file );
	if( !strncmp( idstr, "PLTS", 4 ) )
		tilever = 1;
	else {
		tilever = 0;
		fseek( file, 0, SEEK_SET );
	}

	DWORD n, i, j;
	fread( &n, sizeof(DWORD), 1, file );
	TILEFILESPEC *tfs = new TILEFILESPEC [n];
	fread( tfs, sizeof(TILEFILESPEC), n, file );
	fclose( file );

	//converts from new indexes to old.
	if( bPreloadTiles && tilever >= 1 ) {
		IDXLIST *idxlist = new IDXLIST [n];
		for( i = 0; i < n; i++ ) {
			idxlist[i].idx = i;
			idxlist[i].ofs = tfs[i].sidx;
		}
		qsort( idxlist, n, sizeof(IDXLIST), compare_idx );
		for( i = 0; i < n && idxlist[i].ofs != NOTILE; i++ )
			tfs[idxlist[i].idx].sidx = i;

		for (i = 0; i < n; i++) {
				idxlist[i].idx = i;
				idxlist[i].ofs = tfs[i].midx;
			}
		qsort( idxlist, n, sizeof(IDXLIST), compare_idx );
		for( i = 0; i < n && idxlist[i].ofs != NOTILE; i++ )
			tfs[idxlist[i].idx].midx = i;

		tilever = 0;
		delete [ ] idxlist;
	}

	TILEDESC *tile8 = tiledesc + patchidx[7];
	for( i = 0; i < 364; i++ ) {
		TILEDESC &tile8i = tile8[i];
		for( j = 0; j < 4; j++ )
			if( tfs[i].subidx[j] )
				AddSubtileData( tile8i, tfs, i, j, 9 );
	}
	delete [ ] tfs;
}

Apparently it loads some tiles from a *_tile.bin file. Do you know if the description of these files are present somewhere ? Do they contain tile meshes ? Or tile textures, and the tile meshes get generated at runtime by the client.
 

SolarLiner

It's necessary, TARS.
Addon Developer
Joined
Jun 14, 2010
Messages
1,847
Reaction score
2
Points
0
Location
404 ROAD NOT FOUND
They are Hi-res global planetary tiles (like Earth_tile.bin in the Textures2 directory). So they are textures, and IIRC they are a list of DDS textures put together.
Completely false. See orb's post below.
 
Last edited:

orb

O-F Administrator,
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
The _tile.bin files are just index files for textures. Their record format is like:
Code:
struct TILEFILESPEC {
	DWORD sidx;       // index for surface texture (-1: not present)
	DWORD midx;       // index for land-water mask texture (-1: not present)
	DWORD eidx;       // index for elevation data blocks (not used yet; always -1)
	DWORD flags;      // tile flags: bit 0: has diffuse component; bit 1: has specular component; bit 2: has city lights
	DWORD subidx[4];  // subtile indices
};
The actual textures are sequentially placed DDS records in the _tile.tex files and they are referenced by the tile index records.
 

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
Apparently it loads some tiles from a *_tile.bin file. Do you know if the description of these files are present somewhere ? Do they contain tile meshes ? Or tile textures, and the tile meshes get generated at runtime by the client.
There're no tile meshes for levels >= 8 in D3D11 client - only one mesh that is processed by Vertex/Domain shader according to heightmap and tile coordiantes, in a way that had some precision problems probably becuase of cos/sin functions in shader (on some GPUs it was more obvious than on others). I tried later to fix these problems in the same way it can be done in cube to sphere terrain but it didn't work properly - so probably meshes are needed even in D3D11 as long as you use cylindrical projection.

_tile.bin files contain no textures - only quadtree of TILEFILESPEC structs each of them contain 32-bit file offsets of textures themselves inside _tile.tex files and offsets of 4 TILEFILESPEC structs of subtiles if they exist - so that function doesn't load actually textures - it loads file offsets for them and leaves textures to be loaded when they are needed, unless user chose option to preload textures for some reason, in this case it will actually load textures and create D3D11 resources after offsets for textures were added to the quadtree using quadtree of TILEFILESPECs inside _tile.bin file.
 

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
So I am trying to understand TileManager::LoadTileData()

Code:
void TileManager::LoadTileData() {
	FILE *file;
	char fname[256], cpath[256];

	int compare_idx( const void *el1, const void *el2 );

	if( maxlvl <= 8 )
		return;

	strcpy_s( fname, 256, objname );
	strcat_s( fname, 256, "_tile.bin" );
	if( !gGraphicsClient->TexturePath( fname, cpath ) || !(file = fopen( cpath, "rb" )) ) {
//		LogWrn("Surface Tile TOC not found for %s",fname);
		return;
	}
//	LogAlw("Reading Tile Data for %s",fname);

	char idstr[9] = "        ";
	fread( idstr, 1, 8, file );
	if( !strncmp( idstr, "PLTS", 4 ) )
		tilever = 1;
	else {
		tilever = 0;
		fseek( file, 0, SEEK_SET );
	}

	DWORD n, i, j;
	fread( &n, sizeof(DWORD), 1, file );
	TILEFILESPEC *tfs = new TILEFILESPEC [n];
	fread( tfs, sizeof(TILEFILESPEC), n, file );
	fclose( file );

	//converts from new indexes to old.
	if( bPreloadTiles && tilever >= 1 ) {
		IDXLIST *idxlist = new IDXLIST [n];
		for( i = 0; i < n; i++ ) {
			idxlist[i].idx = i;
			idxlist[i].ofs = tfs[i].sidx;
		}
		qsort( idxlist, n, sizeof(IDXLIST), compare_idx );
		for( i = 0; i < n && idxlist[i].ofs != NOTILE; i++ )
			tfs[idxlist[i].idx].sidx = i;

		for (i = 0; i < n; i++) {
				idxlist[i].idx = i;
				idxlist[i].ofs = tfs[i].midx;
			}
		qsort( idxlist, n, sizeof(IDXLIST), compare_idx );
		for( i = 0; i < n && idxlist[i].ofs != NOTILE; i++ )
			tfs[idxlist[i].idx].midx = i;

		tilever = 0;
		delete [ ] idxlist;
	}

	TILEDESC *tile8 = tiledesc + patchidx[7];
	for( i = 0; i < 364; i++ ) {
		TILEDESC &tile8i = tile8[i];
		for( j = 0; j < 4; j++ )
			if( tfs[i].subidx[j] )
				AddSubtileData( tile8i, tfs, i, j, 9 );
	}
	delete [ ] tfs;
}

int compare_idx( const void *el1, const void *el2 ) {
	IDXLIST *idx1 = (IDXLIST*)el1;
	IDXLIST *idx2 = (IDXLIST*)el2;
	return (idx1->ofs < idx2->ofs ? -1 : (idx1->ofs > idx2->ofs ? 1 : 0 ));
}

What I get is that the code reads n TILEFILESPEC structs from the *_tile.bin file and then sorts them if preloading is needed. I see this tiledesc array of TILEDESC structs. Each TILEDESC has pointers to the Dx11 texture views. So I am guessing that tiledesc is what stores the pointers to ALL textures as they are loaded in. If a texture is not loaded in, then at least the offset of that texture is stored in TILEDESC.ofs. TILEDESC.ofs is the 32 bit offset in the _tile.tex file.

Code:
//Contains textures for tile(L4-L14) or sphere(L1-L3) and links tile to its subtiles(L8-L14);
struct TILEDESC {
	ID3D11ShaderResourceView *tex;      // diffuse surface texture
	ID3D11ShaderResourceView *ltex;     // landmask texture, if applicable
	DWORD flag;
	struct TILEDESC *subtile[4];   // sub-tiles for the next resolution level
	DWORD ofs;                     // refers back to the master list entry for the tile
};

The name of the tex file is simply generated by appending the planet name to _tile.tex at load time from what I see in
Code:
void TileManager::LoadTextures() {
	char fname[256], cpath[256];

	ntex = patchidx[maxbaselvl];
	texbuf = new ID3D11ShaderResourceView *[ntex];
	strcpy_s( fname, 256, objname );
	strcat_s( fname, 256, ".tex" );

So tiledesc is the root of the quadtree and the most important structure that holds the pointers to all loaded structs ? The is 1 for each planet/moon so there is an unique TileManager object for each planet or moon ?

---------- Post added at 02:50 PM ---------- Previous post was at 12:55 PM ----------

In this part :
Code:
TILEDESC *tile8 = tiledesc + patchidx[7];
	for( i = 0; i < 364; i++ ) {
		TILEDESC &tile8i = tile8[i];
		for( j = 0; j < 4; j++ )
			if( tfs[i].subidx[j] )
				AddSubtileData( tile8i, tfs, i, j, 9 );
	}

int TileManager::patchidx[9] = { 0, 1, 2, 3, 5, 13, 37, 137, 501 };
Why add patchidx[7] to tiledesc ? Is it because TILEDESC for level 8 starts at the 137th position ? And its these TILEDESCs that we want to populate with level 8 textures now ?

But then what about the levels below 8 ? I guess TileManager::LoadTileData() does not load for levels below 8 ? Wonder where level 1-7 are loaded then.

---------- Post added at 03:58 PM ---------- Previous post was at 02:50 PM ----------

Does the client really need to use CComPtrEx ? With Visual Studio 2013 I get this error :
Code:
1>------ Build started: Project: D3D11Client, Configuration: Debug Win32 ------
1>  Generating Mercurial version header file
1>  AdvancedAtmosphere.cpp
1>f:\code\orbiter\1 testing grounds\orbiterd3d11\orbitersdk\d3d11client\CComPtrEx.h(2): fatal error C1083: Cannot open include file: 'atlbase.h': No such file or directory
1>  AtmosphereMgr.cpp
1>f:\code\orbiter\1 testing grounds\orbiterd3d11\orbitersdk\d3d11client\CComPtrEx.h(2): fatal error C1083: Cannot open include file: 'atlbase.h': No such file or directory
1>  BasicAtmosphere.cpp
1>f:\code\orbiter\1 testing grounds\orbiterd3d11\orbitersdk\d3d11client\CComPtrEx.h(2): fatal error C1083: Cannot open include file: 'atlbase.h': No such file or directory
1>  CelBackground.cpp
...
....

ATL is no longer provided with the Express version after 2008. Isnt there some other pointer class available ?

For the moment I have installed the Windows Device Driver Kit and that has ATL.
 
Last edited:

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
What I get is that the code reads n TILEFILESPEC structs from the *_tile.bin file and then sorts them if preloading is needed. I see this tiledesc array of TILEDESC structs. Each TILEDESC has pointers to the Dx11 texture views. So I am guessing that tiledesc is what stores the pointers to ALL textures as they are loaded in. If a texture is not loaded in, then at least the offset of that texture is stored in TILEDESC.ofs. TILEDESC.ofs is the 32 bit offset in the _tile.tex file.
correct

The name of the tex file is simply generated by appending the planet name to _tile.tex at load time from what I see in
Yep. names of these textures generated by addition if "_tile.tex" or ".tex" to the name string.

So tiledesc is the root of the quadtree and the most important structure that holds the pointers to all loaded structs ? The is 1 for each planet/moon so there is an unique TileManager object for each planet or moon ?
Yes, one tiledesc per planet and yes it keeps all pointer to resources and texture offsets of tiles with level > 8. Yes theres one unique object for each planet's surface or cloud layer but it is TerrainManager in case of surface and CloudManager (derived from TileManger) in case of cloud layer. The root of the quadtree is level 8 so this root begins with tiledesc[patchidx[7]], only levels >= 8 can be split into 4 subtiles, so levels < 8 have subtiles always equal to null.

int TileManager::patchidx[9] = { 0, 1, 2, 3, 5, 13, 37, 137, 501 };
Why add patchidx[7] to tiledesc ? Is it because TILEDESC for level 8 starts at the 137th position ? And its these TILEDESCs that we want to populate with level 8 textures now ?
first tile of level4 is tiledesc[patchidx[3]], of level 7 is tiledesc[patchidx[6]] and so on. So tiledesc + patchidx[7] is pointer to the first tile of level 8 inside tiledesc array (which contain only levels 1-8 and not higher)

But then what about the levels below 8 ? I guess TileManager::LoadTileData() does not load for levels below 8 ? Wonder where level 1-7 are loaded then.
levels 1-8 are loaded always sequentially with a cycle (not in LoadTileData()) - theres no need for offsets because offset of any texture of level below 9 is just a position of the tile inside tiledesc array multiplied by size of one texture. so if u want to load texture for the first tile of level8 u just compute offset as 137*(sizeof(DDS_HEADER) + 256*256/2).

Does the client really need to use CComPtrEx ? With Visual Studio 2013 I get this error :
Not really (if really means something very important). You can always remove them if u want. CComPtrEx is just a smart pointer for resources and shaders, u can always use C pointers and delete everything manually or write your own template class for a similar smart pointer to replace CComPtrEx.

For the moment I have installed the Windows Device Driver Kit and that has ATL.
So there should be no problem then.
 
Last edited:

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Thank. So till level 8 there is no subdividing. From level 9 onwards, how do you decide when to sub divide the tile ? Are there some camera distances at which point you decide that a particular tile should now be tessellated ?

Also after you break up a tile into 4 tiles, then you load new textures for each of these 4 tiles right ? And these are higher detail textures ? You do not simply use the original texture with the uvs adjusted to divide it into 4 parts.
 

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
Thank. So till level 8 there is no subdividing. From level 9 onwards, how do you decide when to sub divide the tile ? Are there some camera distances at which point you decide that a particular tile should now be tessellated ?
code for deciding when to subdivide tiles is copy-pasted from DX7/9 client and is:
Code:
           static const double rad0 = sqrt( 2.0 )*PI05*0.5;
	VECTOR3 cnt;
	D3DXMATRIX mWorld_tile;

	double rad = rad0/double(td->nlat);
	TileCenter( td, cnt );
	double adist = acos( dotp( RP.cdir, cnt ) ) - rad;

	if( adist >= RP.viewap )
		return false;

	TileWorldMatrix( td, mWorld_tile );

	bool
		bStepDown = (td->level < RP.tgtlevel);

	if( bStepDown && adist > 0.0 )
	{
		float lat1, lat2, lng1, lng2, adist_lng, adist_lat, adist2;
		TileExtents( td, lat1, lat2, lng1, lng2 );

		if( RP.clng < lng1 - float(PI) )			RP.clng += float(PI2);
		else if( RP.clng > lng2 + float(PI) )	RP.clng -= float(PI2);

		if( RP.clng < lng1 )			adist_lng = lng1 - float(RP.clng);
		else if( RP.clng > lng2 )		adist_lng = float(RP.clng) - lng2;
		else							adist_lng = 0.0;

		if( RP.clat < lat1 )			adist_lat = lat1 - float(RP.clat);
		else if( RP.clat > lat2 )		adist_lat = float(RP.clat) - lat2;
		else							adist_lat = 0.0;

		adist2 = adist_lng + adist_lat;

		double cosa = cos( adist2 );
		double a = sin( adist2 );
		double b = RP.cdist - cosa;
		double ctilt = b*cosa/sqrt(a*a*(1.0 + 2.0*b) + b*b);
		if( adist2 > rad*(2.0*ctilt + 0.3) ) {
			bStepDown = false;
		}
	}
it can be found inside bool TerrainManager:: ProcessTile( TILE *td, TILETEXTURE *ttex, TEXCRDRANGE &range, UINT8 sidx ) funstion. It doesn't work very well with planet surface which isn't a sphere because it causes too many obvious changes of tile levels and assumes tiles are flat, but it was supposed to be a temporary solution. In case of terrain its better to use bounding box of tile in local tile coords and use only distance to limit level changes. Nice way to get rid of these level changes would be to blend current heightmap with the heightmap of parent tile inside vertex/domain/geometry shader so that terrain won't suddenly change and will change gradually... but that wasn't implemented.

Also after you break up a tile into 4 tiles, then you load new textures for each of these 4 tiles right ? And these are higher detail textures ? You do not simply use the original texture with the uvs adjusted to divide it into 4 parts.
Yes, after subtiles created they are placed in the loading queue for texture loading if there are any textures for them in _tile.tex. If theres no textures, nothing will be loaded and they will use texture of the parent tile. Of course, original uv won't work in case when u have no tile texture because they are made for full range texture of the same level, so if u have texture for a lower level u have to use only a rectangle within it, and this is what happens when subtiles don't have their own textures or textures are in process of loading.
 
Last edited:

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
A minor issue but there seems to be a misalignment for the D3D11 configuration button in the videotab :

misalignment.png


Does client code have control over where this is placed ?
 
Top