Page MenuHomeFeedback Tracker

Aspect ratio issues with UI2Texture
Feedback, NormalPublic

Description

New UI2Texture procedural texture has a lot of issues with aspect ratios.

Issue #1: Engine doesn't take texture dimensions into account and always renders with 1:1 aspect ratio, even if texture is 2:1 or 1:2 or other. This means that texts will also be squished on non 1:1 aspect ratio texture.

Issue #2: Map drawn icons are drawn with fixed ratio of 4:3 regardless of display's aspect ratio, this makes them impossible to be drawn properly through UI2Texture.

Details

Severity
Minor
Resolution
Open
Reproducibility
Always
Operating System
Windows 10 x64
Category
Scripting
Steps To Reproduce
  1. Start a game with a player
  2. Execute code in debug console:
	testcenter = getPosWorld player;

	if(!isNil"testmarkers") then {{deleteMarker _x} forEach testmarkers};
	testmarkers = [];

	testrectangle = createMarker [str random 1e6, testcenter vectorAdd [-200,60]];
	testrectangle setMarkerShape "RECTANGLE";
	testrectangle setMarkerSize [50, 20];
	testrectangle setMarkerBrush "Solid";
	testrectangle setMarkerColor "ColorBlack";
	testrectangle setMarkerText "Marker ellipse";
	testmarkers pushBack testrectangle;

	testellipse = createMarker [str random 1e6, testcenter vectorAdd [200,60]];
	testellipse setMarkerShape "ELLIPSE";
	testellipse setMarkerSize [50, 20];
	testellipse setMarkerBrush "Solid";
	testellipse setMarkerColor "ColorBlack";
	testellipse setMarkerText "Marker ellipse";
	testmarkers pushBack testellipse;

	testicon = createMarker [str random 1e6, testcenter];
	testicon setMarkerShape "ICON";
	testicon setMarkerSize [2, 2];
	testicon setMarkerType "selector_selectedMission";
	testicon setMarkerColor "ColorBlack";
	testmarkers pushBack testicon;

	if(!isNil"testmap") then {deleteVehicle testmap};
	testmap = createVehicle ["Land_MapBoard_F", player modelToWorld [0.2, 3, 0], [], 0, "CAN_COLLIDE"];
	testmap setDir (player getDir testmap);
	testmap enableSimulation false;

	if(!isNil"testlaptop") then {deleteVehicle testlaptop};
	testlaptop = createVehicle ["Land_Laptop_unfolded_F", player modelToWorld [1, 2, 1], [], 0, "CAN_COLLIDE"];
	testlaptop setDir (testlaptop getDir player);
	testlaptop enableSimulation false;

	if(!isNil"testobj") then {deleteVehicle testobj};
	testobj = createVehicle ["UserTexture_1x2_F", player modelToWorld [-1.1, 2.5, 1.1], [], 0, "CAN_COLLIDE"];
	testobj setDir (player getDir testobj);
	testobj enableSimulation false;

	if(!isNil"testdisplay") then {testdisplay closeDisplay 0};
	testdisplay = findDisplay 46 createDisplay "RscDisplayEmpty";

	testmaptexture = "map" + (diag_frameno toFixed 0);
	testlaptoptexture = "laptop" + (diag_frameno toFixed 0);
	testobjtexture = "obj" + (diag_frameno toFixed 0);

	testmap setObjectTexture [0, format["#(rgb,2048,2048,1)ui('RscDisplayEmpty','%1')", testmaptexture]];
	testlaptop setObjectTexture [0, format["#(rgb,2048,1024,1)ui('RscDisplayEmpty','%1')", testlaptoptexture]];
	testobj setObjectTexture [0, format["#(rgb,1024,2048,1)ui('RscDisplayEmpty','%1')", testobjtexture]];

	testframe = diag_frameno + 5;

	onEachFrame {
		private _displays = [
			 findDisplay testmaptexture
			,findDisplay testlaptoptexture
			,findDisplay testobjtexture
			,testdisplay
		];

		if(_displays findIf {isNull _x} < 0) then {
			testdisplays = _displays;

			{
				for "_i" from 0 to 99 do {
					private _grid = _x ctrlCreate ["RscText", -1];
					_grid ctrlSetPosition [_i % 10 / 10, floor(_i / 10) / 10, 0.1, 0.1];
					_grid ctrlCommit 0;
					_grid ctrlSetText str _i;
					_grid ctrlSetPixelPrecision 2;
					_grid ctrlSetFontHeight 0.1;
					_grid ctrlSetBackgroundColor [random 1, random 1, random 1, 0.5];
				};

				private _map = _x ctrlCreate ["RscMapControl", -1];
				_map ctrlMapSetPosition [0.2, 0.2, 0.6, 0.6];
				_map ctrlMapAnimAdd [0, 0.03, testcenter];
				ctrlMapAnimCommit _map;
				_x setVariable ["map", _map];

				private _marker_color = (["ColorRed", "ColorGreen", "ColorBlue", "ColorYellow"] select (_forEachIndex % 4));

				_map setVariable ["color", getArray(configFile >> "CfgMarkerColors" >> _marker_color >> "color")];
				_map ctrlAddEventHandler ["Draw", {
					private _map = _this select 0;

					_map drawIcon [
						 "\A3\ui_f\data\map\groupicons\selector_selectedMission_ca.paa"
						,_map getVariable "color"
						,_map ctrlMapScreenToWorld [0.5, 0.5]
						,32 * 3
						,32 * 3
						,0
						,""
						,2
						,0.04
						,"PuristaMedium"
						,"right"
					];

					private _angle = (diag_tickTime % 5 / 5) * 360;

					_map drawIcon [
						 "\A3\ui_f\data\map\groupicons\selector_selectedMission_ca.paa"
						,_map getVariable "color"
						,_map ctrlMapScreenToWorld [0.5, 0.5]
						,32 * 4.5
						,32 * 4.5
						,_angle
						,"drawIcon rotating"
						,2
						,0.04
						,"PuristaMedium"
						,"right"
					];

					_map drawEllipse [
						 testcenter vectorAdd [200,-60]
						,50
						,20
						,_angle
						,_map getVariable "color"
						,"#(rgb,8,8,3)color(1,1,1,1)"
					];

					_map drawRectangle [
						 testcenter vectorAdd [-200,-60]
						,50
						,20
						,_angle
						,_map getVariable "color"
						,"#(rgb,8,8,3)color(1,1,1,1)"
					];
				}];

				displayUpdate _x;
			} forEach testdisplays;

			onEachFrame {
				{
					private _map = _x getVariable "map";
					_map ctrlMapAnimAdd [0, linearConversion [-1, 1, cos((((-1 + diag_tickTime % 6)) max 0 min 5) / 5 * 360), 0.01, 0.1], testcenter];
					ctrlMapAnimCommit _map;

					displayUpdate _x;
				} forEach testdisplays;

				{
					_x setMarkerDir (diag_tickTime % 5 / 5) * 360;
				} forEach testmarkers;
			};
		};
	};
  1. Observe squished text (Issue 1) on left and right objects
  2. Observe squished icons on the map control (Issue 2) on all displays

Code also opens same display on the UI as an example of how it should look. Black icons and shapes are map markers, colored shapes are drawn with drawIcon/drawRectangle/drawEllipse commands.

Additional Information

If it was up to me, I'd render UI2Texture displays with same 4:3 ratio as normal displays. And either do:

  1. Fit 4:3 display into texture's aspect ratio leaving transparent bands
  2. Fit 4:3 display into top left of the texture so it fills the texture completely and cut off the rest

Maybe even have an option to render the display onto the texture in these different modes: current, 4:3 fit, 4:3 cutoff.

Whatever the case, fixing map icon drawing is worth it because you can trigger same bugs even without ui2texture by messing with your fovTop and fovLeft settings.

Event Timeline

SaMatra created this task.Fri, Mar 3, 3:39 AM
This comment was removed by Geez.
Geez added a subscriber: Geez.Fri, Mar 3, 9:47 AM
dedmen set Ref Ticket to AIII-55592.Thu, Mar 16, 10:30 AM
dedmen added a subscriber: dedmen.Tue, Mar 28, 2:18 PM


It looks a bit stretched/squished in the center display too. But not as much as the others


It looks a bit stretched/squished in the center display too. But not as much as the others

Yeah, this is a long going bug in the game, since at least Arma 2, probably even Arma 1 or even OFP. I think its caused by messing with your FOV in .Arma3Profile by changing either fovTop or fovLeft and if they're not 4:3 and 3:4, map icons become squished. Here is how I have it at 1080p with

fovTop=0.75;
fovLeft=1.3333334;

Properly square.

Map screen actually used hardcoded 640x480 resolution to calculate rendering.
Which is also why the center display was wrong too.


Better now.

Repro adjusted with big visible text on the map:

	testcenter = getPosWorld player;

	if(!isNil"testmarkers") then {{deleteMarker _x} forEach testmarkers};
	testmarkers = [];

	testrectangle = createMarker [str random 1e6, testcenter vectorAdd [-200,60]];
	testrectangle setMarkerShape "RECTANGLE";
	testrectangle setMarkerSize [50, 20];
	testrectangle setMarkerBrush "Solid";
	testrectangle setMarkerColor "ColorBlack";
	testrectangle setMarkerText "Marker ellipse";
	testmarkers pushBack testrectangle;

	testellipse = createMarker [str random 1e6, testcenter vectorAdd [200,60]];
	testellipse setMarkerShape "ELLIPSE";
	testellipse setMarkerSize [50, 20];
	testellipse setMarkerBrush "Solid";
	testellipse setMarkerColor "ColorBlack";
	testellipse setMarkerText "Marker ellipse";
	testmarkers pushBack testellipse;

	testicon = createMarker [str random 1e6, testcenter];
	testicon setMarkerShape "ICON";
	testicon setMarkerSize [2, 2];
	testicon setMarkerType "selector_selectedMission";
	testicon setMarkerColor "ColorBlack";
	testmarkers pushBack testicon;

	if(!isNil"testmap") then {deleteVehicle testmap};
	testmap = createVehicle ["Land_MapBoard_F", player modelToWorld [0.2, 3, 0], [], 0, "CAN_COLLIDE"];
	testmap setDir (player getDir testmap);
	testmap enableSimulation false;

	if(!isNil"testlaptop") then {deleteVehicle testlaptop};
	testlaptop = createVehicle ["Land_Laptop_unfolded_F", player modelToWorld [1, 2, 1], [], 0, "CAN_COLLIDE"];
	testlaptop setDir (testlaptop getDir player);
	testlaptop enableSimulation false;

	if(!isNil"testobj") then {deleteVehicle testobj};
	testobj = createVehicle ["UserTexture_1x2_F", player modelToWorld [-1.1, 2.5, 1.1], [], 0, "CAN_COLLIDE"];
	testobj setDir (player getDir testobj);
	testobj enableSimulation false;

	if(!isNil"testdisplay") then {testdisplay closeDisplay 0};
	testdisplay = findDisplay 46 createDisplay "RscDisplayEmpty";

	testmaptexture = "map" + (diag_frameno toFixed 0);
	testlaptoptexture = "laptop" + (diag_frameno toFixed 0);
	testobjtexture = "obj" + (diag_frameno toFixed 0);

	testmap setObjectTexture [0, format["#(rgb,2048,2048,1)ui('RscDisplayEmpty','%1')", testmaptexture]];
	testlaptop setObjectTexture [0, format["#(rgb,2048,1024,1)ui('RscDisplayEmpty','%1')", testlaptoptexture]];
	testobj setObjectTexture [0, format["#(rgb,1024,2048,1)ui('RscDisplayEmpty','%1')", testobjtexture]];

	testframe = diag_frameno + 5;

	onEachFrame {
		private _displays = [
			 findDisplay testmaptexture
			,findDisplay testlaptoptexture
			,findDisplay testobjtexture
			,testdisplay
		];

		if(_displays findIf {isNull _x} < 0) then {
			testdisplays = _displays;

			{
				for "_i" from 0 to 99 do {
					private _grid = _x ctrlCreate ["RscText", -1];
					_grid ctrlSetPosition [_i % 10 / 10, floor(_i / 10) / 10, 0.1, 0.1];
					_grid ctrlCommit 0;
					_grid ctrlSetText str _i;
					_grid ctrlSetPixelPrecision 2;
					_grid ctrlSetFontHeight 0.1;
					_grid ctrlSetBackgroundColor [random 1, random 1, random 1, 0.5];
				};

				private _map = _x ctrlCreate ["RscMapControl", -1];
				_map ctrlMapSetPosition [0.2, 0.2, 0.6, 0.6];
				_map ctrlMapAnimAdd [0, 0.03, testcenter];
				ctrlMapAnimCommit _map;
				_x setVariable ["map", _map];

				private _marker_color = (["ColorRed", "ColorGreen", "ColorBlue", "ColorYellow"] select (_forEachIndex % 4));

				_map setVariable ["color", getArray(configFile >> "CfgMarkerColors" >> _marker_color >> "color")];
				_map ctrlAddEventHandler ["Draw", {
					private _map = _this select 0;

					_map drawIcon [
						 "\A3\ui_f\data\map\groupicons\selector_selectedMission_ca.paa"
						,_map getVariable "color"
						,_map ctrlMapScreenToWorld [0.5, 0.5]
						,32 * 3
						,32 * 3
						,0
						,""
						,2
						,0.04
						,"PuristaMedium"
						,"right"
					];

					private _angle = (diag_tickTime % 5 / 5) * 360;

					_map drawIcon [
						 "\A3\ui_f\data\map\groupicons\selector_selectedMission_ca.paa"
						,_map getVariable "color"
						,_map ctrlMapScreenToWorld [0.5, 0.5]
						,32 * 4.5
						,32 * 4.5
						,_angle
						,"drawIcon rotating"
						,2
						,0.04
						,"PuristaMedium"
						,"right"
					];

					_map drawEllipse [
						 testcenter vectorAdd [200,-60]
						,50
						,20
						,_angle
						,_map getVariable "color"
						,"#(rgb,8,8,3)color(1,1,1,1)"
					];

					_map drawRectangle [
						 testcenter vectorAdd [-200,-60]
						,50
						,20
						,_angle
						,_map getVariable "color"
						,"#(rgb,8,8,3)color(1,1,1,1)"
					];

					_map drawIcon [
						 "#(argb,8,8,3)color(0,0,0,0)"
						,_map getVariable "color"
						,_map ctrlMapScreenToWorld [0.3, 0.3]
						,1e-6
						,1e-6
						,0
						,"drawIcon text"
						,2
						,0.08
						,"PuristaMedium"
						,"right"
					];
				}];

				displayUpdate _x;
			} forEach testdisplays;

			onEachFrame {
				{
					private _map = _x getVariable "map";
					_map ctrlMapAnimAdd [0, linearConversion [-1, 1, cos((((-1 + diag_tickTime % 6)) max 0 min 5) / 5 * 360), 0.01, 0.1], testcenter];
					ctrlMapAnimCommit _map;

					displayUpdate _x;
				} forEach testdisplays;

				{
					_x setMarkerDir (diag_tickTime % 5 / 5) * 360;
				} forEach testmarkers;
			};
		};
	};
dedmen changed the task status from New to Feedback.Tue, Mar 28, 3:55 PM

Icon rendering using incorrect aspect ratio is fixed on next dev/prof.
For the other thing probably separate ticket