• ORBITER-FORUM will be temporarily closed at 2026-07-23 18:00 UTC while we complete some OF maintenance tasks. The amount of downtime is expected to take up to one hour, but probably less.

Question Ranger (and other ships) from Interstellar?

Fix: If you can, don't paint on textures, but manipulate vertices.
Fix: The less your code does, the faster it happens.


Not the wind, not the flag; mind is moving.


So like the green level bars. Make green rectangle mesh and scale it?
 
Interesting?

Well I guess I could make it without a VC and see what the loss or gain of FPS is. But that would take away the feel.

We at one time thought about making a mfd to deal with all the engine and cargo info
 
GUepFs2.jpg
no vc I get 115 fps
 
yes d3d9.
On the size the Endurance
80 groups
71058 vert
54480 triangles

vc mesh
85 groups
1518 vert
760 triangles

I can post the code if that will help
 
I'm not a programmer, I just used the codes in the SDK. First of all a lighter vessel.

But your analysis is right. The issue is most likely the painting code. The last version of the code I saw was terribly slow by using the slowest kind of rendering every time step.
 
Not sure about the lighter vessel?

On the endurance this is the only paint on the texture. The rest is mfd or mesh group movement

Code:
void TESTVC::RedrawPanel_Fuelstatus(SURFHANDLE surf, int part)

{
	
	
	
	//SURFHANDLE const tex3 = oapiGetTextureHandle(meshhg_VC,5 );
	char cbuf[20];
	HDC hDC = oapiGetDC(surf);



	
	level2 = GetPropellantMass(tank);

	SelectObject(hDC, g_Param.hBrush[3]);//green box

	level3 = ((level2 / FUELMASS)*237);
	Rectangle(hDC, 110, 34, (int)(110.0 + level3), 75);  //fuel

	//THRUST
	level = GetThrusterLevel(th_main[0]);
	//double level2 = GetPropellantMass(tank);

	SelectObject(hDC, g_Param.hBrush[3]);//green box
	Rectangle(hDC, 114, 111, (int)(114 + level * (346 - 114)), 160);//thrust
	//POD
	SetTextColor(hDC, RGB(0, 153, 0));
	SetTextAlign(hDC, TA_LEFT);
	SetBkMode(hDC, TRANSPARENT);

	SelectObject(hDC, g_Param.hFont[2]);

	if (PODSel == 1) {
		sprintf(cbuf, "POD 1 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 2) {
		sprintf(cbuf, "POD 2 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 3) {
		sprintf(cbuf, "POD 3 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 4) {
		sprintf(cbuf, "POD 4 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 5) {
		sprintf(cbuf, "POD 5 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 6) {
		sprintf(cbuf, "POD 6 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 7) {
		sprintf(cbuf, "POD 7 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 8) {
		sprintf(cbuf, "POD 8 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 9) {
		sprintf(cbuf, "POD 9 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 10) {
		sprintf(cbuf, "POD 10 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 11) {
		sprintf(cbuf, "POD 11 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 12) {
		sprintf(cbuf, "POD 12 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 13) {
		sprintf(cbuf, "POD 13 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 14) {
		sprintf(cbuf, "POD 14 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 15) {
		sprintf(cbuf, "POD 15 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}

	if (PODSel == 16) {
		sprintf(cbuf, "POD 16 Selected", 14);
		TextOut(hDC, 144, 400, cbuf, strlen(cbuf));
	}









	oapiReleaseDC(surf, hDC);
	

}
Code:
bool TESTVC::clbkLoadVC(int id) { // ID is the Preset Camera Position
	SURFHANDLE const tex3 = oapiGetTextureHandle(meshhg_VC, TEX_ENDURANCE35VC_ENDURANCEVC2E);


	viewController->HandleLoadVC(id);
mfdController->HandleLoadVC(id);	
	oapiVCRegisterArea(AID_FUELSTATUS, _R(0, 0, 512, 512), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, tex3);
	//oapiVCRegisterArea(AID_THRUSTSTATUS, _R(0, 0, 512, 512), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, tex3);
	//oapiVCRegisterArea(AID_PODSTATUS, _R(0, 0, 512, 512), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, tex3);

	oapiVCRegisterHUD(&huds);

	return HandleLoadVC(id);
}

bool TESTVC::HandleLoadVC(UINT const id)
{



	return true;
}

bool TESTVC::clbkVCMouseEvent(int id, int event, VECTOR3 &p)
{
	bool result = false;
	result = result || mfdController->HandleMouseEvent(id, event, p);
	result = result || VCMouseEvent(id, event, p);
	return result;
}

bool TESTVC::VCMouseEvent(int const id, int const event, VECTOR3& const p)
{



	return false; // We must return false, as we didn't processed the event!
}



bool TESTVC::clbkVCRedrawEvent(int id, int event, SURFHANDLE surf) {
	bool result = false;
	result = result || mfdController->HandleRedrawEvent(id, event, surf);


	result = result || VCRedrawEvent(id, event, surf);


	{

		switch (id) {
		case AID_FUELSTATUS:
			RedrawPanel_Fuelstatus(surf, id - AID_FUELSTATUS);
		//	sprintf(oapiDebugString(), "Fuel %f", fuel_percent);
			return true;
	
		}
		//	return false;



	}
	return result;
}

bool TESTVC::VCRedrawEvent(int const id, int const event, SURFHANDLE const surf) {
	return false;
}
Code:
void TESTVC::clbkPostStep(double simt, double simdt, double mjd)
{
	if (this->viewController->IsFocused())sprintf_s(oapiDebugString(), 255, "%s : %s", viewController->station()->name.c_str(), viewController->view()->name.c_str());

	for (int i = 1; i < 17; i++) {
		APbeacon[i].active = false;
	}
	for (int i = 1; i < 17; i++) {
		Cbeacon[i].active = false;
	}


fuel_percent = int(100 * (GetFuelMass()) / (FUELMASS));

	if (fuel_percent != fuel_percent_last_redraw){
		fuel_percent_last_redraw = fuel_percent;
			oapiVCTriggerRedrawArea(0, AID_FUELSTATUS);
	}
	current_thrust_level = GetThrusterLevel(th_main[0]);

	if (current_thrust_level != thrust_last_drawn){
		thrust_last_drawn = current_thrust_level;
		oapiVCTriggerRedrawArea(0, AID_FUELSTATUS);
	}

	if (PODSel != PODSel_last_drawn){
		PODSel_last_drawn = PODSel;
		oapiVCTriggerRedrawArea(0, AID_FUELSTATUS);
	}

At one point we saw that if in the copilot view the cargo status would not change unless you switched views


For the cargo there are 3 x16 cubes (red, yellow, green) that move back and forth depending on the status of the cargo.
 
I see the bump up in framerate without the VC but I think the experience is more immersive with the VC.
 
Here is the code for the vc for the lander:
Code:
level = GetThrusterLevel(th_main[0]);
	level2 = GetPropellantMass(tank1);//main fuel
//	HOVERLEVEL = GetThrusterGroupLevel(thg_hover);//hover
	level4 = GetPropellantMass(tank2);//hover fuel
	level5 = GetPropellantMass(tank3);//rcs fuel



	fuel_percent1 = int(100 * (GetFuelMass()) / (FUELMASS1));
	fuel_percent2 = int(100 * (GetFuelMass()) / (FUELMASS2));
	fuel_percent3 = int(100 * (GetFuelMass()) / (FUELMASS3));
	current_thrust_main_level = GetThrusterLevel(th_main[0]);
   current_thrust_hover_level = GetThrusterGroupLevel(thg_hover);
	current_trim_level = PITCHTRIMLEVEL;

	

	if (fuel_percent1 != fuel_percent1_last_redraw){
		fuel_percent1_last_redraw = fuel_percent1;
		redrawpanel = true;
		//oapiVCTriggerRedrawArea(-1, AID_FUELSTATUS);
	}
	if (fuel_percent2 != fuel_percent2_last_redraw){
		fuel_percent2_last_redraw = fuel_percent2;
		redrawpanel = true;
	}
	if (fuel_percent3 != fuel_percent3_last_redraw){
		fuel_percent3_last_redraw = fuel_percent3;
		redrawpanel = true;
	}
	if (current_thrust_main_level != thrust_main_last_drawn){
		thrust_main_last_drawn = current_thrust_main_level;
		redrawpanel = true;
	}
	if (redrawpanel == true) oapiVCTriggerRedrawArea(-1, AID_FUELSTATUS);

	if (current_thrust_hover_level != thrust_hover_last_drawn){
		thrust_hover_last_drawn = current_thrust_hover_level;
		redrawpanel = true;
	}
	
	if (current_trim_level != trim_last_drawn){
		trim_last_drawn = current_trim_level;
		redrawpanel = true;
	}
Code:
void LANDER6::RedrawPanel_Fuelstatus(SURFHANDLE surf, int part)

{
	char cbuf[20];
	HDC hDC = oapiGetDC(surf);

	SelectObject(hDC, g_Param.hBrush[4]);//green box




	Rectangle(hDC, 62, 256, (int)(62 + level * (280)), 280);//thrust

	Rectangle(hDC, hoverx1, hovery1, hoverx2,hovery2);//HOVERthrust

	//Rectangle(hDC, 62, 509, 342, 534);//HOVERthrust

	//178,145
	Rectangle(hDC, 154, 224, 180, (int)(224 - (level2 / 50)));  //fuel
	Rectangle(hDC, 226, 224, 249, (int)(224 - (level2 / 50)));  //fuel

	Rectangle(hDC, 81, 468, 106, (int)(468 - (level4 / 50)));  //fuel
	Rectangle(hDC, 152, 468, 176, (int)(468 - (level4 / 50)));  //fuel
	Rectangle(hDC, 225, 468, 250, (int)(468 - (level4 / 50)));  //fuel
	Rectangle(hDC, 296, 468, 322, (int)(468 - (level4 / 50)));  //fuel

	Rectangle(hDC, 499, 486, 525, (int)(486 - (level5 / 23.8)));  //rscfuel
	Rectangle(hDC, 572, 486, 598, (int)(486 - (level5 / 23.8)));  //rscfuel

	Rectangle(hDC, 499, 223, 525, (int)(223 - (level5 / 23.8)));  //rscfuel
	Rectangle(hDC, 572, 223, 599, (int)(223 - (level5 / 23.8)));  //rscfuel

	
	SelectObject(hDC, g_Param.hFont[3]);

	SetTextColor(hDC, RGB(0, 153, 0));
	SetTextAlign(hDC, TA_LEFT);
	SetBkMode(hDC, TRANSPARENT);

	SelectObject(hDC, g_Param.hFont[4]);
	sprintf(cbuf, "%0.1f", level2 / 2);
	TextOut(hDC, 142, 107, cbuf, strlen(cbuf));
	TextOut(hDC, 212, 107, cbuf, strlen(cbuf));

	sprintf(cbuf, "%0.1f", level4 / 4);
	TextOut(hDC, 67, 350, cbuf, strlen(cbuf));
	TextOut(hDC, 139, 350, cbuf, strlen(cbuf));
	TextOut(hDC, 212, 350, cbuf, strlen(cbuf));
	TextOut(hDC, 283, 350, cbuf, strlen(cbuf));

	sprintf(cbuf, "%0.1f", level5 / 4);
	TextOut(hDC, 500, 353, cbuf, strlen(cbuf));
	TextOut(hDC, 571, 353, cbuf, strlen(cbuf));
	TextOut(hDC, 500, 103, cbuf, strlen(cbuf));
	TextOut(hDC, 571, 103, cbuf, strlen(cbuf));

	trim = (GetControlSurfaceLevel(AIRCTRL_ELEVATORTRIM) - .5);
	//trim1 = GetControlSurfaceLevel(AIRCTRL_ELEVATORTRIM);

	double trim2 = (trim - .5);
	
	double PITCHTRIMLEVELbar = (PITCHTRIMLEVEL - 1);
	Rectangle(hDC, 482, (int)(249 - (30 * PITCHTRIMLEVELbar)), 502, (int)(255 - (30 * PITCHTRIMLEVELbar)));  //TRIM

	SelectObject(hDC, g_Param.hFont[3]);
	SetTextColor(hDC, RGB(0, 153, 0));
	SetTextAlign(hDC, TA_LEFT);
	SetBkMode(hDC, TRANSPARENT);
	
	sprintf(cbuf, "%0.2f", PITCHTRIMLEVEL);
	TextOut(hDC, 545, 273, cbuf, strlen(cbuf));
	SelectObject(hDC, g_Param.hFont[2]);

	if (PITCHTRIMLEVEL<0) {
		sprintf(cbuf, "DN", 2);
		TextOut(hDC, 581, 269, cbuf, strlen(cbuf));
	}
	if (PITCHTRIMLEVEL>0) {
		sprintf(cbuf, "UP", 2);
		TextOut(hDC, 581,269, cbuf, strlen(cbuf));
	}
	
	if (!GetAttachmentStatus(CARGO1)) {
		SetTextColor(hDC, RGB(196, 196, 196));
		sprintf(cbuf, "CARGO1", 6);
		TextOut(hDC, 77, 567, cbuf, strlen(cbuf));
	}

	if (GetAttachmentStatus(CARGO1)) {
		SetTextColor(hDC, RGB(0, 153, 0));
		sprintf(cbuf, "CARGO1", 6);
		TextOut(hDC, 77, 567, cbuf, strlen(cbuf));
	}
	if (!GetAttachmentStatus(CARGO2)) {
		SetTextColor(hDC, RGB(196, 196, 196));
		sprintf(cbuf, "CARGO2", 6);
		TextOut(hDC, 222, 567, cbuf, strlen(cbuf));
	}
	if (GetAttachmentStatus(CARGO2)) {
		SetTextColor(hDC, RGB(0, 153, 0));
		sprintf(cbuf, "CARGO2", 6);
		TextOut(hDC, 222, 567, cbuf, strlen(cbuf));
	}
	redrawpanel = false;
	oapiReleaseDC(surf, hDC);
}
Code:
bool LANDER6::clbkLoadGenericCockpit() {
	viewController->HandleLoadGC();
	return true;
}

bool LANDER6::clbkLoadVC(int id) { // ID is the Preset Camera Position
	SURFHANDLE const tex3 = oapiGetTextureHandle(meshhg_VC, TEX_LANDER17VC_LANDERCENTERVC4);
	huds.size = 0.496;
	huds.nmesh = 7;
	huds.ngroup = GRP_LANDER17VC_HUD;
	
	//static VCHUDSPEC huds = { 7, GRP_LANDER17VC_HUD, { -.842, 3.664734, 8.022912 }, 0.496 };
	oapiVCRegisterHUD(&huds);



	viewController->HandleLoadVC(id);
	mfdController->HandleLoadVC(id);
	oapiVCRegisterArea(AID_FUELSTATUS, _R(0, 0, 1024, 1024), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, tex3);
	//oapiVCRegisterArea(AID_THRUSTSTATUS, _R(0, 0, 512, 512), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, tex3);
	//oapiVCRegisterArea(AID_PODSTATUS, _R(0, 0, 512, 512), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, tex3);
	//caseTerminalScreen->HandleLoadVC(id);
	//TARSTerminalScreen->HandleLoadVC(id);


	return HandleLoadVC(id);
}

bool LANDER6::HandleLoadVC(UINT const id)
{



	return true;
}

bool LANDER6::clbkVCMouseEvent(int id, int event, VECTOR3 &p)
{
	bool result = false;
	result = result || mfdController->HandleMouseEvent(id, event, p);
	result = result || VCMouseEvent(id, event, p);
	return result;
}

bool LANDER6::VCMouseEvent(int const id, int const event, VECTOR3& const p)
{



	return false; // We must return false, as we didn't processed the event!
}



bool LANDER6::clbkVCRedrawEvent(int id, int event, SURFHANDLE surf) {
	bool result = false;
	result = result || mfdController->HandleRedrawEvent(id, event, surf);
//	result = result || caseTerminalScreen->HandleRedrawEvent(id, event, surf);
	//result = result || TARSTerminalScreen->HandleRedrawEvent(id, event, surf);

	result = result || VCRedrawEvent(id, event, surf);


	{

		switch (id) {
		case AID_FUELSTATUS:
			RedrawPanel_Fuelstatus(surf, id - AID_FUELSTATUS);
			//	sprintf(oapiDebugString(), "Fuel %f", fuel_percent);
			return true;

		}
		//	return false;



	}
	return result;
}

bool LANDER6::VCRedrawEvent(int const id, int const event, SURFHANDLE const surf) {
	return false;
}
 
But your analysis is right. The issue is most likely the painting code. The last version of the code I saw was terribly slow by using the slowest kind of rendering every time step.

I believe that the main problem is the will to run an elephant like a gazelle, large mesh and thick texture does not make the vessel fast, if Gattis do not understand this concept is useless post codes, where I see writing as 1024 x 1024, and ships with 50,000 polygons, maybe in 2/3/4 years the Gattis vessel will be fluid, with microprocessors quantum .....
 
What?

So are you saying if will be slow because of the size? or the code.

I really can't do much on the size.
 
I think....

1-must reduce the number of vertices of your vessel:

On the size the Endurance
80 groups
71058 vert
54480 triangles


"As a rough guideline, I would suggest to keep the vertex count below 10 000 vertices
for each spacecraft"
(3DModel pdf)

2-It must reduce the size of the texture and bar indicators

If you have a vessel that no VC, has 115 fps, if you add the VC indicators with bar, you lose even more fps, the more the bars are large, so you reduce the polygons of your vessel, and reduce the size of the bars if you want to have a fluid simulation.

A proverb says to want the barrel full and the wife drunk.
 
Well. Then I don't know. So on the Endurance. I might could gut the whole interior. But as Ben said you lose some stuff.

The Landers are 27618 vert. Well the UCGO arrow is 54000.

On Endurance vc there are just 2 bars. Thrust and fuel level. There are 4 mfd's. The 1 texture I draw on is 512 x512.


I guess I could have 1 set of interior and vc vessels and another without
 
The biggest issue is the painting on textures, which really hurts if you have a low bandwidth between GPU and CPU space. For that, I really recommend to be as effective as possible. Any data transfer between GPU and CPU, that you can avoid, is a data transfer that does not slow your rendering down.

Really really fast would be having a Sketchpad implementation that only operates in GPU memory.
 
Thanks

yes the lander vc is 1024x 1024. I can go to a 512 x512.

Not sure if it matters that one Endurance just 1 vc screen. Lander 2 Pilot.copilot.
 
And how many MFDs at a time?
 
The biggest issue is the painting on textures, which really hurts if you have a low bandwidth between GPU and CPU space. For that, I really recommend to be as effective as possible. Any data transfer between GPU and CPU, that you can avoid, is a data transfer that does not slow your rendering down.

Really really fast would be having a Sketchpad implementation that only operates in GPU memory.

Thanks. Not sure how to implement that?

---------- Post added at 04:40 AM ---------- Previous post was at 04:36 AM ----------

And how many MFDs at a time?

6 on the lander total. 2 sets of 3. We could go with the 2 main ones and just a texture for the 3rd.

If this is an issue then the Ranger which has 7 will be a bigger issue. But we can reduce to 4.
 
Back
Top