Commit a669b865 authored by hybrid's avatar hybrid

Added better support for AntiAliasing levels, based on the patch by Sylence.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2032 dfc29bdd-3216-0410-991c-e03cc46cb475
parent ac8ee527
......@@ -25,7 +25,7 @@ namespace irr
Fullscreen(false),
Stencilbuffer(false),
Vsync(false),
AntiAlias(false),
AntiAlias(0),
WithAlphaChannel(false),
IgnoreInput(false),
HighPrecisionFPU(false),
......@@ -99,9 +99,11 @@ namespace irr
writing a game/application with AntiAlias switched on, it would
be a good idea to make it possible to switch this option off
again by the user.
This is curently not supported in OpenGL under Windows.
Default value: false */
bool AntiAlias;
Value one is usually the same as 0 (disabled), but might be a
special value on some platforms. On D3D devices it maps to
NONMASKABLE.
Default value: 0 - disabled */
u8 AntiAlias;
//! Whether the main framebuffer uses an alpha channel.
/** In some situations it might be desireable to get a color
......
......@@ -144,7 +144,7 @@ void CD3D8Driver::createMaterialRenderers()
//! initialises the Direct3D API
bool CD3D8Driver::initDriver(const core::dimension2d<s32>& screenSize,
HWND hwnd, u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, bool antiAlias)
bool highPrecisionFPU, bool vsync, u8 antiAlias)
{
HRESULT hr;
D3DLibrary = LoadLibrary( "d3d8.dll" );
......@@ -225,21 +225,26 @@ bool CD3D8Driver::initDriver(const core::dimension2d<s32>& screenSize,
#endif
// enable anti alias if possible and whished
if (antiAlias)
if (antiAlias > 0)
{
if (!FAILED(pID3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
devtype , present.BackBufferFormat, !fullScreen,
D3DMULTISAMPLE_2_SAMPLES)))
if(antiAlias > 16)
antiAlias = 16;
while(antiAlias > 0)
{
// enable multi sampling
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
present.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
if(!FAILED(pID3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
devtype , present.BackBufferFormat, !fullScreen,
(D3DMULTISAMPLE_TYPE)antiAlias)))
{
present.MultiSampleType = (D3DMULTISAMPLE_TYPE)antiAlias;
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
break;
}
--antiAlias;
}
else
{
if(antiAlias==0)
os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING);
antiAlias = false;
}
}
// check stencil buffer compatibility
......@@ -346,7 +351,7 @@ bool CD3D8Driver::initDriver(const core::dimension2d<s32>& screenSize,
setVertexShader(EVT_STANDARD);
// enable antialiasing
if (antiAlias)
if (antiAlias>0)
pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
// set fog mode
......@@ -2211,7 +2216,7 @@ namespace video
IVideoDriver* createDirectX8Driver(const core::dimension2d<s32>& screenSize,
HWND window, u32 bits, bool fullscreen, bool stencilbuffer,
io::IFileSystem* io, bool pureSoftware, bool highPrecisionFPU,
bool vsync, bool antiAlias)
bool vsync, u8 antiAlias)
{
CD3D8Driver* dx8 = new CD3D8Driver(screenSize, window, fullscreen,
stencilbuffer, io, pureSoftware);
......
......@@ -103,7 +103,7 @@ namespace video
//! initialises the Direct3D API
bool initDriver(const core::dimension2d<s32>& screenSize, HWND hwnd,
u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, bool antiAlias);
bool highPrecisionFPU, bool vsync, u8 antiAlias);
//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8
//! driver, it would return "Direct3D8.1".
......
......@@ -152,7 +152,7 @@ void CD3D9Driver::createMaterialRenderers()
//! initialises the Direct3D API
bool CD3D9Driver::initDriver(const core::dimension2d<s32>& screenSize,
HWND hwnd, u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, bool antiAlias)
bool highPrecisionFPU, bool vsync, u8 antiAlias)
{
HRESULT hr;
Fullscreen = fullScreen;
......@@ -271,43 +271,30 @@ bool CD3D9Driver::initDriver(const core::dimension2d<s32>& screenSize,
#endif
// enable anti alias if possible and desired
if (antiAlias)
if (antiAlias > 0)
{
if(antiAlias > 16)
antiAlias = 16;
DWORD qualityLevels = 0;
if (SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter,
devtype, present.BackBufferFormat, !fullScreen,
D3DMULTISAMPLE_4_SAMPLES, &qualityLevels)))
while(antiAlias > 0)
{
// enable multi sampling
present.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES;
present.MultiSampleQuality = qualityLevels-1;
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
}
else
if (SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter,
if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter,
devtype, present.BackBufferFormat, !fullScreen,
D3DMULTISAMPLE_2_SAMPLES, &qualityLevels)))
{
// enable multi sampling
present.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
present.MultiSampleQuality = qualityLevels-1;
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
}
else
if (SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter,
devtype, present.BackBufferFormat, !fullScreen,
D3DMULTISAMPLE_NONMASKABLE, &qualityLevels)))
{
// enable non maskable multi sampling
present.MultiSampleType = D3DMULTISAMPLE_NONMASKABLE;
present.MultiSampleQuality = qualityLevels-1;
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
(D3DMULTISAMPLE_TYPE)antiAlias, &qualityLevels)))
{
present.MultiSampleType = (D3DMULTISAMPLE_TYPE)antiAlias;
present.MultiSampleQuality = qualityLevels-1;
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
break;
}
--antiAlias;
}
else
if(antiAlias==0)
{
os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING);
antiAlias = false;
}
}
......@@ -418,7 +405,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<s32>& screenSize,
setVertexShader(EVT_STANDARD);
// enable antialiasing
if (antiAlias)
if (antiAlias!=0)
pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
// set fog mode
......@@ -2834,7 +2821,7 @@ namespace video
IVideoDriver* createDirectX9Driver(const core::dimension2d<s32>& screenSize,
HWND window, u32 bits, bool fullscreen, bool stencilbuffer,
io::IFileSystem* io, bool pureSoftware, bool highPrecisionFPU,
bool vsync, bool antiAlias)
bool vsync, u8 antiAlias)
{
CD3D9Driver* dx9 = new CD3D9Driver(screenSize, window, fullscreen, stencilbuffer, io, pureSoftware);
if (!dx9->initDriver(screenSize, window, bits, fullscreen, pureSoftware, highPrecisionFPU, vsync, antiAlias))
......
......@@ -136,7 +136,7 @@ namespace video
//! initialises the Direct3D API
bool initDriver(const core::dimension2d<s32>& screenSize, HWND hwnd,
u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, bool antiAlias);
bool highPrecisionFPU, bool vsync, u8 antiAlias);
//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8
//! driver, it would return "Direct3D8.1".
......
......@@ -301,7 +301,6 @@ bool CIrrDeviceLinux::createWindow()
{
if (major==1 && minor>2)
{
const int MAX_SAMPLES = 16;
// attribute array for the draw buffer
int visualAttrBuffer[] =
{
......@@ -314,13 +313,13 @@ bool CIrrDeviceLinux::createWindow()
GLX_DOUBLEBUFFER, GL_TRUE,
GLX_STENCIL_SIZE, 1,
GLX_SAMPLE_BUFFERS_ARB, 1,
GLX_SAMPLES_ARB, MAX_SAMPLES,
GLX_SAMPLES_ARB, AntiAlias,
None
};
GLXFBConfig *configList=0;
int nitems=0;
if (!CreationParams.AntiAlias)
if (CreationParams.AntiAlias<2)
{
visualAttrBuffer[17] = 0;
visualAttrBuffer[19] = 0;
......@@ -332,7 +331,7 @@ bool CIrrDeviceLinux::createWindow()
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] >>= 1;
visualAttrBuffer[19] -= 1;
configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
......@@ -343,13 +342,13 @@ bool CIrrDeviceLinux::createWindow()
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
CreationParams.AntiAlias=false;
CreationParams.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = MAX_SAMPLES;
visualAttrBuffer[19] = AntiAlias;
}
}
}
......@@ -367,7 +366,7 @@ bool CIrrDeviceLinux::createWindow()
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] >>= 1;
visualAttrBuffer[19] -= 1;
configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
......@@ -378,13 +377,13 @@ bool CIrrDeviceLinux::createWindow()
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
CreationParams.AntiAlias=false;
CreationParams.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = MAX_SAMPLES;
visualAttrBuffer[19] = AntiAlias;
}
}
}
......@@ -399,7 +398,7 @@ bool CIrrDeviceLinux::createWindow()
{
while (!configList && (visualAttrBuffer[19]>1))
{
visualAttrBuffer[19] >>= 1;
visualAttrBuffer[19] -= 1;
configList=glXChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
}
if (!configList)
......@@ -410,13 +409,13 @@ bool CIrrDeviceLinux::createWindow()
if (configList)
{
os::Printer::log("No FSAA available.", ELL_WARNING);
CreationParams.AntiAlias=false;
CreationParams.AntiAlias=0;
}
else
{
//reenable multisampling
visualAttrBuffer[17] = 1;
visualAttrBuffer[19] = MAX_SAMPLES;
visualAttrBuffer[19] = AntiAlias;
}
}
}
......
......@@ -148,10 +148,34 @@ bool CIrrDeviceSDL::createWindow()
}
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, CreationParams.ZBufferBits);
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
if (CreationParams.AntiAlias>1)
{
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias );
}
}
if ( !Screen )
Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags );
if ( !Screen && CreationParams.AntiAlias>1)
{
while (--CreationParams.AntiAlias>1)
{
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias );
Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags );
if (Screen)
break;
}
if ( !Screen )
{
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, 0 );
Screen = SDL_SetVideoMode( Width, Height, CreationParams.Bits, SDL_Flags );
if (Screen)
os::Printer::log("AntiAliasing disabled due to lack of support!" );
}
}
if ( !Screen )
{
os::Printer::log( "Could not initialize display!" );
......
......@@ -25,13 +25,13 @@ namespace irr
#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_
IVideoDriver* createDirectX8Driver(const core::dimension2d<s32>& screenSize, HWND window,
u32 bits, bool fullscreen, bool stencilbuffer, io::IFileSystem* io,
bool pureSoftware, bool highPrecisionFPU, bool vsync, bool antiAlias);
bool pureSoftware, bool highPrecisionFPU, bool vsync, u8 antiAlias);
#endif
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
IVideoDriver* createDirectX9Driver(const core::dimension2d<s32>& screenSize, HWND window,
u32 bits, bool fullscreen, bool stencilbuffer, io::IFileSystem* io,
bool pureSoftware, bool highPrecisionFPU, bool vsync, bool antiAlias);
bool pureSoftware, bool highPrecisionFPU, bool vsync, u8 antiAlias);
#endif
#ifdef _IRR_COMPILE_WITH_OPENGL_
......
......@@ -71,7 +71,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params)
GLuint PixelFormat;
if (AntiAlias)
if (AntiAlias > 1)
{
// Create a window to test antialiasing support
const c8* ClassName = "GLCIrrDeviceWin32";
......@@ -79,19 +79,19 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params)
// Register Class
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)DefWindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = lhInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = ClassName;
wcex.hIconSm = 0;
wcex.hIcon = 0;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = lhInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = ClassName;
wcex.hIconSm = 0;
wcex.hIcon = 0;
RegisterClassEx(&wcex);
RECT clientSize;
......@@ -186,15 +186,14 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params)
if(wglChoosePixelFormat_ARB)
{
// This value determines the number of samples used for antialiasing
// valid numbers are 2, 4, 8. My experience is that 8 does not
// show a big improvement over 4, but 4 shows a big improvement over
// 2.
const s32 numSamples = 4;
f32 fAttributes[] =
{
0.0, 0.0
};
// My experience is that 8 does not show a big
// improvement over 4, but 4 shows a big improvement
// over 2.
if(AntiAlias > 16)
AntiAlias = 16;
f32 fAttributes[] = {0.0, 0.0};
s32 iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
......@@ -205,12 +204,12 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params)
WGL_DEPTH_BITS_ARB,params.ZBufferBits,
WGL_STENCIL_BITS_ARB,(params.Stencilbuffer) ? 1 : 0,
WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
WGL_SAMPLES_ARB,numSamples,
WGL_SAMPLE_BUFFERS_ARB, 1,
WGL_SAMPLES_ARB,AntiAlias,
0,0
};
s32 rv=0;
s32 rv=0;
// Try to get an acceptable pixel format
while(rv==0 && iAttributes[19]>1)
{
......@@ -221,11 +220,16 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params)
if(valid && numFormats>0)
rv = pixelFormat;
else
iAttributes[19] >>= 1;
iAttributes[19] -= 1;
}
if(rv)
{
PixelFormat=rv;
AntiAlias=iAttributes[19];
}
}
else
AntiAlias=0;
wglMakeCurrent(HDc, NULL);
wglDeleteContext(HRc);
......@@ -242,7 +246,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params)
}
// search for pixel format the simple way
if (!AntiAlias)
if (AntiAlias < 2)
{
for (u32 i=0; i<5; ++i)
{
......@@ -505,7 +509,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<s32>& screenSize,
glDepthFunc(GL_LEQUAL);
glFrontFace( GL_CW );
if (AntiAlias)
if (AntiAlias >= 2)
{
if (MultiSamplingExtension)
glEnable(GL_MULTISAMPLE_ARB);
......
......@@ -385,7 +385,7 @@ namespace video
//! bool to make all renderstates reset if set to true.
bool ResetRenderStates;
bool Transformation3DChanged;
bool AntiAlias;
u8 AntiAlias;
SMaterial Material, LastMaterial;
COpenGLTexture* RenderTargetTexture;
......
Test suite pass at GMT Sun Jan 04 15:10:29 2009
Test suite pass at GMT Sun Jan 04 16:23:39 2009
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment