Project D3D11Client Development

Gendo

New member
Joined
Jun 4, 2013
Messages
16
Reaction score
0
Points
0
DX11TerrainError.jpg

Decided to mess around with the Orbiter beta. With The DX11 w/terrain I get this odd error when I try to enable the D3D11 module. I have no idea what it means, but it prevents the VideoTab from ever appearing.

This is with Win7Pro64 and Orbiter build 130101, or whatever the latest version is on svn://orbithangar.com/orbiter, so maybe it's my own stupidity here trying to make it work with too new of a beta. lol
 
Last edited:

Gendo

New member
Joined
Jun 4, 2013
Messages
16
Reaction score
0
Points
0
Yes, I found that conversation after I posted, and got it to work with that version. So no actual terrain elevation data has been implemented into that yet, am I overlooking something, or am I misinterpreting what they meant by 'terrain'? lol
 

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
Yes, I found that conversation after I posted, and got it to work with that version. So no actual terrain elevation data has been implemented into that yet, am I overlooking something, or am I misinterpreting what they meant by 'terrain'? lol
It was implemented without any collision support but required elevation data file of client-specific format, because terrain isn't supported by Orbiter core. No idea if those files are still available where they were before. I've already deleted them on my PC to free disk space so I don't have them anymore. As you can see this project is abandoned, so if you want a good client use this http://orbiter-forum.com/showthread.php?t=18431 or last version of OGLA for terrain.

Does client code have control over where this is placed ?
its is somewhere in videoTab.cpp IIRC, sorry already forgot this part
 
Last edited:

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Was there any issue with making the window fullscreen if the user had requested it. I am looking at clbkCreateRenderWindow(). It seems if data->fullscreen = true then the window is simply enlarged to cover the fullscreen but it still has the title bar and is movable. Hence there is a call to MoveWindow() inside that code block too.

Code:
HWND D3D11Client::clbkCreateRenderWindow() {
	WLOG2( APP_TITLE " is starting up..." );


	auto data = GetVideoData();
	hWindow = oapi::GraphicsClient::clbkCreateRenderWindow();
	/*auto currStyle = GetWindowLong(hWindow, GWL_STYLE);
	auto currExStyle = GetWindowLong(hWindow, GWL_EXSTYLE);
	auto style = WS_POPUP;
	auto exStyle = WS_EX_TOPMOST;*/
	SetWindowTextA( hWindow, "- "APP_TITLE );
	
	EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &m_currentMode);
	if (!data->fullscreen)
	{
		WINDOWINFO winfo;
		winfo.cbSize = sizeof( WINDOWINFO );
		GetWindowInfo( hWindow, &winfo );
		cfg->cWidth = abs( winfo.rcClient.right - winfo.rcClient.left );
		cfg->cHeight = abs( winfo.rcClient.bottom - winfo.rcClient.top );
	}
	else
	{
		cfg->cWidth = data->winw;
		cfg->cHeight = data->winh;
		auto currExStyle = GetWindowLong(hWindow, GWL_EXSTYLE);
		currExStyle |= WS_EX_TOPMOST;
		SetWindowLong(hWindow, GWL_EXSTYLE, currExStyle);
		if (m_currentMode.dmPelsWidth != cfg->cWidth || m_currentMode.dmPelsHeight != cfg->cHeight)
		{
			DEVMODE mode;
			CopyMemory(&mode, &m_currentMode, sizeof(DEVMODE));
			mode.dmBitsPerPel = 32;
			mode.dmPelsWidth = cfg->cWidth;
			mode.dmPelsHeight = cfg->cHeight;
			mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
			ChangeDisplaySettings(&mode, 0);
			m_modeChanged = true;
		}
		MoveWindow(hWindow, 0, 0, cfg->cWidth, cfg->cHeight, true);
	}
	cfg->Aspect = (float)cfg->cWidth/(float)cfg->cHeight;

	if( !bEnumerate ) {
	//	Device enumeration always fails when placed before clbkCreateRenderWindow).
		cfg->EnumerateAll( GetVideoData() );
		cfg->LoadConfig();
		cfg->ApplyConfig();
		bEnumerate = true;
	}

	cfg->ApplyConfig();
	SC = new Scene( this, cfg );

	InitShaderProfiles(Dev->GetFeatureLevel());
	shaderManager.reset(new ShaderManager(Dev));

	SC->Init3D();
...
....
	return hWindow;
}
 
Last edited:

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
Was there any issue with making the window fullscreen if the user had requested it. I am looking at clbkCreateRenderWindow(). It seems if data->fullscreen = true then the window is simply enlarged to cover the fullscreen but it still has the title bar and is movable. Hence there is a call to MoveWindow() inside that code block too.

Code:
HWND D3D11Client::clbkCreateRenderWindow() {
	WLOG2( APP_TITLE " is starting up..." );


	auto data = GetVideoData();
	hWindow = oapi::GraphicsClient::clbkCreateRenderWindow();
	/*auto currStyle = GetWindowLong(hWindow, GWL_STYLE);
	auto currExStyle = GetWindowLong(hWindow, GWL_EXSTYLE);
	auto style = WS_POPUP;
	auto exStyle = WS_EX_TOPMOST;*/
	SetWindowTextA( hWindow, "- "APP_TITLE );
	
	EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &m_currentMode);
	if (!data->fullscreen)
	{
		WINDOWINFO winfo;
		winfo.cbSize = sizeof( WINDOWINFO );
		GetWindowInfo( hWindow, &winfo );
		cfg->cWidth = abs( winfo.rcClient.right - winfo.rcClient.left );
		cfg->cHeight = abs( winfo.rcClient.bottom - winfo.rcClient.top );
	}
	else
	{
		cfg->cWidth = data->winw;
		cfg->cHeight = data->winh;
		auto currExStyle = GetWindowLong(hWindow, GWL_EXSTYLE);
		currExStyle |= WS_EX_TOPMOST;
		SetWindowLong(hWindow, GWL_EXSTYLE, currExStyle);
		if (m_currentMode.dmPelsWidth != cfg->cWidth || m_currentMode.dmPelsHeight != cfg->cHeight)
		{
			DEVMODE mode;
			CopyMemory(&mode, &m_currentMode, sizeof(DEVMODE));
			mode.dmBitsPerPel = 32;
			mode.dmPelsWidth = cfg->cWidth;
			mode.dmPelsHeight = cfg->cHeight;
			mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
			ChangeDisplaySettings(&mode, 0);
			m_modeChanged = true;
		}
		MoveWindow(hWindow, 0, 0, cfg->cWidth, cfg->cHeight, true);
	}
	cfg->Aspect = (float)cfg->cWidth/(float)cfg->cHeight;

	if( !bEnumerate ) {
	//	Device enumeration always fails when placed before clbkCreateRenderWindow).
		cfg->EnumerateAll( GetVideoData() );
		cfg->LoadConfig();
		cfg->ApplyConfig();
		bEnumerate = true;
	}

	cfg->ApplyConfig();
	SC = new Scene( this, cfg );

	InitShaderProfiles(Dev->GetFeatureLevel());
	shaderManager.reset(new ShaderManager(Dev));

	SC->Init3D();
...
....
	return hWindow;
}
True fullscreen mode isn't possible to use with orbiter, because Orbiter, unlike almost all games, doesn't have its own GUI rendering - it uses windows GUI. Windows GUI can't work with true fullscreen mode (with video mode change) so theres no other way other than to enlarge the window to cover entire screen without actually changing to the fullscreen mode. Actually using true fullscreen mode causes it to change back to default mode whenever any GUI window appears which would be extremely annoying.
 
Last edited:

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Then maybe a windows gui menu should never be popped up and one drawn on the screen using DirectX perhaps. The user licks on this menu and the clicked point is translated into the action.

Hmmm, maybe its not just menus, but also help windows and the other selection related windows which would all need to be somehow suppressed and an alternative would need to be created in DirectX only.
 

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
Then maybe a windows gui menu should never be popped up and one drawn on the screen using DirectX perhaps. The user licks on this menu and the clicked point is translated into the action.
Orbiter doesn't have interface with graphics client for that - it just pops up its windows GUI window so it will be changed back to default mode anyway. Its not possible, like many other things like collision support of terrain for example, without some very ugly, buggy and complicated hack which isn't proper way to do it because ugly hacks never work as expected.

Hmmm, maybe its not just menus, but also help windows and the other selection related windows which would all need to be somehow suppressed and an alternative would need to be created in DirectX only.
Its all F1-F4 windows. Instead making another buggy hack solution, its better to remove windows GUI from core completely and move its rendering to graphics client. But it will take years and has no point instead of addition of true fullscreen mode support which nobody really needs if enlarged window looks exactly as a true fullscreen one.
 
Last edited:

dumbo2007

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

Code:
//=================================================
//Update.
//=================================================

bool Scene::IsVisibleInCamera( D3DXVECTOR3 *pCnt, float radius ) {
//tilemanger, cloudmanager:
float z = camera_z.x*pCnt->x + camera_z.y*pCnt->y + camera_z.z*pCnt->z;
if( z < (-radius) ) return false; 
if( z < 0) z=-z;
float y = camera_y.x*pCnt->x + camera_y.y*pCnt->y + camera_y.z*pCnt->z;
if( y < 0) y=-y;
if( y - (radius*vhf) > (vh*z) ) return false; 
float x = camera_x.x*pCnt->x + camera_x.y*pCnt->y + camera_x.z*pCnt->z;
if( x < 0 ) x=-x;
if( x - (radius*vwf) > (vw*z) ) return false;
return true;
}

I understand that this function will check if a point is within the camera view frustum and return true if it is. Anything outside the radius returns false. This radius can be different for different calls to this function, so its a parameter.

pCnt is the location of the point in the Orbiter global frame ?

What does vhf stand for - view height at the far plane ? This is initialized in :

Code:
void Scene::Update() {
DWORD j;

View = View_new;
Proj = Proj_new;
ViewProj = ViewProj_new;//VP matrix for exterior views
ViewProj_VC = ViewProj_VC_new;//VP matrix for VC
CamPos = CamPos_new;
CamAperture = CamAperture_new;

vh   = (float)tan(CamAperture);
vw   = vh*cfg->Aspect;
vhf  = (float)(1.0f/cos(CamAperture));
vwf  = vhf*cfg->Aspect;

camera_x = D3DXVECTOR3(View._11, View._21, View._31);
camera_y = D3DXVECTOR3(View._12, View._22, View._32);
camera_z = D3DXVECTOR3(View._13, View._23, View._33);

Proxy = Proxy_new;
UpdateSkyColor();//updates cBackground and skybrt using atm params of the nearest planet

for( j = 0; j < VesselCount; j++ )
Vessel[j]->Update();

if( bPause ) {
for( j = 0; j < nstream; j++ )
PStream[j]->Update();
}
bPause = bPause_new;
}

But if CamAperture is half the FoV then vh is actually the aspect ratio of the view as far as I can see. vw or 'view width' would then be = vh*cfg->Aspect which is correct.
What does vhf stand for ? 'view height at far plane' ?

I made a diagram from what I understood so far :
https://docs.google.com/drawings/d/1W1Mfg1S_g9J8CveCzVfrZE28Arck2STWCZyBTH5x21A/edit?usp=sharing

I am assuming the camera view space is right handed, so the camera is looking down the -ve z axis. So say there is a point P within the view frustum as shown in the dig.

float z = camera_z.x*pCnt->x + camera_z.y*pCnt->y + camera_z.z*pCnt->z;

will calculate the projection of the point's position vector in the Orbiter global frame, on the z axis. so

if( z < (-radius) ) return false;

is valid.

float y = camera_y.x*pCnt->x + camera_y.y*pCnt->y + camera_y.z*pCnt->z;

calculates the projection on the +ve y axis. Now I am not sure how this check is working after that line:

if( y - (radius*vhf) > (vh*z) ) return false;

Since vhf = 1/cos(CamAperture)
radius*vhf = ED (in the diagram)

Why would ED be subtracted from y (they do not appear to be in the same direction - ED is not along Y).
vhf*z = HQ

What I understand is that you are trying to check if P'Q < HQ i.e. whether the Y projection of a point P'(i.e. it ht) is less than the frustum height at the point's z projection(EQ in the dig.) Then the point could be inside the view frustum.

So the check should be :
if( y > (vh*z) ) return false;

vh*z makes sense as vh = tan(CamAperture) and z is the projection of P' on the Z-axis.

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

Ok I think I got it. You are testing a sphere and not just a single point in the function.

http://www.lighthouse3d.com/tutorials/view-frustum-culling/radar-approach-implementation-ii/

I'll recheck my calculations.
 
Last edited:

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
I understand that this function will check if a point is within the camera view frustum and return true if it is. Anything outside the radius returns false. This radius can be different for different calls to this function, so its a parameter.
The function checks if boudning sphere can be inside of the camera frustum.

pCnt is the location of the point in the Orbiter global frame ?
No, its world space (centered at camera but with same orientation as global frame). Global frame can only work with 64-bit precision floats because it is centered at the Sun and can have about 15-digit positions, while 32-bit floats work only up to ~7 digits i.e. thousands of km if we use meters.

What does vhf stand for - view height at the far plane ? This is initialized in :

TBH I don't remember how it actually work there and this function was actually copy-pasted from D3D9 client, but I'd just use 6 planes defined with normals directed outside and then do a check like this:
Code:
class CameraFrustum
{
private:
	std::array<Vector4f, 6> m_planes;

public:
	CameraFrustum();
	~CameraFrustum();

	//update planes each frame when camera direction or projection fovs change
	void Update( const Matrix4d &worldToView, float fovx, float fovy );

	bool IsVisible( const Vector3f &boundingSpherePosW, float boundingSphereRadius )
	{
		for( const Vector4f &plane : m_planes )
			if( boundingSphereRadius < (plane.x*boundingSpherePosW.x + plane.y*boundingSpherePosW.y + plane.z*boundingSpherePosW.z + plane.w) )
				return false;

		return true;
	}
};
 

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Ah yes that does look easier. I ll look at implementing the Update() function.

Meanwhile a question on render space an global space. So I see this in
http://sourceforge.net/p/orbitervis/code/HEAD/tree/D3D7Client/Camera.cpp
Code:
// ==============================================================
// Camera.cpp
// Part of the ORBITER VISUALISATION PROJECT (OVP)
// Released under GNU General Public License
// Copyright (C) 2006 Martin Schweiger
// ==============================================================
// ==============================================================
// Class Camera (implementation)
//
// The camera defines the observer position in the 3D world.
// Each scene consists of a camera and a collection of vObjects
// within visual range around it.
// The "render space" (i.e. the coordinate system in which the
// camera and visual objects live) is translated against the
// "global frame" in which orbiter's logical objects live, such
// that the camera is always at the origin. Global and render
// space have however the same orientation.
// ==============================================================

So what this means is that if the camera is at (100, 100, 100) and is looking at a planet at (10 ,10, 10) , both in the global frame thats centered at the sun. There is a translation carried out to move the camera to (0,0,0) and the planet is drawn with DirectX world co-ordinates (-90, -90, -90) ?

Do you by any chance remember if the D3D11 client also does this ? If so where this translation may be:

https://bitbucket.org/face/ovp/src/...bdb32b/Orbitersdk/D3D11Client/?at=D3D11Client
 
Last edited:

Glider

Addon Developer
Addon Developer
Joined
Apr 12, 2008
Messages
226
Reaction score
0
Points
16
Location
Saint-Petersburg
So what this means is that if the camera is at (100, 100, 100) and is looking at a planet at (10 ,10, 10) , both in the global frame thats centered at the sun. There is a translation carried out to move the camera to (0,0,0) and the planet is drawn with DirectX world co-ordinates (-90, -90, -90) ?
Translation is included in the world matrix which translates and rotates local frame of objects (vObject.cpp). every object has its own local frame, its own rotation matrix (rotates local to global/world orientation) and its own world matrix while theres only one view and proejction matrix. If we render a planet at ( 10, 10, 10 ) in the global frame with a camera at ( 100, 100, 100 ) it will compute objectPositionGlobal - cameraPositionGlobal = translation vector which will be position of object in the world space and which will be included in the world matrix. So it goes from local space + world matrix => world space + view matrix => camera view space + projection matrix => projected space.
 

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
I see that there is a breakup of function calls during rendering. There is :

SC->SaveParams();
SC->Update();

https://bitbucket.org/face/ovp/src/...1Client/D3D11Client.cpp?at=D3D11Client#cl-200

In SaveParams you save to *_new member variables. And in Update() you copy from the *_new to the actual members. Was this only to support multi threaded rendering ?

Can I directly save the required data to the original members for a single threaded rendering scenario ?

https://bitbucket.org/face/ovp/src/...k/D3D11Client/Scene.cpp?at=D3D11Client#cl-158
https://bitbucket.org/face/ovp/src/...k/D3D11Client/Scene.cpp?at=D3D11Client#cl-361
 
Last edited:

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
Well I finally got some reasonable output for the Celestial Sphere :
OBGh4gB.png


Code so far is here :
https://code.google.com/p/surface-physics/source/browse/#svn/trunk/SAPClientTests/TestBasicShaders

After I finished refactoring the code and adding CelSphere, the first run got me just a diagonal pink line right across the screen for all my efforts :p
It seems I had not stored the View-Projection matrix correctly, with that fixed, the output followed. So at least I know that I did not mess up anything major so far(hopefully) and the shaders compile and receive parameters correctly.

Currently I only render the Celestial Sphere. I seem to have some adrupt halts while rotating the camera slowly. And sometimes lines disappear. I think that may be due to them being clippedby the far plane :

// Clipping planes
m_fNearPlane = 1.0f;
m_fFarPlane = 1e6;

Incidentally my Celestial Sphere radius is also same, so perhaps some points are being put just beyond. Not sure whether I should increase the far plane or decrease the radius to fix this.
, m_fCelSphereRadius(1e6f)

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

- Aw man! the adrupts halts were due to the fact that I have added too many oapiWriteLogV() in every clbk. As the main/render thread halts to write to disk it halts.
- Checked in D3D9 and the radius is much lower and of course its irrelevant as long as its within the far plane :

Code:
CelestialSphere::CelestialSphere (D3D9Client *_gc)
{
	gc = _gc;
	sphere_r = 1e3f; // the actual render distance for the celestial sphere
	                 // is irrelevant, since it is rendered without z-buffer,
	                 // but it must be within the fustrum limits - check this
	                 // in case the near and far planes are dynamically changed!
	LoadStars ();
	LoadConstellationLines ();
	AllocGrids ();
}

So those 2 are fixed and thats that.

---------- Post added 22-05-14 at 12:45 PM ---------- Previous post was 21-05-14 at 08:37 PM ----------

So the D3D9 and D3D7 clients appear to be using a separate Camera class while D3D11 seems to have put the Camera info into Scene. Maybe separating the Camera info out can help better support multiple cameras.
 
Last edited:

dumbo2007

Crazy about real time sims
Joined
Nov 29, 2009
Messages
675
Reaction score
0
Points
0
Location
India
So I have decided to make the D3D11 client as similar as possible to D3D9, where D3D11 specific optimizations are absent. From what little of the D3D11 client I have covered so far, there arent many differences.

What is the license comment I need to put on the top of each file that I put up in googlecode ? For d3d9 its :

Code:
// ==============================================================
// Part of the ORBITER VISUALISATION PROJECT (OVP)
// Released under GNU General Public License
// Copyright (C) 2007 Martin Schweiger
//                     2012 Jarmo Nikkanen
// ==============================================================
 

f1re

Donator
Donator
Joined
Apr 26, 2016
Messages
24
Reaction score
0
Points
0
Hi.

I've started out on the Instructions thread, but this might be a better place to get involved.

I'd like to contribute to making these cool rendering engines available for latest Beta lineage.

Is there any activity on this at the moment? How big the challenge is? Is there a way to get involved?

I am new to the community, but I am a software engineer, so I might be able to do something useful here, and I'd really like to.
 
Top