Skip to content

Commit e550dfe

Browse files
authored
feat(rendering): Add support for multi sample anti-aliasing (MSAA) (TheSuperHackers#2454)
1 parent acf6797 commit e550dfe

10 files changed

Lines changed: 200 additions & 4 deletions

File tree

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,9 @@ void W3DDisplay::init()
710710
}
711711
}
712712

713+
// TheSuperHackers @feature Mauller 13/03/2026 Add native MSAA support, must be set before creating render device
714+
WW3D::Set_MSAA_Mode(WW3D::MULTISAMPLE_MODE_NONE);
715+
713716
renderDeviceError = WW3D::Set_Render_Device(
714717
0,
715718
getWidth(),

Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ const int DEFAULT_RESOLUTION_WIDTH = 640;
8787
const int DEFAULT_RESOLUTION_HEIGHT = 480;
8888
const int DEFAULT_BIT_DEPTH = 32;
8989
const int DEFAULT_TEXTURE_BIT_DEPTH = 16;
90+
const D3DMULTISAMPLE_TYPE DEFAULT_MSAA = D3DMULTISAMPLE_NONE;
9091

9192
bool DX8Wrapper_IsWindowed = true;
9293

@@ -110,6 +111,7 @@ int DX8Wrapper::BitDepth = DEFAULT_BIT_DEPTH;
110111
int DX8Wrapper::TextureBitDepth = DEFAULT_TEXTURE_BIT_DEPTH;
111112
bool DX8Wrapper::IsWindowed = false;
112113
D3DFORMAT DX8Wrapper::DisplayFormat = D3DFMT_UNKNOWN;
114+
D3DMULTISAMPLE_TYPE DX8Wrapper::MultiSampleAntiAliasing = DEFAULT_MSAA;
113115

114116
D3DMATRIX DX8Wrapper::old_world;
115117
D3DMATRIX DX8Wrapper::old_view;
@@ -951,7 +953,6 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int
951953
_PresentParameters.BackBufferHeight = ResolutionHeight;
952954
_PresentParameters.BackBufferCount = IsWindowed ? 1 : 2;
953955

954-
_PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
955956
_PresentParameters.SwapEffect = IsWindowed ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_FLIP; // Shouldn't this be D3DSWAPEFFECT_FLIP?
956957
_PresentParameters.hDeviceWindow = _Hwnd;
957958
_PresentParameters.Windowed = IsWindowed;
@@ -1024,7 +1025,7 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int
10241025
}
10251026

10261027
/*
1027-
** Time to actually create the device.
1028+
** Set default for depth stencil format if auto Z buffer failed.
10281029
*/
10291030
if (_PresentParameters.AutoDepthStencilFormat==D3DFMT_UNKNOWN) {
10301031
if (BitDepth==32) {
@@ -1035,6 +1036,40 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int
10351036
}
10361037
}
10371038

1039+
/*
1040+
** Check the devices support for the requested MSAA mode then setup the multi sample type
1041+
*/
1042+
if (MultiSampleAntiAliasing > D3DMULTISAMPLE_NONE) {
1043+
1044+
HRESULT hrBack = D3DInterface->CheckDeviceMultiSampleType(
1045+
CurRenderDevice,
1046+
D3DDEVTYPE_HAL,
1047+
_PresentParameters.BackBufferFormat,
1048+
IsWindowed,
1049+
MultiSampleAntiAliasing
1050+
);
1051+
1052+
HRESULT hrDepth = D3DInterface->CheckDeviceMultiSampleType(
1053+
CurRenderDevice,
1054+
D3DDEVTYPE_HAL,
1055+
_PresentParameters.AutoDepthStencilFormat,
1056+
IsWindowed,
1057+
MultiSampleAntiAliasing
1058+
);
1059+
1060+
if (FAILED(hrBack) || FAILED(hrDepth)) {
1061+
// IF we fail then disable MSAA entirely.
1062+
// External code needs to retrieve the configured MSAA mode after device creation
1063+
WWDEBUG_SAY(("Requested MSAA Mode Not Supported"));
1064+
MultiSampleAntiAliasing = D3DMULTISAMPLE_NONE;
1065+
}
1066+
}
1067+
1068+
_PresentParameters.MultiSampleType = MultiSampleAntiAliasing;
1069+
1070+
/*
1071+
** Time to actually create the device.
1072+
*/
10381073
StringClass displayFormat;
10391074
StringClass backbufferFormat;
10401075

Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,9 @@ class DX8Wrapper
590590
static void Set_Texture_Bitdepth(int depth) { WWASSERT(depth==16 || depth==32); TextureBitDepth = depth; }
591591
static int Get_Texture_Bitdepth() { return TextureBitDepth; }
592592

593+
static void Set_MSAA_Mode(D3DMULTISAMPLE_TYPE mode) { MultiSampleAntiAliasing = mode; }
594+
static D3DMULTISAMPLE_TYPE Get_MSAA_Mode() { return MultiSampleAntiAliasing; }
595+
593596
static void Set_Swap_Interval(int swap);
594597
static int Get_Swap_Interval();
595598
static void Set_Polygon_Mode(int mode);
@@ -628,6 +631,7 @@ class DX8Wrapper
628631
static int TextureBitDepth;
629632
static bool IsWindowed;
630633
static D3DFORMAT DisplayFormat;
634+
static D3DMULTISAMPLE_TYPE MultiSampleAntiAliasing;
631635

632636
static D3DMATRIX old_world;
633637
static D3DMATRIX old_view;

Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,52 @@ int WW3D::Get_Texture_Bitdepth()
20142014
return DX8Wrapper::Get_Texture_Bitdepth();
20152015
}
20162016

2017+
void WW3D::Set_MSAA_Mode(MultiSampleModeEnum mode)
2018+
{
2019+
switch (mode) {
2020+
2021+
default:
2022+
case MULTISAMPLE_MODE_NONE:
2023+
DX8Wrapper::Set_MSAA_Mode(D3DMULTISAMPLE_NONE);
2024+
break;
2025+
2026+
case MULTISAMPLE_MODE_2X:
2027+
DX8Wrapper::Set_MSAA_Mode(D3DMULTISAMPLE_2_SAMPLES);
2028+
break;
2029+
2030+
case MULTISAMPLE_MODE_4X:
2031+
DX8Wrapper::Set_MSAA_Mode(D3DMULTISAMPLE_4_SAMPLES);
2032+
break;
2033+
2034+
case MULTISAMPLE_MODE_8X:
2035+
DX8Wrapper::Set_MSAA_Mode(D3DMULTISAMPLE_8_SAMPLES);
2036+
break;
2037+
2038+
}
2039+
}
2040+
2041+
WW3D::MultiSampleModeEnum WW3D::Get_MSAA_Mode()
2042+
{
2043+
D3DMULTISAMPLE_TYPE type = DX8Wrapper::Get_MSAA_Mode();
2044+
2045+
switch (type) {
2046+
2047+
default:
2048+
case D3DMULTISAMPLE_NONE:
2049+
return MULTISAMPLE_MODE_NONE;
2050+
2051+
case D3DMULTISAMPLE_2_SAMPLES:
2052+
return MULTISAMPLE_MODE_2X;
2053+
2054+
case D3DMULTISAMPLE_4_SAMPLES:
2055+
return MULTISAMPLE_MODE_4X;
2056+
2057+
case D3DMULTISAMPLE_8_SAMPLES:
2058+
return MULTISAMPLE_MODE_8X;
2059+
2060+
}
2061+
}
2062+
20172063
void WW3D::Add_To_Static_Sort_List(RenderObjClass *robj, unsigned int sort_level)
20182064
{
20192065
CurrentStaticSortLists->Add_To_List(robj, sort_level);

Generals/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ class WW3D
7272
{
7373
public:
7474

75+
enum MultiSampleModeEnum {
76+
MULTISAMPLE_MODE_NONE,
77+
MULTISAMPLE_MODE_2X,
78+
MULTISAMPLE_MODE_4X,
79+
MULTISAMPLE_MODE_8X
80+
};
81+
7582
enum PrelitModeEnum {
7683
PRELIT_MODE_VERTEX,
7784
PRELIT_MODE_LIGHTMAP_MULTI_PASS,
@@ -259,6 +266,9 @@ class WW3D
259266
static void Set_Texture_Bitdepth(int bitdepth);
260267
static int Get_Texture_Bitdepth();
261268

269+
static void Set_MSAA_Mode(MultiSampleModeEnum mode);
270+
static MultiSampleModeEnum Get_MSAA_Mode();
271+
262272
static void Set_Mesh_Draw_Mode (MeshDrawModeEnum mode) { MeshDrawMode = mode; }
263273
static MeshDrawModeEnum Get_Mesh_Draw_Mode () { return (MeshDrawMode); }
264274

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,9 @@ void W3DDisplay::init()
761761
}
762762
}
763763

764+
// TheSuperHackers @feature Mauller 13/03/2026 Add native MSAA support, must be set before creating render device
765+
WW3D::Set_MSAA_Mode(WW3D::MULTISAMPLE_MODE_NONE);
766+
764767
renderDeviceError = WW3D::Set_Render_Device(
765768
0,
766769
getWidth(),

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ const int DEFAULT_RESOLUTION_WIDTH = 640;
9191
const int DEFAULT_RESOLUTION_HEIGHT = 480;
9292
const int DEFAULT_BIT_DEPTH = 32;
9393
const int DEFAULT_TEXTURE_BIT_DEPTH = 16;
94+
const D3DMULTISAMPLE_TYPE DEFAULT_MSAA = D3DMULTISAMPLE_NONE;
9495

9596
bool DX8Wrapper_IsWindowed = true;
9697

@@ -114,6 +115,7 @@ int DX8Wrapper::BitDepth = DEFAULT_BIT_DEPTH;
114115
int DX8Wrapper::TextureBitDepth = DEFAULT_TEXTURE_BIT_DEPTH;
115116
bool DX8Wrapper::IsWindowed = false;
116117
D3DFORMAT DX8Wrapper::DisplayFormat = D3DFMT_UNKNOWN;
118+
D3DMULTISAMPLE_TYPE DX8Wrapper::MultiSampleAntiAliasing = DEFAULT_MSAA;
117119

118120
D3DMATRIX DX8Wrapper::old_world;
119121
D3DMATRIX DX8Wrapper::old_view;
@@ -1025,7 +1027,6 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int
10251027
_PresentParameters.BackBufferHeight = ResolutionHeight;
10261028
_PresentParameters.BackBufferCount = IsWindowed ? 1 : 2;
10271029

1028-
_PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
10291030
//I changed this to discard all the time (even when full-screen) since that the most efficient. 07-16-03 MW:
10301031
_PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;//IsWindowed ? D3DSWAPEFFECT_DISCARD : D3DSWAPEFFECT_FLIP; // Shouldn't this be D3DSWAPEFFECT_FLIP?
10311032
_PresentParameters.hDeviceWindow = _Hwnd;
@@ -1099,7 +1100,7 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int
10991100
}
11001101

11011102
/*
1102-
** Time to actually create the device.
1103+
** Set default for depth stencil format if auto Z buffer failed.
11031104
*/
11041105
if (_PresentParameters.AutoDepthStencilFormat==D3DFMT_UNKNOWN) {
11051106
if (BitDepth==32) {
@@ -1110,6 +1111,40 @@ bool DX8Wrapper::Set_Render_Device(int dev, int width, int height, int bits, int
11101111
}
11111112
}
11121113

1114+
/*
1115+
** Check the devices support for the requested MSAA mode then setup the multi sample type
1116+
*/
1117+
if (MultiSampleAntiAliasing > D3DMULTISAMPLE_NONE) {
1118+
1119+
HRESULT hrBack = D3DInterface->CheckDeviceMultiSampleType(
1120+
CurRenderDevice,
1121+
D3DDEVTYPE_HAL,
1122+
_PresentParameters.BackBufferFormat,
1123+
IsWindowed,
1124+
MultiSampleAntiAliasing
1125+
);
1126+
1127+
HRESULT hrDepth = D3DInterface->CheckDeviceMultiSampleType(
1128+
CurRenderDevice,
1129+
D3DDEVTYPE_HAL,
1130+
_PresentParameters.AutoDepthStencilFormat,
1131+
IsWindowed,
1132+
MultiSampleAntiAliasing
1133+
);
1134+
1135+
if (FAILED(hrBack) || FAILED(hrDepth)) {
1136+
// IF we fail then disable MSAA entirely.
1137+
// External code needs to retrieve the configured MSAA mode after device creation
1138+
WWDEBUG_SAY(("Requested MSAA Mode Not Supported"));
1139+
MultiSampleAntiAliasing = D3DMULTISAMPLE_NONE;
1140+
}
1141+
}
1142+
1143+
_PresentParameters.MultiSampleType = MultiSampleAntiAliasing;
1144+
1145+
/*
1146+
** Time to actually create the device.
1147+
*/
11131148
StringClass displayFormat;
11141149
StringClass backbufferFormat;
11151150

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/dx8wrapper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,9 @@ class DX8Wrapper
599599
static void Set_Texture_Bitdepth(int depth) { WWASSERT(depth==16 || depth==32); TextureBitDepth = depth; }
600600
static int Get_Texture_Bitdepth() { return TextureBitDepth; }
601601

602+
static void Set_MSAA_Mode(D3DMULTISAMPLE_TYPE mode) { MultiSampleAntiAliasing = mode; }
603+
static D3DMULTISAMPLE_TYPE Get_MSAA_Mode() { return MultiSampleAntiAliasing; }
604+
602605
static void Set_Swap_Interval(int swap);
603606
static int Get_Swap_Interval();
604607
static void Set_Polygon_Mode(int mode);
@@ -637,6 +640,7 @@ class DX8Wrapper
637640
static int TextureBitDepth;
638641
static bool IsWindowed;
639642
static D3DFORMAT DisplayFormat;
643+
static D3DMULTISAMPLE_TYPE MultiSampleAntiAliasing;
640644

641645
static D3DMATRIX old_world;
642646
static D3DMATRIX old_view;

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,52 @@ int WW3D::Get_Texture_Bitdepth()
20172017
return DX8Wrapper::Get_Texture_Bitdepth();
20182018
}
20192019

2020+
void WW3D::Set_MSAA_Mode(MultiSampleModeEnum mode)
2021+
{
2022+
switch (mode) {
2023+
2024+
default:
2025+
case MULTISAMPLE_MODE_NONE:
2026+
DX8Wrapper::Set_MSAA_Mode(D3DMULTISAMPLE_NONE);
2027+
break;
2028+
2029+
case MULTISAMPLE_MODE_2X:
2030+
DX8Wrapper::Set_MSAA_Mode(D3DMULTISAMPLE_2_SAMPLES);
2031+
break;
2032+
2033+
case MULTISAMPLE_MODE_4X:
2034+
DX8Wrapper::Set_MSAA_Mode(D3DMULTISAMPLE_4_SAMPLES);
2035+
break;
2036+
2037+
case MULTISAMPLE_MODE_8X:
2038+
DX8Wrapper::Set_MSAA_Mode(D3DMULTISAMPLE_8_SAMPLES);
2039+
break;
2040+
2041+
}
2042+
}
2043+
2044+
WW3D::MultiSampleModeEnum WW3D::Get_MSAA_Mode()
2045+
{
2046+
D3DMULTISAMPLE_TYPE type = DX8Wrapper::Get_MSAA_Mode();
2047+
2048+
switch (type) {
2049+
2050+
default:
2051+
case D3DMULTISAMPLE_NONE:
2052+
return MULTISAMPLE_MODE_NONE;
2053+
2054+
case D3DMULTISAMPLE_2_SAMPLES:
2055+
return MULTISAMPLE_MODE_2X;
2056+
2057+
case D3DMULTISAMPLE_4_SAMPLES:
2058+
return MULTISAMPLE_MODE_4X;
2059+
2060+
case D3DMULTISAMPLE_8_SAMPLES:
2061+
return MULTISAMPLE_MODE_8X;
2062+
2063+
}
2064+
}
2065+
20202066
void WW3D::Add_To_Static_Sort_List(RenderObjClass *robj, unsigned int sort_level)
20212067
{
20222068
CurrentStaticSortLists->Add_To_List(robj, sort_level);

GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/ww3d.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ class WW3D
7272
{
7373
public:
7474

75+
enum MultiSampleModeEnum {
76+
MULTISAMPLE_MODE_NONE,
77+
MULTISAMPLE_MODE_2X,
78+
MULTISAMPLE_MODE_4X,
79+
MULTISAMPLE_MODE_8X
80+
};
81+
7582
enum PrelitModeEnum {
7683
PRELIT_MODE_VERTEX,
7784
PRELIT_MODE_LIGHTMAP_MULTI_PASS,
@@ -259,6 +266,9 @@ class WW3D
259266
static void Set_Texture_Bitdepth(int bitdepth);
260267
static int Get_Texture_Bitdepth();
261268

269+
static void Set_MSAA_Mode(MultiSampleModeEnum mode);
270+
static MultiSampleModeEnum Get_MSAA_Mode();
271+
262272
static void Set_Mesh_Draw_Mode (MeshDrawModeEnum mode) { MeshDrawMode = mode; }
263273
static MeshDrawModeEnum Get_Mesh_Draw_Mode () { return (MeshDrawMode); }
264274

0 commit comments

Comments
 (0)