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
master
hybrid 2011-05-19 20:07:13 +00:00
parent 65120d77b8
commit 92f1299cd2
8 changed files with 198 additions and 146 deletions

View File

@ -29,6 +29,7 @@ namespace irr
Stencilbuffer(false),
Vsync(false),
AntiAlias(0),
HandleSRGB(false),
WithAlphaChannel(false),
Doublebuffer(true),
IgnoreInput(false),
@ -62,6 +63,7 @@ namespace irr
Stencilbuffer = other.Stencilbuffer;
Vsync = other.Vsync;
AntiAlias = other.AntiAlias;
HandleSRGB = other.HandleSRGB;
WithAlphaChannel = other.WithAlphaChannel;
Doublebuffer = other.Doublebuffer;
IgnoreInput = other.IgnoreInput;
@ -140,6 +142,21 @@ namespace irr
Default value: 0 - disabled */
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.
/** In some situations it might be desireable to get a color
buffer with an alpha channel, e.g. when rendering into a

View File

@ -29,20 +29,17 @@ namespace
}
//! constructor
CD3D9Driver::CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window,
bool fullscreen, bool stencilbuffer,
io::IFileSystem* io, bool pureSoftware)
: CNullDriver(io, screenSize), CurrentRenderMode(ERM_NONE),
CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io)
: CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE),
ResetRenderStates(true), Transformation3DChanged(false),
StencilBuffer(stencilbuffer), AntiAliasing(0),
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
WindowId(0), SceneSourceRect(0),
LastVertexType((video::E_VERTEX_TYPE)-1), VendorID(0),
MaxTextureUnits(0), MaxUserClipPlanes(0), MaxMRTs(1), NumSetMRTs(1),
MaxLightDistance(0.f), LastSetLight(-1), Cached2DModeSignature(0),
ColorFormat(ECF_A8R8G8B8), DeviceLost(false),
Fullscreen(fullscreen), DriverWasReset(true), OcclusionQuerySupport(false),
AlphaToCoverageSupport(false), DisplayAdapter(0)
DriverWasReset(true), OcclusionQuerySupport(false),
AlphaToCoverageSupport(false), Params(params)
{
#ifdef _DEBUG
setDebugName("CD3D9Driver");
@ -164,15 +161,8 @@ void CD3D9Driver::createMaterialRenderers()
//! initialises the Direct3D API
bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
HWND hwnd, u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, u8 antiAlias, u32 displayAdapter)
bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
{
HRESULT hr;
Fullscreen = fullScreen;
CurrentDepthBufferSize = screenSize;
DisplayAdapter = displayAdapter;
if (!pID3D)
{
D3DLibrary = LoadLibrary( __TEXT("d3d9.dll") );
@ -204,7 +194,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
// print device information
D3DADAPTER_IDENTIFIER9 dai;
if (!FAILED(pID3D->GetAdapterIdentifier(DisplayAdapter, 0, &dai)))
if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, 0, &dai)))
{
char tmp[512];
@ -232,8 +222,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
}
D3DDISPLAYMODE d3ddm;
hr = pID3D->GetAdapterDisplayMode(DisplayAdapter, &d3ddm);
if (FAILED(hr))
if (FAILED(pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm)))
{
os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR);
return false;
@ -241,19 +230,19 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
ZeroMemory(&present, sizeof(present));
present.BackBufferCount = 1;
present.EnableAutoDepthStencil = TRUE;
if (vsync)
present.BackBufferCount = 1;
present.EnableAutoDepthStencil = TRUE;
if (Params.Vsync)
present.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
else
present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
if (fullScreen)
if (Params.Fullscreen)
{
present.BackBufferWidth = screenSize.Width;
present.BackBufferHeight = screenSize.Height;
present.BackBufferWidth = Params.WindowSize.Width;
present.BackBufferHeight = Params.WindowSize.Height;
// request 32bit mode if user specified 32 bit, added by Thomas Stuefe
if (bits == 32)
if (Params.Bits == 32)
present.BackBufferFormat = D3DFMT_X8R8G8B8;
else
present.BackBufferFormat = D3DFMT_R5G6B5;
@ -268,7 +257,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
present.Windowed = TRUE;
}
UINT adapter = DisplayAdapter;
UINT adapter = Params.DisplayAdapter;
D3DDEVTYPE devtype = D3DDEVTYPE_HAL;
#ifndef _IRR_D3D_NO_SHADER_DEBUGGING
devtype = D3DDEVTYPE_REF;
@ -287,36 +276,35 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
#endif
// enable anti alias if possible and desired
if (antiAlias > 0)
if (Params.AntiAlias > 0)
{
if(antiAlias > 16)
antiAlias = 16;
if (Params.AntiAlias > 32)
Params.AntiAlias = 32;
DWORD qualityLevels = 0;
while(antiAlias > 0)
while(Params.AntiAlias > 0)
{
if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter,
devtype, present.BackBufferFormat, !fullScreen,
(D3DMULTISAMPLE_TYPE)antiAlias, &qualityLevels)))
devtype, present.BackBufferFormat, !Params.Fullscreen,
(D3DMULTISAMPLE_TYPE)Params.AntiAlias, &qualityLevels)))
{
present.MultiSampleType = (D3DMULTISAMPLE_TYPE)antiAlias;
present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias;
present.MultiSampleQuality = qualityLevels-1;
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
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);
}
}
AntiAliasing = antiAlias;
// check stencil buffer compatibility
if (StencilBuffer)
if (Params.Stencilbuffer)
{
present.AutoDepthStencilFormat = D3DFMT_D24S8;
if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
@ -334,7 +322,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
{
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,
present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat)))
{
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
if (!StencilBuffer)
if (!Params.Stencilbuffer)
{
present.AutoDepthStencilFormat = D3DFMT_D32;
if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
@ -373,18 +361,16 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
// create device
DWORD fpuPrecision = highPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0;
DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0;
if (pureSoftware)
{
hr = pID3D->CreateDevice(DisplayAdapter, D3DDEVTYPE_REF, hwnd,
fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice);
if (FAILED(hr))
if (FAILED(pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd,
fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice)))
os::Printer::log("Was not able to create Direct3D9 software device.", ELL_ERROR);
}
else
{
hr = pID3D->CreateDevice(adapter, devtype, hwnd,
HRESULT hr = pID3D->CreateDevice(adapter, devtype, hwnd,
fpuPrecision | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice);
if(FAILED(hr))
@ -409,13 +395,13 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
pID3DDevice->GetDeviceCaps(&Caps);
// disable stencilbuffer if necessary
if (StencilBuffer &&
if (Params.Stencilbuffer &&
(!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) ||
!(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) ||
!(Caps.StencilCaps & D3DSTENCILCAPS_KEEP)))
{
os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING);
StencilBuffer = false;
Params.Stencilbuffer = false;
}
// set default vertex shader
@ -440,7 +426,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK);
if (VendorID==0x10DE)//NVidia
AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(DisplayAdapter, D3DDEVTYPE_HAL,
AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(Params.DisplayAdapter, D3DDEVTYPE_HAL,
D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE,
(D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK);
else if (VendorID==0x1002)//ATI
@ -461,7 +447,7 @@ bool CD3D9Driver::initDriver(const core::dimension2d<u32>& screenSize,
DriverAttributes->setAttribute("MaxTextureLODBias", 16);
DriverAttributes->setAttribute("Version", 901);
DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)Caps.VertexShaderVersion*100);
DriverAttributes->setAttribute("AntiAlias", AntiAliasing);
DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias);
// set the renderstates
setRenderStates3DMode();
@ -537,7 +523,7 @@ bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color,
if (zBuffer)
flags |= D3DCLEAR_ZBUFFER;
if (StencilBuffer)
if (Params.Stencilbuffer)
flags |= D3DCLEAR_STENCIL;
if (flags)
@ -582,7 +568,10 @@ bool CD3D9Driver::endScene()
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))
return true;
@ -630,7 +619,7 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
// this but actually don't do this at all.
return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0;
case EVDF_STENCIL_BUFFER:
return StencilBuffer && Caps.StencilCaps;
return Params.Stencilbuffer && Caps.StencilCaps;
case EVDF_VERTEX_SHADER_1_1:
return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1);
case EVDF_VERTEX_SHADER_2_0:
@ -2096,6 +2085,10 @@ D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp)
void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates)
{
// This needs only to be updated onresets
if (Params.HandleSRGB && resetAllRenderstates)
pID3DDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE);
if (resetAllRenderstates ||
lastmaterial.AmbientColor != material.AmbientColor ||
lastmaterial.DiffuseColor != material.DiffuseColor ||
@ -2334,7 +2327,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
}
// enable antialiasing
if (AntiAliasing)
if (Params.AntiAlias)
{
if (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY))
pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
@ -2356,6 +2349,9 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
// texture address mode
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)
{
const float tmp = material.TextureLayer[st].LODBias * 0.125f;
@ -2767,7 +2763,7 @@ const wchar_t* CD3D9Driver::getName() const
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail)
{
if (!StencilBuffer || !count)
if (!Params.Stencilbuffer || !count)
return;
setRenderStatesStencilShadowMode(zfail);
@ -2809,7 +2805,7 @@ void CD3D9Driver::drawStencilShadowVolume(const core::vector3df* triangles, s32
void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
{
if (!StencilBuffer)
if (!Params.Stencilbuffer)
return;
S3DVertex vtx[4];
@ -3503,9 +3499,8 @@ IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, HWND window)
{
const bool pureSoftware = false;
CD3D9Driver* dx9 = new CD3D9Driver(params.WindowSize, window, params.Fullscreen, params.Stencilbuffer, io, pureSoftware);
if (!dx9->initDriver(params.WindowSize, window, params.Bits, params.Fullscreen, pureSoftware, params.HighPrecisionFPU,
params.Vsync, params.AntiAlias, params.DisplayAdapter))
CD3D9Driver* dx9 = new CD3D9Driver(params, io);
if (!dx9->initDriver(window, pureSoftware))
{
dx9->drop();
dx9 = 0;

View File

@ -15,6 +15,7 @@
#endif
#include "CNullDriver.h"
#include "SIrrCreationParameters.h"
#include "IMaterialRendererServices.h"
#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#include "irrMath.h" // needed by borland for sqrtf define
@ -50,8 +51,7 @@ namespace video
friend class CD3D9Texture;
//! constructor
CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window, bool fullscreen,
bool stencibuffer, io::IFileSystem* io, bool pureSoftware=false);
CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io);
//! destructor
virtual ~CD3D9Driver();
@ -191,9 +191,7 @@ namespace video
const core::vector3df& end, SColor color = SColor(255,255,255,255));
//! initialises the Direct3D API
bool initDriver(const core::dimension2d<u32>& screenSize, HWND hwnd,
u32 bits, bool fullScreen, bool pureSoftware,
bool highPrecisionFPU, bool vsync, u8 antiAlias, u32 displayAdapter);
bool initDriver(HWND hwnd, bool pureSoftware);
//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8
//! driver, it would return "Direct3D8.1".
@ -412,8 +410,6 @@ namespace video
SMaterial Material, LastMaterial;
bool ResetRenderStates; // bool to make all renderstates be reseted if set.
bool Transformation3DChanged;
bool StencilBuffer;
u8 AntiAliasing;
const ITexture* CurrentTexture[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.
@ -424,13 +420,14 @@ namespace video
IDirect3DSurface9* PrevRenderTarget;
core::dimension2d<u32> CurrentRendertargetSize;
core::dimension2d<u32> CurrentDepthBufferSize;
HWND WindowId;
core::rect<s32>* SceneSourceRect;
D3DCAPS9 Caps;
SIrrlichtCreationParameters Params;
E_VERTEX_TYPE LastVertexType;
SColorf AmbientLight;
@ -459,12 +456,9 @@ namespace video
ECOLOR_FORMAT ColorFormat;
D3DFORMAT D3DColorFormat;
bool DeviceLost;
bool Fullscreen;
bool DriverWasReset;
bool OcclusionQuerySupport;
bool AlphaToCoverageSupport;
u32 DisplayAdapter;
};

View File

@ -312,9 +312,9 @@ bool CD3D9Texture::createTexture(u32 flags, IImage * image)
{
LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9;
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;
HardwareMipMaps = true;

View File

@ -410,6 +410,11 @@ bool CIrrDeviceLinux::createWindow()
#elif defined(GLX_SGIS_multisample)
GLX_SAMPLE_BUFFERS_SGIS, 1,
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
GLX_STEREO, CreationParams.Stereobuffer?True:False,
None
@ -545,7 +550,7 @@ bool CIrrDeviceLinux::createWindow()
// attribute array for the draw buffer
int visualAttrBuffer[] =
{
GLX_RGBA, GL_TRUE,
GLX_RGBA, GLX_USE_GL,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
@ -557,6 +562,11 @@ bool CIrrDeviceLinux::createWindow()
// GLX_USE_GL, which is silently ignored by glXChooseVisual
CreationParams.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14
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
};
@ -613,7 +623,7 @@ bool CIrrDeviceLinux::createWindow()
}
#ifdef _DEBUG
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
// create color map

View File

@ -37,7 +37,7 @@ COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), RenderTargetTexture(0),
CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device),
DeviceType(EIDT_WIN32)
@ -79,7 +79,7 @@ bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrr
}
//! 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
const fschar_t* ClassName = __TEXT("GLCIrrDeviceWin32");
@ -105,11 +105,11 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
RECT clientSize;
clientSize.top = 0;
clientSize.left = 0;
clientSize.right = params.WindowSize.Width;
clientSize.bottom = params.WindowSize.Height;
clientSize.right = Params.WindowSize.Width;
clientSize.bottom = Params.WindowSize.Height;
DWORD style = WS_POPUP;
if (!params.Fullscreen)
if (!Params.Fullscreen)
style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
AdjustWindowRect(&clientSize, style, FALSE);
@ -138,17 +138,17 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
(params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering
(params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer
(Params.Doublebuffer?PFD_DOUBLEBUFFER:0) | // Must Support Double Buffering
(Params.Stereobuffer?PFD_STEREO:0), // Must Support Stereo Buffer
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, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
params.ZBufferBits, // Z-Buffer (Depth Buffer)
params.Stencilbuffer ? 1 : 0, // Stencil Buffer Depth
Params.ZBufferBits, // Z-Buffer (Depth Buffer)
Params.Stencilbuffer ? 1 : 0, // Stencil Buffer Depth
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
@ -161,10 +161,10 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
{
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);
params.Stencilbuffer = false;
Params.Stencilbuffer = false;
pfd.cStencilBits = 0;
}
else
@ -177,7 +177,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
}
if (i == 3)
{
if (params.Bits!=16)
if (Params.Bits!=16)
pfd.cDepthBits = 16;
else
continue;
@ -186,7 +186,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
if (i == 4)
{
// try single buffer
if (params.Doublebuffer)
if (Params.Doublebuffer)
pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
else
continue;
@ -268,15 +268,15 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
f32 fAttributes[] = {0.0, 0.0};
s32 iAttributes[] =
{
WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
WGL_DRAW_TO_WINDOW_ARB,1,
WGL_SUPPORT_OPENGL_ARB,1,
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, // 10,11
WGL_STENCIL_BITS_ARB,(params.Stencilbuffer) ? 1 : 0,
WGL_DOUBLE_BUFFER_ARB,(params.Doublebuffer) ? GL_TRUE : GL_FALSE,
WGL_STEREO_ARB,(params.Stereobuffer) ? GL_TRUE : GL_FALSE,
WGL_COLOR_BITS_ARB,(Params.Bits==32) ? 24 : 15,
WGL_ALPHA_BITS_ARB,(Params.Bits==32) ? 8 : 1,
WGL_DEPTH_BITS_ARB,Params.ZBufferBits, // 10,11
WGL_STENCIL_BITS_ARB,Params.Stencilbuffer ? 1 : 0,
WGL_DOUBLE_BUFFER_ARB,Params.Doublebuffer ? 1 : 0,
WGL_STEREO_ARB,Params.Stereobuffer ? 1 : 0,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
#ifdef WGL_ARB_multisample
WGL_SAMPLES_ARB,AntiAlias, // 20,21
@ -288,21 +288,26 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
WGL_SAMPLES_3DFX,AntiAlias, // 20,21
WGL_SAMPLE_BUFFERS_3DFX, 1,
#endif
#if 0
#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)
WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, GL_TRUE,
WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT, Params.HandleSRGB ? 1:0,
#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)
{
iAttributes[20]=0;
iAttributes[21]=0;
iAttributes[22]=0;
iAttributes[23]=0;
memmove(&iAttributes[20],&iAttributes[24],sizeof(int)*(iAttrSize-24));
iAttrSize -= 4;
}
s32 rv=0;
@ -313,7 +318,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
UINT numFormats=0;
const BOOL valid = wglChoosePixelFormat_ARB(HDc,iAttributes,fAttributes,1,&pixelFormat,&numFormats);
if (valid && numFormats>0)
if (valid && numFormats)
rv = pixelFormat;
else
iAttributes[21] -= 1;
@ -350,10 +355,10 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
{
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);
params.Stencilbuffer = false;
Params.Stencilbuffer = false;
pfd.cStencilBits = 0;
}
else
@ -366,7 +371,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
}
if (i == 3)
{
if (params.Bits!=16)
if (Params.Bits!=16)
pfd.cDepthBits = 16;
else
continue;
@ -391,6 +396,7 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
os::Printer::log("Cannot set the pixel format.", ELL_ERROR);
return false;
}
os::Printer::log("Pixel Format", core::stringc(PixelFormat).c_str(), ELL_DEBUG);
// create rendering context
#ifdef WGL_ARB_create_context
@ -446,9 +452,9 @@ bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDevi
ColorFormat = ECF_R5G6B5;
}
genericDriverInit(params.WindowSize, params.Stencilbuffer);
genericDriverInit();
extGlSwapInterval(params.Vsync ? 1 : 0);
extGlSwapInterval(Params.Vsync ? 1 : 0);
return true;
}
@ -465,14 +471,14 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), RenderTargetTexture(0),
CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
OSXDevice(device), DeviceType(EIDT_OSX)
{
#ifdef _DEBUG
setDebugName("COpenGLDriver");
#endif
genericDriverInit(params.WindowSize, params.Stencilbuffer);
genericDriverInit();
}
#endif
@ -488,7 +494,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
X11Device(device), DeviceType(EIDT_X11)
{
@ -532,18 +538,18 @@ bool COpenGLDriver::changeRenderContext(const SExposedVideoData& videoData, CIrr
//! inits the open gl driver
bool COpenGLDriver::initDriver(irr::SIrrlichtCreationParameters params, CIrrDeviceLinux* device)
bool COpenGLDriver::initDriver(CIrrDeviceLinux* device)
{
ExposedData.OpenGLLinux.X11Context = glXGetCurrentContext();
ExposedData.OpenGLLinux.X11Display = glXGetCurrentDisplay();
ExposedData.OpenGLLinux.X11Window = (unsigned long)params.WindowId;
ExposedData.OpenGLLinux.X11Window = (unsigned long)Params.WindowId;
Drawable = glXGetCurrentDrawable();
X11Display = (Display*)ExposedData.OpenGLLinux.X11Display;
genericDriverInit(params.WindowSize, params.Stencilbuffer);
genericDriverInit();
// set vsync
extGlSwapInterval(params.Vsync ? 1 : 0);
extGlSwapInterval(Params.Vsync ? 1 : 0);
return true;
}
@ -561,7 +567,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
CurrentTarget(ERT_FRAME_BUFFER),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
Doublebuffer(params.Doublebuffer), Stereo(params.Stereobuffer),
SDLDevice(device), DeviceType(EIDT_SDL)
{
@ -569,7 +575,7 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
setDebugName("COpenGLDriver");
#endif
genericDriverInit(params.WindowSize, params.Stencilbuffer);
genericDriverInit();
}
#endif // _IRR_COMPILE_WITH_SDL_DEVICE_
@ -612,7 +618,7 @@ COpenGLDriver::~COpenGLDriver()
// METHODS
// -----------------------------------------------------------------------
bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer)
bool COpenGLDriver::genericDriverInit()
{
Name=L"OpenGL ";
Name.append(glGetString(GL_VERSION));
@ -634,7 +640,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
for (i=0; i<MATERIAL_MAX_TEXTURES; ++i)
CurrentTexture[i]=0;
// load extensions
initExtensions(stencilBuffer);
initExtensions(Params.Stencilbuffer);
if (queryFeature(EVDF_ARB_GLSL))
{
char buf[32];
@ -662,7 +668,7 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
glPixelStorei(GL_PACK_ALIGNMENT, 1);
// Reset The Current Viewport
glViewport(0, 0, screenSize.Width, screenSize.Height);
glViewport(0, 0, Params.WindowSize.Width, Params.WindowSize.Height);
UserClipPlanes.reallocate(MaxUserClipPlanes);
for (i=0; i<MaxUserClipPlanes; ++i)
@ -678,6 +684,13 @@ bool COpenGLDriver::genericDriverInit(const core::dimension2d<u32>& screenSize,
#endif
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
// if ((Version>101) || FeatureAvailable[IRR_EXT_rescale_normal])
// glEnable(GL_RESCALE_NORMAL_EXT);
@ -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;
switch (factor)
@ -4462,7 +4475,7 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
COpenGLDriver* ogl = new COpenGLDriver(params, io, device);
if (!ogl->initDriver(params, device))
if (!ogl->initDriver(device))
{
ogl->drop();
ogl = 0;
@ -4498,7 +4511,7 @@ IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
COpenGLDriver* ogl = new COpenGLDriver(params, io, device);
if (!ogl->initDriver(params, device))
if (!ogl->initDriver(device))
{
ogl->drop();
ogl = 0;

View File

@ -33,19 +33,20 @@ namespace video
class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler
{
friend class COpenGLTexture;
public:
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceWin32* device);
//! 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);
#endif
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceLinux* device);
//! 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);
#endif
@ -392,7 +393,7 @@ namespace video
void uploadClipPlane(u32 index);
//! 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)
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData);
@ -472,6 +473,7 @@ namespace video
//! Render target type for render operations
E_RENDER_TARGET CurrentTarget;
SIrrlichtCreationParameters Params;
bool Doublebuffer;
bool Stereo;

View File

@ -135,26 +135,31 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
filtering = GL_LINEAR;
colorformat = GL_RGBA;
type = GL_UNSIGNED_BYTE;
GLenum internalformat = GL_RGBA;
switch(format)
{
case ECF_A1R5G5B5:
colorformat=GL_BGRA_EXT;
type=GL_UNSIGNED_SHORT_1_5_5_5_REV;
return GL_RGBA;
internalformat = GL_RGBA;
break;
case ECF_R5G6B5:
colorformat=GL_BGR;
type=GL_UNSIGNED_SHORT_5_6_5_REV;
return GL_RGB;
internalformat = GL_RGB;
break;
case ECF_R8G8B8:
colorformat=GL_BGR;
type=GL_UNSIGNED_BYTE;
return GL_RGB;
internalformat = GL_RGB;
break;
case ECF_A8R8G8B8:
colorformat=GL_BGRA_EXT;
if (Driver->Version > 101)
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.
case ECF_R16F:
{
@ -163,11 +168,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RED;
type = GL_FLOAT;
return GL_R16F;
internalformat = GL_R16F;
#else
return GL_RGB8;
internalformat = GL_RGB8;
#endif
}
break;
case ECF_G16R16F:
{
#ifdef GL_ARB_texture_rg
@ -175,11 +181,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RG;
type = GL_FLOAT;
return GL_RG16F;
internalformat = GL_RG16F;
#else
return GL_RGB8;
internalformat = GL_RGB8;
#endif
}
break;
case ECF_A16B16G16R16F:
{
#ifdef GL_ARB_texture_rg
@ -187,11 +194,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RGBA;
type = GL_FLOAT;
return GL_RGBA16F_ARB;
internalformat = GL_RGBA16F_ARB;
#else
return GL_RGBA8;
internalformat = GL_RGBA8;
#endif
}
break;
case ECF_R32F:
{
#ifdef GL_ARB_texture_rg
@ -199,11 +207,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RED;
type = GL_FLOAT;
return GL_R32F;
internalformat = GL_R32F;
#else
return GL_RGB8;
internalformat = GL_RGB8;
#endif
}
break;
case ECF_G32R32F:
{
#ifdef GL_ARB_texture_rg
@ -211,11 +220,12 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RG;
type = GL_FLOAT;
return GL_RG32F;
internalformat = GL_RG32F;
#else
return GL_RGB8;
internalformat = GL_RGB8;
#endif
}
break;
case ECF_A32B32G32R32F:
{
#ifdef GL_ARB_texture_float
@ -223,17 +233,28 @@ GLint COpenGLTexture::getOpenGLFormatAndParametersFromColorFormat(ECOLOR_FORMAT
colorformat = GL_RGBA;
type = GL_FLOAT;
return GL_RGBA32F_ARB;
internalformat = GL_RGBA32F_ARB;
#else
return GL_RGBA8;
internalformat = GL_RGBA8;
#endif
}
break;
default:
{
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;
}