diff --git a/code/lab/renderer/lab_renderer.cpp b/code/lab/renderer/lab_renderer.cpp index eec2c2d1813..df95ad37889 100644 --- a/code/lab/renderer/lab_renderer.cpp +++ b/code/lab/renderer/lab_renderer.cpp @@ -387,6 +387,7 @@ void LabRenderer::useBackground(const SCP_string& mission_name) { currentMissionBackground = mission_name; stars_pre_level_init(true); + Nebula_over_skybox = false; vm_set_identity(&skybox_orientation); // (DahBlount) - Remember to load the debris anims @@ -584,6 +585,10 @@ void LabRenderer::useBackground(const SCP_string& mission_name) { stuff_string(envmap_name, F_NAME, MAX_FILENAME_LEN); } + if (optional_string("$FS1 Nebula Over Skybox:")) { + stuff_boolean(&Nebula_over_skybox); + } + const int size = 512; int gen_flags = (BMP_FLAG_RENDER_TARGET_STATIC | BMP_FLAG_CUBEMAP | BMP_FLAG_RENDER_TARGET_MIPMAP); diff --git a/code/mission/missionparse.cpp b/code/mission/missionparse.cpp index cccd93941ea..b883c87f553 100644 --- a/code/mission/missionparse.cpp +++ b/code/mission/missionparse.cpp @@ -6468,6 +6468,10 @@ void parse_bitmaps(mission *pm) stuff_string(pm->envmap_name, F_NAME, MAX_FILENAME_LEN); } + if (optional_string("$FS1 Nebula Over Skybox:")) { + stuff_boolean(&Nebula_over_skybox); + } + // bypass spurious stuff from e.g. FS1 missions skip_to_start_of_string("#"); } @@ -7501,6 +7505,7 @@ void mission_init(mission *pm, bool quick_init) Nebula_bank = (int)((float)(Random::next() & 0x0fff) * 360.0f / 4096.0f); Nebula_heading = (int)((float)(Random::next() & 0x0fff) * 360.0f / 4096.0f); Nebula_index = -1; + Nebula_over_skybox = false; Mission_palette = 1; } diff --git a/code/missioneditor/missionsave.cpp b/code/missioneditor/missionsave.cpp index 6f57eba347f..68ef82518de 100644 --- a/code/missioneditor/missionsave.cpp +++ b/code/missioneditor/missionsave.cpp @@ -1089,6 +1089,17 @@ int Fred_mission_save::save_bitmaps() bypass_comment(";;FSO 3.6.9;; $Environment Map:"); } + if (Nebula_over_skybox && Nebula_index >= 0 && !The_mission.flags[Mission::Mission_Flags::Fullneb]) { + fso_comment_push(";;FSO 26.1.0;;"); + if (optional_string_fred("$FS1 Nebula Over Skybox:")) { + parse_comments(2); + fout(" YES"); + } else { + fout_version("\n\n$FS1 Nebula Over Skybox: YES"); + } + fso_comment_pop(); + } + fso_comment_pop(true); return err; diff --git a/code/mod_table/mod_table.cpp b/code/mod_table/mod_table.cpp index 2ca750af08c..73ed0b83a7c 100644 --- a/code/mod_table/mod_table.cpp +++ b/code/mod_table/mod_table.cpp @@ -29,6 +29,7 @@ int Directive_wait_time; bool True_loop_argument_sexps; bool Skybox_internal_depth_consistency; +bool Fs1_nebula_backgrounds; bool Fixed_turret_collisions; bool Fixed_missile_detonation; bool Damage_impacted_subsystem_first; @@ -979,6 +980,10 @@ void parse_mod_table(const char *filename) stuff_boolean(&Render_insignias_as_decals); } + if (optional_string("$FS1 nebula backgrounds:")) { + stuff_boolean(&Fs1_nebula_backgrounds); + } + optional_string("#NETWORK SETTINGS"); if (optional_string("$FS2NetD port:")) { @@ -1677,6 +1682,9 @@ static void mod_table_log_settings() else mprintf(("Game Settings Table: Skybox submodels will not use internal depth consistency (retail behavior)\n")); + if (Fs1_nebula_backgrounds) + mprintf(("Game Settings Table: FS1 nebula backgrounds will be drawn for missions that name one\n")); + if (Fixed_turret_collisions) mprintf(("Game Settings Table: Using fixed turret collisions (shooting a turret barrel will always register)\n")); else @@ -1865,6 +1873,7 @@ void mod_table_reset() Directive_wait_time = 3000; True_loop_argument_sexps = false; Skybox_internal_depth_consistency = false; + Fs1_nebula_backgrounds = false; Fixed_turret_collisions = false; Fixed_missile_detonation = false; Damage_impacted_subsystem_first = false; diff --git a/code/mod_table/mod_table.h b/code/mod_table/mod_table.h index d502f96098b..2bcc8b3f47b 100644 --- a/code/mod_table/mod_table.h +++ b/code/mod_table/mod_table.h @@ -49,6 +49,7 @@ struct splash_screen { extern int Directive_wait_time; extern bool True_loop_argument_sexps; extern bool Skybox_internal_depth_consistency; +extern bool Fs1_nebula_backgrounds; extern bool Fixed_turret_collisions; extern bool Fixed_missile_detonation; extern bool Damage_impacted_subsystem_first; diff --git a/code/starfield/nebula.cpp b/code/starfield/nebula.cpp index c2718799fd8..b4611dda11d 100644 --- a/code/starfield/nebula.cpp +++ b/code/starfield/nebula.cpp @@ -9,12 +9,16 @@ +#include "bmpman/bmpman.h" #include "cfile/cfile.h" #include "debugconsole/console.h" #include "math/vecmat.h" #include "mission/missionparse.h" +#include "mod_table/mod_table.h" #include "nebula/neb.h" #include "graphics/material.h" +#include "graphics/matrix.h" +#include "pcxutils/pcxutils.h" #include "render/3d.h" #include "starfield/nebula.h" @@ -32,15 +36,28 @@ static int num_tris = 0; static int tri[MAX_TRIS][3]; static int Nebula_loaded = 0; + +constexpr int NEBULA_RAMP_SIZE = 20; + +static int Nebula_ramp_bitmap = -1; +static ubyte Nebula_ramp_pixels[NEBULA_RAMP_SIZE * 4]; +// too large for the stack; the immediate primitive path copies it at call time +static vertex Nebula_tri_verts[MAX_TRIS * 3]; static angles Nebula_pbh; static matrix Nebula_orient; int Nebula_pitch; int Nebula_bank; int Nebula_heading; +bool Nebula_over_skybox = false; void nebula_close() { + if (Nebula_ramp_bitmap >= 0) { + bm_release(Nebula_ramp_bitmap); + Nebula_ramp_bitmap = -1; + } + if (!Nebula_loaded) return; Nebula_loaded = 0; @@ -82,6 +99,7 @@ int load_nebula_sub(const char *filename) fp = cfopen(filename, "rb"); if ( !fp ) { + mprintf(( "Nebula file %s could not be opened.\n", filename )); return 0; } @@ -89,6 +107,7 @@ int load_nebula_sub(const char *filename) cfread( id, 4, 1, fp ); if ( strncmp( id, NEBULA_FILE_ID, 4) != 0) { mprintf(( "Not a valid nebula file.\n" )); + cfclose(fp); return 0; } cfread( &version, sizeof(int), 1, fp ); @@ -96,6 +115,7 @@ int load_nebula_sub(const char *filename) if ( major != NEBULA_MAJOR_VERSION ) { mprintf(( "An out of date nebula file.\n" )); + cfclose(fp); return 0; } @@ -105,8 +125,10 @@ int load_nebula_sub(const char *filename) Assert( num_tris < MAX_TRIS ); // Cyborg - can't load nonsense. - if (num_pts <= 0 || num_pts >= MAX_POINTS || num_tris <= 0 || num_tris >= MAX_TRIS) + if (num_pts <= 0 || num_pts >= MAX_POINTS || num_tris <= 0 || num_tris >= MAX_TRIS) { + cfclose(fp); return 0; + } int i; for (i=0; i= num_pts) { + mprintf(( "Nebula file %s has a triangle index out of range.\n", filename )); + cfclose(fp); + return 0; + } + } } cfclose(fp); @@ -134,6 +164,34 @@ int load_nebula_sub(const char *filename) return 1; } +// one-row texture of the FS1 palette's first NEBULA_RAMP_SIZE entries, so the GPU interpolates in ramp +// space rather than in RGB between vertex colours +static void nebula_load_ramp(int nebula_index, int palette_index) +{ + if (Nebula_ramp_bitmap >= 0) { + bm_release(Nebula_ramp_bitmap); + Nebula_ramp_bitmap = -1; + } + + char filename[MAX_FILENAME_LEN]; + sprintf_safe(filename, "gamepalette%d-%02d", nebula_index + 1, palette_index + 1); + + ubyte palette[768] = {}; + if (pcx_read_header(filename, nullptr, nullptr, nullptr, nullptr, palette) != PCX_ERROR_NONE) { + mprintf(( "FS1 nebula palette %s.pcx could not be read; the nebula will not be drawn.\n", filename )); + return; + } + + for (int i = 0; i < NEBULA_RAMP_SIZE; i++) { + Nebula_ramp_pixels[i * 4 + 0] = palette[i * 3 + 2]; + Nebula_ramp_pixels[i * 4 + 1] = palette[i * 3 + 1]; + Nebula_ramp_pixels[i * 4 + 2] = palette[i * 3 + 0]; + Nebula_ramp_pixels[i * 4 + 3] = 255; + } + + Nebula_ramp_bitmap = bm_create(32, NEBULA_RAMP_SIZE, 1, Nebula_ramp_pixels, 0); +} + void nebula_init( int index, int pitch, int bank, int heading ) { angles a; @@ -143,6 +201,10 @@ void nebula_init( int index, int pitch, int bank, int heading ) a.h = fl_radians(heading); nebula_init(index < 0 ? nullptr : Nebula_filenames[index], &a); + + if (index >= 0 && Nebula_loaded && Fs1_nebula_backgrounds) { + nebula_load_ramp(index, Mission_palette); + } } void nebula_init( const char *filename, angles * pbh ) @@ -167,6 +229,43 @@ void nebula_init( const char *filename, angles * pbh ) } } +void nebula_render(bool over_skybox) +{ + if (!Fs1_nebula_backgrounds || !Nebula_loaded || Nebula_ramp_bitmap < 0) { + return; + } + if (!Detail.planets_suns) { + return; + } + + // g3_rotate_faraway_vertex would give eye-space points, which this primitive path would transform again + gr_start_instance_matrix(&Eye_position, &Nebula_orient); + + for (int i = 0; i < num_pts; i++) { + nebula_verts[i].world = nebula_vecs[i]; + // map the brightness onto texel centres so the extremes land on the first and last ramp colours + nebula_verts[i].texture_position.u = + (0.5f + (NEBULA_RAMP_SIZE - 1) * (nebula_verts[i].b / 255.0f)) / NEBULA_RAMP_SIZE; + nebula_verts[i].texture_position.v = 0.5f; + } + + for (int i = 0; i < num_tris; i++) { + Nebula_tri_verts[i * 3 + 0] = nebula_verts[tri[i][0]]; + Nebula_tri_verts[i * 3 + 1] = nebula_verts[tri[i][1]]; + Nebula_tri_verts[i * 3 + 2] = nebula_verts[tri[i][2]]; + } + + material mat; + material_set_unlit(&mat, Nebula_ramp_bitmap, 1.0f, true, false); + if (over_skybox) { + // the ramp's dark end is black, so adding leaves the skybox and its stars where the nebula is faint + mat.set_blend_mode(ALPHA_BLEND_ADDITIVE); + } + g3_render_primitives_textured(&mat, Nebula_tri_verts, num_tris * 3, PRIM_TYPE_TRIS, false); + + gr_end_instance_matrix(); +} + DCF(nebula,"Loads a different nebula") { SCP_string filename; diff --git a/code/starfield/nebula.h b/code/starfield/nebula.h index 2d6f86add9d..31daa360398 100644 --- a/code/starfield/nebula.h +++ b/code/starfield/nebula.h @@ -24,5 +24,8 @@ struct angles; void nebula_init( int index, int pitch, int bank, int heading ); void nebula_init( const char *filename, angles *pbh = /*NULL*/ 0 ); void nebula_close(); +void nebula_render(bool over_skybox); + +extern bool Nebula_over_skybox; #endif //_NEBULA_H diff --git a/code/starfield/starfield.cpp b/code/starfield/starfield.cpp index a90ede83880..e110bdc835d 100644 --- a/code/starfield/starfield.cpp +++ b/code/starfield/starfield.cpp @@ -1928,7 +1928,7 @@ void stars_draw_motion_debris() refresh_motion_debris = false; } -void stars_draw(int show_stars, int show_suns, int /*show_nebulas*/, int show_subspace, int env, bool in_mission) +void stars_draw(int show_stars, int show_suns, int show_nebulas, int show_subspace, int env, bool in_mission) { GR_DEBUG_SCOPE("Draw Stars"); TRACE_SCOPE(tracing::DrawStars); @@ -1966,6 +1966,10 @@ void stars_draw(int show_stars, int show_suns, int /*show_nebulas*/, int show_s stars_draw_background(); } + if ( show_nebulas && (Nmodel_num < 0 || Nebula_over_skybox) && (Game_detail_flags & DETAIL_FLAG_NEBULAS) && !(The_mission.flags[Mission::Mission_Flags::Fullneb]) ) { + nebula_render(Nmodel_num >= 0); + } + if ( !env && show_stars && (Nmodel_num < 0) && (Game_detail_flags & DETAIL_FLAG_STARS) && !(The_mission.flags[Mission::Mission_Flags::Fullneb]) && (supernova_stage() < SUPERNOVA_STAGE::TOOLTIME) ) { stars_draw_stars(); } diff --git a/fred2/bgbitmapdlg.cpp b/fred2/bgbitmapdlg.cpp index 74e34e88bb1..a7b68f6d13b 100644 --- a/fred2/bgbitmapdlg.cpp +++ b/fred2/bgbitmapdlg.cpp @@ -50,6 +50,7 @@ bg_bitmap_dlg::bg_bitmap_dlg(CWnd* pParent) : CDialog(bg_bitmap_dlg::IDD, pParen m_pitch = 0; m_neb2_texture = 0; m_subspace = FALSE; + m_nebula_over_skybox = FALSE; m_fullneb = FALSE; m_fog_color_override = FALSE; m_fullneb_background_bitmaps = FALSE; @@ -101,6 +102,7 @@ void bg_bitmap_dlg::DoDataExchange(CDataExchange* pDX) DDX_Control(pDX, IDC_SLIDER1, m_slider); DDX_CBIndex(pDX, IDC_NEB2_TEXTURE, m_neb2_texture); DDX_Check(pDX, IDC_SUBSPACE, m_subspace); + DDX_Check(pDX, IDC_NEB_OVER_SKYBOX, m_nebula_over_skybox); DDX_Check(pDX, IDC_FULLNEB, m_fullneb); DDX_Check(pDX, IDC_NEB2_PALETTE_OVERRIDE, m_fog_color_override); DDX_Check(pDX, IDC_NEB2_BACKGROUND_BITMAPS, m_fullneb_background_bitmaps); @@ -339,8 +341,10 @@ void bg_bitmap_dlg::create() m_nebula_index = Nebula_index + 1; m_nebula_color = Mission_palette; + m_nebula_over_skybox = Nebula_over_skybox ? 1 : 0; if (Nebula_index < 0){ GetDlgItem(IDC_NEBCOLOR)->EnableWindow(FALSE); + GetDlgItem(IDC_NEB_OVER_SKYBOX)->EnableWindow(FALSE); } m_pitch = Nebula_pitch; @@ -506,6 +510,7 @@ void bg_bitmap_dlg::OnClose() Nebula_pitch = m_pitch; Nebula_bank = m_bank; Nebula_heading = m_heading; + Nebula_over_skybox = m_nebula_over_skybox != 0; nebula_init(Nebula_index, m_pitch, m_bank, m_heading); The_mission.flags.set(Mission::Mission_Flags::Subspace, m_subspace != 0); @@ -601,6 +606,7 @@ void bg_bitmap_dlg::OnSelchangeNebcolor() UpdateData(TRUE); Mission_palette = m_nebula_color; + nebula_init(Nebula_index, m_pitch, m_bank, m_heading); Update_window = 1; } @@ -615,6 +621,7 @@ void bg_bitmap_dlg::OnSelchangeNebpattern() Nebula_index = m_nebula_index - 1; GetDlgItem(IDC_NEBCOLOR)->EnableWindow(m_nebula_index ? TRUE : FALSE); + GetDlgItem(IDC_NEB_OVER_SKYBOX)->EnableWindow(m_nebula_index ? TRUE : FALSE); nebula_init(Nebula_index, m_pitch, m_bank, m_heading); Update_window = 1; @@ -678,6 +685,7 @@ void bg_bitmap_dlg::OnFullNeb() // disable non-fullneb controls GetDlgItem(IDC_NEBPATTERN)->EnableWindow(FALSE); GetDlgItem(IDC_NEBCOLOR)->EnableWindow(FALSE); + GetDlgItem(IDC_NEB_OVER_SKYBOX)->EnableWindow(FALSE); GetDlgItem(IDC_PITCH)->EnableWindow(FALSE); GetDlgItem(IDC_BANK)->EnableWindow(FALSE); GetDlgItem(IDC_HEADING)->EnableWindow(FALSE); @@ -685,6 +693,7 @@ void bg_bitmap_dlg::OnFullNeb() // enable all non-fullneb controls GetDlgItem(IDC_NEBPATTERN)->EnableWindow(TRUE); GetDlgItem(IDC_NEBCOLOR)->EnableWindow(TRUE); + GetDlgItem(IDC_NEB_OVER_SKYBOX)->EnableWindow(TRUE); GetDlgItem(IDC_PITCH)->EnableWindow(TRUE); GetDlgItem(IDC_BANK)->EnableWindow(TRUE); GetDlgItem(IDC_HEADING)->EnableWindow(TRUE); diff --git a/fred2/bgbitmapdlg.h b/fred2/bgbitmapdlg.h index 96c8d61b8f7..72d0a55ed24 100644 --- a/fred2/bgbitmapdlg.h +++ b/fred2/bgbitmapdlg.h @@ -56,6 +56,7 @@ class bg_bitmap_dlg : public CDialog CSliderCtrl m_slider; int m_neb2_texture; BOOL m_subspace; + BOOL m_nebula_over_skybox; BOOL m_fullneb; BOOL m_fog_color_override; BOOL m_fullneb_background_bitmaps; diff --git a/fred2/fred.rc b/fred2/fred.rc index d69261b8939..f6e66a88629 100644 --- a/fred2/fred.rc +++ b/fred2/fred.rc @@ -1813,6 +1813,7 @@ BEGIN CONTROL "Toggle ship trails",IDC_NEB2_TOGGLE_TRAILS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,250,65,10 COMBOBOX IDC_NEBPATTERN,42,405,61,108,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_NEBCOLOR,42,421,61,108,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Draw over skybox",IDC_NEB_OVER_SKYBOX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,437,90,10 EDITTEXT IDC_PITCH,166,388,40,14,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_BANK,166,405,40,14,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_HEADING,166,422,40,14,ES_AUTOHSCROLL | ES_NUMBER diff --git a/fred2/resource.h b/fred2/resource.h index f03b894bf21..ff8aa446e5a 100644 --- a/fred2/resource.h +++ b/fred2/resource.h @@ -563,6 +563,7 @@ #define IDC_SET_FROM_SHIP_CLASS 1203 #define IDC_CURRENT_CONTAINER_NAME 1203 #define IDC_NEBCOLOR 1204 +#define IDC_NEB_OVER_SKYBOX 1747 #define IDC_SUBSTITUTE_EVENT_MUSIC 1205 #define IDC_OPEN_CUSTOM_DATA 1206 #define IDC_AI_PROFILE 1207 @@ -1638,7 +1639,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 340 -#define _APS_NEXT_CONTROL_VALUE 1747 +#define _APS_NEXT_CONTROL_VALUE 1748 #define _APS_NEXT_COMMAND_VALUE 33124 #define _APS_NEXT_SYMED_VALUE 105 #endif diff --git a/qtfred/src/mission/dialogs/BackgroundEditorDialogModel.cpp b/qtfred/src/mission/dialogs/BackgroundEditorDialogModel.cpp index 5c1e47c175f..783e1c8f309 100644 --- a/qtfred/src/mission/dialogs/BackgroundEditorDialogModel.cpp +++ b/qtfred/src/mission/dialogs/BackgroundEditorDialogModel.cpp @@ -1028,6 +1028,7 @@ void BackgroundEditorDialogModel::setOldNebulaPattern(const SCP_string& name) } modify(Nebula_index, newIndex); + nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading); } SCP_string BackgroundEditorDialogModel::getOldNebulaColorName() @@ -1045,12 +1046,23 @@ void BackgroundEditorDialogModel::setOldNebulaColorName(const SCP_string& name) for (int i = 0; i < NUM_NEBULA_COLORS; ++i) { if (!stricmp(Nebula_colors[i], name.c_str())) { modify(Mission_palette, i); + nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading); return; } } // name not found: ignore } +bool BackgroundEditorDialogModel::getOldNebulaOverSkybox() +{ + return Nebula_over_skybox; +} + +void BackgroundEditorDialogModel::setOldNebulaOverSkybox(bool over) +{ + modify(Nebula_over_skybox, over); +} + int BackgroundEditorDialogModel::getOldNebulaPitch() { return Nebula_pitch; @@ -1062,6 +1074,7 @@ void BackgroundEditorDialogModel::setOldNebulaPitch(int deg) if (Nebula_pitch != deg) { Nebula_pitch = deg; modify(Nebula_pitch, deg); + nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading); } } @@ -1076,6 +1089,7 @@ void BackgroundEditorDialogModel::setOldNebulaBank(int deg) if (Nebula_bank != deg) { Nebula_bank = deg; modify(Nebula_bank, deg); + nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading); } } @@ -1090,6 +1104,7 @@ void BackgroundEditorDialogModel::setOldNebulaHeading(int deg) if (Nebula_heading != deg) { Nebula_heading = deg; modify(Nebula_heading, deg); + nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading); } } diff --git a/qtfred/src/mission/dialogs/BackgroundEditorDialogModel.h b/qtfred/src/mission/dialogs/BackgroundEditorDialogModel.h index 36118b3aa8d..d7a6f595d13 100644 --- a/qtfred/src/mission/dialogs/BackgroundEditorDialogModel.h +++ b/qtfred/src/mission/dialogs/BackgroundEditorDialogModel.h @@ -125,6 +125,8 @@ class BackgroundEditorDialogModel : public AbstractDialogModel { static SCP_vector getOldNebulaColorOptions(); static SCP_string getOldNebulaColorName(); void setOldNebulaColorName(const SCP_string& name); + static bool getOldNebulaOverSkybox(); + void setOldNebulaOverSkybox(bool over); static SCP_string getOldNebulaPattern(); void setOldNebulaPattern(const SCP_string& name); static int getOldNebulaPitch(); diff --git a/qtfred/src/ui/dialogs/BackgroundEditorDialog.cpp b/qtfred/src/ui/dialogs/BackgroundEditorDialog.cpp index 075274477ed..59e0aabc431 100644 --- a/qtfred/src/ui/dialogs/BackgroundEditorDialog.cpp +++ b/qtfred/src/ui/dialogs/BackgroundEditorDialog.cpp @@ -334,12 +334,14 @@ void BackgroundEditorDialog::updateOldNebulaControls() ui->oldNebulaPatternCombo->setEnabled(enabled); ui->oldNebulaColorCombo->setEnabled(enabled && old_enabled); + ui->oldNebulaOverSkyboxCheck->setEnabled(enabled && old_enabled); ui->oldNebulaPitchSpinBox->setEnabled(enabled && old_enabled); ui->oldNebulaBankSpinBox->setEnabled(enabled && old_enabled); ui->oldNebulaHeadingSpinBox->setEnabled(enabled && old_enabled); ui->oldNebulaPatternCombo->setCurrentIndex(ui->oldNebulaPatternCombo->findText(QString::fromStdString(_model->getOldNebulaPattern()))); ui->oldNebulaColorCombo->setCurrentIndex(ui->oldNebulaColorCombo->findText(QString::fromStdString(_model->getOldNebulaColorName()))); + ui->oldNebulaOverSkyboxCheck->setChecked(_model->getOldNebulaOverSkybox()); ui->oldNebulaPitchSpinBox->setValue(_model->getOldNebulaPitch()); ui->oldNebulaBankSpinBox->setValue(_model->getOldNebulaBank()); ui->oldNebulaHeadingSpinBox->setValue(_model->getOldNebulaHeading()); @@ -813,6 +815,11 @@ void BackgroundEditorDialog::on_oldNebulaColorCombo_currentIndexChanged(int inde _model->setOldNebulaColorName(text.toUtf8().constData()); } +void BackgroundEditorDialog::on_oldNebulaOverSkyboxCheck_toggled(bool checked) +{ + _model->setOldNebulaOverSkybox(checked); +} + void BackgroundEditorDialog::on_oldNebulaPitchSpinBox_valueChanged(int arg1) { _model->setOldNebulaPitch(arg1); diff --git a/qtfred/src/ui/dialogs/BackgroundEditorDialog.h b/qtfred/src/ui/dialogs/BackgroundEditorDialog.h index 42ea46fb77f..8b44fb9f5ec 100644 --- a/qtfred/src/ui/dialogs/BackgroundEditorDialog.h +++ b/qtfred/src/ui/dialogs/BackgroundEditorDialog.h @@ -73,6 +73,7 @@ private slots: // Old Nebula void on_oldNebulaPatternCombo_currentIndexChanged(int index); void on_oldNebulaColorCombo_currentIndexChanged(int index); + void on_oldNebulaOverSkyboxCheck_toggled(bool checked); void on_oldNebulaPitchSpinBox_valueChanged(int arg1); void on_oldNebulaBankSpinBox_valueChanged(int arg1); void on_oldNebulaHeadingSpinBox_valueChanged(int arg1); diff --git a/qtfred/ui/BackgroundEditor.ui b/qtfred/ui/BackgroundEditor.ui index 779d8ab0311..24d3e842344 100644 --- a/qtfred/ui/BackgroundEditor.ui +++ b/qtfred/ui/BackgroundEditor.ui @@ -731,6 +731,16 @@ + + + + Draw the FS1 nebula over the skybox model with additive blending; without this a skybox hides it + + + Draw over skybox + + + @@ -1190,6 +1200,7 @@ lightingProfileCombo oldNebulaPatternCombo oldNebulaColorCombo + oldNebulaOverSkyboxCheck oldNebulaPitchSpinBox oldNebulaBankSpinBox oldNebulaHeadingSpinBox