Commit 540c3396 authored by hybrid's avatar hybrid

Changed createOpenGLDriver to use SIrrlichtCreationParameters.

Added Fullscreen AntiAliasing for Win32/OpenGL. Screenshot not working in this mode ATM.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1713 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 9136b843
......@@ -35,9 +35,7 @@ namespace irr
#endif
#ifdef _IRR_COMPILE_WITH_OPENGL_
IVideoDriver* createOpenGLDriver(const core::dimension2d<s32>& screenSize, HWND window,
u32 bits, bool stencilBuffer, io::IFileSystem* io,
bool vsync, bool antiAlias);
IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io);
#endif
}
} // end namespace irr
......@@ -293,7 +291,6 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
IsNonNTWindows(false), Resized(false),
ExternalWindow(false), Win32CursorControl(0)
{
#ifdef _DEBUG
setDebugName("CIrrDeviceWin32");
#endif
......@@ -363,6 +360,7 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
HWnd = CreateWindow( ClassName, "", style, windowLeft, windowTop,
realWidth, realHeight, NULL, NULL, hInstance, NULL);
CreationParams.WindowId = HWnd;
ShowWindow(HWnd, SW_SHOW);
UpdateWindow(HWnd);
......@@ -370,10 +368,9 @@ CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params)
// fix ugly ATI driver bugs. Thanks to ariaci
MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE);
}
// attach external window
if (CreationParams.WindowId)
else if (CreationParams.WindowId)
{
// attach external window
HWnd = static_cast<HWND>(CreationParams.WindowId);
RECT r;
GetWindowRect(HWnd, &r);
......@@ -478,9 +475,7 @@ void CIrrDeviceWin32::createDriver()
if (CreationParams.Fullscreen)
switchToFullScreen(CreationParams.WindowSize.Width, CreationParams.WindowSize.Height, CreationParams.Bits);
VideoDriver = video::createOpenGLDriver(CreationParams.WindowSize, HWnd, CreationParams.Bits,
CreationParams.Stencilbuffer, FileSystem,
CreationParams.Vsync, CreationParams.AntiAlias);
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem);
if (!VideoDriver)
{
os::Printer::log("Could not create OpenGL driver.", ELL_ERROR);
......
......@@ -40,9 +40,7 @@ namespace irr
#endif
#ifdef _IRR_COMPILE_WITH_OPENGL_
IVideoDriver* createOpenGLDriver(const core::dimension2d<s32>& screenSize, HWND window,
u32 bits, bool fullscreen, bool stencilBuffer, io::IFileSystem* io,
bool vsync, bool antiAlias);
IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io);
#endif
}
} // end namespace irr
......@@ -276,7 +274,7 @@ namespace irr
//! constructor
CIrrDeviceWinCE::CIrrDeviceWinCE(const SIrrlichtCreationParameters& params)
: CIrrDeviceStub(params), HWnd(reinterpret_cast<HWND>(CreationParams.WindowId)),
: CIrrDeviceStub(params), HWnd(0),
Win32CursorControl(0), ChangedToFullScreen(false), Resized(false),
ExternalWindow(false)
{
......@@ -292,7 +290,7 @@ CIrrDeviceWinCE::CIrrDeviceWinCE(const SIrrlichtCreationParameters& params)
HINSTANCE hInstance = GetModuleHandle(0);
// create the window only if we do not use the null device
if (!HWnd && (CreationParams.DriverType != video::EDT_NULL))
if (!CreationParams.WindowId && (CreationParams.DriverType != video::EDT_NULL))
{
const wchar_t* ClassName = L"CIrrDeviceWinCE";
......@@ -346,10 +344,10 @@ CIrrDeviceWinCE::CIrrDeviceWinCE(const SIrrlichtCreationParameters& params)
// fix ugly ATI driver bugs. Thanks to ariaci
MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE);
}
// attach external window
if (CreationParams.WindowId)
else if (CreationParams.WindowId)
{
// attach external window
HWnd = static_cast<HWND>(CreationParams.WindowId);
RECT r;
GetWindowRect(HWnd, &r);
CreationParams.WindowSize.Width = r.right - r.left;
......@@ -383,7 +381,6 @@ CIrrDeviceWinCE::CIrrDeviceWinCE(const SIrrlichtCreationParameters& params)
}
//! destructor
CIrrDeviceWinCE::~CIrrDeviceWinCE()
{
......@@ -399,12 +396,9 @@ CIrrDeviceWinCE::~CIrrDeviceWinCE()
EnvMap.erase(it);
break;
}
}
//! create the driver
void CIrrDeviceWinCE::createDriver()
{
......@@ -443,8 +437,7 @@ void CIrrDeviceWinCE::createDriver()
#ifdef _IRR_COMPILE_WITH_OPENGL_
if (CreationParams.Fullscreen)
switchToFullScreen();
VideoDriver = video::createOpenGLDriver(CreationParams.WindowSize, HWnd, CreationParams.Bits, CreationParams.Fullscreen, CreationParams.Stencilbuffer, FileSystem,
CreationParams.Vsync, CreationParams.AntiAlias);
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem);
if (!VideoDriver)
{
os::Printer::log("Could not create OpenGL driver.", ELL_ERROR);
......
......@@ -31,14 +31,13 @@ namespace video
// -----------------------------------------------------------------------
#ifdef _IRR_USE_WINDOWS_DEVICE_
//! Windows constructor and init code
COpenGLDriver::COpenGLDriver(const core::dimension2d<s32>& screenSize,
HWND window, bool stencilBuffer,
io::IFileSystem* io, bool antiAlias)
: CNullDriver(io, screenSize), COpenGLExtensionHandler(),
COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params,
io::IFileSystem* io)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(antiAlias), RenderTargetTexture(0), LastSetLight(-1),
AntiAlias(params.AntiAlias), RenderTargetTexture(0), LastSetLight(-1),
CurrentRendertargetSize(0,0),
HDc(0), Window(window), HRc(0)
HDc(0), Window(static_cast<HWND>(params.WindowId)), HRc(0)
{
#ifdef _DEBUG
setDebugName("COpenGLDriver");
......@@ -46,8 +45,7 @@ COpenGLDriver::COpenGLDriver(const core::dimension2d<s32>& screenSize,
}
//! inits the open gl driver
bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
HWND window, u32 bits, bool vsync, bool stencilBuffer)
bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params)
{
// Set up ixel format descriptor with desired parameters
PIXELFORMATDESCRIPTOR pfd = {
......@@ -57,14 +55,14 @@ bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
params.Bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // Z-Buffer (Depth Buffer)
stencilBuffer ? 1 : 0, // Stencil Buffer Depth
params.Stencilbuffer ? 1 : 0, // Stencil Buffer Depth
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
......@@ -73,21 +71,185 @@ bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
GLuint PixelFormat;
if (AntiAlias)
{
// Create a window to test antialiasing support
const c8* ClassName = "GLCIrrDeviceWin32";
HINSTANCE lhInstance = GetModuleHandle(0);
// Register Class
WNDCLASSEX wcex;
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;
RegisterClassEx(&wcex);
RECT clientSize;
clientSize.top = 0;
clientSize.left = 0;
clientSize.right = params.WindowSize.Width;
clientSize.bottom = params.WindowSize.Height;
DWORD style = WS_POPUP;
if (!params.Fullscreen)
style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
AdjustWindowRect(&clientSize, style, FALSE);
const s32 realWidth = clientSize.right - clientSize.left;
const s32 realHeight = clientSize.bottom - clientSize.top;
const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2;
const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2;
HWND temporary_wnd=CreateWindow(ClassName, "", style, windowLeft, windowTop,
realWidth, realHeight, NULL, NULL, lhInstance, NULL);
if(!temporary_wnd)
{
os::Printer::log("Cannot create a temporary window.", ELL_ERROR);
return false;
}
HDc = GetDC(temporary_wnd);
for (u32 i=0; i<5; ++i)
{
if (i == 1)
{
if (params.Stencilbuffer)
{
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
params.Stencilbuffer = false;
pfd.cStencilBits = 0;
}
else
continue;
}
else
if (i == 2)
{
pfd.cDepthBits = 24;
}
if (i == 3)
{
if (params.Bits!=16)
pfd.cDepthBits = 16;
else
continue;
}
else
if (i == 4)
{
os::Printer::log("Cannot create a GL device context", "No suitable format for temporary window.", ELL_ERROR);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
// choose pixelformat
if ((PixelFormat = ChoosePixelFormat(HDc, &pfd)))
break;
}
SetPixelFormat(HDc, PixelFormat, &pfd);
HRc=wglCreateContext(HDc);
if(!HRc)
{
os::Printer::log("Cannot create a temporary GL rendering context.", ELL_ERROR);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
if(!wglMakeCurrent(HDc, HRc))
{
os::Printer::log("Cannot activate a temporary GL rendering context.", ELL_ERROR);
wglDeleteContext(HRc);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
return false;
}
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat_ARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
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
};
s32 iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB,(params.Bits==32) ? 24 : 15,
WGL_ALPHA_BITS_ARB,(params.Bits==32) ? 8 : 1,
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,
0,0
};
s32 rv=0;
// Try to get an acceptable pixel format
while(rv==0 && iAttributes[19]>1)
{
s32 pixelFormat=0;
u32 numFormats=0;
const s32 valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
if(valid && numFormats>0)
rv = pixelFormat;
else
iAttributes[19] >>= 1;
}
if(rv)
PixelFormat=rv;
}
wglMakeCurrent(HDc, NULL);
wglDeleteContext(HRc);
ReleaseDC(temporary_wnd, HDc);
DestroyWindow(temporary_wnd);
}
// get hdc
if (!(HDc=GetDC(window)))
if (!(HDc=GetDC(Window)))
{
os::Printer::log("Cannot create a GL device context.", ELL_ERROR);
return false;
}
// search for pixel format the simple way
if (!AntiAlias)
{
for (u32 i=0; i<5; ++i)
{
if (i == 1)
{
if (stencilBuffer)
if (params.Stencilbuffer)
{
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
stencilBuffer = false;
params.Stencilbuffer = false;
pfd.cStencilBits = 0;
}
else
......@@ -100,7 +262,7 @@ bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
}
if (i == 3)
{
if (bits!=16)
if (params.Bits!=16)
pfd.cDepthBits = 16;
else
continue;
......@@ -108,15 +270,14 @@ bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
else
if (i == 4)
{
os::Printer::log("Cannot create a GL device context.", ELL_ERROR);
os::Printer::log("Cannot create a GL device context", "No suitable format.", ELL_ERROR);
return false;
}
// choose pixelformat
if ((PixelFormat = ChoosePixelFormat(HDc, &pfd)))
break;
else
os::Printer::log("Cannot find a suitable pixelformat.", ELL_ERROR);
}
}
// set pixel format
......@@ -158,11 +319,11 @@ bool COpenGLDriver::initDriver(const core::dimension2d<s32>& screenSize,
ColorFormat = ECF_R5G6B5;
}
genericDriverInit(screenSize, stencilBuffer);
genericDriverInit(params.WindowSize, params.Stencilbuffer);
// set vsync
if (wglSwapIntervalEXT)
wglSwapIntervalEXT(vsync ? 1 : 0);
wglSwapIntervalEXT(params.Vsync ? 1 : 0);
// set exposed data
ExposedData.OpenGLWin32.HDc = HDc;
......@@ -2848,12 +3009,12 @@ namespace video
// WINDOWS VERSION
// -----------------------------------
#ifdef _IRR_USE_WINDOWS_DEVICE_
IVideoDriver* createOpenGLDriver(const core::dimension2d<s32>& screenSize,
HWND window, u32 bits, bool stencilBuffer, io::IFileSystem* io, bool vsync, bool antiAlias)
IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params,
io::IFileSystem* io)
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
COpenGLDriver* ogl = new COpenGLDriver(screenSize, window, stencilBuffer, io, antiAlias);
if (!ogl->initDriver(screenSize, window, bits, vsync, stencilBuffer))
COpenGLDriver* ogl = new COpenGLDriver(params, io);
if (!ogl->initDriver(params))
{
ogl->drop();
ogl = 0;
......
......@@ -76,17 +76,7 @@ namespace video
{
public:
#ifdef _IRR_WINDOWS_API_
//! win32 constructor
COpenGLDriver(const core::dimension2d<s32>& screenSize, HWND window,
bool stencilBuffer, io::IFileSystem* io, bool antiAlias);
//! inits the windows specific parts of the open gl driver
bool initDriver(const core::dimension2d<s32>& screenSize, HWND window,
u32 bits, bool vsync, bool stencilBuffer);
#endif
#if defined(_IRR_USE_LINUX_DEVICE_) || defined(_IRR_USE_SDL_DEVICE_)
#if defined(_IRR_WINDOWS_API_) || defined(_IRR_USE_LINUX_DEVICE_) || defined(_IRR_USE_SDL_DEVICE_)
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io);
#endif
......@@ -95,6 +85,11 @@ namespace video
io::IFileSystem* io, CIrrDeviceMacOSX *device);
#endif
#ifdef _IRR_WINDOWS_API_
//! inits the windows specific parts of the open gl driver
bool initDriver(SIrrlichtCreationParameters params);
#endif
//! destructor
virtual ~COpenGLDriver();
......
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