2525import javafx .scene .control .Label ;
2626import javafx .scene .control .ScrollPane ;
2727import javafx .scene .layout .*;
28+ import org .jackhuang .hmcl .game .GraphicsAPI ;
2829import org .jackhuang .hmcl .game .NativesDirectoryType ;
2930import org .jackhuang .hmcl .game .Renderer ;
3031import org .jackhuang .hmcl .setting .Profile ;
3637import org .jackhuang .hmcl .util .io .FileUtils ;
3738import org .jackhuang .hmcl .util .platform .OperatingSystem ;
3839import org .jackhuang .hmcl .util .platform .Platform ;
40+ import org .jackhuang .hmcl .util .versioning .GameVersionNumber ;
3941import org .jetbrains .annotations .Nullable ;
4042
4143import java .nio .file .FileSystems ;
@@ -69,6 +71,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
6971 private final ComponentSublist nativesDirSublist ;
7072 private final MultiFileItem <NativesDirectoryType > nativesDirItem ;
7173 private final MultiFileItem .FileOption <NativesDirectoryType > nativesDirCustomOption ;
74+ private final LineSelectButton <GraphicsAPI > graphicsBackendPane ;
7275 private final LineSelectButton <Renderer > rendererPane ;
7376
7477 public AdvancedVersionSettingPage (Profile profile , @ Nullable String versionId , VersionSetting versionSetting ) {
@@ -79,6 +82,10 @@ public AdvancedVersionSettingPage(Profile profile, @Nullable String versionId, V
7982 versionId == null ? i18n ("settings.advanced" ) : i18n ("settings.advanced.title" , versionId )
8083 ));
8184
85+ @ Nullable GameVersionNumber gameVersion = versionId != null
86+ ? GameVersionNumber .asGameVersion (profile .getRepository ().getGameVersion (versionId ))
87+ : null ;
88+
8289 this .getStyleClass ().add ("gray-background" );
8390
8491 ScrollPane scrollPane = new ScrollPane ();
@@ -185,14 +192,51 @@ public AdvancedVersionSettingPage(Profile profile, @Nullable String versionId, V
185192 nativesDirHint .setText (i18n ("settings.advanced.natives_directory.hint" ));
186193 nativesDirItem .getChildren ().add (nativesDirHint );
187194
195+ graphicsBackendPane = new LineSelectButton <>();
196+ graphicsBackendPane .setTitle (i18n ("settings.advanced.graphics_backend" ));
197+ graphicsBackendPane .setConverter (backend -> i18n ("settings.advanced.graphics_backend." + backend .name ().toLowerCase (Locale .ROOT )));
198+ graphicsBackendPane .setDescriptionConverter (backend -> switch (backend ) {
199+ case DEFAULT -> i18n ("settings.advanced.graphics_backend.default.desc" );
200+ case OPENGL -> i18n ("settings.advanced.graphics_backend.opengl.desc" );
201+ case VULKAN -> {
202+ if (gameVersion == null )
203+ yield i18n ("settings.advanced.graphics_backend.vulkan.desc.global" );
204+ else if (gameVersion .compareTo ("26.2-snapshot-2" ) < 0 )
205+ yield i18n ("settings.advanced.graphics_backend.vulkan.desc.unsupported" );
206+ else
207+ yield i18n ("settings.advanced.graphics_backend.vulkan.desc" );
208+ }
209+ default -> null ;
210+ });
211+ graphicsBackendPane .setValue (GraphicsAPI .DEFAULT );
212+ graphicsBackendPane .setItems (GraphicsAPI .values ());
213+
188214 rendererPane = new LineSelectButton <>();
189215 rendererPane .setTitle (i18n ("settings.advanced.renderer" ));
190216 rendererPane .setConverter (e -> i18n ("settings.advanced.renderer." + e .name ().toLowerCase (Locale .ROOT )));
191217 rendererPane .setDescriptionConverter (e -> {
192218 String bundleKey = "settings.advanced.renderer." + e .name ().toLowerCase (Locale .ROOT ) + ".desc" ;
193219 return I18n .hasKey (bundleKey ) ? i18n (bundleKey ) : null ;
194220 });
195- rendererPane .setItems (Renderer .values ());
221+ rendererPane .setValue (Renderer .DEFAULT );
222+ rendererPane .setItems (Renderer .DEFAULT );
223+
224+ FXUtils .onChangeAndOperate (graphicsBackendPane .valueProperty (), backend -> {
225+ if (backend == null ) { // unbind
226+ return ;
227+ }
228+
229+ rendererPane .setItems (Renderer .SUPPORTED .get (backend ));
230+ if (backend == GraphicsAPI .DEFAULT ) {
231+ rendererPane .setDisable (true );
232+ rendererPane .setValue (Renderer .DEFAULT );
233+ } else {
234+ rendererPane .setDisable (false );
235+ if (rendererPane .getValue () == null || !rendererPane .getValue ().isSupported (backend )) {
236+ rendererPane .setValue (Renderer .DEFAULT );
237+ }
238+ }
239+ });
196240
197241 noJVMArgsPane = new LineToggleButton ();
198242 noJVMArgsPane .setTitle (i18n ("settings.advanced.no_jvm_args" ));
@@ -219,7 +263,7 @@ public AdvancedVersionSettingPage(Profile profile, @Nullable String versionId, V
219263 useNativeOpenALPane .setSubtitle (i18n ("settings.advanced.linux_freebsd_only" ));
220264
221265 workaroundPane .getContent ().setAll (
222- nativesDirSublist , rendererPane , noJVMArgsPane , noOptimizingJVMArgsPane , noGameCheckPane ,
266+ nativesDirSublist , graphicsBackendPane , rendererPane , noJVMArgsPane , noOptimizingJVMArgsPane , noGameCheckPane ,
223267 noJVMCheckPane , noNativesPatchPane
224268 );
225269
@@ -252,6 +296,7 @@ void bindProperties() {
252296 FXUtils .bindString (txtPreLaunchCommand , versionSetting .preLaunchCommandProperty ());
253297 FXUtils .bindString (txtPostExitCommand , versionSetting .postExitCommandProperty ());
254298 rendererPane .valueProperty ().bindBidirectional (versionSetting .rendererProperty ());
299+ graphicsBackendPane .valueProperty ().bindBidirectional (versionSetting .graphicsBackendProperty ());
255300 noGameCheckPane .selectedProperty ().bindBidirectional (versionSetting .notCheckGameProperty ());
256301 noJVMCheckPane .selectedProperty ().bindBidirectional (versionSetting .notCheckJVMProperty ());
257302 noJVMArgsPane .selectedProperty ().bindBidirectional (versionSetting .noJVMArgsProperty ());
@@ -294,6 +339,7 @@ void unbindProperties() {
294339 FXUtils .unbind (txtPreLaunchCommand , versionSetting .preLaunchCommandProperty ());
295340 FXUtils .unbind (txtPostExitCommand , versionSetting .postExitCommandProperty ());
296341 rendererPane .valueProperty ().unbindBidirectional (versionSetting .rendererProperty ());
342+ graphicsBackendPane .valueProperty ().unbindBidirectional (versionSetting .graphicsBackendProperty ());
297343 noGameCheckPane .selectedProperty ().unbindBidirectional (versionSetting .notCheckGameProperty ());
298344 noJVMCheckPane .selectedProperty ().unbindBidirectional (versionSetting .notCheckJVMProperty ());
299345 noJVMArgsPane .selectedProperty ().unbindBidirectional (versionSetting .noJVMArgsProperty ());
0 commit comments