Commit 92f1299c authored by hybrid's avatar hybrid

Add flag to enable sRGB correct color calculations (e.g. blend and lighting)....

Add flag to enable sRGB correct color calculations (e.g. blend and lighting). This allows for much better color calculations, but requires to change the explicitly defined colors in the code to be converted to linear color space.
Changed many init routines to use SIrrlichtCreationParameters struct instead of many single parameters.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3729 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 65120d77
...@@ -29,6 +29,7 @@ namespace irr ...@@ -29,6 +29,7 @@ namespace irr
Stencilbuffer(false), Stencilbuffer(false),
Vsync(false), Vsync(false),
AntiAlias(0), AntiAlias(0),
HandleSRGB(false),
WithAlphaChannel(false), WithAlphaChannel(false),
Doublebuffer(true), Doublebuffer(true),
IgnoreInput(false), IgnoreInput(false),
...@@ -62,6 +63,7 @@ namespace irr ...@@ -62,6 +63,7 @@ namespace irr
Stencilbuffer = other.Stencilbuffer; Stencilbuffer = other.Stencilbuffer;
Vsync = other.Vsync; Vsync = other.Vsync;
AntiAlias = other.AntiAlias; AntiAlias = other.AntiAlias;
HandleSRGB = other.HandleSRGB;
WithAlphaChannel = other.WithAlphaChannel; WithAlphaChannel = other.WithAlphaChannel;
Doublebuffer = other.Doublebuffer; Doublebuffer = other.Doublebuffer;
IgnoreInput = other.IgnoreInput; IgnoreInput = other.IgnoreInput;
...@@ -140,6 +142,21 @@ namespace irr ...@@ -140,6 +142,21 @@ namespace irr
Default value: 0 - disabled */ Default value: 0 - disabled */
u8 AntiAlias; u8 AntiAlias;
//! Flag to enable proper sRGB and linear color handling
/** In most situations, it is desireable to have the color handling in
non-linear sRGB color space, and only do the intermediate color
calculations in linear RGB space. If this flag is enabled, the device and
driver try to assure that all color input and output are color corrected
and only the internal color representation is linear. This means, that
the color output is properly gamma-adjusted to provide the brighter
colors for monitor display. And that blending and lighting give a more
natural look, due to proper conversion from non-linear colors into linear
color space for blend operations. If this flag is enabled, all texture colors
(which are usually in sRGB space) are correctly displayed. However vertex colors
and other explicitly set values have to be manually encoded in linear color space.
Default value: false. */
bool HandleSRGB;
//! Whether the main framebuffer uses an alpha channel. //! Whether the main framebuffer uses an alpha channel.
/** In some situations it might be desireable to get a color /** In some situations it might be desireable to get a color
buffer with an alpha channel, e.g. when rendering into a buffer with an alpha channel, e.g. when rendering into a
......
...@@ -29,20 +29,17 @@ namespace ...@@ -29,20 +29,17 @@ namespace
} }
//! constructor //! constructor
CD3D9Driver::CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window, CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io)
bool fullscreen, bool stencilbuffer, : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE),
io::IFileSystem* io, bool pureSoftware)
: CNullDriver(io, screenSize), CurrentRenderMode(ERM_NONE),
ResetRenderStates(true), Transformation3DChanged(false), ResetRenderStates(true), Transformation3DChanged(false),
StencilBuffer(stencilbuffer), AntiAliasing(0),
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
WindowId(0), SceneSourceRect(0), WindowId(0), SceneSourceRect(0),
LastVertexType((video::E_VERTEX_TYPE)-1), VendorID(0), LastVertexType((video::E_VERTEX_TYPE)-1), VendorID(0),
MaxTextureUnits(0), MaxUserClipPlanes(0), MaxMRTs(1), NumSetMRTs(1), MaxTextureUnits(0), MaxUserClipPlanes(0), MaxMRTs(1), NumSetMRTs(1),
MaxLightDistance(0.f), LastSetLight(-1), Cached2DModeSignature(0), MaxLightDistance(0.f), LastSetLight(-1), Cached2DModeSignature(0),
ColorFormat(ECF_A8R8G8B8), DeviceLost(false), ColorFormat(ECF_A8R8G8B8), DeviceLost(false),
Fullscreen(fullscreen), DriverWasReset(true), OcclusionQuerySupport(false), DriverWasReset(true), OcclusionQuerySupport(false),
AlphaToCoverageSupport(false), DisplayAdapter(0) AlphaToCoverageSupport(false), Params(params)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CD3D9Driver"); setDebugName("CD3D9Driver");
...@@ -164,15 +161,8 @@ void CD3D9Driver::createMaterialRenderers() ...@@ -164,15 +161,8 @@ void CD3D9Driver::createMaterialRenderers()
//! initialises the Direct3D API //! initialises the Direct3D API
bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
HWND hwnd, u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, u8 antiAlias, u32 displayAdapter)
{ {
HRESULT hr;
Fullscreen = fullScreen;
CurrentDepthBufferSize = screenSize;
DisplayAdapter = displayAdapter;
if (!pID3D) if (!pID3D)
{ {
D3DLibrary = LoadLibrary( __TEXT("d3d9.dll") ); D3DLibrary = LoadLibrary( __TEXT("d3d9.dll") );
...@@ -204,7 +194,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -204,7 +194,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
// print device information // print device information
D3DADAPTER_IDENTIFIER9 dai; D3DADAPTER_IDENTIFIER9 dai;
if (!FAILED(pID3D->GetAdapterIdentifier(DisplayAdapter, 0, &dai))) if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, 0, &dai)))
{ {
char tmp[512]; char tmp[512];
...@@ -232,8 +222,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -232,8 +222,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
} }
D3DDISPLAYMODE d3ddm; D3DDISPLAYMODE d3ddm;
hr = pID3D->GetAdapterDisplayMode(DisplayAdapter, &d3ddm); if (FAILED(pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm)))
if (FAILED(hr))
{ {
os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR);
return false; return false;
...@@ -243,17 +232,17 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -243,17 +232,17 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
present.BackBufferCount = 1; present.BackBufferCount = 1;
present.EnableAutoDepthStencil = TRUE; present.EnableAutoDepthStencil = TRUE;
if (vsync) if (Params.Vsync)
present.PresentationInterval = D3DPRESENT_INTERVAL_ONE; present.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
else else
present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
if (fullScreen) if (Params.Fullscreen)
{ {
present.BackBufferWidth = screenSize.Width; present.BackBufferWidth = Params.WindowSize.Width;
present.BackBufferHeight = screenSize.Height; present.BackBufferHeight = Params.WindowSize.Height;
// request 32bit mode if user specified 32 bit, added by Thomas Stuefe // request 32bit mode if user specified 32 bit, added by Thomas Stuefe
if (bits == 32) if (Params.Bits == 32)
present.BackBufferFormat = D3DFMT_X8R8G8B8; present.BackBufferFormat = D3DFMT_X8R8G8B8;
else else
present.BackBufferFormat = D3DFMT_R5G6B5; present.BackBufferFormat = D3DFMT_R5G6B5;
...@@ -268,7 +257,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -268,7 +257,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
present.Windowed = TRUE; present.Windowed = TRUE;
} }
UINT adapter = DisplayAdapter; UINT adapter = Params.DisplayAdapter;
D3DDEVTYPE devtype = D3DDEVTYPE_HAL; D3DDEVTYPE devtype = D3DDEVTYPE_HAL;
#ifndef _IRR_D3D_NO_SHADER_DEBUGGING #ifndef _IRR_D3D_NO_SHADER_DEBUGGING
devtype = D3DDEVTYPE_REF; devtype = D3DDEVTYPE_REF;
...@@ -287,36 +276,35 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -287,36 +276,35 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
#endif #endif
// enable anti alias if possible and desired // enable anti alias if possible and desired
if (antiAlias > 0) if (Params.AntiAlias > 0)
{ {
if(antiAlias > 16) if (Params.AntiAlias > 32)
antiAlias = 16; Params.AntiAlias = 32;
DWORD qualityLevels = 0; DWORD qualityLevels = 0;
while(antiAlias > 0) while(Params.AntiAlias > 0)
{ {
if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter, if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter,
devtype, present.BackBufferFormat, !fullScreen, devtype, present.BackBufferFormat, !Params.Fullscreen,
(D3DMULTISAMPLE_TYPE)antiAlias, &qualityLevels))) (D3DMULTISAMPLE_TYPE)Params.AntiAlias, &qualityLevels)))
{ {
present.MultiSampleType = (D3DMULTISAMPLE_TYPE)antiAlias; present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias;
present.MultiSampleQuality = qualityLevels-1; present.MultiSampleQuality = qualityLevels-1;
present.SwapEffect = D3DSWAPEFFECT_DISCARD; present.SwapEffect = D3DSWAPEFFECT_DISCARD;
break; break;
} }
--antiAlias; --Params.AntiAlias;
} }
if(antiAlias==0) if (Params.AntiAlias==0)
{ {
os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING);
} }
} }
AntiAliasing = antiAlias;
// check stencil buffer compatibility // check stencil buffer compatibility
if (StencilBuffer) if (Params.Stencilbuffer)
{ {
present.AutoDepthStencilFormat = D3DFMT_D24S8; present.AutoDepthStencilFormat = D3DFMT_D24S8;
if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
...@@ -334,7 +322,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -334,7 +322,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
{ {
os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING);
StencilBuffer = false; Params.Stencilbuffer = false;
} }
} }
} }
...@@ -343,11 +331,11 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -343,11 +331,11 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat)))
{ {
os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING);
StencilBuffer = false; Params.Stencilbuffer = false;
} }
} }
// do not use else here to cope with flag change in previous block // do not use else here to cope with flag change in previous block
if (!StencilBuffer) if (!Params.Stencilbuffer)
{ {
present.AutoDepthStencilFormat = D3DFMT_D32; present.AutoDepthStencilFormat = D3DFMT_D32;
if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
...@@ -373,18 +361,16 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -373,18 +361,16 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
// create device // create device
DWORD fpuPrecision = highPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0;
if (pureSoftware) if (pureSoftware)
{ {
hr = pID3D->CreateDevice(DisplayAdapter, D3DDEVTYPE_REF, hwnd, if (FAILED(pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd,
fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice)))
if (FAILED(hr))
os::Printer::log("Was not able to create Direct3D9 software device.", ELL_ERROR); os::Printer::log("Was not able to create Direct3D9 software device.", ELL_ERROR);
} }
else else
{ {
hr = pID3D->CreateDevice(adapter, devtype, hwnd, HRESULT hr = pID3D->CreateDevice(adapter, devtype, hwnd,
fpuPrecision | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); fpuPrecision | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice);
if(FAILED(hr)) if(FAILED(hr))
...@@ -409,13 +395,13 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -409,13 +395,13 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
pID3DDevice->GetDeviceCaps(&Caps); pID3DDevice->GetDeviceCaps(&Caps);
// disable stencilbuffer if necessary // disable stencilbuffer if necessary
if (StencilBuffer && if (Params.Stencilbuffer &&
(!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) || (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) ||
!(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) || !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) ||
!(Caps.StencilCaps & D3DSTENCILCAPS_KEEP))) !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP)))
{ {
os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING); os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING);
StencilBuffer = false; Params.Stencilbuffer = false;
} }
// set default vertex shader // set default vertex shader
...@@ -440,7 +426,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -440,7 +426,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK); OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK);
if (VendorID==0x10DE)//NVidia if (VendorID==0x10DE)//NVidia
AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(DisplayAdapter, D3DDEVTYPE_HAL, AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(Params.DisplayAdapter, D3DDEVTYPE_HAL,
D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE,
(D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK); (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK);
else if (VendorID==0x1002)//ATI else if (VendorID==0x1002)//ATI
...@@ -461,7 +447,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize, ...@@ -461,7 +447,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
DriverAttributes->setAttribute("MaxTextureLODBias", 16); DriverAttributes->setAttribute("MaxTextureLODBias", 16);
DriverAttributes->setAttribute("Version", 901); DriverAttributes->setAttribute("Version", 901);
DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)Caps.VertexShaderVersion*100); DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)Caps.VertexShaderVersion*100);
DriverAttributes->setAttribute("AntiAlias", AntiAliasing); DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias);
// set the renderstates // set the renderstates
setRenderStates3DMode(); setRenderStates3DMode();
...@@ -537,7 +523,7 @@ bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, ...@@ -537,7 +523,7 @@ bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color,
if (zBuffer) if (zBuffer)
flags |= D3DCLEAR_ZBUFFER; flags |= D3DCLEAR_ZBUFFER;
if (StencilBuffer) if (Params.Stencilbuffer)
flags |= D3DCLEAR_STENCIL; flags |= D3DCLEAR_STENCIL;
if (flags) if (flags)
...@@ -582,7 +568,10 @@ bool CD3D9Driver::endScene() ...@@ -582,7 +568,10 @@ bool CD3D9Driver::endScene()
sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y; sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y;
} }
hr = pID3DDevice->Present(srcRct, NULL, WindowId, NULL); IDirect3DSwapChain9* swChain;
hr = pID3DDevice->GetSwapChain(0, &swChain);
DWORD flags = (Caps.Caps3&D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION)?D3DPRESENT_LINEAR_CONTENT:0;
hr = swChain->Present(srcRct, NULL, WindowId, NULL, flags);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return true; return true;
...@@ -630,7 +619,7 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const ...@@ -630,7 +619,7 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
// this but actually don't do this at all. // this but actually don't do this at all.
return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0; return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0;
case EVDF_STENCIL_BUFFER: case EVDF_STENCIL_BUFFER:
return StencilBuffer && Caps.StencilCaps; return Params.Stencilbuffer && Caps.StencilCaps;
case EVDF_VERTEX_SHADER_1_1: case EVDF_VERTEX_SHADER_1_1:
return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1);
case EVDF_VERTEX_SHADER_2_0: case EVDF_VERTEX_SHADER_2_0:
...@@ -2096,6 +2085,10 @@ D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp) ...@@ -2096,6 +2085,10 @@ D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp)
void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates) bool resetAllRenderstates)
{ {
// This needs only to be updated onresets
if (Params.HandleSRGB && resetAllRenderstates)
pID3DDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE);
if (resetAllRenderstates || if (resetAllRenderstates ||
lastmaterial.AmbientColor != material.AmbientColor || lastmaterial.AmbientColor != material.AmbientColor ||
lastmaterial.DiffuseColor != material.DiffuseColor || lastmaterial.DiffuseColor != material.DiffuseColor ||
...@@ -2334,7 +2327,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria ...@@ -2334,7 +2327,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
} }
// enable antialiasing // enable antialiasing
if (AntiAliasing) if (Params.AntiAlias)
{ {
if (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY)) if (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY))
pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
...@@ -2356,6 +2349,9 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria ...@@ -2356,6 +2349,9 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
// texture address mode // texture address mode
for (u32 st=0; st<MaxTextureUnits; ++st) for (u32 st=0; st<MaxTextureUnits; ++st)
{ {
if (resetAllRenderstates && Params.HandleSRGB)
pID3DDevice->SetSamplerState(st, D3DSAMP_SRGBTEXTURE, TRUE);
if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias) if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias)
{ {
const float tmp = material.TextureLayer[st].LODBias * 0.125f; const float tmp = material.TextureLayer[st].LODBias * 0.125f;
...@@ -2767,7 +2763,7 @@ const wchar_t* CD3D9Driver::getName() const ...@@ -2767,7 +2763,7 @@ const wchar_t* CD3D9Driver::getName() const
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail) void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail)
{ {
if (!StencilBuffer || !count) if (!Params.Stencilbuffer || !count)
return; return;
setRenderStatesStencilShadowMode(zfail); setRenderStatesStencilShadowMode(zfail);
...@@ -2809,7 +2805,7 @@ void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 ...@@ -2809,7 +2805,7 @@ void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32
void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
{ {
if (!StencilBuffer) if (!Params.Stencilbuffer)
return; return;
S3DVertex vtx[4]; S3DVertex vtx[4];
...@@ -3503,9 +3499,8 @@ IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params, ...@@ -3503,9 +3499,8 @@ IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, HWND window) io::IFileSystem* io, HWND window)
{ {
const bool pureSoftware = false; const bool pureSoftware = false;
CD3D9Driver* dx9 = new CD3D9Driver(params.WindowSize, window, params.Fullscreen, params.Stencilbuffer, io, pureSoftware); CD3D9Driver* dx9 = new CD3D9Driver(params, io);
if (!dx9->initDriver(params.WindowSize, window, params.Bits, params.Fullscreen, pureSoftware, params.HighPrecisionFPU, if (!dx9->initDriver(window, pureSoftware))
params.Vsync, params.AntiAlias, params.DisplayAdapter))
{ {
dx9->drop(); dx9->drop();
dx9 = 0; dx9 = 0;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#endif #endif
#include "CNullDriver.h" #include "CNullDriver.h"
#include "SIrrCreationParameters.h"
#include "IMaterialRendererServices.h" #include "IMaterialRendererServices.h"
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) #if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define #include "irrMath.h" // needed by borland for sqrtf define
...@@ -50,8 +51,7 @@ namespace video ...@@ -50,8 +51,7 @@ namespace video
friend class CD3D9Texture; friend class CD3D9Texture;
//! constructor //! constructor
CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window, bool fullscreen, CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io);
bool stencibuffer, io::IFileSystem* io, bool pureSoftware=false);
//! destructor //! destructor
virtual ~CD3D9Driver(); virtual ~CD3D9Driver();
...@@ -191,9 +191,7 @@ namespace video ...@@ -191,9 +191,7 @@ namespace video
const core::vector3df& end, SColor color = SColor(255,255,255,255)); const core::vector3df& end, SColor color = SColor(255,255,255,255));
//! initialises the Direct3D API //! initialises the Direct3D API
bool initDriver(const core::dimension2d<u32>& screenSize, HWND hwnd, bool initDriver(HWND hwnd, bool pureSoftware);
u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, u8 antiAlias, u32 displayAdapter);
//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8
//! driver, it would return "Direct3D8.1". //! driver, it would return "Direct3D8.1".
...@@ -412,8 +410,6 @@ namespace video ...@@ -412,8 +410,6 @@ namespace video
SMaterial Material, LastMaterial; SMaterial Material, LastMaterial;
bool ResetRenderStates; // bool to make all renderstates be reseted if set. bool ResetRenderStates; // bool to make all renderstates be reseted if set.
bool Transformation3DChanged; bool Transformation3DChanged;
bool StencilBuffer;
u8 AntiAliasing;
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
bool LastTextureMipMapsAvailable[MATERIAL_MAX_TEXTURES]; bool LastTextureMipMapsAvailable[MATERIAL_MAX_TEXTURES];
core::matrix4 Matrices[ETS_COUNT]; // matrizes of the 3d mode we need to restore when we switch back from the 2d mode. core::matrix4 Matrices[ETS_COUNT]; // matrizes of the 3d mode we need to restore when we switch back from the 2d mode.
...@@ -424,13 +420,14 @@ namespace video ...@@ -424,13 +420,14 @@ namespace video
IDirect3DSurface9* PrevRenderTarget; IDirect3DSurface9* PrevRenderTarget;
core::dimension2d<u32> CurrentRendertargetSize; core::dimension2d<u32> CurrentRendertargetSize;
core::dimension2d<u32> CurrentDepthBufferSize;
HWND WindowId; HWND WindowId;
core::rect<s32>* SceneSourceRect; core::rect<s32>* SceneSourceRect;
D3DCAPS9 Caps; D3DCAPS9 Caps;
SIrrlichtCreationParameters Params;
E_VERTEX_TYPE LastVertexType; E_VERTEX_TYPE LastVertexType;
SColorf AmbientLight; SColorf AmbientLight;
...@@ -459,12 +456,9 @@ namespace video ...@@ -459,12 +456,9 @@ namespace video
ECOLOR_FORMAT ColorFormat; ECOLOR_FORMAT ColorFormat;
D3DFORMAT D3DColorFormat; D3DFORMAT D3DColorFormat;
bool DeviceLost; bool DeviceLost;
bool Fullscreen;
bool DriverWasReset; bool DriverWasReset;
bool OcclusionQuerySupport; bool OcclusionQuerySupport;
bool AlphaToCoverageSupport; bool AlphaToCoverageSupport;
u32 DisplayAdapter;
}; };
......
...@@ -312,9 +312,9 @@ bool CD3D9Texture::createTexture(u32 flags, IImage * image) ...@@ -312,9 +312,9 @@ bool CD3D9Texture::createTexture(u32 flags, IImage * image)
{ {
LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9; LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9;
D3DDISPLAYMODE d3ddm; D3DDISPLAYMODE d3ddm;
intf->GetAdapterDisplayMode(Driver->DisplayAdapter, &d3ddm); intf->GetAdapterDisplayMode(Driver->Params.DisplayAdapter, &d3ddm);
if (D3D_OK==intf->CheckDeviceFormat(Driver->DisplayAdapter,D3DDEVTYPE_HAL,d3ddm.Format,D3DUSAGE_AUTOGENMIPMAP,D3DRTYPE_TEXTURE,format)) if (D3D_OK==intf->CheckDeviceFormat(Driver->Params.DisplayAdapter,D3DDEVTYPE_HAL,d3ddm.Format,D3DUSAGE_AUTOGENMIPMAP,D3DRTYPE_TEXTURE,format))
{ {
usage = D3DUSAGE_AUTOGENMIPMAP; usage = D3DUSAGE_AUTOGENMIPMAP;
HardwareMipMaps = true; HardwareMipMaps = true;
......
...@@ -410,6 +410,11 @@ bool CIrrDeviceLinux::createWindow() ...@@ -410,6 +410,11 @@ bool CIrrDeviceLinux::createWindow()
#elif defined(GLX_SGIS_multisample) #elif defined(GLX_SGIS_multisample)
GLX_SAMPLE_BUFFERS_SGIS, 1, GLX_SAMPLE_BUFFERS_SGIS, 1,
GLX_SAMPLES_SGIS, CreationParams.AntiAlias, // 18,19 GLX_SAMPLES_SGIS, CreationParams.AntiAlias, // 18,19
#endif
#ifdef GL_ARB_framebuffer_sRGB
CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL,
#elif defined(GL_EXT_framebuffer_sRGB)
CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL,
#endif #endif
GLX_STEREO, CreationParams.Stereobuffer?True:False, GLX_STEREO, CreationParams.Stereobuffer?True:False,
None None
...@@ -545,7 +550,7 @@ bool CIrrDeviceLinux::createWindow() ...@@ -545,7 +550,7 @@ bool CIrrDeviceLinux::createWindow()
// attribute array for the draw buffer // attribute array for the draw buffer
int visualAttrBuffer[] = int visualAttrBuffer[] =
{ {
GLX_RGBA, GL_TRUE, GLX_RGBA, GLX_USE_GL,
GLX_RED_SIZE, 4, GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4, GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4, GLX_BLUE_SIZE, 4,
...@@ -557,6 +562,11 @@ bool CIrrDeviceLinux::createWindow() ...@@ -557,6 +562,11 @@ bool CIrrDeviceLinux::createWindow()
// GLX_USE_GL, which is silently ignored by glXChooseVisual // GLX_USE_GL, which is silently ignored by glXChooseVisual
CreationParams.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14 CreationParams.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14
CreationParams.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15 CreationParams.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15
#ifdef GL_ARB_framebuffer_sRGB
CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL,
#elif defined(GL_EXT_framebuffer_sRGB)
CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL,
#endif
None None
}; };
...@@ -613,7 +623,7 @@ bool CIrrDeviceLinux::createWindow() ...@@ -613,7 +623,7 @@ bool CIrrDeviceLinux::createWindow()
} }
#ifdef _DEBUG #ifdef _DEBUG
else else
os::Printer::log("Visual chosen: ", core::stringc(static_cast<u32>(visual->visualid)).c_str(), ELL_INFORMATION); os::Printer::log("Visual chosen: ", core::stringc(static_cast<u32>(visual->visualid)).c_str(), ELL_DEBUG);
#endif #endif
// create color map // create color map
......
...@@ -37,7 +37,7 @@ COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params, ...@@ -37,7 +37,7 @@ COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), RenderTargetTexture(0), AntiAlias(params.AntiAlias), RenderTargetTexture(0),
CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER), CurrentTarget(ERT_FRAME_BUFFER), Params(params),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer), Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device), HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device),
DeviceType(EIDT_WIN32) DeviceType(EIDT_WIN32)
...@@ -79,7 +79,7 @@ bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrr ...@@ -79,7 +79,7 @@ bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrr
} }
//! inits the open gl driver //! inits the open gl driver
bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDeviceWin32* device) bool COpenGLDriver::initDriver(CIrrDeviceWin32* device)
{ {
// Create a window to test antialiasing support // Create a window to test antialiasing support
const fschar_t* ClassName = __TEXT("GLCIrrDeviceWin32"); const fschar_t* ClassName = __TEXT("GLCIrrDeviceWin32");
...@@ -105,11 +105,11 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -105,11 +105,11 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
RECT clientSize; RECT clientSize;
clientSize.top = 0; clientSize.top = 0;
clientSize.left = 0; clientSize.left = 0;
clientSize.right = params.WindowSize.Width; clientSize.right = Params.WindowSize.Width;
clientSize.bottom = params.WindowSize.Height; clientSize.bottom = Params.WindowSize.Height;
DWORD style = WS_POPUP; DWORD style = WS_POPUP;
if (!params.Fullscreen) if (!Params.Fullscreen)
style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
AdjustWindowRect(&clientSize, style, FALSE); AdjustWindowRect(&clientSize, style, FALSE);
...@@ -138,17 +138,17 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -138,17 +138,17 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
1, // Version Number 1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
(params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering (Params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering
(params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer (Params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer
PFD_TYPE_RGBA, // Request An RGBA Format PFD_TYPE_RGBA, // Request An RGBA Format
params.Bits, // Select Our Color Depth Params.Bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored 0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer 0, // No Alpha Buffer
0, // Shift Bit Ignored 0, // Shift Bit Ignored
0, // No Accumulation Buffer 0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored 0, 0, 0, 0, // Accumulation Bits Ignored
params.ZBufferBits, // Z-Buffer (Depth Buffer) Params.ZBufferBits, // Z-Buffer (Depth Buffer)
params.Stencilbuffer ? 1 : 0, // Stencil Buffer Depth Params.Stencilbuffer ? 1 : 0, // Stencil Buffer Depth
0, // No Auxiliary Buffer 0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved 0, // Reserved
...@@ -161,10 +161,10 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -161,10 +161,10 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
{ {
if (i == 1) if (i == 1)
{ {
if (params.Stencilbuffer) if (Params.Stencilbuffer)
{ {
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING); os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
params.Stencilbuffer = false; Params.Stencilbuffer = false;
pfd.cStencilBits = 0; pfd.cStencilBits = 0;
} }
else else
...@@ -177,7 +177,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -177,7 +177,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
} }
if (i == 3) if (i == 3)
{ {
if (params.Bits!=16) if (Params.Bits!=16)
pfd.cDepthBits = 16; pfd.cDepthBits = 16;
else else
continue; continue;
...@@ -186,7 +186,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -186,7 +186,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
if (i == 4) if (i == 4)
{ {
// try single buffer // try single buffer
if (params.Doublebuffer) if (Params.Doublebuffer)
pfd.dwFlags &= ~PFD_DOUBLEBUFFER; pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
else else
continue; continue;
...@@ -268,15 +268,15 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -268,15 +268,15 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
f32 fAttributes[] = {0.0, 0.0}; f32 fAttributes[] = {0.0, 0.0};
s32 iAttributes[] = s32 iAttributes[] =
{ {
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE, WGL_DRAW_TO_WINDOW_ARB,1,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE, WGL_SUPPORT_OPENGL_ARB,1,
WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
WGL_COLOR_BITS_ARB,(params.Bits==32) ? 24 : 15, WGL_COLOR_BITS_ARB,(Params.Bits==32) ? 24 : 15,
WGL_ALPHA_BITS_ARB,(params.Bits==32) ? 8 : 1, WGL_ALPHA_BITS_ARB,(Params.Bits==32) ? 8 : 1,
WGL_DEPTH_BITS_ARB,params.ZBufferBits, // 10,11 WGL_DEPTH_BITS_ARB,Params.ZBufferBits, // 10,11
WGL_STENCIL_BITS_ARB,(params.Stencilbuffer) ? 1 : 0, WGL_STENCIL_BITS_ARB,Params.Stencilbuffer ? 1 : 0,
WGL_DOUBLE_BUFFER_ARB,(params.Doublebuffer) ? GL_TRUE : GL_FALSE, WGL_DOUBLE_BUFFER_ARB,Params.Doublebuffer ? 1 : 0,
WGL_STEREO_ARB,(params.Stereobuffer) ? GL_TRUE : GL_FALSE, WGL_STEREO_ARB,Params.Stereobuffer ? 1 : 0,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
#ifdef WGL_ARB_multisample #ifdef WGL_ARB_multisample
WGL_SAMPLES_ARB,AntiAlias, // 20,21 WGL_SAMPLES_ARB,AntiAlias, // 20,21
...@@ -288,21 +288,26 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -288,21 +288,26 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
WGL_SAMPLES_3DFX,AntiAlias, // 20,21 WGL_SAMPLES_3DFX,AntiAlias, // 20,21
WGL_SAMPLE_BUFFERS_3DFX, 1, WGL_SAMPLE_BUFFERS_3DFX, 1,
#endif #endif
#if 0
#ifdef WGL_ARB_framebuffer_sRGB #ifdef WGL_ARB_framebuffer_sRGB
WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, GL_TRUE, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, Params.HandleSRGB ? 1:0,
#elif defined(WGL_EXT_framebuffer_sRGB) #elif defined(WGL_EXT_framebuffer_sRGB)
WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, GL_TRUE, WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB ? 1:0,
#endif
#endif #endif
0,0 // WGL_DEPTH_FLOAT_EXT, 1,
0,0,0,0
}; };
int iAttrSize = sizeof(iAttributes)/sizeof(int);
const bool framebuffer_srgb_supported = ((wglExtensions.find("WGL_ARB_framebuffer_sRGB") != -1) ||
(wglExtensions.find("WGL_EXT_framebuffer_sRGB") != -1));
if (!framebuffer_srgb_supported)
{
memmove(&iAttributes[24],&iAttributes[26],sizeof(int)*(iAttrSize-26));
iAttrSize -= 2;
}
if (!multi_sample_supported) if (!multi_sample_supported)
{ {
iAttributes[20]=0; memmove(&iAttributes[20],&iAttributes[24],sizeof(int)*(iAttrSize-24));
iAttributes[21]=0; iAttrSize -= 4;
iAttributes[22]=0;
iAttributes[23]=0;
} }
s32 rv=0; s32 rv=0;
...@@ -313,7 +318,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -313,7 +318,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
UINT numFormats=0; UINT numFormats=0;
const BOOL valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats); const BOOL valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
if (valid && numFormats>0) if (valid && numFormats)
rv = pixelFormat; rv = pixelFormat;
else else
iAttributes[21] -= 1; iAttributes[21] -= 1;
...@@ -350,10 +355,10 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -350,10 +355,10 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
{ {
if (i == 1) if (i == 1)
{ {
if (params.Stencilbuffer) if (Params.Stencilbuffer)
{ {
os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING); os::Printer::log("Cannot create a GL device with stencil buffer, disabling stencil shadows.", ELL_WARNING);
params.Stencilbuffer = false; Params.Stencilbuffer = false;
pfd.cStencilBits = 0; pfd.cStencilBits = 0;
} }
else else
...@@ -366,7 +371,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -366,7 +371,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
} }
if (i == 3) if (i == 3)
{ {
if (params.Bits!=16) if (Params.Bits!=16)
pfd.cDepthBits = 16; pfd.cDepthBits = 16;
else else
continue; continue;
...@@ -391,6 +396,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -391,6 +396,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
os::Printer::log("Cannot set the pixel format.", ELL_ERROR); os::Printer::log("Cannot set the pixel format.", ELL_ERROR);
return false; return false;
} }
os::Printer::log("Pixel Format", core::stringc(PixelFormat).c_str(), ELL_DEBUG);
// create rendering context // create rendering context
#ifdef WGL_ARB_create_context #ifdef WGL_ARB_create_context
...@@ -446,9 +452,9 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi ...@@ -446,9 +452,9 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
ColorFormat = ECF_R5G6B5; ColorFormat = ECF_R5G6B5;
} }
genericDriverInit(params.WindowSize, params.Stencilbuffer); genericDriverInit();
extGlSwapInterval(params.Vsync ? 1 : 0); extGlSwapInterval(Params.Vsync ? 1 : 0);
return true; return true;
} }
...@@ -465,14 +471,14 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, ...@@ -465,14 +471,14 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), RenderTargetTexture(0), AntiAlias(params.AntiAlias), RenderTargetTexture(0),
CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER), CurrentTarget(ERT_FRAME_BUFFER), Params(params),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer), Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
OSXDevice(device), DeviceType(EIDT_OSX) OSXDevice(device), DeviceType(EIDT_OSX)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("COpenGLDriver"); setDebugName("COpenGLDriver");
#endif #endif
genericDriverInit(params.WindowSize, params.Stencilbuffer); genericDriverInit();
} }
#endif #endif
...@@ -488,7 +494,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, ...@@ -488,7 +494,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias), Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER), CurrentTarget(ERT_FRAME_BUFFER), Params(params),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer), Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
X11Device(device), DeviceType(EIDT_X11) X11Device(device), DeviceType(EIDT_X11)
{ {
...@@ -532,18 +538,18 @@ bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrr ...@@ -532,18 +538,18 @@ bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrr
//! inits the open gl driver //! inits the open gl driver
bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDeviceLinux* device) bool COpenGLDriver::initDriver(CIrrDeviceLinux* device)
{ {
ExposedData.OpenGLLinux.X11Context = glXGetCurrentContext(); ExposedData.OpenGLLinux.X11Context = glXGetCurrentContext();
ExposedData.OpenGLLinux.X11Display = glXGetCurrentDisplay(); ExposedData.OpenGLLinux.X11Display = glXGetCurrentDisplay();
ExposedData.OpenGLLinux.X11Window = (unsigned long)params.WindowId; ExposedData.OpenGLLinux.X11Window = (unsigned long)Params.WindowId;
Drawable = glXGetCurrentDrawable(); Drawable = glXGetCurrentDrawable();
X11Display = (Display*)ExposedData.OpenGLLinux.X11Display; X11Display = (Display*)ExposedData.OpenGLLinux.X11Display;
genericDriverInit(params.WindowSize, params.Stencilbuffer); genericDriverInit();
// set vsync // set vsync
extGlSwapInterval(params.Vsync ? 1 : 0); extGlSwapInterval(Params.Vsync ? 1 : 0);
return true; return true;
} }
...@@ -561,7 +567,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, ...@@ -561,7 +567,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias), Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER), CurrentTarget(ERT_FRAME_BUFFER), Params(params),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer), Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
SDLDevice(device), DeviceType(EIDT_SDL) SDLDevice(device), DeviceType(EIDT_SDL)
{ {
...@@ -569,7 +575,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, ...@@ -569,7 +575,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
setDebugName("COpenGLDriver"); setDebugName("COpenGLDriver");
#endif #endif
genericDriverInit(params.WindowSize, params.Stencilbuffer); genericDriverInit();
} }
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_ #endif // _IRR_COMPILE_WITH_SDL_DEVICE_
...@@ -612,7 +618,7 @@ COpenGLDriver::~COpenGLDriver() ...@@ -612,7 +618,7 @@ COpenGLDriver::~COpenGLDriver()
// METHODS // METHODS
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer) bool COpenGLDriver::genericDriverInit()
{ {
Name=L"OpenGL "; Name=L"OpenGL ";
Name.append(glGetString(GL_VERSION)); Name.append(glGetString(GL_VERSION));
...@@ -634,7 +640,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize, ...@@ -634,7 +640,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
CurrentTexture[i]=0; CurrentTexture[i]=0;
// load extensions // load extensions
initExtensions(stencilBuffer); initExtensions(Params.Stencilbuffer);
if (queryFeature(EVDF_ARB_GLSL)) if (queryFeature(EVDF_ARB_GLSL))
{ {
char buf[32]; char buf[32];
...@@ -662,7 +668,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize, ...@@ -662,7 +668,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
// Reset The Current Viewport // Reset The Current Viewport
glViewport(0, 0, screenSize.Width, screenSize.Height); glViewport(0, 0, Params.WindowSize.Width, Params.WindowSize.Height);
UserClipPlanes.reallocate(MaxUserClipPlanes); UserClipPlanes.reallocate(MaxUserClipPlanes);
for (i=0; i<MaxUserClipPlanes; ++i) for (i=0; i<MaxUserClipPlanes; ++i)
...@@ -678,6 +684,13 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize, ...@@ -678,6 +684,13 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
#endif #endif
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
Params.HandleSRGB &= ((FeatureAvailable[IRR_ARB_framebuffer_sRGB] || FeatureAvailable[IRR_EXT_framebuffer_sRGB]) &&
FeatureAvailable[IRR_EXT_texture_sRGB]);
#if defined(GL_ARB_framebuffer_sRGB) || defined(GL_EXT_framebuffer_sRGB)
if (Params.HandleSRGB)
glEnable(GL_FRAMEBUFFER_SRGB);
#endif
// This is a fast replacement for NORMALIZE_NORMALS // This is a fast replacement for NORMALIZE_NORMALS
// if ((Version>101) || FeatureAvailable[IRR_EXT_rescale_normal]) // if ((Version>101) || FeatureAvailable[IRR_EXT_rescale_normal])
// glEnable(GL_RESCALE_NORMAL_EXT); // glEnable(GL_RESCALE_NORMAL_EXT);
...@@ -4421,7 +4434,7 @@ GLenum COpenGLDriver::primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const ...@@ -4421,7 +4434,7 @@ GLenum COpenGLDriver::primitiveTypeToGL(scene::E_PRIMITIVE_TYPE type) const
} }
GLenum COpenGLDriver::getGLBlend (E_BLEND_FACTOR factor) const GLenum COpenGLDriver::getGLBlend(E_BLEND_FACTOR factor) const
{ {
GLenum r = 0; GLenum r = 0;
switch (factor) switch (factor)
...@@ -4462,7 +4475,7 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, ...@@ -4462,7 +4475,7 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
{ {
#ifdef _IRR_COMPILE_WITH_OPENGL_ #ifdef _IRR_COMPILE_WITH_OPENGL_
COpenGLDriver* ogl = new COpenGLDriver(params, io, device); COpenGLDriver* ogl = new COpenGLDriver(params, io, device);
if (!ogl->initDriver(params, device)) if (!ogl->initDriver(device))
{ {
ogl->drop(); ogl->drop();
ogl = 0; ogl = 0;
...@@ -4498,7 +4511,7 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, ...@@ -4498,7 +4511,7 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
{ {
#ifdef _IRR_COMPILE_WITH_OPENGL_ #ifdef _IRR_COMPILE_WITH_OPENGL_
COpenGLDriver* ogl = new COpenGLDriver(params, io, device); COpenGLDriver* ogl = new COpenGLDriver(params, io, device);
if (!ogl->initDriver(params, device)) if (!ogl->initDriver(device))
{ {
ogl->drop(); ogl->drop();
ogl = 0; ogl = 0;
......
...@@ -33,19 +33,20 @@ namespace video ...@@ -33,19 +33,20 @@ namespace video
class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler
{ {
friend class COpenGLTexture;
public: public:
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceWin32* device); COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceWin32* device);
//! inits the windows specific parts of the open gl driver //! inits the windows specific parts of the open gl driver
bool initDriver(SIrrlichtCreationParameters params, CIrrDeviceWin32* device); bool initDriver(CIrrDeviceWin32* device);
bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceWin32* device); bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceWin32* device);
#endif #endif
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ #ifdef _IRR_COMPILE_WITH_X11_DEVICE_
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceLinux* device); COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceLinux* device);
//! inits the GLX specific parts of the open gl driver //! inits the GLX specific parts of the open gl driver
bool initDriver(SIrrlichtCreationParameters params, CIrrDeviceLinux* device); bool initDriver(CIrrDeviceLinux* device);
bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceLinux* device); bool changeRenderContext(const SExposedVideoData& videoData, CIrrDeviceLinux* device);
#endif #endif
...@@ -392,7 +393,7 @@ namespace video ...@@ -392,7 +393,7 @@ namespace video
void uploadClipPlane(u32 index); void uploadClipPlane(u32 index);
//! inits the parts of the open gl driver used on all platforms //! inits the parts of the open gl driver used on all platforms
bool genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer); bool genericDriverInit();
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData); virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData);
...@@ -472,6 +473,7 @@ namespace video ...@@ -472,6 +473,7 @@ namespace video
//! Render target type for render operations //! Render target type for render operations
E_RENDER_TARGET CurrentTarget; E_RENDER_TARGET CurrentTarget;
SIrrlichtCreationParameters Params;
bool Doublebuffer; bool Doublebuffer;
bool Stereo; bool Stereo;
......
...@@ -135,26 +135,31 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT ...@@ -135,26 +135,31 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
filtering = GL_LINEAR; filtering = GL_LINEAR;
colorformat = GL_RGBA; colorformat = GL_RGBA;
type = GL_UNSIGNED_BYTE; type = GL_UNSIGNED_BYTE;
GLenum internalformat = GL_RGBA;
switch(format) switch(format)
{ {
case ECF_A1R5G5B5: case ECF_A1R5G5B5:
colorformat=GL_BGRA_EXT; colorformat=GL_BGRA_EXT;
type=GL_UNSIGNED_SHORT_1_5_5_5_REV; type=GL_UNSIGNED_SHORT_1_5_5_5_REV;
return GL_RGBA; internalformat = GL_RGBA;
break;
case ECF_R5G6B5: case ECF_R5G6B5:
colorformat=GL_BGR; colorformat=GL_BGR;
type=GL_UNSIGNED_SHORT_5_6_5_REV; type=GL_UNSIGNED_SHORT_5_6_5_REV;
return GL_RGB; internalformat = GL_RGB;
break;
case ECF_R8G8B8: case ECF_R8G8B8:
colorformat=GL_BGR; colorformat=GL_BGR;
type=GL_UNSIGNED_BYTE; type=GL_UNSIGNED_BYTE;
return GL_RGB; internalformat = GL_RGB;
break;
case ECF_A8R8G8B8: case ECF_A8R8G8B8:
colorformat=GL_BGRA_EXT; colorformat=GL_BGRA_EXT;
if (Driver->Version > 101) if (Driver->Version > 101)
type=GL_UNSIGNED_INT_8_8_8_8_REV; type=GL_UNSIGNED_INT_8_8_8_8_REV;
return GL_RGBA; internalformat = GL_RGBA;
break;
// Floating Point texture formats. Thanks to Patryk "Nadro" Nadrowski. // Floating Point texture formats. Thanks to Patryk "Nadro" Nadrowski.
case ECF_R16F: case ECF_R16F:
{ {
...@@ -163,11 +168,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT ...@@ -163,11 +168,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RED; colorformat = GL_RED;
type = GL_FLOAT; type = GL_FLOAT;
return GL_R16F; internalformat = GL_R16F;
#else #else
return GL_RGB8; internalformat = GL_RGB8;
#endif #endif
} }
break;
case ECF_G16R16F: case ECF_G16R16F:
{ {
#ifdef GL_ARB_texture_rg #ifdef GL_ARB_texture_rg
...@@ -175,11 +181,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT ...@@ -175,11 +181,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RG; colorformat = GL_RG;
type = GL_FLOAT; type = GL_FLOAT;
return GL_RG16F; internalformat = GL_RG16F;
#else #else
return GL_RGB8; internalformat = GL_RGB8;
#endif #endif
} }
break;
case ECF_A16B16G16R16F: case ECF_A16B16G16R16F:
{ {
#ifdef GL_ARB_texture_rg #ifdef GL_ARB_texture_rg
...@@ -187,11 +194,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT ...@@ -187,11 +194,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RGBA; colorformat = GL_RGBA;
type = GL_FLOAT; type = GL_FLOAT;
return GL_RGBA16F_ARB; internalformat = GL_RGBA16F_ARB;
#else #else
return GL_RGBA8; internalformat = GL_RGBA8;
#endif #endif
} }
break;
case ECF_R32F: case ECF_R32F:
{ {
#ifdef GL_ARB_texture_rg #ifdef GL_ARB_texture_rg
...@@ -199,11 +207,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT ...@@ -199,11 +207,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RED; colorformat = GL_RED;
type = GL_FLOAT; type = GL_FLOAT;
return GL_R32F; internalformat = GL_R32F;
#else #else
return GL_RGB8; internalformat = GL_RGB8;
#endif #endif
} }
break;
case ECF_G32R32F: case ECF_G32R32F:
{ {
#ifdef GL_ARB_texture_rg #ifdef GL_ARB_texture_rg
...@@ -211,11 +220,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT ...@@ -211,11 +220,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RG; colorformat = GL_RG;
type = GL_FLOAT; type = GL_FLOAT;
return GL_RG32F; internalformat = GL_RG32F;
#else #else
return GL_RGB8; internalformat = GL_RGB8;
#endif #endif
} }
break;
case ECF_A32B32G32R32F: case ECF_A32B32G32R32F:
{ {
#ifdef GL_ARB_texture_float #ifdef GL_ARB_texture_float
...@@ -223,17 +233,28 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT ...@@ -223,17 +233,28 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RGBA; colorformat = GL_RGBA;
type = GL_FLOAT; type = GL_FLOAT;
return GL_RGBA32F_ARB; internalformat = GL_RGBA32F_ARB;
#else #else
return GL_RGBA8; internalformat = GL_RGBA8;
#endif #endif
} }
break;
default: default:
{ {
os::Printer::log("Unsupported texture format", ELL_ERROR); os::Printer::log("Unsupported texture format", ELL_ERROR);
return GL_RGBA8; internalformat = GL_RGBA8;
} }
} }
#if defined(GL_ARB_framebuffer_sRGB) || defined(GL_EXT_framebuffer_sRGB)
if (Driver->Params.HandleSRGB)
{
if (internalformat==GL_RGBA)
internalformat=GL_SRGB_ALPHA_EXT;
else if (internalformat==GL_RGB)
internalformat=GL_SRGB_EXT;
}
#endif
return internalformat;
} }
......
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