diff --git a/lib/irrlicht/source/Irrlicht/CD3D8Driver.cpp b/lib/irrlicht/source/Irrlicht/CD3D8Driver.cpp deleted file mode 100644 index 9886b3756..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8Driver.cpp +++ /dev/null @@ -1,2455 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" - -#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE -#include "CD3D8Driver.h" - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ - -#include "os.h" -#include "S3DVertex.h" -#include "CD3D8Texture.h" -#include "CD3D8MaterialRenderer.h" -#include "CD3D8ShaderMaterialRenderer.h" -#include "CD3D8NormalMapRenderer.h" -#include "CD3D8ParallaxMapRenderer.h" -#include "SIrrCreationParameters.h" - -namespace irr -{ -namespace video -{ - - -//! constructor -CD3D8Driver::CD3D8Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) - : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE), - ResetRenderStates(true), Transformation3DChanged(false), - D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), - WindowId(0), SceneSourceRect(0), - LastVertexType((video::E_VERTEX_TYPE)-1), - MaxTextureUnits(0), MaxUserClipPlanes(0), - MaxLightDistance(0), LastSetLight(-1), DeviceLost(false), - DriverWasReset(true), Params(params) -{ - #ifdef _DEBUG - setDebugName("CD3D8Driver"); - #endif - - printVersion(); - - for (u32 i=0; iRelease(); - - if (pID3D) - pID3D->Release(); -} - - -void CD3D8Driver::createMaterialRenderers() -{ - // create D3D8 material renderers - - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); - - // add the same renderer for all lightmap types - CD3D8MaterialRenderer_LIGHTMAP* lmr = new CD3D8MaterialRenderer_LIGHTMAP(pID3DDevice, this); - addMaterialRenderer(lmr); // for EMT_LIGHTMAP: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: - lmr->drop(); - - // add remaining material renderers - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); - - // add normal map renderers - s32 tmp = 0; - video::IMaterialRenderer* renderer = 0; - - renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_SOLID].Renderer); - renderer->drop(); - - renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); - renderer->drop(); - - renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); - renderer->drop(); - - // add parallax map renderers - - renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_SOLID].Renderer); - renderer->drop(); - - renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); - renderer->drop(); - - renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); - renderer->drop(); - - // add basic 1 texture blending - addAndDropMaterialRenderer(new CD3D8MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); -} - - -//! initialises the Direct3D API -bool CD3D8Driver::initDriver(HWND hwnd, bool pureSoftware) -{ - HRESULT hr; - typedef IDirect3D8 * (__stdcall *D3DCREATETYPE)(UINT); - -#if defined( _IRR_XBOX_PLATFORM_) - D3DCREATETYPE d3dCreate = (D3DCREATETYPE) &Direct3DCreate8; -#else - D3DLibrary = LoadLibrary( __TEXT("d3d8.dll") ); - - if (!D3DLibrary) - { - os::Printer::log("Error, could not load d3d8.dll.", ELL_ERROR); - return false; - } - - D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate8"); - - if (!d3dCreate) - { - os::Printer::log("Error, could not get proc adress of Direct3DCreate8.", ELL_ERROR); - return false; - } -#endif - - //just like pID3D = Direct3DCreate8(D3D_SDK_VERSION); - pID3D = (*d3dCreate)(D3D_SDK_VERSION); - - if (!pID3D) - { - os::Printer::log("Error initializing D3D.", ELL_ERROR); - return false; - } - - // print device information - D3DADAPTER_IDENTIFIER8 dai; - if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, D3DENUM_NO_WHQL_LEVEL, &dai))) - { - char tmp[512]; - - s32 Product = HIWORD(dai.DriverVersion.HighPart); - s32 Version = LOWORD(dai.DriverVersion.HighPart); - s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); - s32 Build = LOWORD(dai.DriverVersion.LowPart); - - sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, - SubVersion, Build); - os::Printer::log(tmp, ELL_INFORMATION); - } - - D3DDISPLAYMODE d3ddm; - hr = pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm); - if (FAILED(hr)) - { - os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); - return false; - } - - ZeroMemory(&present, sizeof(present)); - - present.SwapEffect = D3DSWAPEFFECT_DISCARD; - present.Windowed = TRUE; - present.BackBufferFormat = d3ddm.Format; - present.EnableAutoDepthStencil = TRUE; - - if (Params.Fullscreen) - { - present.SwapEffect = D3DSWAPEFFECT_FLIP; - present.Windowed = FALSE; - present.BackBufferWidth = Params.WindowSize.Width; - present.BackBufferHeight = Params.WindowSize.Height; - present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - - if (Params.Vsync) - present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; - else - present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - - if (Params.Bits == 32) - present.BackBufferFormat = D3DFMT_X8R8G8B8; - else - present.BackBufferFormat = D3DFMT_R5G6B5; - } - - D3DDEVTYPE devtype = D3DDEVTYPE_HAL; - #ifndef _IRR_D3D_NO_SHADER_DEBUGGING - devtype = D3DDEVTYPE_REF; - #endif - - // enable anti alias if possible and whished - if (Params.AntiAlias > 0) - { - if(Params.AntiAlias > 16) - Params.AntiAlias = 16; - - while(Params.AntiAlias > 0) - { - if(!FAILED(pID3D->CheckDeviceMultiSampleType(Params.DisplayAdapter, - devtype , present.BackBufferFormat, !Params.Fullscreen, - (D3DMULTISAMPLE_TYPE)Params.AntiAlias))) - { - present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias; - present.SwapEffect = D3DSWAPEFFECT_DISCARD; - break; - } - --Params.AntiAlias; - } - - if(Params.AntiAlias==0) - os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); - } - - // check stencil buffer compatibility - if (Params.Stencilbuffer) - { - present.AutoDepthStencilFormat = D3DFMT_D24S8; - if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { -#if !defined( _IRR_XBOX_PLATFORM_) - present.AutoDepthStencilFormat = D3DFMT_D24X4S4; - if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - present.AutoDepthStencilFormat = D3DFMT_D15S1; - if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); - Params.Stencilbuffer = false; - } - } -#endif - } - else - if(FAILED(pID3D->CheckDepthStencilMatch(Params.DisplayAdapter, devtype, - present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) - { - os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); - Params.Stencilbuffer = false; - } - } - // do not use else here to cope with flag change in previous block - if (!Params.Stencilbuffer) - { -#if !defined( _IRR_XBOX_PLATFORM_) - present.AutoDepthStencilFormat = D3DFMT_D32; - if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - present.AutoDepthStencilFormat = D3DFMT_D24X8; - if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - present.AutoDepthStencilFormat = D3DFMT_D16; - if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); - return false; - } - } - } -#else - present.AutoDepthStencilFormat = D3DFMT_D16; - if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); - return false; - } -#endif - } - - // create device -#if defined( _IRR_XBOX_PLATFORM_) - DWORD fpuPrecision = 0; -#else - DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; - DWORD multithreaded = Params.DriverMultithreaded ? D3DCREATE_MULTITHREADED : 0; -#endif - if (pureSoftware) - { - hr = pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd, - fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); - - if (FAILED(hr)) - os::Printer::log("Was not able to create Direct3D8 software device.", ELL_ERROR); - } - else - { - hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, - fpuPrecision | multithreaded | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); - - if(FAILED(hr)) - hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, - fpuPrecision | multithreaded | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); - if(FAILED(hr)) - hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, - fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); - if (FAILED(hr)) - os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); - } - - if (!pID3DDevice) - { - os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); - return false; - } - - // get caps - pID3DDevice->GetDeviceCaps(&Caps); - - 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); - Params.Stencilbuffer = false; - } - - // set default vertex shader - setVertexShader(EVT_STANDARD); - - // enable antialiasing - if (Params.AntiAlias>0) - pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); - - // set fog mode - setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); - - // set exposed data - ExposedData.D3D8.D3D8 = pID3D; - ExposedData.D3D8.D3DDev8 = pID3DDevice; - ExposedData.D3D8.HWnd = hwnd; - - ResetRenderStates = true; - - // create materials - createMaterialRenderers(); - - MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); - MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; - - DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits); - DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures); - DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights); - DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy); - DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes); - DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex); - DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth)); - DriverAttributes->setAttribute("MaxTextureLODBias", 16.f); - DriverAttributes->setAttribute("Version", 800); - DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)Caps.VertexShaderVersion*100); - DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias); - - // set the renderstates - setRenderStates3DMode(); - - // so far so good. - return true; -} - - -//! applications must call this method before performing any rendering. returns false if failed. -bool CD3D8Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, - const SExposedVideoData& videoData, core::rect* sourceRect) -{ - CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); - WindowId = (HWND)videoData.D3D8.HWnd; - SceneSourceRect = sourceRect; - - if (!pID3DDevice) - return false; - - HRESULT hr; - if (DeviceLost) - { -#ifndef _IRR_XBOX_PLATFORM_ - if(FAILED(hr = pID3DDevice->TestCooperativeLevel())) - { - if (hr == D3DERR_DEVICELOST) - { - Sleep(100); - hr = pID3DDevice->TestCooperativeLevel(); - if (hr == D3DERR_DEVICELOST) - return false; - } - - if ((hr == D3DERR_DEVICENOTRESET) && !reset()) - return false; - } -#endif - } - - DWORD flags = 0; - - if (backBuffer) - flags |= D3DCLEAR_TARGET; - - if (zBuffer) - flags |= D3DCLEAR_ZBUFFER; - - if (Params.Stencilbuffer) - flags |= D3DCLEAR_STENCIL; - - if (flags) - { - hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); - if (FAILED(hr)) - os::Printer::log("Direct3D8 clear failed.", ELL_WARNING); - } - - hr = pID3DDevice->BeginScene(); - if (FAILED(hr)) - { - os::Printer::log("Direct3D8 begin scene failed.", ELL_WARNING); - return false; - } - - return true; -} - - -//! applications must call this method after performing any rendering. returns false if failed. -bool CD3D8Driver::endScene() -{ - CNullDriver::endScene(); - DriverWasReset=false; - - HRESULT hr = pID3DDevice->EndScene(); - if (FAILED(hr)) - { - os::Printer::log("DIRECT3D8 end scene failed.", ELL_WARNING); - return false; - } - - RECT* srcRct = 0; - RECT sourceRectData; - if ( SceneSourceRect) - { - srcRct = &sourceRectData; - sourceRectData.left = SceneSourceRect->UpperLeftCorner.X; - sourceRectData.top = SceneSourceRect->UpperLeftCorner.Y; - sourceRectData.right = SceneSourceRect->LowerRightCorner.X; - sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y; - } - - hr = pID3DDevice->Present(srcRct, NULL, WindowId, NULL); - - if (SUCCEEDED(hr)) - return true; - - if (hr == D3DERR_DEVICELOST) - { - DeviceLost = true; - os::Printer::log("DIRECT3D8 device lost.", ELL_WARNING); - } - else - os::Printer::log("DIRECT3D8 present failed.", ELL_WARNING); - return false; -} - - -//! resets the device -bool CD3D8Driver::reset() -{ - u32 i; - os::Printer::log("Resetting D3D8 device.", ELL_INFORMATION); - - for (i=0; iisRenderTarget()) - { - IDirect3DTexture8* tex = ((CD3D8Texture*)(Textures[i].Surface))->getDX8Texture(); - if (tex) - tex->Release(); - } - } - DriverWasReset=true; - - HRESULT hr = pID3DDevice->Reset(&present); - - for (i=0; iisRenderTarget()) - ((CD3D8Texture*)(Textures[i].Surface))->createRenderTarget(); - } - - if (FAILED(hr)) - { - if (hr == D3DERR_DEVICELOST) - { - DeviceLost = true; - os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); - } - else - os::Printer::log("Resetting failed.", ELL_WARNING); - return false; - } - - DeviceLost = false; - ResetRenderStates = true; - LastVertexType = (E_VERTEX_TYPE)-1; - - for (i=0; i= D3DVS_VERSION(1,1); - case EVDF_VERTEX_SHADER_2_0: - return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); - case EVDF_VERTEX_SHADER_3_0: - return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); - case EVDF_PIXEL_SHADER_1_1: - return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); - case EVDF_PIXEL_SHADER_1_2: - return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); - case EVDF_PIXEL_SHADER_1_3: - return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); - case EVDF_PIXEL_SHADER_1_4: - return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); - case EVDF_PIXEL_SHADER_2_0: - return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); - case EVDF_PIXEL_SHADER_3_0: - return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); - case EVDF_TEXTURE_NSQUARE: - return (Caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0; - case EVDF_TEXTURE_NPOT: - return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; - case EVDF_COLOR_MASK: - return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; - case EVDF_BLEND_OPERATIONS: - case EVDF_TEXTURE_MATRIX: - return true; - default: - return false; - }; -} - - -//! sets transformation -void CD3D8Driver::setTransform(E_TRANSFORMATION_STATE state, - const core::matrix4& mat) -{ - switch(state) - { - case ETS_VIEW: - pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); - Transformation3DChanged = true; - break; - case ETS_WORLD: - pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); - Transformation3DChanged = true; - break; - case ETS_PROJECTION: - pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); - Transformation3DChanged = true; - break; - case ETS_COUNT: - return; - default: - if (state-ETS_TEXTURE_0 < MATERIAL_MAX_TEXTURES) - { - pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); - pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), - (D3DMATRIX*)((void*)mat.pointer())); - } - break; - } - - Matrices[state] = mat; -} - - -//! sets the current Texture -bool CD3D8Driver::setActiveTexture(u32 stage, const video::ITexture* texture) -{ - if (CurrentTexture[stage] == texture) - return true; - - if (texture && (texture->getDriverType() != EDT_DIRECT3D8)) - { - os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); - return false; - } - - CurrentTexture[stage] = texture; - - if (!texture) - { - pID3DDevice->SetTexture(stage, 0); - pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - } - else - { - pID3DDevice->SetTexture(stage, ((const CD3D8Texture*)texture)->getDX8Texture()); - } - return true; -} - - -//! sets a material -void CD3D8Driver::setMaterial(const SMaterial& material) -{ - Material = material; - OverrideMaterial.apply(Material); - - for (u32 i=0; igetDriverType() != EDT_DIRECT3D8) - { - os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); - return false; - } - - // check for valid render target - - CD3D8Texture* tex = (CD3D8Texture*)texture; - - if (texture && !tex->isRenderTarget()) - { - os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); - return false; - } - - if (texture && (tex->getSize().Width > ScreenSize.Width || - tex->getSize().Height > ScreenSize.Height )) - { - os::Printer::log("Error: Tried to set a render target texture which is bigger than the screen.", ELL_ERROR); - return false; - } - - // check if we should set the previous RT back - - bool ret = true; - - if (tex == 0) - { - if (PrevRenderTarget) - { - IDirect3DSurface8* dss = 0; - pID3DDevice->GetDepthStencilSurface(&dss); - - if (FAILED(pID3DDevice->SetRenderTarget(PrevRenderTarget, dss))) - { - os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); - ret = false; - } - - if (dss) - dss->Release(); - - CurrentRendertargetSize = core::dimension2d(0,0); - PrevRenderTarget->Release(); - PrevRenderTarget = 0; - } - } - else - { - // we want to set a new target. so do this. - - // store previous target - - if (!PrevRenderTarget && (FAILED(pID3DDevice->GetRenderTarget(&PrevRenderTarget)))) - { - os::Printer::log("Could not get previous render target.", ELL_ERROR); - return false; - } - - // set new render target - - IDirect3DSurface8* dss = 0; - pID3DDevice->GetDepthStencilSurface(&dss); - - if (FAILED(pID3DDevice->SetRenderTarget(tex->getRenderTargetSurface(), dss))) - { - os::Printer::log("Error: Could not set render target.", ELL_ERROR); - ret = false; - } - - if (dss) - dss->Release(); - - CurrentRendertargetSize = tex->getSize(); - } - Transformation3DChanged = true; - - if (clearBackBuffer || clearZBuffer) - { - DWORD flags = 0; - - if (clearBackBuffer) - flags |= D3DCLEAR_TARGET; - - if (clearZBuffer) - flags |= D3DCLEAR_ZBUFFER; - - pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); - } - - return ret; -} - - -//! Creates a render target texture. -ITexture* CD3D8Driver::addRenderTargetTexture( - const core::dimension2d& size, const io::path& name, - const ECOLOR_FORMAT format) -{ - CD3D8Texture* tex = new CD3D8Texture(this, size, name); - if (tex) - { - if (!tex->Texture) - { - tex->drop(); - return 0; - } - addTexture(tex); - tex->drop(); - } - return tex; -} - - -//! sets a viewport -void CD3D8Driver::setViewPort(const core::rect& area) -{ - core::rect vp(area); - core::rect rendert(0,0, ScreenSize.Width, ScreenSize.Height); - vp.clipAgainst(rendert); - - D3DVIEWPORT8 viewPort; - viewPort.X = vp.UpperLeftCorner.X; - viewPort.Y = vp.UpperLeftCorner.Y; - viewPort.Width = vp.getWidth(); - viewPort.Height = vp.getHeight(); - viewPort.MinZ = 0.0f; - viewPort.MaxZ = 1.0f; - - HRESULT hr = D3DERR_INVALIDCALL; - if (vp.getHeight()>0 && vp.getWidth()>0) - hr = pID3DDevice->SetViewport(&viewPort); - - if (FAILED(hr)) - os::Printer::log("Failed setting the viewport.", ELL_WARNING); - - ViewPort = vp; -} - - -//! gets the area of the current viewport -const core::rect& CD3D8Driver::getViewPort() const -{ - return ViewPort; -} - - -//! draws a vertex primitive list -void CD3D8Driver::drawVertexPrimitiveList(const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType) -{ - if (!checkPrimitiveCount(primitiveCount)) - return; - - CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); - - if (!vertexCount || !primitiveCount) - return; - - draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, - vType, pType, iType, true); -} - - -//! draws a vertex primitive list in 2d -void CD3D8Driver::draw2DVertexPrimitiveList(const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType) -{ - if (!checkPrimitiveCount(primitiveCount)) - return; - - CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); - - if (!vertexCount || !primitiveCount) - return; - - draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, - vType, pType, iType, false); -} - - -void CD3D8Driver::draw2D3DVertexPrimitiveList(const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType, bool is3D) -{ - setVertexShader(vType); - - const u32 stride = getVertexPitchFromType(vType); - - D3DFORMAT indexType=D3DFMT_UNKNOWN; - switch (iType) - { - case (EIT_16BIT): - { - indexType=D3DFMT_INDEX16; - break; - } - case (EIT_32BIT): - { - indexType=D3DFMT_INDEX32; - break; - } - } - - if (is3D) - { - if (!setRenderStates3DMode()) - return; - } - else - { - if (Material.MaterialType==EMT_ONETEXTURE_BLEND) - { - E_BLEND_FACTOR srcFact; - E_BLEND_FACTOR dstFact; - E_MODULATE_FUNC modulo; - u32 alphaSource; - unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); - setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); - } - else - setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); - } - - switch (pType) - { - case scene::EPT_POINT_SPRITES: - case scene::EPT_POINTS: - { - f32 tmp=Material.Thickness/getScreenSize().Height; - if (pType==scene::EPT_POINT_SPRITES) - pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&tmp)); - tmp=1.0f; - pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp)); - pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp)); - pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp)); - tmp=0.0f; - pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp)); - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); - if (pType==scene::EPT_POINT_SPRITES) - pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); - } - break; - case scene::EPT_LINE_STRIP: - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - break; - case scene::EPT_LINE_LOOP: - { - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, - primitiveCount - 1, indexList, indexType, vertices, stride); - u16 tmpIndices[] = {primitiveCount - 1, 0}; - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, - 1, tmpIndices, indexType, vertices, stride); - } - break; - case scene::EPT_LINES: - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - break; - case scene::EPT_TRIANGLE_STRIP: - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - break; - case scene::EPT_TRIANGLE_FAN: - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - break; - case scene::EPT_TRIANGLES: - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - break; - } -} - - -//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. -void CD3D8Driver::draw2DImage(const video::ITexture* texture, - const core::position2d& pos, - const core::rect& sourceRect, - const core::rect* clipRect, SColor color, - bool useAlphaChannelOfTexture) -{ - if (!texture) - return; - - if (!sourceRect.isValid()) - return; - - if (!setActiveTexture(0, texture)) - return; - - core::position2d targetPos = pos; - core::position2d sourcePos = sourceRect.UpperLeftCorner; - // This needs to be signed as it may go negative. - core::dimension2d sourceSize(sourceRect.getSize()); - const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - - if (clipRect) - { - if (targetPos.X < clipRect->UpperLeftCorner.X) - { - sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; - if (sourceSize.Width <= 0) - return; - - sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; - targetPos.X = clipRect->UpperLeftCorner.X; - } - - if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) - { - sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; - if (sourceSize.Width <= 0) - return; - } - - if (targetPos.Y < clipRect->UpperLeftCorner.Y) - { - sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; - if (sourceSize.Height <= 0) - return; - - sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; - targetPos.Y = clipRect->UpperLeftCorner.Y; - } - - if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) - { - sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; - if (sourceSize.Height <= 0) - return; - } - } - - // clip these coordinates - - if (targetPos.X<0) - { - sourceSize.Width += targetPos.X; - if (sourceSize.Width <= 0) - return; - - sourcePos.X -= targetPos.X; - targetPos.X = 0; - } - - if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) - { - sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; - if (sourceSize.Width <= 0) - return; - } - - if (targetPos.Y<0) - { - sourceSize.Height += targetPos.Y; - if (sourceSize.Height <= 0) - return; - - sourcePos.Y -= targetPos.Y; - targetPos.Y = 0; - } - - if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) - { - sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; - if (sourceSize.Height <= 0) - return; - } - - // ok, we've clipped everything. - // now draw it. - - core::rect tcoords; - tcoords.UpperLeftCorner.X = (f32)sourcePos.X / texture->getOriginalSize().Width ; - tcoords.UpperLeftCorner.Y = (f32)sourcePos.Y / texture->getOriginalSize().Height; - tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + (f32)sourceSize.Width / texture->getOriginalSize().Width; - tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + (f32)sourceSize.Height / texture->getOriginalSize().Height; - - const core::rect poss(targetPos, sourceSize); - - setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); - - S3DVertex vtx[4]; - vtx[0] = S3DVertex((f32)poss.UpperLeftCorner.X, - (f32)poss.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); - vtx[1] = S3DVertex((f32)poss.LowerRightCorner.X, - (f32)poss.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); - vtx[2] = S3DVertex((f32)poss.LowerRightCorner.X, - (f32)poss.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); - vtx[3] = S3DVertex((f32)poss.UpperLeftCorner.X, - (f32)poss.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); - - const s16 indices[6] = {0,1,2,0,2,3}; - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], - D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); -} - - -void CD3D8Driver::draw2DImage(const video::ITexture* texture, - const core::rect& destRect, - const core::rect& sourceRect, - const core::rect* clipRect, - const video::SColor* const colors, - bool useAlphaChannelOfTexture) -{ - if(!texture) - return; - - const core::dimension2d& ss = texture->getOriginalSize(); - core::rect tcoords; - tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; - tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; - tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; - tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; - - core::rect clippedRect(destRect); - if (clipRect) - { - clippedRect.clipAgainst(*clipRect); - - //tcoords must be clipped by the same factors - const f32 tcWidth = tcoords.getWidth(); - const f32 tcHeight = tcoords.getHeight(); - - const f32 invDestRectWidth = 1.f / (f32)(destRect.getWidth()); - f32 scale = (f32)(clippedRect.UpperLeftCorner.X - destRect.UpperLeftCorner.X) * invDestRectWidth; - tcoords.UpperLeftCorner.X += scale * tcWidth; - scale = (f32)(destRect.LowerRightCorner.X - clippedRect.LowerRightCorner.X) * invDestRectWidth; - tcoords.LowerRightCorner.X -= scale * tcWidth; - - const f32 invDestRectHeight = 1.f / (f32)(destRect.getHeight()); - scale = (f32)(clippedRect.UpperLeftCorner.Y - destRect.UpperLeftCorner.Y) * invDestRectHeight; - tcoords.UpperLeftCorner.Y += scale * tcHeight; - scale = (f32)(destRect.LowerRightCorner.Y - clippedRect.LowerRightCorner.Y) * invDestRectHeight; - tcoords.LowerRightCorner.Y -= scale * tcHeight; - } - - const video::SColor temp[4] = - { - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF - }; - - const video::SColor* const useColor = colors ? colors : temp; - - S3DVertex vtx[4]; // clock wise - vtx[0] = S3DVertex((f32)clippedRect.UpperLeftCorner.X, (f32)clippedRect.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, useColor[0], - tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); - vtx[1] = S3DVertex((f32)clippedRect.LowerRightCorner.X, (f32)clippedRect.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, useColor[3], - tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); - vtx[2] = S3DVertex((f32)clippedRect.LowerRightCorner.X, (f32)clippedRect.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, useColor[2], - tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); - vtx[3] = S3DVertex((f32)clippedRect.UpperLeftCorner.X, (f32)clippedRect.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, useColor[1], - tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); - - const s16 indices[6] = {0,1,2,0,2,3}; - - setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || - useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, - true, useAlphaChannelOfTexture); - - setActiveTexture(0, texture); - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], - D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); -} - - -//!Draws an 2d rectangle with a gradient. -void CD3D8Driver::draw2DRectangle(const core::rect& position, - SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, - SColor colorRightDown, const core::rect* clip) -{ - core::rect pos(position); - - if (clip) - pos.clipAgainst(*clip); - - if (!pos.isValid()) - return; - - S3DVertex vtx[4]; - vtx[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); - vtx[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); - vtx[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); - vtx[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); - - const s16 indices[6] = {0,1,2,0,2,3}; - - setRenderStates2DMode( - colorLeftUp.getAlpha() < 255 || - colorRightUp.getAlpha() < 255 || - colorLeftDown.getAlpha() < 255 || - colorRightDown.getAlpha() < 255, false, false); - - setActiveTexture(0,0); - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], - D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); -} - - -//! Draws a 2d line. -void CD3D8Driver::draw2DLine(const core::position2d& start, - const core::position2d& end, - SColor color) -{ - if (start==end) - drawPixel(start.X, start.Y, color); - else - { - // thanks to Vash TheStampede who sent in his implementation - S3DVertex vtx[2]; - vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f, - 0.0f, 0.0f, 0.0f, // normal - color, 0.0f, 0.0f); // texture - - vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f, - 0.0f, 0.0f, 0.0f, - color, 0.0f, 0.0f); - - setRenderStates2DMode(color.getAlpha() < 255, false, false); - setActiveTexture(0,0); - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &vtx[0], sizeof(S3DVertex)); - } -} - - -//! Draws a pixel -void CD3D8Driver::drawPixel(u32 x, u32 y, const SColor & color) -{ - const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - if (x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) - return; - - setRenderStates2DMode(color.getAlpha() < 255, false, false); - setActiveTexture(0,0); - - setVertexShader(EVT_STANDARD); - - S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); - - pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); -} - - -//! sets right vertex shader -void CD3D8Driver::setVertexShader(E_VERTEX_TYPE newType) -{ - // Because we don't know if a vertex shader was set in a material instead of a - // fvf, this call cannot be prevented in D3D8. - //if (newType != LastVertexType) - { - LastVertexType = newType; - HRESULT hr = 0; - - switch(newType) - { - case EVT_STANDARD: - hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); - break; - case EVT_2TCOORDS: - hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); - break; - case EVT_TANGENTS: - hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | - D3DFVF_TEXCOORDSIZE2(0) | // real texture coord - D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent - D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal - ); - break; - } - - if (FAILED(hr)) - { - os::Printer::log("Could not set vertex Shader.", ELL_ERROR); - return; - } - } -} - - -//! sets the needed renderstates -bool CD3D8Driver::setRenderStates3DMode() -{ - if (!pID3DDevice) - return false; - - if (CurrentRenderMode != ERM_3D) - { - // switch back the matrices - pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); - pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); - pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); - - pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - - ResetRenderStates = true; - } - - if (ResetRenderStates || LastMaterial != Material) - { - // unset old material - - if (CurrentRenderMode == ERM_3D && - LastMaterial.MaterialType != Material.MaterialType && - LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) - MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); - - // set new material. - - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( - Material, LastMaterial, ResetRenderStates, this); - } - - bool shaderOK = true; - - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); - - LastMaterial = Material; - - ResetRenderStates = false; - - CurrentRenderMode = ERM_3D; - - return shaderOK; -} - - -//! Map Irrlicht texture wrap mode to native values -D3DTEXTUREADDRESS CD3D8Driver::getTextureWrapMode(const u8 clamp) -{ - switch (clamp) - { - case ETC_REPEAT: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP) - return D3DTADDRESS_WRAP; - case ETC_CLAMP: - case ETC_CLAMP_TO_EDGE: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP) - return D3DTADDRESS_CLAMP; - case ETC_MIRROR: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) - return D3DTADDRESS_MIRROR; - case ETC_CLAMP_TO_BORDER: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) - return D3DTADDRESS_BORDER; - else - return D3DTADDRESS_CLAMP; - case ETC_MIRROR_CLAMP: - case ETC_MIRROR_CLAMP_TO_EDGE: - case ETC_MIRROR_CLAMP_TO_BORDER: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE) - return D3DTADDRESS_MIRRORONCE; - else - return D3DTADDRESS_CLAMP; - default: - return D3DTADDRESS_WRAP; - } -} - - -//! Can be called by an IMaterialRenderer to make its work easier. -void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, - bool resetAllRenderstates) -{ - if (resetAllRenderstates || - lastmaterial.AmbientColor != material.AmbientColor || - lastmaterial.DiffuseColor != material.DiffuseColor || - lastmaterial.SpecularColor != material.SpecularColor || - lastmaterial.EmissiveColor != material.EmissiveColor || - lastmaterial.Shininess != material.Shininess) - { - D3DMATERIAL8 mat; - mat.Diffuse = colorToD3D(material.DiffuseColor); - mat.Ambient = colorToD3D(material.AmbientColor); - mat.Specular = colorToD3D(material.SpecularColor); - mat.Emissive = colorToD3D(material.EmissiveColor); - mat.Power = material.Shininess; - pID3DDevice->SetMaterial(&mat); - } - - if (lastmaterial.ColorMaterial != material.ColorMaterial) - { - pID3DDevice->SetRenderState(D3DRS_COLORVERTEX, (material.ColorMaterial != ECM_NONE)); - pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, - ((material.ColorMaterial == ECM_DIFFUSE)|| - (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); - pID3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, - ((material.ColorMaterial == ECM_AMBIENT)|| - (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); - pID3DDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, - (material.ColorMaterial == ECM_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); - pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, - (material.ColorMaterial == ECM_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); - } - - // fillmode - if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) - { - if (material.Wireframe) - pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); - else - if (material.PointCloud) - pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); - else - pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - } - - // shademode - if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) - { - if (material.GouraudShading) - pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); - else - pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); - } - - // lighting - if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) - { - if (material.Lighting) - pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); - else - pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); - } - - // zbuffer - if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) - { - switch (material.ZBuffer) - { - case ECFN_NEVER: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); - break; - case ECFN_LESSEQUAL: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - break; - case ECFN_EQUAL: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); - break; - case ECFN_LESS: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); - break; - case ECFN_NOTEQUAL: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); - break; - case ECFN_GREATEREQUAL: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); - break; - case ECFN_GREATER: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); - break; - case ECFN_ALWAYS: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - break; - } - } - - // zwrite -// if (resetAllRenderstates || lastmaterial.ZWriteEnable != material.ZWriteEnable) - { - if (material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) - pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); - else - pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); - } - - // back face culling - if (resetAllRenderstates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) - { -// if (material.FrontfaceCulling && material.BackfaceCulling) -// pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW|D3DCULL_CCW); -// else - if (material.FrontfaceCulling) - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); - else - if (material.BackfaceCulling) - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); - else - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - } - - // fog - if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) - { - pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); - } - - // specular highlights - if (resetAllRenderstates || !core::equals(lastmaterial.Shininess, material.Shininess)) - { - bool enable = (material.Shininess!=0); - pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); - pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, enable); - pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); - } - - // normalization - if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) - { - pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); - } - - // Color Mask - if (queryFeature(EVDF_COLOR_MASK) && - (resetAllRenderstates || lastmaterial.ColorMask != material.ColorMask)) - { - const DWORD flag = - ((material.ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | - ((material.ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | - ((material.ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | - ((material.ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); - pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); - } - - if (queryFeature(EVDF_BLEND_OPERATIONS) && - (resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation)) - { - if (material.BlendOperation==EBO_NONE) - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - else - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - switch (material.BlendOperation) - { - case EBO_MAX: - case EBO_MAX_FACTOR: - case EBO_MAX_ALPHA: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); - break; - case EBO_MIN: - case EBO_MIN_FACTOR: - case EBO_MIN_ALPHA: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); - break; - case EBO_SUBTRACT: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); - break; - case EBO_REVSUBTRACT: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); - break; - default: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - break; - } - } - } - - // Polygon offset - if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || - lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || - lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) - { - pID3DDevice->SetRenderState(D3DRS_ZBIAS, material.PolygonOffsetFactor); - } - - // thickness - if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) - { - pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&material.Thickness)); - } - - // texture address mode - for (u32 st=0; stSetTextureStageState(st, D3DTSS_MIPMAPLODBIAS, *(DWORD*)(&tmp)); - } - - if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU) - pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); - // If separate UV not supported reuse U for V - if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV)) - pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); - else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV) - pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV)); - - // Bilinear and/or trilinear - if (resetAllRenderstates || - lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || - lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || - lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter || - lastmaterial.UseMipMaps != material.UseMipMaps) - { - if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter>1) - { - const D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && - material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; - const D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && - material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; - const D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE; - - if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC) - pID3DDevice->SetTextureStageState(st, D3DTSS_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy)); - pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, tftMag); - pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, tftMin); - pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, tftMip); - } - else - { - pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, D3DTEXF_POINT); - pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, D3DTEXF_NONE); - pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - } - } -} - - -//! sets the needed renderstates -void CD3D8Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible) -{ - if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && - CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || - Transformation3DChanged) - { - // unset last 3d material - if (CurrentRenderMode == ERM_3D && - static_cast(Material.MaterialType) < MaterialRenderers.size()) - { - MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); - ResetRenderStates = true; - } - // switch back the matrices - pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); - pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); - pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); - - Transformation3DChanged = false; - - setActiveTexture(0,0); - setActiveTexture(1,0); - setActiveTexture(2,0); - setActiveTexture(3,0); - - pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - - pID3DDevice->SetVertexShader(D3DFVF_XYZ); - LastVertexType = (video::E_VERTEX_TYPE)(-1); - - pID3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); - //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); - //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - - pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); - pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x0); - pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); - pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); - if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) - pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); - if ((debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)) - pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); - } - - if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) - { - // USE THE ZPASS METHOD - pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); - pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); - pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); - } - else - if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) - { - // USE THE ZFAIL METHOD - pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); - pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); - pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); - } - - CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; -} - - -//! sets the needed renderstates -void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha) -{ - if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) - { - pID3DDevice->SetTransform(D3DTS_VIEW, &UnitMatrixD3D8); - pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D8); - pID3DDevice->SetTransform(D3DTS_PROJECTION, &UnitMatrixD3D8); - - pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); - pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); - pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - - pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1 ); - pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); - //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); - pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); - pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); - pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); - pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); - - pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); - - Transformation3DChanged = false; - - if (alpha) - { - pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); - } - else - { - pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } - - CurrentRenderMode = ERM_STENCIL_FILL; -} - - -//! sets the needed renderstates -void CD3D8Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) -{ - if (!pID3DDevice) - return; - - if (CurrentRenderMode != ERM_2D || Transformation3DChanged) - { - // unset last 3d material - if (CurrentRenderMode == ERM_3D) - { - if (static_cast(LastMaterial.MaterialType) < MaterialRenderers.size()) - MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); - } - if (!OverrideMaterial2DEnabled) - { - setBasicRenderStates(InitMaterial2D, LastMaterial, true); - LastMaterial=InitMaterial2D; - - // fix everything that is wrongly set by SMaterial default - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE ); - - } - pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D8); - core::matrix4 m; - m.setTranslation(core::vector3df(-0.5f,-0.5f,0)); - pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)m.pointer())); - - const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0, 1.0); - m.setTranslation(core::vector3df(-1,1,0)); - pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer())); - - Transformation3DChanged = false; - } - if (OverrideMaterial2DEnabled) - { - OverrideMaterial2D.Lighting=false; - setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); - LastMaterial = OverrideMaterial2D; - } - - // no alphaChannel without texture - alphaChannel &= texture; - - if (alpha || alphaChannel) - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - } - else - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - if (texture) - { - setTransform(ETS_TEXTURE_0, core::IdentityMatrix); - // Due to the transformation change, the previous line would call a reset each frame - // but we can safely reset the variable as it was false before - Transformation3DChanged=false; - } - if (alphaChannel) - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - - if (alpha) - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - } - else - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - } - - } - else - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); - if (alpha) - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); - } - else - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - } - } - - CurrentRenderMode = ERM_2D; -} - - -//! deletes all dynamic lights there are -void CD3D8Driver::deleteAllDynamicLights() -{ - for (s32 i=0; iLightEnable(i, false); - - LastSetLight = -1; - - CNullDriver::deleteAllDynamicLights(); -} - - -//! adds a dynamic light -s32 CD3D8Driver::addDynamicLight(const SLight& dl) -{ - CNullDriver::addDynamicLight(dl); - - D3DLIGHT8 light; - - switch (dl.Type) - { - case ELT_POINT: - light.Type = D3DLIGHT_POINT; - break; - case ELT_SPOT: - light.Type = D3DLIGHT_SPOT; - break; - case ELT_DIRECTIONAL: - light.Type = D3DLIGHT_DIRECTIONAL; - break; - } - - light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); - light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); - - light.Range = core::min_(dl.Radius, MaxLightDistance); - light.Falloff = dl.Falloff; - - light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); - light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); - light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); - - light.Attenuation0 = dl.Attenuation.X; - light.Attenuation1 = dl.Attenuation.Y; - light.Attenuation2 = dl.Attenuation.Z; - - light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; - light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; - - ++LastSetLight; - - if(D3D_OK == pID3DDevice->SetLight(LastSetLight, &light)) - { - // I don't care if this succeeds - (void)pID3DDevice->LightEnable(LastSetLight, true); - return LastSetLight; - } - - return -1; -} - - -void CD3D8Driver::turnLightOn(s32 lightIndex, bool turnOn) -{ - if(lightIndex < 0 || lightIndex > LastSetLight) - return; - - (void)pID3DDevice->LightEnable(lightIndex, turnOn); -} - - -//! returns the maximal amount of dynamic lights the device can handle -u32 CD3D8Driver::getMaximalDynamicLightAmount() const -{ - return Caps.MaxActiveLights; -} - - -//! Sets the dynamic ambient light color. The default color is -//! (0,0,0,0) which means it is dark. -//! \param color: New color of the ambient light. -void CD3D8Driver::setAmbientLight(const SColorf& color) -{ - if (!pID3DDevice) - return; - - AmbientLight = color; - D3DCOLOR col = color.toSColor().color; - pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); -} - - -//! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 -//! driver, it would return "Direct3D8.1". -const wchar_t* CD3D8Driver::getName() const -{ - return L"Direct3D 8.1"; -} - - -//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do -//! this: First, draw all geometry. Then use this method, to draw the shadow -//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. -void CD3D8Driver::drawStencilShadowVolume(const core::array& triangles, bool zfail, u32 debugDataVisible) -{ - const u32 count = triangles.size(); - if (!Params.Stencilbuffer || !count) - return; - - setRenderStatesStencilShadowMode(zfail, debugDataVisible); - - if (!zfail) - { - // ZPASS Method - - // Draw front-side of shadow volume in stencil only - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW ); - pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT); - pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); - - // Now reverse cull order so front sides of shadow volume are written. - pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); - pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECRSAT); - pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); - } - else - { - // ZFAIL Method - - // Draw front-side of shadow volume in stencil only - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW ); - pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT ); - pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); - - // Now reverse cull order so front sides of shadow volume are written. - pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); - pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECRSAT ); - pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); - } -} - - -//! Fills the stencil shadow with color. After the shadow volume has been drawn -//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this -//! to draw the color of the shadow. -void CD3D8Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, - video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) -{ - if (!Params.Stencilbuffer) - return; - - S3DVertex vtx[4]; - vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); - vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); - vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); - vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); - - const s16 indices[6] = {0,1,2,1,3,2}; - - setRenderStatesStencilFillMode( - leftUpEdge.getAlpha() < 255 || - rightUpEdge.getAlpha() < 255 || - leftDownEdge.getAlpha() < 255 || - rightDownEdge.getAlpha() < 255); - - setActiveTexture(0,0); - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], - D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); - - if (clearStencilBuffer) - pID3DDevice->Clear(0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); -} - - -//! Returns the maximum amount of primitives (mostly vertices) which -//! the device is able to render with one drawIndexedTriangleList -//! call. -u32 CD3D8Driver::getMaximalPrimitiveCount() const -{ - return Caps.MaxPrimitiveCount; -} - - -//! Sets the fog mode. -void CD3D8Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, - f32 end, f32 density, bool pixelFog, bool rangeFog) -{ - CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); - - if (!pID3DDevice) - return; - - pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); - - pID3DDevice->SetRenderState( -#if defined( _IRR_XBOX_PLATFORM_) - D3DRS_FOGTABLEMODE, -#else - pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, -#endif - (fogType==EFT_FOG_LINEAR)? D3DFOG_LINEAR : (fogType==EFT_FOG_EXP)?D3DFOG_EXP:D3DFOG_EXP2); - - if (fogType==EFT_FOG_LINEAR) - { - pID3DDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start)); - pID3DDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end)); - } - else - pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD*)(&density)); - - if(!pixelFog) - pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); -} - - -//! Draws a 3d line. -void CD3D8Driver::draw3DLine(const core::vector3df& start, - const core::vector3df& end, SColor color) -{ - setVertexShader(EVT_STANDARD); - setRenderStates3DMode(); - video::S3DVertex v[2]; - v[0].Color = color; - v[1].Color = color; - v[0].Pos = start; - v[1].Pos = end; - - pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); -} - - -void CD3D8Driver::OnResize(const core::dimension2d& size) -{ - if (!pID3DDevice) - return; - - CNullDriver::OnResize(size); - reset(); -} - - -//! Returns type of video driver -E_DRIVER_TYPE CD3D8Driver::getDriverType() const -{ - return EDT_DIRECT3D8; -} - - -//! Returns the transformation set by setTransform -const core::matrix4& CD3D8Driver::getTransform(E_TRANSFORMATION_STATE state) const -{ - return Matrices[state]; -} - - -//! Sets a vertex shader constant. -void CD3D8Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) -{ - if (data) - pID3DDevice->SetVertexShaderConstant(startRegister, data, constantAmount); -} - - -//! Sets a pixel shader constant. -void CD3D8Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) -{ - if (data) - pID3DDevice->SetPixelShaderConstant(startRegister, data, constantAmount); -} - - -//! Sets a constant for the vertex shader based on a name. -bool CD3D8Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) -{ - os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); - return false; -} - - -//! Bool interface for the above. -bool CD3D8Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count) -{ - os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); - return false; -} - - -//! Int interface for the above. -bool CD3D8Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count) -{ - os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); - return false; -} - - -//! Sets a constant for the pixel shader based on a name. -bool CD3D8Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) -{ - os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); - return false; -} - - -//! Bool interface for the above. -bool CD3D8Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count) -{ - os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); - return false; -} - - -//! Int interface for the above. -bool CD3D8Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count) -{ - os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); - return false; -} - - -//! Adds a new material renderer to the VideoDriver, using pixel and/or -//! vertex shaders to render geometry. -s32 CD3D8Driver::addShaderMaterial(const c8* vertexShaderProgram, - const c8* pixelShaderProgram, - IShaderConstantSetCallBack* callback, - E_MATERIAL_TYPE baseMaterial, s32 userData) -{ - s32 nr = -1; - CD3D8ShaderMaterialRenderer* r = new CD3D8ShaderMaterialRenderer( - pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, - callback, getMaterialRenderer(baseMaterial), userData); - - r->drop(); - return nr; -} - - -//! Returns a pointer to the IVideoDriver interface. (Implementation for -//! IMaterialRendererServices) -IVideoDriver* CD3D8Driver::getVideoDriver() -{ - return this; -} - - -//! Clears the ZBuffer. -void CD3D8Driver::clearZBuffer() -{ - const HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); - - if (FAILED(hr)) - os::Printer::log("CD3D8Driver clearZBuffer() failed.", ELL_WARNING); -} - - -//! Returns an image created from the last rendered frame. -IImage* CD3D8Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) -{ -#if defined( _IRR_XBOX_PLATFORM_) - return 0; -#else - if (target != video::ERT_FRAME_BUFFER) - return 0; - - // query the screen dimensions of the current adapter - D3DDISPLAYMODE displayMode; - pID3DDevice->GetDisplayMode(&displayMode); - - if (format==video::ECF_UNKNOWN) - format=video::ECF_A8R8G8B8; - - // create the image surface to store the front buffer image [always A8R8G8B8] - HRESULT hr; - LPDIRECT3DSURFACE8 lpSurface; - if (FAILED(hr = pID3DDevice->CreateImageSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, &lpSurface))) - return 0; - - // read the front buffer into the image surface - if (FAILED(hr = pID3DDevice->GetFrontBuffer(lpSurface))) - { - lpSurface->Release(); - return 0; - } - - RECT clientRect; - { - POINT clientPoint; - clientPoint.x = 0; - clientPoint.y = 0; - - ClientToScreen( (HWND)getExposedVideoData().D3D8.HWnd, &clientPoint ); - - clientRect.left = clientPoint.x; - clientRect.top = clientPoint.y; - clientRect.right = clientRect.left + ScreenSize.Width; - clientRect.bottom = clientRect.top + ScreenSize.Height; - - // window can be off-screen partly, we can't take screenshots from that - clientRect.left = core::max_(clientRect.left, 0l); - clientRect.top = core::max_(clientRect.top, 0l); - clientRect.right = core::min_(clientRect.right, (long)displayMode.Width); - clientRect.bottom = core::min_(clientRect.bottom, (long)displayMode.Height ); - } - - // lock our area of the surface - D3DLOCKED_RECT lockedRect; - if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) - { - lpSurface->Release(); - return 0; - } - - irr::core::dimension2d shotSize; - shotSize.Width = core::min_( ScreenSize.Width, (u32)(clientRect.right-clientRect.left) ); - shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) ); - - // this could throw, but we aren't going to worry about that case very much - IImage* newImage = createImage(format, shotSize); - - if (newImage) - { - // d3d pads the image, so we need to copy the correct number of bytes - u32* dP = (u32*)newImage->lock(); - u8 * sP = (u8 *)lockedRect.pBits; - - // If the display mode format doesn't promise anything about the Alpha value - // and it appears that it's not presenting 255, then we should manually - // set each pixel alpha value to 255. - if(D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000))) - { - for (u32 y = 0; y < shotSize.Height; ++y) - { - for(u32 x = 0; x < shotSize.Width; ++x) - { - newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000); - sP += 4; - } - - sP += lockedRect.Pitch - (4 * shotSize.Width); - } - } - else - { - for (u32 y = 0; y < shotSize.Height; ++y) - { - convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format); - sP += lockedRect.Pitch; - dP += shotSize.Width; - } - } - - newImage->unlock(); - } - - // we can unlock and release the surface - lpSurface->UnlockRect(); - - // release the image surface - lpSurface->Release(); - - // return status of save operation to caller - return newImage; -#endif -} - - -// returns the current size of the screen or rendertarget -const core::dimension2d& CD3D8Driver::getCurrentRenderTargetSize() const -{ - if ( CurrentRendertargetSize.Width == 0 ) - return ScreenSize; - else - return CurrentRendertargetSize; -} - - -// Set/unset a clipping plane. -bool CD3D8Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) -{ -#if defined( _IRR_XBOX_PLATFORM_) - return false; -#else - if (index >= MaxUserClipPlanes) - return false; - pID3DDevice->SetClipPlane(index, (const float*)&plane); - enableClipPlane(index, enable); - return true; -#endif -} - - -// Enable/disable a clipping plane. -void CD3D8Driver::enableClipPlane(u32 index, bool enable) -{ -#if defined( _IRR_XBOX_PLATFORM_) - return; -#else - if (index >= MaxUserClipPlanes) - return; - DWORD renderstate; - pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); - if (enable) - renderstate |= (1 << index); - else - renderstate &= ~(1 << index); - pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); -#endif -} - - -core::dimension2du CD3D8Driver::getMaxTextureSize() const -{ - return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight); -} - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - - -namespace irr -{ -namespace video -{ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -//! creates a video driver -IVideoDriver* createDirectX8Driver(const SIrrlichtCreationParameters& params, - io::IFileSystem* io, HWND window) -{ - const bool pureSoftware = false; - CD3D8Driver* dx8 = new CD3D8Driver(params, io); - - if (!dx8->initDriver(window, pureSoftware)) - { - dx8->drop(); - dx8 = 0; - } - - return dx8; -} -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - -} // end namespace video -} // end namespace irr diff --git a/lib/irrlicht/source/Irrlicht/CD3D8Driver.h b/lib/irrlicht/source/Irrlicht/CD3D8Driver.h deleted file mode 100644 index e9428a9ff..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8Driver.h +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_VIDEO_DIRECTX_8_H_INCLUDED__ -#define __C_VIDEO_DIRECTX_8_H_INCLUDED__ - -#include "IrrCompileConfig.h" - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ - -#ifdef _IRR_WINDOWS_ - #define WIN32_LEAN_AND_MEAN - #include -#endif - -#include "SIrrCreationParameters.h" -// always included for static createDriver function -#include "CNullDriver.h" -#include "IMaterialRendererServices.h" - -#include - -namespace irr -{ -namespace video -{ - class CD3D8Driver : public CNullDriver, IMaterialRendererServices - { - friend class CD3D8Texture; - - public: - - //! constructor - CD3D8Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io); - - //! destructor - virtual ~CD3D8Driver(); - - //! applications must call this method before performing any rendering. returns false if failed. - virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, - SColor color=SColor(255,0,0,0), - const SExposedVideoData& videoData=SExposedVideoData(), - core::rect* sourceRect=0); - - //! applications must call this method after performing any rendering. returns false if failed. - virtual bool endScene(); - - //! queries the features of the driver, returns true if feature is available - virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; - - //! sets transformation - virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); - - //! sets a material - virtual void setMaterial(const SMaterial& material); - - //! sets a render target - virtual bool setRenderTarget(video::ITexture* texture, - bool clearBackBuffer=true, bool clearZBuffer=true, - SColor color=video::SColor(0,0,0,0)); - - //! sets a viewport - virtual void setViewPort(const core::rect& area); - - //! gets the area of the current viewport - virtual const core::rect& getViewPort() const; - - //! draws a vertex primitive list - virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, - const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType); - - //! draws a vertex primitive list in 2d - virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, - const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType); - - //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. - virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, - const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); - - //! Draws a part of the texture into the rectangle. - virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect = 0, - const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false); - - //!Draws an 2d rectangle with a gradient. - virtual void draw2DRectangle(const core::rect& pos, - SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, - const core::rect* clip = 0); - - //! Draws a 2d line. - virtual void draw2DLine(const core::position2d& start, - const core::position2d& end, - SColor color=SColor(255,255,255,255)); - - //! Draws a pixel. - virtual void drawPixel(u32 x, u32 y, const SColor & color); - - //! Draws a 3d line. - virtual void draw3DLine(const core::vector3df& start, - const core::vector3df& end, SColor color = SColor(255,255,255,255)); - - //! initialises the Direct3D API - 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". - virtual const wchar_t* getName() const; - - //! deletes all dynamic lights there are - virtual void deleteAllDynamicLights(); - - //! adds a dynamic light, returning an index to the light - //! \param light: the light data to use to create the light - //! \return An index to the light, or -1 if an error occurs - virtual s32 addDynamicLight(const SLight& light); - - //! Turns a dynamic light on or off - //! \param lightIndex: the index returned by addDynamicLight - //! \param turnOn: true to turn the light on, false to turn it off - virtual void turnLightOn(s32 lightIndex, bool turnOn); - - //! returns the maximal amount of dynamic lights the device can handle - virtual u32 getMaximalDynamicLightAmount() const; - - //! Sets the dynamic ambient light color. The default color is - //! (0,0,0,0) which means it is dark. - //! \param color: New color of the ambient light. - virtual void setAmbientLight(const SColorf& color); - - //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do - //! this: Frist, draw all geometry. Then use this method, to draw the shadow - //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. - virtual void drawStencilShadowVolume(const core::array& triangles, bool zfail=true, u32 debugDataVisible=0); - - //! Fills the stencil shadow with color. After the shadow volume has been drawn - //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this - //! to draw the color of the shadow. - virtual void drawStencilShadow(bool clearStencilBuffer=false, - video::SColor leftUpEdge = video::SColor(0,0,0,0), - video::SColor rightUpEdge = video::SColor(0,0,0,0), - video::SColor leftDownEdge = video::SColor(0,0,0,0), - video::SColor rightDownEdge = video::SColor(0,0,0,0)); - - //! Returns the maximum amount of primitives (mostly vertices) which - //! the device is able to render with one drawIndexedTriangleList - //! call. - virtual u32 getMaximalPrimitiveCount() const; - - //! Enables or disables a texture creation flag. - virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled); - - //! Sets the fog mode. - virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start, - f32 end, f32 density, bool pixelFog, bool rangeFog); - - //! Only used by the internal engine. Used to notify the driver that - //! the window was resized. - virtual void OnResize(const core::dimension2d& size); - - //! Returns type of video driver - virtual E_DRIVER_TYPE getDriverType() const; - - //! Returns the transformation set by setTransform - virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; - - //! Can be called by an IMaterialRenderer to make its work easier. - virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates); - - //! Sets a vertex shader constant. - virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); - - //! Sets a pixel shader constant. - virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); - - //! Sets a constant for the vertex shader based on a name. - virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); - - //! Bool interface for the above. - virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count); - - //! Int interface for the above. - virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count); - - //! Sets a constant for the pixel shader based on a name. - virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); - - //! Bool interface for the above. - virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count); - - //! Int interface for the above. - virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count); - - //! Returns a pointer to the IVideoDriver interface. (Implementation for - //! IMaterialRendererServices) - virtual IVideoDriver* getVideoDriver(); - - //! Creates a render target texture. - virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, - const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); - - //! Clears the ZBuffer. - virtual void clearZBuffer(); - - //! Returns an image created from the last rendered frame. - virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER); - - //! Set/unset a clipping plane. - //! There are at least 6 clipping planes available for the user to set at will. - //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. - //! \param plane: The plane itself. - //! \param enable: If true, enable the clipping plane else disable it. - virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); - - //! Enable/disable a clipping plane. - //! There are at least 6 clipping planes available for the user to set at will. - //! \param index: The plane index. Must be between 0 and MaxUserClipPlanes. - //! \param enable: If true, enable the clipping plane else disable it. - virtual void enableClipPlane(u32 index, bool enable); - - //! Returns the maximum texture size supported. - virtual core::dimension2du getMaxTextureSize() const; - - virtual bool checkDriverReset() {return DriverWasReset;} - private: - - // enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. - enum E_RENDER_MODE - { - ERM_NONE = 0, // no render state has been set yet. - ERM_2D, // 2d drawing rendermode - ERM_3D, // 3d rendering mode - ERM_STENCIL_FILL, // stencil fill mode - ERM_SHADOW_VOLUME_ZFAIL, // stencil volume draw mode - ERM_SHADOW_VOLUME_ZPASS // stencil volume draw mode - }; - - //! sets right vertex shader - void setVertexShader(video::E_VERTEX_TYPE newType); - - //! sets the needed renderstates - bool setRenderStates3DMode(); - - //! sets the needed renderstates - void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); - - //! sets the needed renderstates - void setRenderStatesStencilFillMode(bool alpha); - - //! sets the needed renderstates - void setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible); - - //! sets the current Texture - bool setActiveTexture(u32 stage, const video::ITexture* texture); - - //! resets the device - bool reset(); - - //! returns a device dependent texture from a software surface (IImage) - //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES - virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0); - - // returns the current size of the screen or rendertarget - virtual const core::dimension2d& getCurrentRenderTargetSize() const; - - //! Adds a new material renderer to the VideoDriver, using pixel and/or - //! vertex shaders to render geometry. - s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram, - IShaderConstantSetCallBack* callback, - E_MATERIAL_TYPE baseMaterial, s32 userData); - - void createMaterialRenderers(); - - void draw2D3DVertexPrimitiveList(const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType, bool is3D); - - D3DTEXTUREADDRESS getTextureWrapMode(const u8 clamp); - - inline D3DCOLORVALUE colorToD3D(const SColor& col) - { - const f32 f = 1.0f / 255.0f; - D3DCOLORVALUE v; - v.r = col.getRed() * f; - v.g = col.getGreen() * f; - v.b = col.getBlue() * f; - v.a = col.getAlpha() * f; - return v; - } - - E_RENDER_MODE CurrentRenderMode; - D3DPRESENT_PARAMETERS present; - - SMaterial Material, LastMaterial; - bool ResetRenderStates; // bool to make all renderstates be reseted if set. - bool Transformation3DChanged; - const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; - core::matrix4 Matrices[ETS_COUNT]; // matrices of the 3d mode we need to restore when we switch back from the 2d mode. - - HINSTANCE D3DLibrary; - IDirect3D8* pID3D; - IDirect3DDevice8* pID3DDevice; - - IDirect3DSurface8* PrevRenderTarget; - core::dimension2d CurrentRendertargetSize; - - HWND WindowId; - core::rect* SceneSourceRect; - - D3DCAPS8 Caps; - - E_VERTEX_TYPE LastVertexType; - - D3DMATRIX UnitMatrix; - - u32 MaxTextureUnits; - u32 MaxUserClipPlanes; - f32 MaxLightDistance; - s32 LastSetLight; - bool DeviceLost; - bool DriverWasReset; - - SColorf AmbientLight; - - SIrrlichtCreationParameters Params; - }; - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - -#endif // __C_VIDEO_DIRECTX_8_H_INCLUDED__ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8MaterialRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D8MaterialRenderer.h deleted file mode 100644 index 5eb883c67..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8MaterialRenderer.h +++ /dev/null @@ -1,581 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D8_MATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D8_MATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_API_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include - -#include "IMaterialRenderer.h" - -namespace irr -{ -namespace video -{ - -namespace -{ -D3DMATRIX UnitMatrixD3D8; -D3DMATRIX SphereMapMatrixD3D8; -inline void setTextureColorStage(IDirect3DDevice8* dev, DWORD i, - DWORD arg1, DWORD op, DWORD arg2) -{ - dev->SetTextureStageState(i, D3DTSS_COLOROP, op); - dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1); - dev->SetTextureStageState(i, D3DTSS_COLORARG2, arg2); -} -inline void setTextureColorStage(IDirect3DDevice8* dev, DWORD i, DWORD arg1) -{ - dev->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1); -} - -inline void setTextureAlphaStage(IDirect3DDevice8* dev, DWORD i, - DWORD arg1, DWORD op, DWORD arg2) -{ - dev->SetTextureStageState(i, D3DTSS_ALPHAOP, op); - dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1); - dev->SetTextureStageState(i, D3DTSS_ALPHAARG2, arg2); -} -inline void setTextureAlphaStage(IDirect3DDevice8* dev, DWORD i, DWORD arg1) -{ - dev->SetTextureStageState(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1); -} -} // anonymous namespace - -//! Base class for all internal D3D8 material renderers -class CD3D8MaterialRenderer : public IMaterialRenderer -{ -public: - - //! Constructor - CD3D8MaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver) - : pID3DDevice(d3ddev), Driver(driver) - { - } - -protected: - - IDirect3DDevice8* pID3DDevice; - video::IVideoDriver* Driver; -}; - - -//! Solid material renderer -class CD3D8MaterialRenderer_SOLID : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_SOLID(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - } - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } -}; - -//! Generic Texture Blend -class CD3D8MaterialRenderer_ONETEXTURE_BLEND : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || - material.MaterialTypeParam != lastMaterial.MaterialTypeParam || - resetAllRenderstates) - { - - E_BLEND_FACTOR srcFact,dstFact; - E_MODULATE_FUNC modulate; - u32 alphaSource; - unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam ); - - if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO) - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - else - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) ); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) ); - } - - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, getD3DModulate(modulate), D3DTA_DIFFUSE); - - if ( alphaSource && (textureBlendFunc_hasAlpha ( srcFact ) || textureBlendFunc_hasAlpha ( dstFact ) )) - { - if (alphaSource==EAS_VERTEX_COLOR) - { - setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); - } - else if (alphaSource==EAS_TEXTURE) - { - setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); - } - else - { - setTextureAlphaStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - } - } - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - } - } - - //! Returns if the material is transparent. - /** The scene management needs to know this for being able to sort the - materials by opaque and transparent. - The return value could be optimized, but we'd need to know the - MaterialTypeParam for it. */ - virtual bool isTransparent() const - { - return true; - } - - private: - - u32 getD3DBlend ( E_BLEND_FACTOR factor ) const - { - u32 r = 0; - switch ( factor ) - { - case EBF_ZERO: r = D3DBLEND_ZERO; break; - case EBF_ONE: r = D3DBLEND_ONE; break; - case EBF_DST_COLOR: r = D3DBLEND_DESTCOLOR; break; - case EBF_ONE_MINUS_DST_COLOR: r = D3DBLEND_INVDESTCOLOR; break; - case EBF_SRC_COLOR: r = D3DBLEND_SRCCOLOR; break; - case EBF_ONE_MINUS_SRC_COLOR: r = D3DBLEND_INVSRCCOLOR; break; - case EBF_SRC_ALPHA: r = D3DBLEND_SRCALPHA; break; - case EBF_ONE_MINUS_SRC_ALPHA: r = D3DBLEND_INVSRCALPHA; break; - case EBF_DST_ALPHA: r = D3DBLEND_DESTALPHA; break; - case EBF_ONE_MINUS_DST_ALPHA: r = D3DBLEND_INVDESTALPHA; break; - case EBF_SRC_ALPHA_SATURATE: r = D3DBLEND_SRCALPHASAT; break; - } - return r; - } - - u32 getD3DModulate ( E_MODULATE_FUNC func ) const - { - u32 r = D3DTOP_MODULATE; - switch ( func ) - { - case EMFN_MODULATE_1X: r = D3DTOP_MODULATE; break; - case EMFN_MODULATE_2X: r = D3DTOP_MODULATE2X; break; - case EMFN_MODULATE_4X: r = D3DTOP_MODULATE4X; break; - } - return r; - } - -}; - - -//! Solid 2 layer material renderer -class CD3D8MaterialRenderer_SOLID_2_LAYER : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); - - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } -}; - - -//! Transparent add color material renderer -class CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); - } - } - - //! Returns if the material is transparent. The scene management needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return true; - } -}; - - -//! Transparent vertex alpha material renderer -class CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - } - } - - //! Returns if the material is transparent. The scene managment needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return true; - } -}; - - -//! Transparent alpha channel material renderer -class CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates - || material.MaterialTypeParam != lastMaterial.MaterialTypeParam ) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); - setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); - - pID3DDevice->SetRenderState(D3DRS_ALPHAREF, core::floor32(material.MaterialTypeParam * 255.f)); - pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); - pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - } - - //! Returns if the material is transparent. The scene managment needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return true; - } -}; - - -//! Transparent alpha channel material renderer -class CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); - setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - - // 127 is required by EMT_TRANSPARENT_ALPHA_CHANNEL_REF - pID3DDevice->SetRenderState(D3DRS_ALPHAREF, 127); - pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); - pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - } - - //! Returns if the material is transparent. The scene managment needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return false; // this material is not really transparent because it does no blending. - } -}; - - -//! material renderer for all kinds of lightmaps -class CD3D8MaterialRenderer_LIGHTMAP : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_LIGHTMAP(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - if (material.MaterialType >= EMT_LIGHTMAP_LIGHTING) - { - // with lighting - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - } - else - { - setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE); - } - - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - - setTextureColorStage(pID3DDevice, 1, - D3DTA_TEXTURE, - (material.MaterialType == EMT_LIGHTMAP_ADD)? - D3DTOP_ADD: - (material.MaterialType == EMT_LIGHTMAP_M4 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M4)? - D3DTOP_MODULATE4X: - (material.MaterialType == EMT_LIGHTMAP_M2 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M2)? - D3DTOP_MODULATE2X: - D3DTOP_MODULATE, - D3DTA_CURRENT); - - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } -}; - - -//! material renderer for detail maps -class CD3D8MaterialRenderer_DETAIL_MAP : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_DETAIL_MAP(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - setTextureColorStage(pID3DDevice, 1, - D3DTA_TEXTURE, D3DTOP_ADDSIGNED, D3DTA_CURRENT); - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } -}; - - -//! sphere map material renderer -class CD3D8MaterialRenderer_SPHERE_MAP : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_SPHERE_MAP(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - - pID3DDevice->SetTransform( D3DTS_TEXTURE0, &SphereMapMatrixD3D8 ); - pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); - pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL ); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0); - pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D8 ); - } -}; - - -//! reflection 2 layer material renderer -class CD3D8MaterialRenderer_REFLECTION_2_LAYER : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - - setTextureColorStage(pID3DDevice, 1, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); - - pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D8 ); - pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); - pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); - pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D8 ); - } -}; - - -//! reflection 2 layer material renderer -class CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D8MaterialRenderer -{ -public: - - CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice8* p, video::IVideoDriver* d) - : CD3D8MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); - setTextureColorStage(pID3DDevice, 1, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); - setTextureAlphaStage(pID3DDevice, 1, D3DTA_CURRENT); - - pID3DDevice->SetTransform(D3DTS_TEXTURE1, &SphereMapMatrixD3D8 ); - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); - - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - pID3DDevice->SetTransform(D3DTS_TEXTURE1, &UnitMatrixD3D8); - } - - //! Returns if the material is transparent. The scene managment needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return true; - } -}; - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8NormalMapRenderer.cpp b/lib/irrlicht/source/Irrlicht/CD3D8NormalMapRenderer.cpp deleted file mode 100644 index c5e039d3a..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8NormalMapRenderer.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ - -#include "CD3D8NormalMapRenderer.h" -#include "IMaterialRendererServices.h" -#include "IVideoDriver.h" -#include "os.h" -#include "SLight.h" - -namespace irr -{ -namespace video -{ - - // 1.1 Shaders with two lights and vertex based attenuation - - // Irrlicht Engine D3D8 render path normal map vertex shader - const char D3D8_NORMAL_MAP_VSH[] = - ";Irrlicht Engine 0.8 D3D8 render path normal map vertex shader\n"\ - "; c0-3: Transposed world matrix \n"\ - "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ - "; c12: Light01 position \n"\ - "; c13: x,y,z: Light01 color; .w: 1/LightRadius˛ \n"\ - "; c14: Light02 position \n"\ - "; c15: x,y,z: Light02 color; .w: 1/LightRadius˛ \n"\ - "\n"\ - "; v0 - position \n"\ - "; v1 - normal \n"\ - "; v2 - color \n"\ - "; v3 - texture coord \n"\ - "; v4 - tangent \n"\ - "; v5 - binormal \n"\ - "\n"\ - "vs.1.1\n"\ - "\n"\ - "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ - "\n"\ - "m3x3 r5, v4, c0 ; transform tangent U\n"\ - "m3x3 r7, v1, c0 ; transform normal W\n"\ - "m3x3 r6, v5, c0 ; transform binormal V\n"\ - "\n"\ - "m4x4 r4, v0, c0 ; vertex into world position\n"\ - "add r2, c12, -r4 ; vtxpos - lightpos1\n"\ - "add r3, c14, -r4 ; vtxpos - lightpos2\n"\ - "\n"\ - "dp3 r8.x, r5, r2 ; transform the light vector 1 with U, V, W\n"\ - "dp3 r8.y, r6, r2 \n"\ - "dp3 r8.z, r7, r2 \n"\ - "dp3 r9.x, r5, r3 ; transform the light vector 2 with U, V, W\n"\ - "dp3 r9.y, r6, r3 \n"\ - "dp3 r9.z, r7, r3 \n"\ - "\n"\ - "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ - "rsq r8.w, r8.w \n"\ - "mul r8, r8, r8.w \n"\ - "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ - "rsq r9.w, r9.w \n"\ - "mul r9, r9, r9.w \n"\ - "\n"\ - "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ - "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ - "\n"\ - " ; calculate attenuation of light 1 \n"\ - "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x˛ + r2.y˛ + r2.z˛ \n"\ - "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ - "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ - "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ - "\n"\ - " ; calculate attenuation of light 2 \n"\ - "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x˛ + r3.y˛ + r3.z˛ \n"\ - "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ - "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ - "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ - "\n"\ - "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ - "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ - "mov oD0.a, v2.a ; move out original alpha value \n"\ - "\n"; - - // Irrlicht Engine D3D8 render path normal map pixel shader - const char D3D8_NORMAL_MAP_PSH[] = - ";Irrlicht Engine 0.8 D3D8 render path normal map pixel shader\n"\ - ";Input: \n"\ - ";t0: color map texture coord \n"\ - ";t1: normal map texture coords \n"\ - ";t2: light 1 vector in tangent space \n"\ - ";v0: light 1 color \n"\ - ";t3: light 2 vector in tangent space \n"\ - ";v1: light 2 color \n"\ - ";v0.a: vertex alpha value \n"\ - "ps.1.1 \n"\ - "tex t0 ; sample color map \n"\ - "tex t1 ; sample normal map\n"\ - "texcoord t2 ; fetch light vector 1\n"\ - "texcoord t3 ; fetch light vector 2\n"\ - "\n"\ - "dp3_sat r0, t1_bx2, t2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1)\n"\ - "mul r0, r0, v0 ; luminance1 * light color 1 \n"\ - "\n"\ - "dp3_sat r1, t1_bx2, t3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1)\n"\ - "mad r0, r1, v1, r0 ; (luminance2 * light color 2) + luminance 1 \n"\ - "\n"\ - "mul r0, t0, r0 ; total luminance * base color\n"\ - "mov r0.a, v0.a ; write interpolated vertex alpha value \n"\ - "\n"\ - ""; - - CD3D8NormalMapRenderer::CD3D8NormalMapRenderer( - IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) - : CD3D8ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), - CompiledShaders(true) - { - - #ifdef _DEBUG - setDebugName("CD3D8NormalMapRenderer"); - #endif - - // set this as callback. We could have done this in - // the initialization list, but some compilers don't like it. - - CallBack = this; - - // basicly, this thing simply compiles these hardcoded shaders if the - // hardware is able to do them, otherwise it maps to the base material - - if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) || - !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) - { - // this hardware is not able to do shaders. Fall back to - // base material. - outMaterialTypeNr = driver->addMaterialRenderer(this); - return; - } - - // check if already compiled normal map shaders are there. - - video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID); - if (renderer) - { - // use the already compiled shaders - video::CD3D8NormalMapRenderer* nmr = (video::CD3D8NormalMapRenderer*)renderer; - CompiledShaders = false; - - VertexShader = nmr->VertexShader; - PixelShader = nmr->PixelShader; - - outMaterialTypeNr = driver->addMaterialRenderer(this); - } - else - { - // compile shaders on our own - init(outMaterialTypeNr, D3D8_NORMAL_MAP_VSH, D3D8_NORMAL_MAP_PSH, EVT_TANGENTS); - } - // something failed, use base material - if (-1==outMaterialTypeNr) - driver->addMaterialRenderer(this); - } - - - CD3D8NormalMapRenderer::~CD3D8NormalMapRenderer() - { - if (CallBack == this) - CallBack = 0; - - if (!CompiledShaders) - { - // prevent this from deleting shaders we did not create - VertexShader = 0; - PixelShader = 0; - } - } - - - bool CD3D8NormalMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) - { - if (vtxtype != video::EVT_TANGENTS) - { - os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); - return false; - } - - return CD3D8ShaderMaterialRenderer::OnRender(service, vtxtype); - } - - //! Returns the render capability of the material. - s32 CD3D8NormalMapRenderer::getRenderCapability() const - { - if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && - Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) - return 0; - - return 1; - } - - - //! Called by the engine when the vertex and/or pixel shader constants for an - //! material renderer should be set. - void CD3D8NormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) - { - video::IVideoDriver* driver = services->getVideoDriver(); - - // set transposed world matrix - services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); - - // set transposed worldViewProj matrix - core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); - worldViewProj *= driver->getTransform(video::ETS_VIEW); - worldViewProj *= driver->getTransform(video::ETS_WORLD); - services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); - - // here we've got to fetch the fixed function lights from the - // driver and set them as constants - - u32 cnt = driver->getDynamicLightCount(); - - for (u32 i=0; i<2; ++i) - { - SLight light; - - if (igetDynamicLight(i); - else - { - light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; - } - - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation - - services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); - services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); - } - - f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; - services->setVertexShaderConstant(c95, 95, 1); - } - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8NormalMapRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D8NormalMapRenderer.h deleted file mode 100644 index e53ab650c..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8NormalMapRenderer.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D8_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D8_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_API_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include - -#include "CD3D8ShaderMaterialRenderer.h" -#include "IShaderConstantSetCallBack.h" - -namespace irr -{ -namespace video -{ - -//! Renderer for normal maps -class CD3D8NormalMapRenderer : public CD3D8ShaderMaterialRenderer, IShaderConstantSetCallBack -{ -public: - - CD3D8NormalMapRenderer( - IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); - ~CD3D8NormalMapRenderer(); - - //! Called by the engine when the vertex and/or pixel shader constants for an - //! material renderer should be set. - virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); - - bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); - - //! Returns the render capability of the material. - virtual s32 getRenderCapability() const; - -private: - - //! stores if this shader compiled the shaders and is - //! allowed to delete them again. D3D8 lacks reference counting - //! support for shaders. - bool CompiledShaders; - -}; - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8ParallaxMapRenderer.cpp b/lib/irrlicht/source/Irrlicht/CD3D8ParallaxMapRenderer.cpp deleted file mode 100644 index ca30966b5..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8ParallaxMapRenderer.cpp +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ - -#include "CD3D8ParallaxMapRenderer.h" -#include "IMaterialRendererServices.h" -#include "IVideoDriver.h" -#include "os.h" -#include "SLight.h" - -namespace irr -{ -namespace video -{ - // 1.1/1.4 Shaders with two lights and vertex based attenuation - - // Irrlicht Engine D3D8 render path normal map vertex shader - const char D3D8_PARALLAX_MAP_VSH[] = - ";Irrlicht Engine 0.10 D3D8 render path parallax mapping vertex shader\n"\ - "; c0-3: Transposed world matrix \n"\ - "; c4: Eye position \n"\ - "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ - "; c12: Light01 position \n"\ - "; c13: x,y,z: Light01 color; .w: 1/LightRadius˛ \n"\ - "; c14: Light02 position \n"\ - "; c15: x,y,z: Light02 color; .w: 1/LightRadius˛ \n"\ - "vs.1.1\n"\ - "; v0 ; position \n"\ - "; v1 ; normal \n"\ - "; v2 ; color \n"\ - "; v3 ; texture coord \n"\ - "; v4 ; tangent \n"\ - "; v5 ; binormal \n"\ - "\n"\ - "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ - "def c96, -1, 1, 1, 1 ; somewhere I've got a bug. flipping the vectors with this fixes it. \n"\ - "\n"\ - "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ - "\n"\ - "m3x3 r5, v4, c0 ; transform tangent U\n"\ - "m3x3 r7, v1, c0 ; transform normal W\n"\ - "m3x3 r6, v5, c0 ; transform binormal V\n"\ - "\n"\ - "m4x4 r4, v0, c0 ; vertex into world position\n"\ - "add r2, c12, -r4 ; vtxpos - light1 pos\n"\ - "add r3, c14, -r4 ; vtxpos - light2 pos\n"\ - "add r1, -c4, r4 ; eye - vtxpos \n"\ - "\n"\ - "dp3 r8.x, r5, r2 ; transform the light1 vector with U, V, W\n"\ - "dp3 r8.y, r6, r2 \n"\ - "dp3 r8.z, r7, r2 \n"\ - "dp3 r9.x, r5, r3 ; transform the light2 vector with U, V, W\n"\ - "dp3 r9.y, r6, r3 \n"\ - "dp3 r9.z, r7, r3 \n"\ - "dp3 r10.x, r5, r1 ; transform the eye vector with U, V, W\n"\ - "dp3 r10.y, r6, r1 \n"\ - "dp3 r10.z, r7, r1 \n"\ - "\n"\ - "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ - "rsq r8.w, r8.w \n"\ - "mul r8, r8, r8.w \n"\ - ";mul r8, r8, c96 \n"\ - "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ - "rsq r9.w, r9.w \n"\ - "mul r9, r9, r9.w \n"\ - ";mul r9, r9, c96 \n"\ - "dp3 r10.w, r10, r10 ; normalize eye vector (r10)\n"\ - "rsq r10.w, r10.w \n"\ - "mul r10, r10, r10.w \n"\ - "mul r10, r10, c96 \n"\ - "\n"\ - "\n"\ - "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ - "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ - "mad oT4.xyz, r10.xyz, c95, c95 ; move eye vector from -1..1 into 0..1 \n"\ - "\n"\ - " ; calculate attenuation of light 1 \n"\ - "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x˛ + r2.y˛ + r2.z˛ \n"\ - "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ - "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ - "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ - "\n"\ - " ; calculate attenuation of light 2 \n"\ - "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x˛ + r3.y˛ + r3.z˛ \n"\ - "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ - "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ - "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ - "\n"\ - "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ - "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ - "mov oD0.a, v2.a ; move out original alpha value \n"\ - "\n"; - - - // Irrlicht Engine D3D8 render path normal map pixel shader version 1.4 - const char D3D8_PARALLAX_MAP_PSH[] = - ";Irrlicht Engine 0.10 D3D8 render path parallax mapping pixel shader \n"\ - ";Input: \n"\ - ";t0: color map texture coord \n"\ - ";t1: normal map texture coords \n"\ - ";t2: light 1 vector in tangent space \n"\ - ";t4: eye vector in tangent space \n"\ - ";v0: light 1 color \n"\ - ";t3: light 2 vector in tangent space \n"\ - ";v1: light 2 color \n"\ - ";v0.a: vertex alpha value \n"\ - " \n"\ - "ps.1.4 \n"\ - " \n"\ - ";def c6, 0.02f, 0.02f, 0.02f, 0.0f ; scale factor, now set in callback \n"\ - " \n"\ - "texld r1, t1 ; sample (normal.x, normal.y, normal.z, height) \n"\ - "texcrd r4.xyz, t4 ; fetch eye vector \n"\ - "texcrd r0.xyz, t0 ; color map \n"\ - " \n"\ - "; original parallax mapping: \n"\ - ";mul r3, r1_bx2.wwww, c6; ; r3 = (height, height, height) * scale \n"\ - ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ - " \n"\ - "; modified parallax mapping to reduce swimming effect: \n"\ - "mul r3, r1_bx2.wwww, r1_bx2.zzzz ; (nh,nh,nh,nh) = (h,h,h,h) * (n.z,n.z,n.z,n.z,) \n"\ - "mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ - "mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ - " \n"\ - "phase \n"\ - " \n"\ - "texld r0, r2 ; load diffuse texture with new tex coord \n"\ - "texld r1, r2 ; sample normal map \n"\ - "texcrd r2.xyz, t2 ; fetch light vector 1 \n"\ - "texcrd r3.xyz, t3 ; fetch light vector 2 \n"\ - " \n"\ - "dp3_sat r2, r1_bx2, r2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ - "mul r2, r2, v0 ; luminance1 * light color 1 \n"\ - " \n"\ - "dp3_sat r3, r1_bx2, r3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ - "mad r3, r3, v1, r2 ; (luminance2 * light color 2) + luminance1 \n"\ - " \n"\ - "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ - "+mov r0.a, v0.a ; write original alpha value \n"\ - "\n"; - - - CD3D8ParallaxMapRenderer::CD3D8ParallaxMapRenderer( - IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) - : CD3D8ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), - CompiledShaders(true), CurrentScale(0.0f) - { - - #ifdef _DEBUG - setDebugName("CD3D8ParallaxMapRenderer"); - #endif - - // set this as callback. We could have done this in - // the initialization list, but some compilers don't like it. - - CallBack = this; - - // basicly, this thing simply compiles these hardcoded shaders if the - // hardware is able to do them, otherwise it maps to the base material - - if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) || - !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) - { - // this hardware is not able to do shaders. Fall back to - // base material. - outMaterialTypeNr = driver->addMaterialRenderer(this); - return; - } - - // check if already compiled parallax map shaders are there. - - video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); - if (renderer) - { - // use the already compiled shaders - video::CD3D8ParallaxMapRenderer* nmr = (video::CD3D8ParallaxMapRenderer*)renderer; - CompiledShaders = false; - - VertexShader = nmr->VertexShader; - PixelShader = nmr->PixelShader; - - outMaterialTypeNr = driver->addMaterialRenderer(this); - } - else - { - // compile shaders on our own - init(outMaterialTypeNr, D3D8_PARALLAX_MAP_VSH, D3D8_PARALLAX_MAP_PSH, EVT_TANGENTS); - } - // something failed, use base material - if (-1==outMaterialTypeNr) - driver->addMaterialRenderer(this); - } - - - CD3D8ParallaxMapRenderer::~CD3D8ParallaxMapRenderer() - { - if (CallBack == this) - CallBack = 0; - - if (!CompiledShaders) - { - // prevent this from deleting shaders we did not create - VertexShader = 0; - PixelShader = 0; - } - } - - - bool CD3D8ParallaxMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) - { - if (vtxtype != video::EVT_TANGENTS) - { - os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); - return false; - } - - return CD3D8ShaderMaterialRenderer::OnRender(service, vtxtype); - } - - - void CD3D8ParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material, - const video::SMaterial& lastMaterial, - bool resetAllRenderstates, video::IMaterialRendererServices* services) - { - CD3D8ShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, - resetAllRenderstates, services); - - CurrentScale = material.MaterialTypeParam; - } - - - //! Returns the render capability of the material. - s32 CD3D8ParallaxMapRenderer::getRenderCapability() const - { - if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) && - Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) - return 0; - - return 1; - } - - - //! Called by the engine when the vertex and/or pixel shader constants - //! for an material renderer should be set. - void CD3D8ParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) - { - video::IVideoDriver* driver = services->getVideoDriver(); - - // set transposed world matrix - services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); - - // set eye position - - // The viewpoint is at (0., 0., 0.) in eye space. - // Turning this into a vector [0 0 0 1] and multiply it by - // the inverse of the view matrix, the resulting vector is the - // object space location of the camera. - - f32 floats[4] = {0,0,0,1}; - core::matrix4 minv(driver->getTransform(video::ETS_VIEW)); - minv.makeInverse(); - minv.multiplyWith1x4Matrix(floats); - services->setVertexShaderConstant(floats, 4, 1); - - // set transposed worldViewProj matrix - core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); - worldViewProj *= driver->getTransform(video::ETS_VIEW); - worldViewProj *= driver->getTransform(video::ETS_WORLD); - services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); - - // here we've got to fetch the fixed function lights from the driver - // and set them as constants - - const u32 cnt = driver->getDynamicLightCount(); - - for (u32 i=0; i<2; ++i) - { - SLight light; - - if (igetDynamicLight(i); - else - { - light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; - } - - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation - - services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); - services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); - } - - // this is not really necessary in d3d9 (used a def instruction), but to be sure: - f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; - services->setVertexShaderConstant(c95, 95, 1); - f32 c96[] = {-1, 1, 1, 1}; - services->setVertexShaderConstant(c96, 96, 1); - - // set scale factor - f32 factor = 0.02f; // default value - if (CurrentScale != 0) - factor = CurrentScale; - - f32 c6[] = {factor, factor, factor, 0}; - services->setPixelShaderConstant(c6, 6, 1); - } - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8ParallaxMapRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D8ParallaxMapRenderer.h deleted file mode 100644 index 4543ab775..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8ParallaxMapRenderer.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D8_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D8_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_API_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include - -#include "CD3D8ShaderMaterialRenderer.h" -#include "IShaderConstantSetCallBack.h" - -namespace irr -{ -namespace video -{ - -//! Renderer for parallax maps -class CD3D8ParallaxMapRenderer : public CD3D8ShaderMaterialRenderer, IShaderConstantSetCallBack -{ -public: - - CD3D8ParallaxMapRenderer( - IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); - ~CD3D8ParallaxMapRenderer(); - - //! Called by the engine when the vertex and/or pixel shader constants for an - //! material renderer should be set. - virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); - - virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); - - virtual void OnSetMaterial(const SMaterial& material) { } - virtual void OnSetMaterial(const video::SMaterial& material, - const video::SMaterial& lastMaterial, - bool resetAllRenderstates, video::IMaterialRendererServices* services); - - //! Returns the render capability of the material. - virtual s32 getRenderCapability() const; - -private: - - //! stores if this shader compiled the shaders and is - //! allowed to delete them again. D3D8 lacks reference counting - //! support for shaders. - bool CompiledShaders; - - f32 CurrentScale; -}; - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp b/lib/irrlicht/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp deleted file mode 100644 index f46d5837f..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "CD3D8ShaderMaterialRenderer.h" - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include -#include -#pragma comment (lib, "d3dx8.lib") - -#include "IShaderConstantSetCallBack.h" -#include "IMaterialRendererServices.h" -#include "IVideoDriver.h" -#include "os.h" - -#ifndef _IRR_D3D_NO_SHADER_DEBUGGING -#include -#endif - -namespace irr -{ -namespace video -{ - -//! Public constructor -CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, - IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) -: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), - VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) -{ - - #ifdef _DEBUG - setDebugName("CD3D8ShaderMaterialRenderer"); - #endif - - if (BaseMaterial) - BaseMaterial->grab(); - - if (CallBack) - CallBack->grab(); - - init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram, EVT_STANDARD); -} - -//! constructor only for use by derived classes who want to -//! create a fall back material for example. -CD3D8ShaderMaterialRenderer::CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, - video::IVideoDriver* driver, - IShaderConstantSetCallBack* callback, - IMaterialRenderer* baseMaterial, - s32 userData) -: pID3DDevice(d3ddev), Driver(driver), BaseMaterial(baseMaterial), CallBack(callback), - VertexShader(0), PixelShader(0), UserData(userData) -{ - if (BaseMaterial) - BaseMaterial->grab(); - - if (CallBack) - CallBack->grab(); -} - - - -//! Destructor -CD3D8ShaderMaterialRenderer::~CD3D8ShaderMaterialRenderer() -{ - if (CallBack) - CallBack->drop(); - - if (VertexShader) - pID3DDevice->DeleteVertexShader(VertexShader); - - if (PixelShader) - pID3DDevice->DeletePixelShader(PixelShader); - - if (BaseMaterial) - BaseMaterial->drop (); -} - - -void CD3D8ShaderMaterialRenderer::init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, - const c8* pixelShaderProgram, E_VERTEX_TYPE type) -{ - outMaterialTypeNr = -1; - - // create vertex shader - if (!createVertexShader(vertexShaderProgram, type)) - return; - - // create pixel shader - if (!createPixelShader(pixelShaderProgram)) - return; - - // register myself as new material - outMaterialTypeNr = Driver->addMaterialRenderer(this); -} - - -bool CD3D8ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) -{ - // call callback to set shader constants - if (CallBack && (VertexShader || PixelShader)) - CallBack->OnSetConstants(service, UserData); - - return true; -} - - -void CD3D8ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, - bool resetAllRenderstates, video::IMaterialRendererServices* services) -{ - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - if (VertexShader) - { - // We do not need to save and reset the old vertex shader, because - // in D3D8, this is mixed up with the fvf, and this is set by the driver - // every time. - //pID3DDevice->GetVertexShader(&OldVertexShader); - - // set new vertex shader - if (FAILED(pID3DDevice->SetVertexShader(VertexShader))) - os::Printer::log("Could not set vertex shader.", ELL_ERROR); - } - - // set new pixel shader - if (PixelShader) - { - if (FAILED(pID3DDevice->SetPixelShader(PixelShader))) - os::Printer::log("Could not set pixel shader.", ELL_ERROR); - } - - if (BaseMaterial) - BaseMaterial->OnSetMaterial(material, material, true, services); - } - - //let callback know used material - if (CallBack) - CallBack->OnSetMaterial(material); - - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); -} - -void CD3D8ShaderMaterialRenderer::OnUnsetMaterial() -{ - // We do not need to save and reset the old vertex shader, because - // in D3D8, this is mixed up with the fvf, and this is set by the driver - // every time. - // if (VertexShader) - // pID3DDevice->SetVertexShader(OldVertexShader); - - if (PixelShader) - pID3DDevice->SetPixelShader(0); - - if (BaseMaterial) - BaseMaterial->OnUnsetMaterial(); -} - - -//! Returns if the material is transparent. The scene managment needs to know this -//! for being able to sort the materials by opaque and transparent. -bool CD3D8ShaderMaterialRenderer::isTransparent() const -{ - return BaseMaterial ? BaseMaterial->isTransparent() : false; -} - -bool CD3D8ShaderMaterialRenderer::createPixelShader(const c8* pxsh) -{ - if (!pxsh) - return true; - -#if defined( _IRR_XBOX_PLATFORM_) - return false; -#else - // compile shader - - LPD3DXBUFFER code = 0; - LPD3DXBUFFER errors = 0; - - #ifdef _IRR_D3D_NO_SHADER_DEBUGGING - - // compile shader without debug info - D3DXAssembleShader(pxsh, (UINT)strlen(pxsh), 0, 0, &code, &errors); - - #else - - // compile shader and emitt some debug informations to - // make it possible to debug the shader in visual studio - - static int irr_dbg_file_nr = 0; - ++irr_dbg_file_nr; - char tmp[32]; - sprintf(tmp, "irr_d3d8_dbg_shader_%d.psh", irr_dbg_file_nr); - - FILE* f = fopen(tmp, "wb"); - fwrite(pxsh, strlen(pxsh), 1, f); - fflush(f); - fclose(f); - - D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors); - #endif - if (errors) - { - // print out compilation errors. - os::Printer::log("Pixel shader compilation failed:", ELL_ERROR); - os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); - - if (code) - code->Release(); - - errors->Release(); - return false; - } - - if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &PixelShader))) - { - os::Printer::log("Could not create pixel shader.", ELL_ERROR); - code->Release(); - return false; - } - - code->Release(); - return true; -#endif - -} - - - -bool CD3D8ShaderMaterialRenderer::createVertexShader(const char* vtxsh, E_VERTEX_TYPE type) -{ - if (!vtxsh) - return true; - - // compile shader -#if defined( _IRR_XBOX_PLATFORM_) - return false; -#else - - LPD3DXBUFFER code = 0; - LPD3DXBUFFER errors = 0; - - #ifdef _IRR_D3D_NO_SHADER_DEBUGGING - - // compile shader without debug info - D3DXAssembleShader(vtxsh, (UINT)strlen(vtxsh), 0, 0, &code, &errors); - - #else - - // compile shader and emitt some debug informations to - // make it possible to debug the shader in visual studio - static int irr_dbg_file_nr = 0; - ++irr_dbg_file_nr; - char tmp[32]; - sprintf(tmp, "irr_d3d8_dbg_shader_%d.vsh", irr_dbg_file_nr); - - FILE* f = fopen(tmp, "wb"); - fwrite(vtxsh, strlen(vtxsh), 1, f); - fflush(f); - fclose(f); - - D3DXAssembleShaderFromFile(tmp, D3DXASM_DEBUG, 0, &code, &errors); - - #endif - - - if (errors) - { - // print out compilation errors. - os::Printer::log("Vertex shader compilation failed:", ELL_ERROR); - os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); - - if (code) - code->Release(); - - errors->Release(); - return false; - } - - DWORD* decl = 0; - - DWORD dwStdDecl[] = - { - D3DVSD_STREAM(0), - D3DVSD_REG(0, D3DVSDT_FLOAT3), // position 0 - D3DVSD_REG(1, D3DVSDT_FLOAT3), // normal 1 - D3DVSD_REG(2, D3DVSDT_D3DCOLOR ),// color 2 - D3DVSD_REG(3, D3DVSDT_FLOAT2 ), // tex1 3 - D3DVSD_REG(4, D3DVSDT_FLOAT2 ), // tex2 4 - D3DVSD_END() - }; - - DWORD dwTngtDecl[] = - { - D3DVSD_STREAM(0), - D3DVSD_REG(0 , D3DVSDT_FLOAT3), // position 0 - D3DVSD_REG(1 , D3DVSDT_FLOAT3), // normal 1 - D3DVSD_REG(2 , D3DVSDT_D3DCOLOR ),// color 2 - D3DVSD_REG(3 , D3DVSDT_FLOAT2 ), // tex1 3 - D3DVSD_REG(4, D3DVSDT_FLOAT3 ), // tangent 4 - D3DVSD_REG(5, D3DVSDT_FLOAT3 ), // binormal 5 - D3DVSD_END() - }; - - if (type == EVT_TANGENTS) - decl = dwTngtDecl; - else - decl = dwStdDecl; - - if (FAILED(pID3DDevice->CreateVertexShader(decl, - (DWORD*)code->GetBufferPointer(), &VertexShader, 0))) - { - os::Printer::log("Could not create vertex shader.", ELL_ERROR); - code->Release(); - return false; - } - - code->Release(); - return true; -#endif -} - - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8ShaderMaterialRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D8ShaderMaterialRenderer.h deleted file mode 100644 index 02156a190..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8ShaderMaterialRenderer.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D8_SHADER_MATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D8_SHADER_MATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_API_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ -#include -#include - -#include "IMaterialRenderer.h" -#include "S3DVertex.h" - -namespace irr -{ -namespace video -{ - -class IVideoDriver; -class IShaderConstantSetCallBack; -class IMaterialRenderer; - -//! Class for using vertex and pixel shaders with D3D8 -class CD3D8ShaderMaterialRenderer : public IMaterialRenderer -{ -public: - - //! Public constructor - CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, - IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData); - - //! Destructor - ~CD3D8ShaderMaterialRenderer(); - - virtual void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, - bool resetAllRenderstates, video::IMaterialRendererServices* services); - - virtual void OnUnsetMaterial(); - - virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); - - //! Returns if the material is transparent. - virtual bool isTransparent() const; - -protected: - - //! constructor only for use by derived classes who want to - //! create a fall back material for example. - CD3D8ShaderMaterialRenderer(IDirect3DDevice8* d3ddev, - video::IVideoDriver* driver, - IShaderConstantSetCallBack* callback, - IMaterialRenderer* baseMaterial, s32 userData=0); - - void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, - E_VERTEX_TYPE type); - bool createPixelShader(const c8* pxsh); - bool createVertexShader(const char* vtxsh, E_VERTEX_TYPE type); - - IDirect3DDevice8* pID3DDevice; - video::IVideoDriver* Driver; - IShaderConstantSetCallBack* CallBack; - IMaterialRenderer* BaseMaterial; - - DWORD VertexShader; - DWORD OldVertexShader; - DWORD PixelShader; - s32 UserData; -}; - - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8Texture.cpp b/lib/irrlicht/source/Irrlicht/CD3D8Texture.cpp deleted file mode 100644 index 990efbeb7..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8Texture.cpp +++ /dev/null @@ -1,659 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ - -#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE -#include "CD3D8Texture.h" -#include "CD3D8Driver.h" -#include "os.h" - - -#ifndef _IRR_COMPILE_WITH_DIRECT3D_9_ -// The D3DXFilterTexture function seems to get linked wrong when -// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. -// So mipmapgeneration is replaced with my own bad generation in d3d 8 when -// compiling with both D3D 8 and 9. -//#define _IRR_USE_D3DXFilterTexture_ -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ - -#include - -#ifdef _IRR_USE_D3DXFilterTexture_ -#pragma comment (lib, "d3dx8.lib") -#endif // _IRR_USE_D3DXFilterTexture_ - -namespace irr -{ -namespace video -{ - -//! rendertarget constructor -CD3D8Texture::CD3D8Texture(CD3D8Driver* driver, const core::dimension2d& size, const io::path& name) -: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), - TextureSize(size), ImageSize(size), Pitch(0), - HasMipMaps(false), IsRenderTarget(true) -{ - #ifdef _DEBUG - setDebugName("CD3D8Texture"); - #endif - - Device=driver->getExposedVideoData().D3D8.D3DDev8; - if (Device) - Device->AddRef(); - - createRenderTarget(); -} - - -//! constructor -CD3D8Texture::CD3D8Texture(IImage* image, CD3D8Driver* driver, - u32 flags, const io::path& name, void* mipmapData) -: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), -TextureSize(0,0), ImageSize(0,0), Pitch(0), -HasMipMaps(false), IsRenderTarget(false) -{ - #ifdef _DEBUG - setDebugName("CD3D8Texture"); - #endif - - HasMipMaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); - - Device=driver->getExposedVideoData().D3D8.D3DDev8; - if (Device) - Device->AddRef(); - - if (image) - { - if (createTexture(flags, image)) - { - if (copyTexture(image)) - { - regenerateMipMapLevels(mipmapData); - } - } - else - os::Printer::log("Could not create DIRECT3D8 Texture.", ELL_WARNING); - } -} - - -//! destructor -CD3D8Texture::~CD3D8Texture() -{ - if (Texture) - Texture->Release(); - - if (RTTSurface) - RTTSurface->Release(); - - if (Device) - Device->Release(); -} - - -//! creates the hardware texture -bool CD3D8Texture::createTexture(u32 flags, video::IImage* image) -{ - ImageSize = image->getDimension(); - - core::dimension2d optSize = ImageSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); - - D3DFORMAT format = D3DFMT_A1R5G5B5; - switch(getTextureFormatFromFlags(flags)) - { - case ETCF_ALWAYS_16_BIT: - format = D3DFMT_A1R5G5B5; break; - case ETCF_ALWAYS_32_BIT: - format = D3DFMT_A8R8G8B8; break; - case ETCF_OPTIMIZED_FOR_QUALITY: - { - switch(image->getColorFormat()) - { - case ECF_R8G8B8: - case ECF_A8R8G8B8: - format = D3DFMT_A8R8G8B8; break; - case ECF_A1R5G5B5: - case ECF_R5G6B5: - format = D3DFMT_A1R5G5B5; break; - } - } - break; - case ETCF_OPTIMIZED_FOR_SPEED: - format = D3DFMT_A1R5G5B5; break; - } - - if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL)) - { - if (format == D3DFMT_A8R8G8B8) - -#ifdef _IRR_XBOX_PLATFORM_ - format = D3DFMT_X8R8G8B8; -#else - format = D3DFMT_R8G8B8; -#endif - - else if (format == D3DFMT_A1R5G5B5) - format = D3DFMT_R5G6B5; - } - - const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); - - HRESULT hr = Device->CreateTexture(optSize.Width, optSize.Height, - mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) - 0, format, D3DPOOL_MANAGED, &Texture); - - if (FAILED(hr)) - { - // try brute force 16 bit - if (format == D3DFMT_A8R8G8B8) - format = D3DFMT_A1R5G5B5; -#ifdef _IRR_XBOX_PLATFORM_ - else if (format == D3DFMT_X8R8G8B8) - format = D3DFMT_R5G6B5; -#else - else if (format == D3DFMT_R8G8B8) - format = D3DFMT_R5G6B5; -#endif - else - return false; - - hr = Device->CreateTexture(optSize.Width, optSize.Height, - mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) - 0, format, D3DPOOL_MANAGED, &Texture); - } - - ColorFormat = getColorFormatFromD3DFormat(format); - return (SUCCEEDED(hr)); -} - - -//! copies the image to the texture -bool CD3D8Texture::copyTexture(video::IImage* image) -{ - if (Texture && image) - { - D3DSURFACE_DESC desc; - Texture->GetLevelDesc(0, &desc); - - TextureSize.Width = desc.Width; - TextureSize.Height = desc.Height; - - D3DLOCKED_RECT rect; - HRESULT hr = Texture->LockRect(0, &rect, 0, 0); - if (FAILED(hr)) - { - os::Printer::log("Could not lock D3D8 Texture.", ELL_ERROR); - return false; - } - - Pitch = rect.Pitch; - image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); - - hr = Texture->UnlockRect(0); - if (FAILED(hr)) - { - os::Printer::log("Could not unlock D3D8 Texture.", ELL_ERROR); - return false; - } - } - - return true; -} - - -//! lock function -void* CD3D8Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) -{ - if (!Texture) - return 0; - - MipLevelLocked=mipmapLevel; - HRESULT hr; - D3DLOCKED_RECT rect; - if(!IsRenderTarget) - { - hr = Texture->LockRect(mipmapLevel, &rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); - if (FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); - return 0; - } - } - else - { - if (!RTTSurface) - { - // Make RTT surface large enough for all miplevels (including 0) - D3DSURFACE_DESC desc; - Texture->GetLevelDesc(0, &desc); - hr = Device->CreateImageSurface(desc.Width, desc.Height, desc.Format, &RTTSurface); - if (FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); - return 0; - } - } - - IDirect3DSurface8 *surface = 0; - hr = Texture->GetSurfaceLevel(mipmapLevel, &surface); - if (FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D8 Texture.", "Could not get surface.", ELL_ERROR); - return 0; - } - hr = Device->CopyRects(surface, 0, 0, RTTSurface, 0); - surface->Release(); - if(FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D8 Texture.", "Data copy failed.", ELL_ERROR); - return 0; - } - hr = RTTSurface->LockRect(&rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); - if(FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D8 Texture.", "LockRect failed.", ELL_ERROR); - return 0; - } - } - return rect.pBits; -} - - -//! unlock function -void CD3D8Texture::unlock() -{ - if (!Texture) - return; - - if (!IsRenderTarget) - Texture->UnlockRect(MipLevelLocked); - else if (RTTSurface) - RTTSurface->UnlockRect(); -} - - -//! Returns original size of the texture. -const core::dimension2d& CD3D8Texture::getOriginalSize() const -{ - return ImageSize; -} - - -//! Returns (=size) of the texture. -const core::dimension2d& CD3D8Texture::getSize() const -{ - return TextureSize; -} - - -//! returns driver type of texture (=the driver, who created the texture) -E_DRIVER_TYPE CD3D8Texture::getDriverType() const -{ - return EDT_DIRECT3D8; -} - - -//! returns color format of texture -ECOLOR_FORMAT CD3D8Texture::getColorFormat() const -{ - return ColorFormat; -} - - -//! returns pitch of texture (in bytes) -u32 CD3D8Texture::getPitch() const -{ - return Pitch; -} - - -//! returns the DIRECT3D8 Texture -IDirect3DTexture8* CD3D8Texture::getDX8Texture() const -{ - return Texture; -} - - -//! returns if texture has mipmap levels -bool CD3D8Texture::hasMipMaps() const -{ - return HasMipMaps; -} - - -// The D3DXFilterTexture function seems to get linked wrong when -// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. -// So mipmapgeneration is replaced with my own bad generation in d3d 8 when -// compiling with both D3D 8 and 9. -bool CD3D8Texture::createMipMaps(u32 level) -{ - if (level==0) - return true; - - IDirect3DSurface8* upperSurface = 0; - IDirect3DSurface8* lowerSurface = 0; - - // get upper level - HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface); - if (FAILED(hr) || !upperSurface) - { - os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING); - return false; - } - - // get lower level - hr = Texture->GetSurfaceLevel(level, &lowerSurface); - if (FAILED(hr) || !lowerSurface) - { - os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING); - upperSurface->Release(); - return false; - } - - D3DSURFACE_DESC upperDesc, lowerDesc; - upperSurface->GetDesc(&upperDesc); - lowerSurface->GetDesc(&lowerDesc); - - D3DLOCKED_RECT upperlr; - D3DLOCKED_RECT lowerlr; - - // lock upper surface - if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0))) - { - os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING); - upperSurface->Release(); - lowerSurface->Release(); - return false; - } - - // lock lower surface - if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0))) - { - os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING); - upperSurface->UnlockRect(); - upperSurface->Release(); - lowerSurface->Release(); - return false; - } - - if (upperDesc.Format != lowerDesc.Format) - { - os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING); - } - else - { - if (upperDesc.Format == D3DFMT_A1R5G5B5) - copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, - lowerDesc.Width, lowerDesc.Height, - upperlr.Pitch, lowerlr.Pitch); - else - if (upperDesc.Format == D3DFMT_A8R8G8B8) - copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, - lowerDesc.Width, lowerDesc.Height, - upperlr.Pitch, lowerlr.Pitch); - else - os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING); - } - - bool result=true; - // unlock - if (FAILED(upperSurface->UnlockRect())) - result=false; - if (FAILED(lowerSurface->UnlockRect())) - result=false; - - // release - upperSurface->Release(); - lowerSurface->Release(); - - if (!result || upperDesc.Width < 3 || upperDesc.Height < 3) - return result; // stop generating levels - - // generate next level - return createMipMaps(level+1); -} - - -ECOLOR_FORMAT CD3D8Texture::getColorFormatFromD3DFormat(D3DFORMAT format) -{ - switch(format) - { - case D3DFMT_X1R5G5B5: - case D3DFMT_A1R5G5B5: - Pitch = TextureSize.Width * 2; - return ECF_A1R5G5B5; - break; - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - Pitch = TextureSize.Width * 4; - return ECF_A8R8G8B8; - break; - case D3DFMT_R5G6B5: - Pitch = TextureSize.Width * 2; - return ECF_R5G6B5; - break; - default: - return (ECOLOR_FORMAT)0; - }; -} - - - -void CD3D8Texture::copy16BitMipMap(char* src, char* tgt, - s32 width, s32 height, - s32 pitchsrc, s32 pitchtgt) const -{ - u16 c; - - for (int x=0; x>= 2; - r >>= 2; - g >>= 2; - b >>= 2; - - c = ((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff); - *(u32*)((void*)&tgt[(x*4)+(y*pitchtgt)]) = c.color; - } - } -} - - -void CD3D8Texture::createRenderTarget() -{ - TextureSize = TextureSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); - - // get backbuffer format to create the render target in the - // same format - - IDirect3DSurface8* bb; - D3DFORMAT d3DFormat = D3DFMT_A8R8G8B8; - - if (!FAILED(Device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &bb))) - { - D3DSURFACE_DESC desc; - bb->GetDesc(&desc); - d3DFormat = desc.Format; - - if (d3DFormat == D3DFMT_X8R8G8B8) - d3DFormat = D3DFMT_A8R8G8B8; - - bb->Release(); - } - else - { - os::Printer::log("Could not create RenderTarget texture: could not get BackBuffer.", - ELL_WARNING); - return; - } - - // create texture - HRESULT hr; - - hr = Device->CreateTexture( - TextureSize.Width, - TextureSize.Height, - 1, // mip map level count, we don't want mipmaps here - D3DUSAGE_RENDERTARGET, - d3DFormat, - D3DPOOL_DEFAULT, - &Texture); - - // get irrlicht format from D3D format - ColorFormat = getColorFormatFromD3DFormat(d3DFormat); - - if (FAILED(hr)) - os::Printer::log("Could not create render target texture"); -} - - -//! Regenerates the mip map levels of the texture. Useful after locking and -//! modifying the texture -void CD3D8Texture::regenerateMipMapLevels(void* mipmapData) -{ - if (mipmapData) - { - core::dimension2du size = TextureSize; - u32 level=0; - do - { - if (size.Width>1) - size.Width /=2; - if (size.Height>1) - size.Height /=2; - ++level; - IDirect3DSurface8* mipSurface = 0; - HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface); - if (FAILED(hr) || !mipSurface) - { - os::Printer::log("Could not get mipmap level", ELL_WARNING); - return; - } - D3DSURFACE_DESC mipDesc; - mipSurface->GetDesc(&mipDesc); - D3DLOCKED_RECT miplr; - - // lock mipmap surface - if (FAILED(mipSurface->LockRect(&miplr, NULL, 0))) - { - mipSurface->Release(); - os::Printer::log("Could not lock texture", ELL_WARNING); - return; - } - - memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width); - mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width; - // unlock - mipSurface->UnlockRect(); - // release - mipSurface->Release(); - } while (size.Width != 1 || size.Height != 1); - } - else if (HasMipMaps) - { - // create mip maps. -#ifndef _IRR_USE_D3DXFilterTexture_ - // The D3DXFilterTexture function seems to get linked wrong when - // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. - // So mipmapgeneration is replaced with my own bad generation in d3d 8 when - // compiling with both D3D 8 and 9. - HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT , D3DX_DEFAULT ); - if (FAILED(hr)) -#endif - createMipMaps(); - } -} - - -//! returns if it is a render target -bool CD3D8Texture::isRenderTarget() const -{ - return IsRenderTarget; -} - - -//! Returns pointer to the render target surface -IDirect3DSurface8* CD3D8Texture::getRenderTargetSurface() -{ - if (!IsRenderTarget) - return 0; - - IDirect3DSurface8 *pRTTSurface = 0; - if (Texture) - Texture->GetSurfaceLevel(0, &pRTTSurface); - - if (pRTTSurface) - pRTTSurface->Release(); - - return pRTTSurface; -} - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D8Texture.h b/lib/irrlicht/source/Irrlicht/CD3D8Texture.h deleted file mode 100644 index 4a73c540c..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D8Texture.h +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_DIRECTX8_TEXTURE_H_INCLUDED__ -#define __C_DIRECTX8_TEXTURE_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ - -#include "ITexture.h" -#include "IImage.h" - -#include - -namespace irr -{ -namespace video -{ - -class CD3D8Driver; - -/*! - interface for a Video Driver dependent Texture. -*/ -class CD3D8Texture : public ITexture -{ -public: - - //! constructor - CD3D8Texture(IImage* image, CD3D8Driver* driver, - u32 flags, const io::path& name, void* mipmapData=0); - - //! rendertarget constructor - CD3D8Texture(CD3D8Driver* driver, const core::dimension2d& size, const io::path& name); - - //! destructor - virtual ~CD3D8Texture(); - - //! lock function - virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0); - - //! unlock function - virtual void unlock(); - - //! Returns original size of the texture. - virtual const core::dimension2d& getOriginalSize() const; - - //! Returns (=size) of the texture. - virtual const core::dimension2d& getSize() const; - - //! returns driver type of texture (=the driver, who created the texture) - virtual E_DRIVER_TYPE getDriverType() const; - - //! returns color format of texture - virtual ECOLOR_FORMAT getColorFormat() const; - - //! returns pitch of texture (in bytes) - virtual u32 getPitch() const; - - //! returns the DIRECT3D8 Texture - IDirect3DTexture8* getDX8Texture() const; - - //! returns if texture has mipmap levels - bool hasMipMaps() const; - - //! Regenerates the mip map levels of the texture. Useful after locking and - //! modifying the texture - virtual void regenerateMipMapLevels(void* mipmapData=0); - - //! returns if it is a render target - virtual bool isRenderTarget() const; - - //! Returns pointer to the render target surface - IDirect3DSurface8* getRenderTargetSurface(); - -private: - friend class CD3D8Driver; - - void createRenderTarget(); - - //! creates the hardware texture - bool createTexture(u32 flags, IImage* Image); - - //! copies the image to the texture - bool copyTexture(IImage* Image); - - //! convert color formats - ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format); - - bool createMipMaps(u32 level=1); - - void copy16BitMipMap(char* src, char* tgt, - s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; - - void copy32BitMipMap(char* src, char* tgt, - s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; - - IDirect3DDevice8* Device; - IDirect3DTexture8* Texture; - IDirect3DSurface8* RTTSurface; - CD3D8Driver* Driver; - core::dimension2d TextureSize; - core::dimension2d ImageSize; - s32 Pitch; - u32 MipLevelLocked; - ECOLOR_FORMAT ColorFormat; - - bool HasMipMaps; - bool IsRenderTarget; -}; - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - -#endif // __C_DIRECTX8_TEXTURE_H_INCLUDED__ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9CgMaterialRenderer.cpp b/lib/irrlicht/source/Irrlicht/CD3D9CgMaterialRenderer.cpp deleted file mode 100644 index 8220a7eaa..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9CgMaterialRenderer.cpp +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (C) 2012-2012 Patryk Nadrowski -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#if defined(_IRR_COMPILE_WITH_DIRECT3D_9_) && defined(_IRR_COMPILE_WITH_CG_) - -#include "CD3D9CgMaterialRenderer.h" -#include "CD3D9Driver.h" -#include "CD3D9Texture.h" - -namespace irr -{ -namespace video -{ - -CD3D9CgUniformSampler2D::CD3D9CgUniformSampler2D(const CGparameter& parameter, bool global) : CCgUniform(parameter, global) -{ - Type = CG_SAMPLER2D; -} - -void CD3D9CgUniformSampler2D::update(const void* data, const SMaterial& material) const -{ - s32* Data = (s32*)data; - s32 LayerID = *Data; - - if (material.TextureLayer[LayerID].Texture) - { - IDirect3DBaseTexture9* Texture = reinterpret_cast(material.TextureLayer[LayerID].Texture)->getDX9Texture(); - - cgD3D9SetTextureParameter(Parameter, Texture); - } -} - -CD3D9CgMaterialRenderer::CD3D9CgMaterialRenderer(CD3D9Driver* driver, s32& materialType, - const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, - const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, - const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, - scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices, - IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) : - Driver(driver), CCgMaterialRenderer(callback, baseMaterial, userData) -{ - #ifdef _DEBUG - setDebugName("CD3D9CgMaterialRenderer"); - #endif - - init(materialType, vertexProgram, vertexEntry, vertexProfile, fragmentProgram, fragmentEntry, fragmentProfile, - geometryProgram, geometryEntry, geometryProfile, inType, outType, vertices); -} - -CD3D9CgMaterialRenderer::~CD3D9CgMaterialRenderer() -{ - if (VertexProgram) - { - cgD3D9UnloadProgram(VertexProgram); - cgDestroyProgram(VertexProgram); - } - if (FragmentProgram) - { - cgD3D9UnloadProgram(FragmentProgram); - cgDestroyProgram(FragmentProgram); - } - /*if (GeometryProgram) - { - cgD3D9UnloadProgram(GeometryProgram); - cgDestroyProgram(GeometryProgram); - }*/ -} - -void CD3D9CgMaterialRenderer::OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates, IMaterialRendererServices* services) -{ - Material = material; - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - if (VertexProgram) - cgD3D9BindProgram(VertexProgram); - - if (FragmentProgram) - cgD3D9BindProgram(FragmentProgram); - - /*if (GeometryProgram) - cgD3D9BindProgram(GeometryProgram);*/ - - if (BaseMaterial) - BaseMaterial->OnSetMaterial(material, material, true, this); - } - - if (CallBack) - CallBack->OnSetMaterial(material); - - Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); -} - -bool CD3D9CgMaterialRenderer::OnRender(IMaterialRendererServices* services, E_VERTEX_TYPE vtxtype) -{ - if (CallBack && (VertexProgram || FragmentProgram || GeometryProgram)) - CallBack->OnSetConstants(this, UserData); - - return true; -} - -void CD3D9CgMaterialRenderer::OnUnsetMaterial() -{ - if (VertexProgram) - cgD3D9UnbindProgram(VertexProgram); - if (FragmentProgram) - cgD3D9UnbindProgram(FragmentProgram); - /*if (GeometryProgram) - cgD3D9UnbindProgram(GeometryProgram);*/ - - if (BaseMaterial) - BaseMaterial->OnUnsetMaterial(); - - Material = IdentityMaterial;; -} - -void CD3D9CgMaterialRenderer::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) -{ - Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); -} - -IVideoDriver* CD3D9CgMaterialRenderer::getVideoDriver() -{ - return Driver; -} - -void CD3D9CgMaterialRenderer::init(s32& materialType, - const c8* vertexProgram, const c8* vertexEntry, E_VERTEX_SHADER_TYPE vertexProfile, - const c8* fragmentProgram, const c8* fragmentEntry, E_PIXEL_SHADER_TYPE fragmentProfile, - const c8* geometryProgram, const c8* geometryEntry, E_GEOMETRY_SHADER_TYPE geometryProfile, - scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, u32 vertices) -{ - bool Status = true; - CGerror Error = CG_NO_ERROR; - materialType = -1; - - // TODO: add profile selection - - if (vertexProgram) - { - VertexProfile = cgD3D9GetLatestVertexProfile(); - - if (VertexProfile) - VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, vertexProgram, VertexProfile, vertexEntry, 0); - - if (!VertexProgram) - { - Error = cgGetError(); - os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR); - os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); - - Status = false; - } - else - cgD3D9LoadProgram(VertexProgram, 0, 0); - } - - if (fragmentProgram) - { - FragmentProfile = cgD3D9GetLatestPixelProfile(); - - if (FragmentProfile) - FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, fragmentProgram, FragmentProfile, fragmentEntry, 0); - - if (!FragmentProgram) - { - Error = cgGetError(); - os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR); - os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); - - Status = false; - } - else - cgD3D9LoadProgram(FragmentProgram, 0, 0); - } - - /*if (geometryProgram) - { - GeometryProfile = cgD3D9GetLatestGeometryProfile(); - - if (GeometryProfile) - GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, geometryProgram, GeometryProfile, geometryEntry, 0); - - if (!GeometryProgram) - { - Error = cgGetError(); - os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR); - os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR); - - Status = false; - } - else - cgD3D9LoadProgram(GeometryProgram, 0, 0); - }*/ - - getUniformList(); - - // create D3D9 specifics sampler uniforms. - for(unsigned int i = 0; i < UniformInfo.size(); ++i) - { - if (UniformInfo[i]->getType() == CG_SAMPLER2D) - { - bool IsGlobal = true; - - if (UniformInfo[i]->getSpace() == CG_PROGRAM) - IsGlobal = false; - - CCgUniform* Uniform = new CD3D9CgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal); - delete UniformInfo[i]; - UniformInfo[i] = Uniform; - } - } - - if (Status) - materialType = Driver->addMaterialRenderer(this); -} - -} -} - -#endif diff --git a/lib/irrlicht/source/Irrlicht/CD3D9CgMaterialRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D9CgMaterialRenderer.h deleted file mode 100644 index 7cb4b0f41..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9CgMaterialRenderer.h +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2012-2012 Patryk Nadrowski -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_DIRECT3D_9_CG_MATERIAL_RENDERER_H_INCLUDED__ -#define __C_DIRECT3D_9_CG_MATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#if defined(_IRR_COMPILE_WITH_DIRECT3D_9_) && defined(_IRR_COMPILE_WITH_CG_) - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include "CCgMaterialRenderer.h" -#include "Cg/cgD3D9.h" - -#ifdef _MSC_VER - #pragma comment(lib, "cgD3D9.lib") -#endif - -namespace irr -{ -namespace video -{ - -class CD3D9Driver; -class IShaderConstantSetCallBack; - -class CD3D9CgUniformSampler2D : public CCgUniform -{ -public: - CD3D9CgUniformSampler2D(const CGparameter& parameter, bool global); - - void update(const void* data, const SMaterial& material) const; -}; - -class CD3D9CgMaterialRenderer : public CCgMaterialRenderer -{ -public: - CD3D9CgMaterialRenderer(CD3D9Driver* driver, s32& materialType, - const c8* vertexProgram = 0, const c8* vertexEntry = "main", - E_VERTEX_SHADER_TYPE vertexProfile = video::EVST_VS_1_1, - const c8* fragmentProgram = 0, const c8* fragmentEntry = "main", - E_PIXEL_SHADER_TYPE fragmentProfile = video::EPST_PS_1_1, - const c8* geometryProgram = 0, const c8* geometryEntry = "main", - E_GEOMETRY_SHADER_TYPE geometryProfile = video::EGST_GS_4_0, - scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, - scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, - u32 vertices = 0, IShaderConstantSetCallBack* callback = 0, - IMaterialRenderer* baseMaterial = 0, s32 userData = 0); - - virtual ~CD3D9CgMaterialRenderer(); - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates, IMaterialRendererServices* services); - virtual bool OnRender(IMaterialRendererServices* services, E_VERTEX_TYPE vtxtype); - virtual void OnUnsetMaterial(); - - virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates); - virtual IVideoDriver* getVideoDriver(); - -protected: - void init(s32& materialType, - const c8* vertexProgram = 0, const c8* vertexEntry = "main", - E_VERTEX_SHADER_TYPE vertexProfile = video::EVST_VS_1_1, - const c8* fragmentProgram = 0, const c8* fragmentEntry = "main", - E_PIXEL_SHADER_TYPE fragmentProfile = video::EPST_PS_1_1, - const c8* geometryProgram = 0, const c8* geometryEntry = "main", - E_GEOMETRY_SHADER_TYPE geometryProfile = video::EGST_GS_4_0, - scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, - scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, - u32 vertices = 0); - - CD3D9Driver* Driver; -}; - -} -} - -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9Driver.cpp b/lib/irrlicht/source/Irrlicht/CD3D9Driver.cpp deleted file mode 100644 index 740489413..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9Driver.cpp +++ /dev/null @@ -1,3633 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE -#include "CD3D9Driver.h" - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#include "os.h" -#include "S3DVertex.h" -#include "CD3D9Texture.h" -#include "CD3D9MaterialRenderer.h" -#include "CD3D9ShaderMaterialRenderer.h" -#include "CD3D9NormalMapRenderer.h" -#include "CD3D9ParallaxMapRenderer.h" -#include "CD3D9HLSLMaterialRenderer.h" -#include "CD3D9CgMaterialRenderer.h" -#include "SIrrCreationParameters.h" - -namespace irr -{ -namespace video -{ - -namespace -{ - inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); } -} - -//! constructor -CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) - : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE), - ResetRenderStates(true), Transformation3DChanged(false), - 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), - ColorFormat(ECF_A8R8G8B8), DeviceLost(false), - DriverWasReset(true), OcclusionQuerySupport(false), - AlphaToCoverageSupport(false), Params(params) -{ - #ifdef _DEBUG - setDebugName("CD3D9Driver"); - #endif - - printVersion(); - - for (u32 i=0; idrop(); - } - DepthBuffers.clear(); - - // drop d3d9 - - if (pID3DDevice) - pID3DDevice->Release(); - - if (pID3D) - pID3D->Release(); - - #ifdef _IRR_COMPILE_WITH_CG_ - cgD3D9SetDevice(0); - - if(CgContext) - { - cgDestroyContext(CgContext); - } - #endif -} - - -void CD3D9Driver::createMaterialRenderers() -{ - // create D3D9 material renderers - - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); - - // add the same renderer for all lightmap types - - CD3D9MaterialRenderer_LIGHTMAP* lmr = new CD3D9MaterialRenderer_LIGHTMAP(pID3DDevice, this); - addMaterialRenderer(lmr); // for EMT_LIGHTMAP: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: - addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: - lmr->drop(); - - // add remaining fixed function pipeline material renderers - - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); - - // add normal map renderers - - s32 tmp = 0; - video::IMaterialRenderer* renderer = 0; - - renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_SOLID].Renderer); - renderer->drop(); - - renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); - renderer->drop(); - - renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); - renderer->drop(); - - // add parallax map renderers - - renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_SOLID].Renderer); - renderer->drop(); - - renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); - renderer->drop(); - - renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, - MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); - renderer->drop(); - - // add basic 1 texture blending - addAndDropMaterialRenderer(new CD3D9MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); -} - - -//! initialises the Direct3D API -bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware) -{ - if (!pID3D) - { - D3DLibrary = LoadLibrary( __TEXT("d3d9.dll") ); - - if (!D3DLibrary) - { - os::Printer::log("Error, could not load d3d9.dll.", ELL_ERROR); - return false; - } - - typedef IDirect3D9 * (__stdcall *D3DCREATETYPE)(UINT); - D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate9"); - - if (!d3dCreate) - { - os::Printer::log("Error, could not get proc adress of Direct3DCreate9.", ELL_ERROR); - return false; - } - - //just like pID3D = Direct3DCreate9(D3D_SDK_VERSION); - pID3D = (*d3dCreate)(D3D_SDK_VERSION); - - if (!pID3D) - { - os::Printer::log("Error initializing D3D.", ELL_ERROR); - return false; - } - } - - // print device information - D3DADAPTER_IDENTIFIER9 dai; - if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, 0, &dai))) - { - char tmp[512]; - - s32 Product = HIWORD(dai.DriverVersion.HighPart); - s32 Version = LOWORD(dai.DriverVersion.HighPart); - s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); - s32 Build = LOWORD(dai.DriverVersion.LowPart); - - sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, - SubVersion, Build); - os::Printer::log(tmp, ELL_INFORMATION); - - // Assign vendor name based on vendor id. - VendorID= static_cast(dai.VendorId); - switch(dai.VendorId) - { - case 0x1002 : VendorName = "ATI Technologies Inc."; break; - case 0x10DE : VendorName = "NVIDIA Corporation"; break; - case 0x102B : VendorName = "Matrox Electronic Systems Ltd."; break; - case 0x121A : VendorName = "3dfx Interactive Inc"; break; - case 0x5333 : VendorName = "S3 Graphics Co., Ltd."; break; - case 0x8086 : VendorName = "Intel Corporation"; break; - default: VendorName = "Unknown VendorId: ";VendorName += (u32)dai.VendorId; break; - } - } - - D3DDISPLAYMODE d3ddm; - if (FAILED(pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm))) - { - os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); - return false; - } - - ZeroMemory(&present, sizeof(present)); - - present.BackBufferCount = 1; - present.EnableAutoDepthStencil = TRUE; - if (Params.Vsync) - present.PresentationInterval = D3DPRESENT_INTERVAL_ONE; - else - present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - - if (Params.Fullscreen) - { - present.BackBufferWidth = Params.WindowSize.Width; - present.BackBufferHeight = Params.WindowSize.Height; - // request 32bit mode if user specified 32 bit, added by Thomas Stuefe - if (Params.Bits == 32) - present.BackBufferFormat = D3DFMT_X8R8G8B8; - else - present.BackBufferFormat = D3DFMT_R5G6B5; - present.SwapEffect = D3DSWAPEFFECT_FLIP; - present.Windowed = FALSE; - present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; - } - else - { - present.BackBufferFormat = d3ddm.Format; - present.SwapEffect = D3DSWAPEFFECT_DISCARD; - present.Windowed = TRUE; - } - - UINT adapter = Params.DisplayAdapter; - D3DDEVTYPE devtype = D3DDEVTYPE_HAL; - #ifndef _IRR_D3D_NO_SHADER_DEBUGGING - devtype = D3DDEVTYPE_REF; - #elif defined(_IRR_USE_NVIDIA_PERFHUD_) - for (UINT adapter_i = 0; adapter_i < pID3D->GetAdapterCount(); ++adapter_i) - { - D3DADAPTER_IDENTIFIER9 identifier; - pID3D->GetAdapterIdentifier(adapter_i,0,&identifier); - if (strstr(identifier.Description,"PerfHUD") != 0) - { - adapter = adapter_i; - devtype = D3DDEVTYPE_REF; - break; - } - } - #endif - - // enable anti alias if possible and desired - if (Params.AntiAlias > 0) - { - if (Params.AntiAlias > 32) - Params.AntiAlias = 32; - - DWORD qualityLevels = 0; - - while(Params.AntiAlias > 0) - { - if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter, - devtype, present.BackBufferFormat, !Params.Fullscreen, - (D3DMULTISAMPLE_TYPE)Params.AntiAlias, &qualityLevels))) - { - present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias; - present.MultiSampleQuality = qualityLevels-1; - present.SwapEffect = D3DSWAPEFFECT_DISCARD; - break; - } - --Params.AntiAlias; - } - - if (Params.AntiAlias==0) - { - os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); - } - } - - // check stencil buffer compatibility - if (Params.Stencilbuffer) - { - present.AutoDepthStencilFormat = D3DFMT_D24S8; - if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - present.AutoDepthStencilFormat = D3DFMT_D24X4S4; - if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - present.AutoDepthStencilFormat = D3DFMT_D15S1; - if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); - Params.Stencilbuffer = false; - } - } - } - else - if(FAILED(pID3D->CheckDepthStencilMatch(adapter, devtype, - present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) - { - os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); - Params.Stencilbuffer = false; - } - } - // do not use else here to cope with flag change in previous block - if (!Params.Stencilbuffer) - { - present.AutoDepthStencilFormat = D3DFMT_D32; - if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - present.AutoDepthStencilFormat = D3DFMT_D24X8; - if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - present.AutoDepthStencilFormat = D3DFMT_D16; - if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, - present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) - { - os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); - return false; - } - } - } - } - - // create device - - DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; - DWORD multithreaded = Params.DriverMultithreaded ? D3DCREATE_MULTITHREADED : 0; - if (pureSoftware) - { - 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 - { - HRESULT hr = pID3D->CreateDevice(adapter, devtype, hwnd, - fpuPrecision | multithreaded | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); - - if(FAILED(hr)) - hr = pID3D->CreateDevice(adapter, devtype, hwnd, - fpuPrecision | multithreaded | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); - - if(FAILED(hr)) - hr = pID3D->CreateDevice(adapter, devtype, hwnd, - fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); - - if (FAILED(hr)) - os::Printer::log("Was not able to create Direct3D9 device.", ELL_ERROR); - } - - if (!pID3DDevice) - { - os::Printer::log("Was not able to create DIRECT3D9 device.", ELL_ERROR); - return false; - } - - // get caps - pID3DDevice->GetDeviceCaps(&Caps); - - os::Printer::log("Currently available Video Memory (kB)", core::stringc(pID3DDevice->GetAvailableTextureMem()/1024).c_str()); - - // disable stencilbuffer if necessary - 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); - Params.Stencilbuffer = false; - } - - // set default vertex shader - setVertexShader(EVT_STANDARD); - - // set fog mode - setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); - - // set exposed data - ExposedData.D3D9.D3D9 = pID3D; - ExposedData.D3D9.D3DDev9 = pID3DDevice; - ExposedData.D3D9.HWnd = hwnd; - - ResetRenderStates = true; - - // create materials - createMaterialRenderers(); - - MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); - MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; - MaxMRTs = (s32)Caps.NumSimultaneousRTs; - OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK); - - if (VendorID==0x10DE)//NVidia - AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, - D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, - (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK); - else if (VendorID==0x1002)//ATI - AlphaToCoverageSupport = true; // TODO: Check unknown -#if 0 - AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, - D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, - (D3DFORMAT)MAKEFOURCC('A','2','M','1')) == S_OK); -#endif - - DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits); - DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures); - DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights); - DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy); - DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes); - DriverAttributes->setAttribute("MaxMultipleRenderTargets", (s32)Caps.NumSimultaneousRTs); - DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex); - DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth)); - DriverAttributes->setAttribute("MaxTextureLODBias", 16); - DriverAttributes->setAttribute("Version", 901); - DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)(((0x00ff00 & Caps.VertexShaderVersion)>>8)*100 + (Caps.VertexShaderVersion&0xff))); - DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias); - - // set the renderstates - setRenderStates3DMode(); - - // store the screen's depth buffer - DepthBuffers.push_back(new SDepthSurface()); - if (SUCCEEDED(pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface)))) - { - D3DSURFACE_DESC desc; - DepthBuffers[0]->Surface->GetDesc(&desc); - DepthBuffers[0]->Size.set(desc.Width, desc.Height); - } - else - { - os::Printer::log("Was not able to get main depth buffer.", ELL_ERROR); - return false; - } - - D3DColorFormat = D3DFMT_A8R8G8B8; - IDirect3DSurface9* bb=0; - if (SUCCEEDED(pID3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb))) - { - D3DSURFACE_DESC desc; - bb->GetDesc(&desc); - D3DColorFormat = desc.Format; - - if (D3DColorFormat == D3DFMT_X8R8G8B8) - D3DColorFormat = D3DFMT_A8R8G8B8; - - bb->Release(); - } - ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat); - - #ifdef _IRR_COMPILE_WITH_CG_ - CgContext = cgCreateContext(); - cgD3D9SetDevice(pID3DDevice); - #endif - - // so far so good. - return true; -} - - -//! applications must call this method before performing any rendering. returns false if failed. -bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, - const SExposedVideoData& videoData, core::rect* sourceRect) -{ - CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); - WindowId = (HWND)videoData.D3D9.HWnd; - SceneSourceRect = sourceRect; - - if (!pID3DDevice) - return false; - - HRESULT hr; - if (DeviceLost) - { - if (FAILED(hr = pID3DDevice->TestCooperativeLevel())) - { - if (hr == D3DERR_DEVICELOST) - { - Sleep(100); - hr = pID3DDevice->TestCooperativeLevel(); - if (hr == D3DERR_DEVICELOST) - return false; - } - - if ((hr == D3DERR_DEVICENOTRESET) && !reset()) - return false; - } - } - - DWORD flags = 0; - - if (backBuffer) - flags |= D3DCLEAR_TARGET; - - if (zBuffer) - flags |= D3DCLEAR_ZBUFFER; - - if (Params.Stencilbuffer) - flags |= D3DCLEAR_STENCIL; - - if (flags) - { - hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); - if (FAILED(hr)) - os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING); - } - - hr = pID3DDevice->BeginScene(); - if (FAILED(hr)) - { - os::Printer::log("DIRECT3D9 begin scene failed.", ELL_WARNING); - return false; - } - - return true; -} - - -//! applications must call this method after performing any rendering. returns false if failed. -bool CD3D9Driver::endScene() -{ - CNullDriver::endScene(); - DriverWasReset=false; - - HRESULT hr = pID3DDevice->EndScene(); - if (FAILED(hr)) - { - os::Printer::log("DIRECT3D9 end scene failed.", ELL_WARNING); - return false; - } - - RECT* srcRct = 0; - RECT sourceRectData; - if ( SceneSourceRect ) - { - srcRct = &sourceRectData; - sourceRectData.left = SceneSourceRect->UpperLeftCorner.X; - sourceRectData.top = SceneSourceRect->UpperLeftCorner.Y; - sourceRectData.right = SceneSourceRect->LowerRightCorner.X; - sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y; - } - - IDirect3DSwapChain9* swChain; - hr = pID3DDevice->GetSwapChain(0, &swChain); - DWORD flags = (Params.HandleSRGB && (Caps.Caps3&D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION))?D3DPRESENT_LINEAR_CONTENT:0; - hr = swChain->Present(srcRct, NULL, WindowId, NULL, flags); - swChain->Release(); - - if (SUCCEEDED(hr)) - return true; - - if (hr == D3DERR_DEVICELOST) - { - DeviceLost = true; - os::Printer::log("Present failed", "DIRECT3D9 device lost.", ELL_WARNING); - } -#ifdef D3DERR_DEVICEREMOVED - else if (hr == D3DERR_DEVICEREMOVED) - { - os::Printer::log("Present failed", "Device removed.", ELL_WARNING); - } -#endif - else if (hr == D3DERR_INVALIDCALL) - { - os::Printer::log("Present failed", "Invalid Call", ELL_WARNING); - } - else - os::Printer::log("DIRECT3D9 present failed.", ELL_WARNING); - return false; -} - - -//! queries the features of the driver, returns true if feature is available -bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const -{ - if (!FeatureEnabled[feature]) - return false; - - switch (feature) - { - case EVDF_MULTITEXTURE: - case EVDF_BILINEAR_FILTER: - return true; - case EVDF_RENDER_TO_TARGET: - return Caps.NumSimultaneousRTs > 0; - case EVDF_HARDWARE_TL: - return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; - case EVDF_MIP_MAP: - return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0; - case EVDF_MIP_MAP_AUTO_UPDATE: - // always return false because a lot of drivers claim they do - // this but actually don't do this at all. - return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0; - case EVDF_STENCIL_BUFFER: - return Params.Stencilbuffer && Caps.StencilCaps; - case EVDF_VERTEX_SHADER_1_1: - return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); - case EVDF_VERTEX_SHADER_2_0: - return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); - case EVDF_VERTEX_SHADER_3_0: - return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); - case EVDF_PIXEL_SHADER_1_1: - return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); - case EVDF_PIXEL_SHADER_1_2: - return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); - case EVDF_PIXEL_SHADER_1_3: - return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); - case EVDF_PIXEL_SHADER_1_4: - return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); - case EVDF_PIXEL_SHADER_2_0: - return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); - case EVDF_PIXEL_SHADER_3_0: - return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); - case EVDF_HLSL: - return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); - case EVDF_TEXTURE_NSQUARE: - return (Caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0; - case EVDF_TEXTURE_NPOT: - return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; - case EVDF_COLOR_MASK: - return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; - case EVDF_MULTIPLE_RENDER_TARGETS: - return Caps.NumSimultaneousRTs > 1; - case EVDF_MRT_COLOR_MASK: - return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_INDEPENDENTWRITEMASKS) != 0; - case EVDF_MRT_BLEND: - return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0; - case EVDF_OCCLUSION_QUERY: - return OcclusionQuerySupport; - case EVDF_POLYGON_OFFSET: - return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0; - case EVDF_BLEND_OPERATIONS: - case EVDF_TEXTURE_MATRIX: -#ifdef _IRR_COMPILE_WITH_CG_ - // available iff. define is present - case EVDF_CG: -#endif - return true; - default: - return false; - }; -} - - -//! sets transformation -void CD3D9Driver::setTransform(E_TRANSFORMATION_STATE state, - const core::matrix4& mat) -{ - Transformation3DChanged = true; - - switch(state) - { - case ETS_VIEW: - pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); - break; - case ETS_WORLD: - pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); - break; - case ETS_PROJECTION: - pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); - break; - case ETS_COUNT: - return; - default: - if (state-ETS_TEXTURE_0 < MATERIAL_MAX_TEXTURES) - { - if (mat.isIdentity()) - pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - else - { - pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); - pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), - (D3DMATRIX*)((void*)mat.pointer())); - } - } - break; - } - - Matrices[state] = mat; -} - - -//! sets the current Texture -bool CD3D9Driver::setActiveTexture(u32 stage, const video::ITexture* texture) -{ - if (CurrentTexture[stage] == texture) - return true; - - if (texture && texture->getDriverType() != EDT_DIRECT3D9) - { - os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); - return false; - } - - CurrentTexture[stage] = texture; - - if (!texture) - { - pID3DDevice->SetTexture(stage, 0); - pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - } - else - { - pID3DDevice->SetTexture(stage, ((const CD3D9Texture*)texture)->getDX9Texture()); - } - return true; -} - - -//! sets a material -void CD3D9Driver::setMaterial(const SMaterial& material) -{ - Material = material; - OverrideMaterial.apply(Material); - - for (u32 i=0; igetDriverType() != EDT_DIRECT3D9) - { - os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); - return false; - } - - // check for valid render target - - if (texture && !texture->isRenderTarget()) - { - os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); - return false; - } - - CD3D9Texture* tex = static_cast(texture); - - // check if we should set the previous RT back - - bool ret = true; - - for(u32 i = 1; i < NumSetMRTs; i++) - { - // First texture handled elsewhere - pID3DDevice->SetRenderTarget(i, NULL); - } - if (tex == 0) - { - if (PrevRenderTarget) - { - if (FAILED(pID3DDevice->SetRenderTarget(0, PrevRenderTarget))) - { - os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); - ret = false; - } - if (FAILED(pID3DDevice->SetDepthStencilSurface(DepthBuffers[0]->Surface))) - { - os::Printer::log("Error: Could not set main depth buffer.", ELL_ERROR); - } - - CurrentRendertargetSize = core::dimension2d(0,0); - PrevRenderTarget->Release(); - PrevRenderTarget = 0; - } - } - else - { - // we want to set a new target. so do this. - - // store previous target - - if (!PrevRenderTarget) - { - if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget))) - { - os::Printer::log("Could not get previous render target.", ELL_ERROR); - return false; - } - } - - // set new render target - - if (FAILED(pID3DDevice->SetRenderTarget(0, tex->getRenderTargetSurface()))) - { - os::Printer::log("Error: Could not set render target.", ELL_ERROR); - return false; - } - CurrentRendertargetSize = tex->getSize(); - - if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface))) - { - os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR); - } - } - Transformation3DChanged=true; - - if (clearBackBuffer || clearZBuffer) - { - DWORD flags = 0; - - if (clearBackBuffer) - flags |= D3DCLEAR_TARGET; - - if (clearZBuffer) - flags |= D3DCLEAR_ZBUFFER; - - pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); - } - - return ret; -} - - -//! Sets multiple render targets -bool CD3D9Driver::setRenderTarget(const core::array& targets, - bool clearBackBuffer, bool clearZBuffer, SColor color) -{ - if (targets.size()==0) - return setRenderTarget(0, clearBackBuffer, clearZBuffer, color); - - u32 maxMultipleRTTs = core::min_(MaxMRTs, targets.size()); - - for (u32 i = 0; i < maxMultipleRTTs; ++i) - { - if (targets[i].TargetType != ERT_RENDER_TEXTURE || !targets[i].RenderTexture) - { - maxMultipleRTTs = i; - os::Printer::log("Missing texture for MRT.", ELL_WARNING); - break; - } - - // check for right driver type - - if (targets[i].RenderTexture->getDriverType() != EDT_DIRECT3D9) - { - maxMultipleRTTs = i; - os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING); - break; - } - - // check for valid render target - - if (!targets[i].RenderTexture->isRenderTarget()) - { - maxMultipleRTTs = i; - os::Printer::log("Tried to set a non render target texture as render target.", ELL_WARNING); - break; - } - - // check for valid size - - if (targets[0].RenderTexture->getSize() != targets[i].RenderTexture->getSize()) - { - maxMultipleRTTs = i; - os::Printer::log("Render target texture has wrong size.", ELL_WARNING); - break; - } - } - if (maxMultipleRTTs==0) - { - os::Printer::log("Fatal Error: No valid MRT found.", ELL_ERROR); - return false; - } - - CD3D9Texture* tex = static_cast(targets[0].RenderTexture); - - // check if we should set the previous RT back - - bool ret = true; - - // we want to set a new target. so do this. - // store previous target - - if (!PrevRenderTarget) - { - if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget))) - { - os::Printer::log("Could not get previous render target.", ELL_ERROR); - return false; - } - } - - // set new render target - - // In d3d9 we have at most 4 MRTs, so the following is enough - D3DRENDERSTATETYPE colorWrite[4]={D3DRS_COLORWRITEENABLE, D3DRS_COLORWRITEENABLE1, D3DRS_COLORWRITEENABLE2, D3DRS_COLORWRITEENABLE3}; - for (u32 i = 0; i < maxMultipleRTTs; ++i) - { - if (FAILED(pID3DDevice->SetRenderTarget(i, static_cast(targets[i].RenderTexture)->getRenderTargetSurface()))) - { - os::Printer::log("Error: Could not set render target.", ELL_ERROR); - return false; - } - if (i<4 && (i==0 || queryFeature(EVDF_MRT_COLOR_MASK))) - { - const DWORD flag = - ((targets[i].ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | - ((targets[i].ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | - ((targets[i].ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | - ((targets[i].ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); - pID3DDevice->SetRenderState(colorWrite[i], flag); - } - } - for(u32 i = maxMultipleRTTs; i < NumSetMRTs; i++) - { - pID3DDevice->SetRenderTarget(i, NULL); - } - NumSetMRTs=maxMultipleRTTs; - - CurrentRendertargetSize = tex->getSize(); - - if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface))) - { - os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR); - } - - if (clearBackBuffer || clearZBuffer) - { - DWORD flags = 0; - - if (clearBackBuffer) - flags |= D3DCLEAR_TARGET; - - if (clearZBuffer) - flags |= D3DCLEAR_ZBUFFER; - - pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); - } - - return ret; -} - - -//! sets a viewport -void CD3D9Driver::setViewPort(const core::rect& area) -{ - core::rect vp = area; - core::rect rendert(0,0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height); - vp.clipAgainst(rendert); - if (vp.getHeight()>0 && vp.getWidth()>0) - { - D3DVIEWPORT9 viewPort; - viewPort.X = vp.UpperLeftCorner.X; - viewPort.Y = vp.UpperLeftCorner.Y; - viewPort.Width = vp.getWidth(); - viewPort.Height = vp.getHeight(); - viewPort.MinZ = 0.0f; - viewPort.MaxZ = 1.0f; - - HRESULT hr = pID3DDevice->SetViewport(&viewPort); - if (FAILED(hr)) - os::Printer::log("Failed setting the viewport.", ELL_WARNING); - else - ViewPort = vp; - } -} - - -//! gets the area of the current viewport -const core::rect& CD3D9Driver::getViewPort() const -{ - return ViewPort; -} - - -bool CD3D9Driver::updateVertexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer) -{ - if (!hwBuffer) - return false; - - const scene::IMeshBuffer* mb = hwBuffer->MeshBuffer; - const void* vertices=mb->getVertices(); - const u32 vertexCount=mb->getVertexCount(); - const E_VERTEX_TYPE vType=mb->getVertexType(); - const u32 vertexSize = getVertexPitchFromType(vType); - const u32 bufSize = vertexSize * vertexCount; - - if (!hwBuffer->vertexBuffer || (bufSize > hwBuffer->vertexBufferSize)) - { - if (hwBuffer->vertexBuffer) - { - hwBuffer->vertexBuffer->Release(); - hwBuffer->vertexBuffer=0; - } - - DWORD FVF; - // Get the vertex sizes and cvf - switch (vType) - { - case EVT_STANDARD: - FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1; - break; - case EVT_2TCOORDS: - FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2; - break; - case EVT_TANGENTS: - FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3; - break; - default: - return false; - } - - DWORD flags = D3DUSAGE_WRITEONLY; // SIO2: Default to D3DUSAGE_WRITEONLY - if (hwBuffer->Mapped_Vertex != scene::EHM_STATIC) - flags |= D3DUSAGE_DYNAMIC; - - if (FAILED(pID3DDevice->CreateVertexBuffer(bufSize, flags, FVF, D3DPOOL_DEFAULT, &hwBuffer->vertexBuffer, NULL))) - return false; - hwBuffer->vertexBufferSize = bufSize; - - flags = 0; // SIO2: Reset flags before Lock - if (hwBuffer->Mapped_Vertex != scene::EHM_STATIC) - flags = D3DLOCK_DISCARD; - - void* lockedBuffer = 0; - hwBuffer->vertexBuffer->Lock(0, bufSize, (void**)&lockedBuffer, flags); - memcpy(lockedBuffer, vertices, bufSize); - hwBuffer->vertexBuffer->Unlock(); - } - else - { - void* lockedBuffer = 0; - hwBuffer->vertexBuffer->Lock(0, bufSize, (void**)&lockedBuffer, D3DLOCK_DISCARD); - memcpy(lockedBuffer, vertices, bufSize); - hwBuffer->vertexBuffer->Unlock(); - } - - return true; -} - - -bool CD3D9Driver::updateIndexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer) -{ - if (!hwBuffer) - return false; - - const scene::IMeshBuffer* mb = hwBuffer->MeshBuffer; - const u16* indices=mb->getIndices(); - const u32 indexCount=mb->getIndexCount(); - u32 indexSize = 2; - D3DFORMAT indexType=D3DFMT_UNKNOWN; - switch (mb->getIndexType()) - { - case EIT_16BIT: - { - indexType=D3DFMT_INDEX16; - indexSize = 2; - break; - } - case EIT_32BIT: - { - indexType=D3DFMT_INDEX32; - indexSize = 4; - break; - } - } - - const u32 bufSize = indexSize * indexCount; - if (!hwBuffer->indexBuffer || (bufSize > hwBuffer->indexBufferSize)) - { - if (hwBuffer->indexBuffer) - { - hwBuffer->indexBuffer->Release(); - hwBuffer->indexBuffer=0; - } - - DWORD flags = D3DUSAGE_WRITEONLY; // SIO2: Default to D3DUSAGE_WRITEONLY - if (hwBuffer->Mapped_Index != scene::EHM_STATIC) - flags |= D3DUSAGE_DYNAMIC; // SIO2: Add DYNAMIC flag for dynamic buffer data - - if (FAILED(pID3DDevice->CreateIndexBuffer(bufSize, flags, indexType, D3DPOOL_DEFAULT, &hwBuffer->indexBuffer, NULL))) - return false; - - flags = 0; // SIO2: Reset flags before Lock - if (hwBuffer->Mapped_Index != scene::EHM_STATIC) - flags = D3DLOCK_DISCARD; - - void* lockedBuffer = 0; - if (FAILED(hwBuffer->indexBuffer->Lock( 0, 0, (void**)&lockedBuffer, flags))) - return false; - - memcpy(lockedBuffer, indices, bufSize); - hwBuffer->indexBuffer->Unlock(); - - hwBuffer->indexBufferSize = bufSize; - } - else - { - void* lockedBuffer = 0; - if( SUCCEEDED(hwBuffer->indexBuffer->Lock( 0, 0, (void**)&lockedBuffer, D3DLOCK_DISCARD))) - { - memcpy(lockedBuffer, indices, bufSize); - hwBuffer->indexBuffer->Unlock(); - } - } - - return true; -} - - -//! updates hardware buffer if needed -bool CD3D9Driver::updateHardwareBuffer(SHWBufferLink *hwBuffer) -{ - if (!hwBuffer) - return false; - - if (hwBuffer->Mapped_Vertex!=scene::EHM_NEVER) - { - if (hwBuffer->ChangedID_Vertex != hwBuffer->MeshBuffer->getChangedID_Vertex() - || !((SHWBufferLink_d3d9*)hwBuffer)->vertexBuffer) - { - hwBuffer->ChangedID_Vertex = hwBuffer->MeshBuffer->getChangedID_Vertex(); - - if (!updateVertexHardwareBuffer((SHWBufferLink_d3d9*)hwBuffer)) - return false; - } - } - - if (hwBuffer->Mapped_Index!=scene::EHM_NEVER) - { - if (hwBuffer->ChangedID_Index != hwBuffer->MeshBuffer->getChangedID_Index() - || !((SHWBufferLink_d3d9*)hwBuffer)->indexBuffer) - { - hwBuffer->ChangedID_Index = hwBuffer->MeshBuffer->getChangedID_Index(); - - if (!updateIndexHardwareBuffer((SHWBufferLink_d3d9*)hwBuffer)) - return false; - } - } - - return true; -} - - -//! Create hardware buffer from meshbuffer -CD3D9Driver::SHWBufferLink *CD3D9Driver::createHardwareBuffer(const scene::IMeshBuffer* mb) -{ - // Looks like d3d does not support only partial buffering, so refuse - // in any case of NEVER - if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER || mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) - return 0; - - SHWBufferLink_d3d9 *hwBuffer=new SHWBufferLink_d3d9(mb); - - //add to map - HWBufferMap.insert(hwBuffer->MeshBuffer, hwBuffer); - - hwBuffer->ChangedID_Vertex=hwBuffer->MeshBuffer->getChangedID_Vertex(); - hwBuffer->ChangedID_Index=hwBuffer->MeshBuffer->getChangedID_Index(); - hwBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex(); - hwBuffer->Mapped_Index=mb->getHardwareMappingHint_Index(); - hwBuffer->LastUsed=0; - hwBuffer->vertexBuffer=0; - hwBuffer->indexBuffer=0; - hwBuffer->vertexBufferSize=0; - hwBuffer->indexBufferSize=0; - - if (!updateHardwareBuffer(hwBuffer)) - { - deleteHardwareBuffer(hwBuffer); - return 0; - } - - return hwBuffer; -} - - -void CD3D9Driver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer) -{ - if (!_HWBuffer) - return; - - SHWBufferLink_d3d9 *HWBuffer=(SHWBufferLink_d3d9*)_HWBuffer; - if (HWBuffer->indexBuffer) - { - HWBuffer->indexBuffer->Release(); - HWBuffer->indexBuffer = 0; - } - - if (HWBuffer->vertexBuffer) - { - HWBuffer->vertexBuffer->Release(); - HWBuffer->vertexBuffer = 0; - } - - CNullDriver::deleteHardwareBuffer(_HWBuffer); -} - - -//! Draw hardware buffer -void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) -{ - if (!_HWBuffer) - return; - - SHWBufferLink_d3d9 *HWBuffer=(SHWBufferLink_d3d9*)_HWBuffer; - - updateHardwareBuffer(HWBuffer); //check if update is needed - - HWBuffer->LastUsed=0;//reset count - - const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; - const E_VERTEX_TYPE vType = mb->getVertexType(); - const u32 stride = getVertexPitchFromType(vType); - const void* vPtr = mb->getVertices(); - const void* iPtr = mb->getIndices(); - if (HWBuffer->vertexBuffer) - { - pID3DDevice->SetStreamSource(0, HWBuffer->vertexBuffer, 0, stride); - vPtr=0; - } - if (HWBuffer->indexBuffer) - { - pID3DDevice->SetIndices(HWBuffer->indexBuffer); - iPtr=0; - } - - drawVertexPrimitiveList(vPtr, mb->getVertexCount(), iPtr, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); - - if (HWBuffer->vertexBuffer) - pID3DDevice->SetStreamSource(0, 0, 0, 0); - if (HWBuffer->indexBuffer) - pID3DDevice->SetIndices(0); -} - - -//! Create occlusion query. -/** Use node for identification and mesh for occlusion test. */ -void CD3D9Driver::addOcclusionQuery(scene::ISceneNode* node, - const scene::IMesh* mesh) -{ - if (!queryFeature(EVDF_OCCLUSION_QUERY)) - return; - CNullDriver::addOcclusionQuery(node, mesh); - const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); - if ((index != -1) && (OcclusionQueries[index].PID == 0)) - pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast(&OcclusionQueries[index].PID)); -} - - -//! Remove occlusion query. -void CD3D9Driver::removeOcclusionQuery(scene::ISceneNode* node) -{ - const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); - if (index != -1) - { - if (OcclusionQueries[index].PID != 0) - reinterpret_cast(OcclusionQueries[index].PID)->Release(); - CNullDriver::removeOcclusionQuery(node); - } -} - - -//! Run occlusion query. Draws mesh stored in query. -/** If the mesh shall not be rendered visible, use -overrideMaterial to disable the color and depth buffer. */ -void CD3D9Driver::runOcclusionQuery(scene::ISceneNode* node, bool visible) -{ - if (!node) - return; - - const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); - if (index != -1) - { - if (OcclusionQueries[index].PID) - reinterpret_cast(OcclusionQueries[index].PID)->Issue(D3DISSUE_BEGIN); - CNullDriver::runOcclusionQuery(node,visible); - if (OcclusionQueries[index].PID) - reinterpret_cast(OcclusionQueries[index].PID)->Issue(D3DISSUE_END); - } -} - - -//! Update occlusion query. Retrieves results from GPU. -/** If the query shall not block, set the flag to false. -Update might not occur in this case, though */ -void CD3D9Driver::updateOcclusionQuery(scene::ISceneNode* node, bool block) -{ - const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); - if (index != -1) - { - // not yet started - if (OcclusionQueries[index].Run==u32(~0)) - return; - bool available = block?true:false; - int tmp=0; - if (!block) - available=(reinterpret_cast(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), 0)==S_OK); - else - { - do - { - HRESULT hr = reinterpret_cast(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), D3DGETDATA_FLUSH); - available = (hr == S_OK); - if (hr!=S_FALSE) - break; - } while (!available); - } - if (available) - OcclusionQueries[index].Result = tmp; - } -} - - -//! Return query result. -/** Return value is the number of visible pixels/fragments. -The value is a safe approximation, i.e. can be larger than the -actual value of pixels. */ -u32 CD3D9Driver::getOcclusionQueryResult(scene::ISceneNode* node) const -{ - const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); - if (index != -1) - return OcclusionQueries[index].Result; - else - return ~0; -} - - -//! draws a vertex primitive list -void CD3D9Driver::drawVertexPrimitiveList(const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType) -{ - if (!checkPrimitiveCount(primitiveCount)) - return; - - CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); - - if (!vertexCount || !primitiveCount) - return; - - draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, - vType, pType, iType, true); -} - - -//! draws a vertex primitive list -void CD3D9Driver::draw2DVertexPrimitiveList(const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType) -{ - if (!checkPrimitiveCount(primitiveCount)) - return; - - CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); - - if (!vertexCount || !primitiveCount) - return; - - draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, - vType, pType, iType, false); -} - - -void CD3D9Driver::draw2D3DVertexPrimitiveList(const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType, bool is3D) -{ - setVertexShader(vType); - - const u32 stride = getVertexPitchFromType(vType); - - D3DFORMAT indexType=D3DFMT_UNKNOWN; - switch (iType) - { - case (EIT_16BIT): - { - indexType=D3DFMT_INDEX16; - break; - } - case (EIT_32BIT): - { - indexType=D3DFMT_INDEX32; - break; - } - } - - if (is3D) - { - if (!setRenderStates3DMode()) - return; - } - else - { - if (Material.MaterialType==EMT_ONETEXTURE_BLEND) - { - E_BLEND_FACTOR srcFact; - E_BLEND_FACTOR dstFact; - E_MODULATE_FUNC modulo; - u32 alphaSource; - unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); - setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); - } - else - setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); - } - - switch (pType) - { - case scene::EPT_POINT_SPRITES: - case scene::EPT_POINTS: - { - f32 tmp=Material.Thickness/getScreenSize().Height; - if (pType==scene::EPT_POINT_SPRITES) - pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(tmp)); - tmp=1.0f; - pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, F2DW(tmp)); - pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, F2DW(tmp)); - pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, F2DW(tmp)); - tmp=0.0f; - pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, F2DW(tmp)); - - if (!vertices) - { - pID3DDevice->DrawIndexedPrimitive(D3DPT_POINTLIST, 0, 0, vertexCount, 0, primitiveCount); - } - else - { - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - } - - pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); - if (pType==scene::EPT_POINT_SPRITES) - pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); - } - break; - case scene::EPT_LINE_STRIP: - if(!vertices) - pID3DDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 0, vertexCount, 0, primitiveCount); - else - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - break; - case scene::EPT_LINE_LOOP: - if(!vertices) - { - // TODO: Implement proper hardware support for this primitive type. - // (No looping occurs currently because this would require a way to - // draw the hardware buffer with a custom set of indices. We may even - // need to create a new mini index buffer specifically for this - // primitive type.) - pID3DDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount); - } - else - { - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, - primitiveCount - 1, indexList, indexType, vertices, stride); - - u16 tmpIndices[] = {primitiveCount - 1, 0}; - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, - 1, tmpIndices, indexType, vertices, stride); - } - break; - case scene::EPT_LINES: - if(!vertices) - pID3DDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount); - else - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - break; - case scene::EPT_TRIANGLE_STRIP: - if(!vertices) - pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, vertexCount, 0, primitiveCount); - else - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, primitiveCount, - indexList, indexType, vertices, stride); - break; - case scene::EPT_TRIANGLE_FAN: - if(!vertices) - pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0, 0, vertexCount, 0, primitiveCount); - else - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, primitiveCount, - indexList, indexType, vertices, stride); - break; - case scene::EPT_TRIANGLES: - if(!vertices) - { - pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vertexCount, 0, primitiveCount); - } - else - { - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, - primitiveCount, indexList, indexType, vertices, stride); - } - break; - } -} - - -void CD3D9Driver::draw2DImage(const video::ITexture* texture, - const core::rect& destRect, - const core::rect& sourceRect, - const core::rect* clipRect, - const video::SColor* const colors, - bool useAlphaChannelOfTexture) -{ - if(!texture) - return; - - const core::dimension2d& ss = texture->getOriginalSize(); - core::rect tcoords; - tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; - tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; - tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; - tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; - - const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - - const video::SColor temp[4] = - { - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF - }; - - const video::SColor* const useColor = colors ? colors : temp; - - S3DVertex vtx[4]; // clock wise - vtx[0] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, useColor[0], - tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); - vtx[1] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, useColor[3], - tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); - vtx[2] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, useColor[2], - tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); - vtx[3] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, useColor[1], - tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); - - s16 indices[6] = {0,1,2,0,2,3}; - - setActiveTexture(0, const_cast(texture)); - - setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || - useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, - true, useAlphaChannelOfTexture); - - setVertexShader(EVT_STANDARD); - - if (clipRect) - { - pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - RECT scissor; - scissor.left = clipRect->UpperLeftCorner.X; - scissor.top = clipRect->UpperLeftCorner.Y; - scissor.right = clipRect->LowerRightCorner.X; - scissor.bottom = clipRect->LowerRightCorner.Y; - pID3DDevice->SetScissorRect(&scissor); - } - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], - D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); - - if (clipRect) - pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); -} - - -void CD3D9Driver::draw2DImageBatch(const video::ITexture* texture, - const core::array >& positions, - const core::array >& sourceRects, - const core::rect* clipRect, - SColor color, - bool useAlphaChannelOfTexture) -{ - if (!texture) - return; - - if (!setActiveTexture(0, const_cast(texture))) - return; - - setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); - - const irr::u32 drawCount = core::min_(positions.size(), sourceRects.size()); - - core::array vtx(drawCount * 4); - core::array indices(drawCount * 6); - - for(u32 i = 0;i < drawCount;i++) - { - core::position2d targetPos = positions[i]; - core::position2d sourcePos = sourceRects[i].UpperLeftCorner; - // This needs to be signed as it may go negative. - core::dimension2d sourceSize(sourceRects[i].getSize()); - - if (clipRect) - { - if (targetPos.X < clipRect->UpperLeftCorner.X) - { - sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; - if (sourceSize.Width <= 0) - continue; - - sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; - targetPos.X = clipRect->UpperLeftCorner.X; - } - - if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) - { - sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; - if (sourceSize.Width <= 0) - continue; - } - - if (targetPos.Y < clipRect->UpperLeftCorner.Y) - { - sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; - if (sourceSize.Height <= 0) - continue; - - sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; - targetPos.Y = clipRect->UpperLeftCorner.Y; - } - - if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) - { - sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; - if (sourceSize.Height <= 0) - continue; - } - } - - // clip these coordinates - - if (targetPos.X<0) - { - sourceSize.Width += targetPos.X; - if (sourceSize.Width <= 0) - continue; - - sourcePos.X -= targetPos.X; - targetPos.X = 0; - } - - const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - - if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) - { - sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; - if (sourceSize.Width <= 0) - continue; - } - - if (targetPos.Y<0) - { - sourceSize.Height += targetPos.Y; - if (sourceSize.Height <= 0) - continue; - - sourcePos.Y -= targetPos.Y; - targetPos.Y = 0; - } - - if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) - { - sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; - if (sourceSize.Height <= 0) - continue; - } - - // ok, we've clipped everything. - // now draw it. - - core::rect tcoords; - tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; - tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; - tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); - tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); - - const core::rect poss(targetPos, sourceSize); - - vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y)); - vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y)); - vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y)); - vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y)); - - const u32 curPos = vtx.size()-4; - indices.push_back(0+curPos); - indices.push_back(1+curPos); - indices.push_back(2+curPos); - - indices.push_back(0+curPos); - indices.push_back(2+curPos); - indices.push_back(3+curPos); - } - - if (vtx.size()) - { - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vtx.size(), indices.size() / 3, indices.pointer(), - D3DFMT_INDEX16,vtx.pointer(), sizeof(S3DVertex)); - } -} - - -//! draws a 2d image, using a color and the alpha channel of the texture if -//! desired. The image is drawn at pos and clipped against clipRect (if != 0). -void CD3D9Driver::draw2DImage(const video::ITexture* texture, - const core::position2d& pos, - const core::rect& sourceRect, - const core::rect* clipRect, SColor color, - bool useAlphaChannelOfTexture) -{ - if (!texture) - return; - - if (!sourceRect.isValid()) - return; - - if (!setActiveTexture(0, const_cast(texture))) - return; - - core::position2d targetPos = pos; - core::position2d sourcePos = sourceRect.UpperLeftCorner; - // This needs to be signed as it may go negative. - core::dimension2d sourceSize(sourceRect.getSize()); - - if (clipRect) - { - if (targetPos.X < clipRect->UpperLeftCorner.X) - { - sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; - if (sourceSize.Width <= 0) - return; - - sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; - targetPos.X = clipRect->UpperLeftCorner.X; - } - - if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) - { - sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; - if (sourceSize.Width <= 0) - return; - } - - if (targetPos.Y < clipRect->UpperLeftCorner.Y) - { - sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; - if (sourceSize.Height <= 0) - return; - - sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; - targetPos.Y = clipRect->UpperLeftCorner.Y; - } - - if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) - { - sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; - if (sourceSize.Height <= 0) - return; - } - } - - // clip these coordinates - - if (targetPos.X<0) - { - sourceSize.Width += targetPos.X; - if (sourceSize.Width <= 0) - return; - - sourcePos.X -= targetPos.X; - targetPos.X = 0; - } - - const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - - if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) - { - sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; - if (sourceSize.Width <= 0) - return; - } - - if (targetPos.Y<0) - { - sourceSize.Height += targetPos.Y; - if (sourceSize.Height <= 0) - return; - - sourcePos.Y -= targetPos.Y; - targetPos.Y = 0; - } - - if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) - { - sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; - if (sourceSize.Height <= 0) - return; - } - - // ok, we've clipped everything. - // now draw it. - - core::rect tcoords; - tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; - tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; - tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); - tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); - - const core::rect poss(targetPos, sourceSize); - - setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); - - S3DVertex vtx[4]; - vtx[0] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); - vtx[1] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); - vtx[2] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); - vtx[3] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, color, - tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); - - s16 indices[6] = {0,1,2,0,2,3}; - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], - D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); -} - - -//!Draws a 2d rectangle with a gradient. -void CD3D9Driver::draw2DRectangle(const core::rect& position, - SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, - const core::rect* clip) -{ - core::rect pos(position); - - if (clip) - pos.clipAgainst(*clip); - - if (!pos.isValid()) - return; - - S3DVertex vtx[4]; - vtx[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); - vtx[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); - vtx[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); - vtx[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, - 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); - - s16 indices[6] = {0,1,2,0,2,3}; - - setRenderStates2DMode( - colorLeftUp.getAlpha() < 255 || - colorRightUp.getAlpha() < 255 || - colorLeftDown.getAlpha() < 255 || - colorRightDown.getAlpha() < 255, false, false); - - setActiveTexture(0,0); - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], - D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); -} - - -//! Draws a 2d line. -void CD3D9Driver::draw2DLine(const core::position2d& start, - const core::position2d& end, - SColor color) -{ - if (start==end) - drawPixel(start.X, start.Y, color); - else - { - // thanks to Vash TheStampede who sent in his implementation - S3DVertex vtx[2]; - vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f, - 0.0f, 0.0f, 0.0f, // normal - color, 0.0f, 0.0f); // texture - - vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f, - 0.0f, 0.0f, 0.0f, - color, 0.0f, 0.0f); - - setRenderStates2DMode(color.getAlpha() < 255, false, false); - setActiveTexture(0,0); - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, - &vtx[0], sizeof(S3DVertex) ); - } -} - - -//! Draws a pixel -void CD3D9Driver::drawPixel(u32 x, u32 y, const SColor & color) -{ - const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - if(x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) - return; - - setRenderStates2DMode(color.getAlpha() < 255, false, false); - setActiveTexture(0,0); - - setVertexShader(EVT_STANDARD); - - S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); - - pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); -} - - -//! sets right vertex shader -void CD3D9Driver::setVertexShader(E_VERTEX_TYPE newType) -{ - if (newType != LastVertexType) - { - LastVertexType = newType; - HRESULT hr = 0; - - switch(newType) - { - case EVT_STANDARD: - hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); - break; - case EVT_2TCOORDS: - hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); - break; - case EVT_TANGENTS: - hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | - D3DFVF_TEXCOORDSIZE2(0) | // real texture coord - D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent - D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal - ); - break; - } - - if (FAILED(hr)) - { - os::Printer::log("Could not set vertex Shader.", ELL_ERROR); - return; - } - } -} - - -//! sets the needed renderstates -bool CD3D9Driver::setRenderStates3DMode() -{ - if (!pID3DDevice) - return false; - - if (CurrentRenderMode != ERM_3D) - { - // switch back the matrices - pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); - pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); - pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); - - pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - pID3DDevice->SetRenderState(D3DRS_CLIPPING, TRUE); - - ResetRenderStates = true; - } - - if (ResetRenderStates || LastMaterial != Material) - { - // unset old material - - if (CurrentRenderMode == ERM_3D && - LastMaterial.MaterialType != Material.MaterialType && - LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) - MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); - - // set new material. - - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( - Material, LastMaterial, ResetRenderStates, this); - } - - bool shaderOK = true; - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); - - LastMaterial = Material; - - ResetRenderStates = false; - - CurrentRenderMode = ERM_3D; - - return shaderOK; -} - - -//! Map Irrlicht texture wrap mode to native values -D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp) -{ - switch (clamp) - { - case ETC_REPEAT: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP) - return D3DTADDRESS_WRAP; - case ETC_CLAMP: - case ETC_CLAMP_TO_EDGE: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP) - return D3DTADDRESS_CLAMP; - case ETC_MIRROR: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) - return D3DTADDRESS_MIRROR; - case ETC_CLAMP_TO_BORDER: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) - return D3DTADDRESS_BORDER; - else - return D3DTADDRESS_CLAMP; - case ETC_MIRROR_CLAMP: - case ETC_MIRROR_CLAMP_TO_EDGE: - case ETC_MIRROR_CLAMP_TO_BORDER: - if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE) - return D3DTADDRESS_MIRRORONCE; - else - return D3DTADDRESS_CLAMP; - default: - return D3DTADDRESS_WRAP; - } -} - - -//! Can be called by an IMaterialRenderer to make its work easier. -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 || - lastmaterial.SpecularColor != material.SpecularColor || - lastmaterial.EmissiveColor != material.EmissiveColor || - lastmaterial.Shininess != material.Shininess) - { - D3DMATERIAL9 mat; - mat.Diffuse = colorToD3D(material.DiffuseColor); - mat.Ambient = colorToD3D(material.AmbientColor); - mat.Specular = colorToD3D(material.SpecularColor); - mat.Emissive = colorToD3D(material.EmissiveColor); - mat.Power = material.Shininess; - pID3DDevice->SetMaterial(&mat); - } - - if (lastmaterial.ColorMaterial != material.ColorMaterial) - { - pID3DDevice->SetRenderState(D3DRS_COLORVERTEX, (material.ColorMaterial != ECM_NONE)); - pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, - ((material.ColorMaterial == ECM_DIFFUSE)|| - (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); - pID3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, - ((material.ColorMaterial == ECM_AMBIENT)|| - (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); - pID3DDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, - (material.ColorMaterial == ECM_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); - pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, - (material.ColorMaterial == ECM_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); - } - - // fillmode - if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) - { - if (material.Wireframe) - pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); - else - if (material.PointCloud) - pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); - else - pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - } - - // shademode - - if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) - { - if (material.GouraudShading) - pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); - else - pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); - } - - // lighting - - if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) - { - if (material.Lighting) - pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); - else - pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); - } - - // zbuffer - - if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) - { - switch (material.ZBuffer) - { - case ECFN_NEVER: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); - break; - case ECFN_LESSEQUAL: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - break; - case ECFN_EQUAL: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); - break; - case ECFN_LESS: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); - break; - case ECFN_NOTEQUAL: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); - break; - case ECFN_GREATEREQUAL: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); - break; - case ECFN_GREATER: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); - break; - case ECFN_ALWAYS: - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - break; - } - } - - // zwrite -// if (resetAllRenderstates || (lastmaterial.ZWriteEnable != material.ZWriteEnable)) - { - if ( material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) - pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); - else - pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); - } - - // back face culling - - if (resetAllRenderstates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) - { -// if (material.FrontfaceCulling && material.BackfaceCulling) -// pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW|D3DCULL_CCW); -// else - if (material.FrontfaceCulling) - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); - else - if (material.BackfaceCulling) - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); - else - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - } - - // fog - if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) - { - pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); - } - - // specular highlights - if (resetAllRenderstates || !core::equals(lastmaterial.Shininess,material.Shininess)) - { - const bool enable = (material.Shininess!=0.0f); - pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); - pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); - } - - // normalization - if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) - { - pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); - } - - // Color Mask - if (queryFeature(EVDF_COLOR_MASK) && - (resetAllRenderstates || lastmaterial.ColorMask != material.ColorMask)) - { - const DWORD flag = - ((material.ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | - ((material.ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | - ((material.ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | - ((material.ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); - pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); - } - - if (queryFeature(EVDF_BLEND_OPERATIONS) && - (resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation)) - { - if (material.BlendOperation==EBO_NONE) - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - else - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - switch (material.BlendOperation) - { - case EBO_SUBTRACT: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); - break; - case EBO_REVSUBTRACT: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); - break; - case EBO_MIN: - case EBO_MIN_FACTOR: - case EBO_MIN_ALPHA: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); - break; - case EBO_MAX: - case EBO_MAX_FACTOR: - case EBO_MAX_ALPHA: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); - break; - default: - pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - break; - } - } - } - - // Polygon offset - if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || - lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || - lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) - { - if (material.PolygonOffsetFactor) - { - if (material.PolygonOffsetDirection==EPO_BACK) - { - pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(1.f)); - pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)material.PolygonOffsetFactor)); - } - else - { - pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(-1.f)); - pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)-material.PolygonOffsetFactor)); - } - } - else - { - pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); - pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); - } - } - - // Anti Aliasing - if (resetAllRenderstates || lastmaterial.AntiAliasing != material.AntiAliasing) - { - if (AlphaToCoverageSupport && (material.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)) - { - if (VendorID==0x10DE)//NVidia - pID3DDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, MAKEFOURCC('A','T','O','C')); - // SSAA could give better results on NVidia cards - else if (VendorID==0x1002)//ATI - pID3DDevice->SetRenderState(D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','1')); - } - else if (AlphaToCoverageSupport && (lastmaterial.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)) - { - if (VendorID==0x10DE) - pID3DDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN); - else if (VendorID==0x1002) - pID3DDevice->SetRenderState(D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','0')); - } - - // enable antialiasing - if (Params.AntiAlias) - { - if (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY)) - pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); - else if (lastmaterial.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY)) - pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); - if (material.AntiAliasing & (EAAM_LINE_SMOOTH)) - pID3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, TRUE); - else if (lastmaterial.AntiAliasing & (EAAM_LINE_SMOOTH)) - pID3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE); - } - } - - // thickness - if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) - { - pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(material.Thickness)); - } - - // texture address mode - for (u32 st=0; stSetSamplerState(st, D3DSAMP_SRGBTEXTURE, TRUE); - - if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias) - { - const float tmp = material.TextureLayer[st].LODBias * 0.125f; - pID3DDevice->SetSamplerState(st, D3DSAMP_MIPMAPLODBIAS, F2DW(tmp)); - } - - if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU) - pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); - // If separate UV not supported reuse U for V - if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV)) - pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); - else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV) - pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV)); - - // Bilinear, trilinear, and anisotropic filter - if (resetAllRenderstates || - lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || - lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || - lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter || - lastmaterial.UseMipMaps != material.UseMipMaps) - { - if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter) - { - D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && - material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; - D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && - material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; - D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE; - - if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC) - pID3DDevice->SetSamplerState(st, D3DSAMP_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy)); - pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, tftMag); - pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, tftMin); - pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, tftMip); - } - else - { - pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, D3DTEXF_POINT); - pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, D3DTEXF_NONE); - pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - } - } - } -} - - -//! sets the needed renderstates -void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible) -{ - if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && - CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || - Transformation3DChanged) - { - // unset last 3d material - if (CurrentRenderMode == ERM_3D && - static_cast(Material.MaterialType) < MaterialRenderers.size()) - { - MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); - ResetRenderStates = true; - } - // switch back the matrices - pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); - pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); - pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); - - Transformation3DChanged = false; - - setActiveTexture(0,0); - setActiveTexture(1,0); - setActiveTexture(2,0); - setActiveTexture(3,0); - - pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - - pID3DDevice->SetFVF(D3DFVF_XYZ); - LastVertexType = (video::E_VERTEX_TYPE)(-1); - - pID3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); - //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); - //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - - pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); - pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x0); - pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); - pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); - - pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); - pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); - pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); - - pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); - - //if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) - // pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); - if ((debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)) - pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); - } - - if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) - { - // USE THE ZPASS METHOD - pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); - pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); - //pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); // does not matter, will be set later - } - else - if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) - { - // USE THE ZFAIL METHOD - pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); - //pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); // does not matter, will be set later - pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); - } - - CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; -} - - -//! sets the needed renderstates -void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha) -{ - if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) - { - core::matrix4 mat; - pID3DDevice->SetTransform(D3DTS_VIEW, &UnitMatrixD3D9); - pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D9); - pID3DDevice->SetTransform(D3DTS_PROJECTION, &UnitMatrixD3D9); - - pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); - pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); - pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1); - pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); - //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); - pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); - pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); - pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); - pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); - pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); - - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); - - Transformation3DChanged = false; - - pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - if (alpha) - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - } - else - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } - - CurrentRenderMode = ERM_STENCIL_FILL; -} - - -//! Enable the 2d override material -void CD3D9Driver::enableMaterial2D(bool enable) -{ - if (!enable) - CurrentRenderMode = ERM_NONE; - CNullDriver::enableMaterial2D(enable); -} - - -//! sets the needed renderstates -void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) -{ - if (!pID3DDevice) - return; - - if (CurrentRenderMode != ERM_2D || Transformation3DChanged) - { - // unset last 3d material - if (CurrentRenderMode == ERM_3D) - { - if (static_cast(LastMaterial.MaterialType) < MaterialRenderers.size()) - MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); - } - if (!OverrideMaterial2DEnabled) - { - setBasicRenderStates(InitMaterial2D, LastMaterial, true); - LastMaterial=InitMaterial2D; - - // fix everything that is wrongly set by InitMaterial2D default - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - } - core::matrix4 m; -// this fixes some problems with pixel exact rendering, but also breaks nice texturing -// moreover, it would have to be tested in each call, as the texture flag can change each time -// if (!texture) -// m.setTranslation(core::vector3df(0.5f,0.5f,0)); - pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)m.pointer())); - - // adjust the view such that pixel center aligns with texels - // Otherwise, subpixel artifacts will occur - m.setTranslation(core::vector3df(-0.5f,-0.5f,0)); - pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)m.pointer())); - - const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0, 1.0); - m.setTranslation(core::vector3df(-1,1,0)); - pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer())); - - // 2d elements are clipped in software - pID3DDevice->SetRenderState(D3DRS_CLIPPING, FALSE); - - Transformation3DChanged = false; - } - if (OverrideMaterial2DEnabled) - { - OverrideMaterial2D.Lighting=false; - setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); - LastMaterial = OverrideMaterial2D; - } - - // no alphaChannel without texture - alphaChannel &= texture; - - if (alpha || alphaChannel) - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - } - else - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - if (texture) - { - setTransform(ETS_TEXTURE_0, core::IdentityMatrix); - // Due to the transformation change, the previous line would call a reset each frame - // but we can safely reset the variable as it was false before - Transformation3DChanged=false; - } - if (alphaChannel) - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - - if (alpha) - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - } - else - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - } - } - else - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - if (alpha) - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); - } - else - { - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - } - } - - CurrentRenderMode = ERM_2D; -} - - -//! deletes all dynamic lights there are -void CD3D9Driver::deleteAllDynamicLights() -{ - for (s32 i=0; iLightEnable(i, false); - - LastSetLight = -1; - - CNullDriver::deleteAllDynamicLights(); -} - - -//! adds a dynamic light -s32 CD3D9Driver::addDynamicLight(const SLight& dl) -{ - CNullDriver::addDynamicLight(dl); - - D3DLIGHT9 light; - - switch (dl.Type) - { - case ELT_POINT: - light.Type = D3DLIGHT_POINT; - break; - case ELT_SPOT: - light.Type = D3DLIGHT_SPOT; - break; - case ELT_DIRECTIONAL: - light.Type = D3DLIGHT_DIRECTIONAL; - break; - } - - light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); - light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); - - light.Range = core::min_(dl.Radius, MaxLightDistance); - light.Falloff = dl.Falloff; - - light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); - light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); - light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); - - light.Attenuation0 = dl.Attenuation.X; - light.Attenuation1 = dl.Attenuation.Y; - light.Attenuation2 = dl.Attenuation.Z; - - light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; - light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; - - ++LastSetLight; - - if(D3D_OK == pID3DDevice->SetLight(LastSetLight, &light)) - { - // I don't care if this succeeds - (void)pID3DDevice->LightEnable(LastSetLight, true); - return LastSetLight; - } - - return -1; -} - -//! Turns a dynamic light on or off -//! \param lightIndex: the index returned by addDynamicLight -//! \param turnOn: true to turn the light on, false to turn it off -void CD3D9Driver::turnLightOn(s32 lightIndex, bool turnOn) -{ - if(lightIndex < 0 || lightIndex > LastSetLight) - return; - - (void)pID3DDevice->LightEnable(lightIndex, turnOn); -} - - -//! returns the maximal amount of dynamic lights the device can handle -u32 CD3D9Driver::getMaximalDynamicLightAmount() const -{ - return Caps.MaxActiveLights; -} - - -//! Sets the dynamic ambient light color. The default color is -//! (0,0,0,0) which means it is dark. -//! \param color: New color of the ambient light. -void CD3D9Driver::setAmbientLight(const SColorf& color) -{ - if (!pID3DDevice) - return; - - AmbientLight = color; - D3DCOLOR col = color.toSColor().color; - pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); -} - - -//! \return Returns the name of the video driver. Example: In case of the DIRECT3D9 -//! driver, it would return "Direct3D9.0". -const wchar_t* CD3D9Driver::getName() const -{ - return L"Direct3D 9.0"; -} - - -//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do -//! this: First, draw all geometry. Then use this method, to draw the shadow -//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. -void CD3D9Driver::drawStencilShadowVolume(const core::array& triangles, bool zfail, u32 debugDataVisible) -{ - if (!Params.Stencilbuffer) - return; - - setRenderStatesStencilShadowMode(zfail, debugDataVisible); - - const u32 count = triangles.size(); - if (!count) - return; - - if (!zfail) - { - // ZPASS Method - - // Draw front-side of shadow volume in stencil only - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); - pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); - pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); - - // Now reverse cull order so front sides of shadow volume are written. - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); - pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR); - pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); - } - else - { - // ZFAIL Method - - // Draw front-side of shadow volume in stencil only - pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); - pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); - pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); - - // Now reverse cull order so front sides of shadow volume are written. - pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); - pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR); - pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); - } -} - - -//! Fills the stencil shadow with color. After the shadow volume has been drawn -//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this -//! to draw the color of the shadow. -void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, - video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) -{ - if (!Params.Stencilbuffer) - return; - - S3DVertex vtx[4]; - vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); - vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); - vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); - vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); - - s16 indices[6] = {0,1,2,1,3,2}; - - setRenderStatesStencilFillMode( - leftUpEdge.getAlpha() < 255 || - rightUpEdge.getAlpha() < 255 || - leftDownEdge.getAlpha() < 255 || - rightDownEdge.getAlpha() < 255); - - setActiveTexture(0,0); - - setVertexShader(EVT_STANDARD); - - pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], - D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); - - if (clearStencilBuffer) - pID3DDevice->Clear( 0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); -} - - -//! Returns the maximum amount of primitives (mostly vertices) which -//! the device is able to render with one drawIndexedTriangleList -//! call. -u32 CD3D9Driver::getMaximalPrimitiveCount() const -{ - return Caps.MaxPrimitiveCount; -} - - -//! Sets the fog mode. -void CD3D9Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, - f32 end, f32 density, bool pixelFog, bool rangeFog) -{ - CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); - - if (!pID3DDevice) - return; - - pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); - - pID3DDevice->SetRenderState( - pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, - (fogType==EFT_FOG_LINEAR)? D3DFOG_LINEAR : (fogType==EFT_FOG_EXP)?D3DFOG_EXP:D3DFOG_EXP2); - - if (fogType==EFT_FOG_LINEAR) - { - pID3DDevice->SetRenderState(D3DRS_FOGSTART, F2DW(start)); - pID3DDevice->SetRenderState(D3DRS_FOGEND, F2DW(end)); - } - else - pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, F2DW(density)); - - if(!pixelFog) - pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); -} - - -//! Draws a 3d line. -void CD3D9Driver::draw3DLine(const core::vector3df& start, - const core::vector3df& end, SColor color) -{ - setVertexShader(EVT_STANDARD); - setRenderStates3DMode(); - video::S3DVertex v[2]; - v[0].Color = color; - v[1].Color = color; - v[0].Pos = start; - v[1].Pos = end; - - pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); -} - - -//! resets the device -bool CD3D9Driver::reset() -{ - u32 i; - os::Printer::log("Resetting D3D9 device.", ELL_INFORMATION); - - for (i=0; iisRenderTarget()) - { - IDirect3DBaseTexture9* tex = ((CD3D9Texture*)(Textures[i].Surface))->getDX9Texture(); - if (tex) - tex->Release(); - } - } - for (i=0; iSurface) - DepthBuffers[i]->Surface->Release(); - } - for (i=0; i(OcclusionQueries[i].PID)->Release(); - OcclusionQueries[i].PID=0; - } - } - // this does not require a restore in the reset method, it's updated - // automatically in the next render cycle. - removeAllHardwareBuffers(); - - DriverWasReset=true; - - HRESULT hr = pID3DDevice->Reset(&present); - - // restore RTTs - for (i=0; iisRenderTarget()) - ((CD3D9Texture*)(Textures[i].Surface))->createRenderTarget(); - } - - // restore screen depthbuffer - pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface)); - D3DSURFACE_DESC desc; - // restore other depth buffers - // depth format is taken from main depth buffer - DepthBuffers[0]->Surface->GetDesc(&desc); - // multisampling is taken from rendertarget - D3DSURFACE_DESC desc2; - for (i=1; iDepthSurface==DepthBuffers[i]) - { - ((CD3D9Texture*)(Textures[j].Surface))->Texture->GetLevelDesc(0,&desc2); - break; - } - } - - pID3DDevice->CreateDepthStencilSurface(DepthBuffers[i]->Size.Width, - DepthBuffers[i]->Size.Height, - desc.Format, - desc2.MultiSampleType, - desc2.MultiSampleQuality, - TRUE, - &(DepthBuffers[i]->Surface), - NULL); - } - for (i=0; iCreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast(&OcclusionQueries[i].PID)); - } - - if (FAILED(hr)) - { - if (hr == D3DERR_DEVICELOST) - { - DeviceLost = true; - os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); - } -#ifdef D3DERR_DEVICEREMOVED - else if (hr == D3DERR_DEVICEREMOVED) - { - os::Printer::log("Resetting failed due to device removed.", ELL_WARNING); - } -#endif - else if (hr == D3DERR_DRIVERINTERNALERROR) - { - os::Printer::log("Resetting failed due to internal error.", ELL_WARNING); - } - else if (hr == D3DERR_OUTOFVIDEOMEMORY) - { - os::Printer::log("Resetting failed due to out of memory.", ELL_WARNING); - } - else if (hr == D3DERR_DEVICENOTRESET) - { - os::Printer::log("Resetting failed due to not reset.", ELL_WARNING); - } - else if (hr == D3DERR_INVALIDCALL) - { - os::Printer::log("Resetting failed due to invalid call", "You need to release some more surfaces.", ELL_WARNING); - } - else - { - os::Printer::log("Resetting failed due to unknown reason.", core::stringc((int)hr).c_str(), ELL_WARNING); - } - return false; - } - - DeviceLost = false; - ResetRenderStates = true; - LastVertexType = (E_VERTEX_TYPE)-1; - - for (u32 i=0; i& size) -{ - if (!pID3DDevice) - return; - - CNullDriver::OnResize(size); - present.BackBufferWidth = size.Width; - present.BackBufferHeight = size.Height; - - reset(); -} - - -//! Returns type of video driver -E_DRIVER_TYPE CD3D9Driver::getDriverType() const -{ - return EDT_DIRECT3D9; -} - - -//! Returns the transformation set by setTransform -const core::matrix4& CD3D9Driver::getTransform(E_TRANSFORMATION_STATE state) const -{ - return Matrices[state]; -} - - -//! Sets a vertex shader constant. -void CD3D9Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) -{ - if (data) - pID3DDevice->SetVertexShaderConstantF(startRegister, data, constantAmount); -} - - -//! Sets a pixel shader constant. -void CD3D9Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) -{ - if (data) - pID3DDevice->SetPixelShaderConstantF(startRegister, data, constantAmount); -} - - -//! Sets a constant for the vertex shader based on a name. -bool CD3D9Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) -{ - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - { - CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; - return r->setVariable(true, name, floats, count); - } - - return false; -} - - -//! Bool interface for the above. -bool CD3D9Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count) -{ - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - { - CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; - return r->setVariable(true, name, bools, count); - } - - return false; -} - - -//! Int interface for the above. -bool CD3D9Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count) -{ - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - { - CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; - return r->setVariable(true, name, ints, count); - } - - return false; -} - - -//! Sets a constant for the pixel shader based on a name. -bool CD3D9Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) -{ - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - { - CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; - return r->setVariable(false, name, floats, count); - } - - return false; -} - - -//! Bool interface for the above. -bool CD3D9Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count) -{ - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - { - CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; - return r->setVariable(false, name, bools, count); - } - - return false; -} - - -//! Int interface for the above. -bool CD3D9Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count) -{ - if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) - { - CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; - return r->setVariable(false, name, ints, count); - } - - return false; -} - - -//! Adds a new material renderer to the VideoDriver, using pixel and/or -//! vertex shaders to render geometry. -s32 CD3D9Driver::addShaderMaterial(const c8* vertexShaderProgram, - const c8* pixelShaderProgram, - IShaderConstantSetCallBack* callback, - E_MATERIAL_TYPE baseMaterial, s32 userData) -{ - s32 nr = -1; - CD3D9ShaderMaterialRenderer* r = new CD3D9ShaderMaterialRenderer( - pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, - callback, getMaterialRenderer(baseMaterial), userData); - - r->drop(); - return nr; -} - - -//! Adds a new material renderer to the VideoDriver, based on a high level shading -//! language. -s32 CD3D9Driver::addHighLevelShaderMaterial( - const c8* vertexShaderProgram, - const c8* vertexShaderEntryPointName, - E_VERTEX_SHADER_TYPE vsCompileTarget, - const c8* pixelShaderProgram, - const c8* pixelShaderEntryPointName, - E_PIXEL_SHADER_TYPE psCompileTarget, - const c8* geometryShaderProgram, - const c8* geometryShaderEntryPointName, - E_GEOMETRY_SHADER_TYPE gsCompileTarget, - scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, - u32 verticesOut, - IShaderConstantSetCallBack* callback, - E_MATERIAL_TYPE baseMaterial, s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) -{ - s32 nr = -1; - - #ifdef _IRR_COMPILE_WITH_CG_ - if(shadingLang == EGSL_CG) - { - CD3D9CgMaterialRenderer* r = new CD3D9CgMaterialRenderer( - this, nr, - vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget, - pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, - geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget, - inType, outType, verticesOut, - callback,getMaterialRenderer(baseMaterial), userData); - - r->drop(); - } - else - #endif - { - CD3D9HLSLMaterialRenderer* r = new CD3D9HLSLMaterialRenderer( - pID3DDevice, this, nr, - vertexShaderProgram, - vertexShaderEntryPointName, - vsCompileTarget, - pixelShaderProgram, - pixelShaderEntryPointName, - psCompileTarget, - callback, - getMaterialRenderer(baseMaterial), - userData); - - r->drop(); - } - - return nr; -} - - -//! Returns a pointer to the IVideoDriver interface. (Implementation for -//! IMaterialRendererServices) -IVideoDriver* CD3D9Driver::getVideoDriver() -{ - return this; -} - - -//! Creates a render target texture. -ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d& size, - const io::path& name, - const ECOLOR_FORMAT format) -{ - CD3D9Texture* tex = new CD3D9Texture(this, size, name, format); - if (tex) - { - if (!tex->Texture) - { - tex->drop(); - return 0; - } - checkDepthBuffer(tex); - addTexture(tex); - tex->drop(); - } - return tex; -} - - -//! Clears the ZBuffer. -void CD3D9Driver::clearZBuffer() -{ - HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); - - if (FAILED(hr)) - os::Printer::log("CD3D9Driver clearZBuffer() failed.", ELL_WARNING); -} - - -//! Returns an image created from the last rendered frame. -IImage* CD3D9Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) -{ - if (target != video::ERT_FRAME_BUFFER) - return 0; - - // query the screen dimensions of the current adapter - D3DDISPLAYMODE displayMode; - pID3DDevice->GetDisplayMode(0, &displayMode); - - if (format==video::ECF_UNKNOWN) - format=video::ECF_A8R8G8B8; - - // create the image surface to store the front buffer image [always A8R8G8B8] - HRESULT hr; - LPDIRECT3DSURFACE9 lpSurface; - if (FAILED(hr = pID3DDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &lpSurface, 0))) - return 0; - - // read the front buffer into the image surface - if (FAILED(hr = pID3DDevice->GetFrontBufferData(0, lpSurface))) - { - lpSurface->Release(); - return 0; - } - - RECT clientRect; - { - POINT clientPoint; - clientPoint.x = 0; - clientPoint.y = 0; - - ClientToScreen((HWND)getExposedVideoData().D3D9.HWnd, &clientPoint); - - clientRect.left = clientPoint.x; - clientRect.top = clientPoint.y; - clientRect.right = clientRect.left + ScreenSize.Width; - clientRect.bottom = clientRect.top + ScreenSize.Height; - - // window can be off-screen partly, we can't take screenshots from that - clientRect.left = core::max_(clientRect.left, 0l); - clientRect.top = core::max_(clientRect.top, 0l); - clientRect.right = core::min_(clientRect.right, (long)displayMode.Width); - clientRect.bottom = core::min_(clientRect.bottom, (long)displayMode.Height ); - } - - // lock our area of the surface - D3DLOCKED_RECT lockedRect; - if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) - { - lpSurface->Release(); - return 0; - } - - irr::core::dimension2d shotSize; - shotSize.Width = core::min_( ScreenSize.Width, (u32)(clientRect.right-clientRect.left) ); - shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) ); - - // this could throw, but we aren't going to worry about that case very much - IImage* newImage = createImage(format, shotSize); - - if (newImage) - { - // d3d pads the image, so we need to copy the correct number of bytes - u32* dP = (u32*)newImage->lock(); - u8 * sP = (u8 *)lockedRect.pBits; - - // If the display mode format doesn't promise anything about the Alpha value - // and it appears that it's not presenting 255, then we should manually - // set each pixel alpha value to 255. - if (D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000))) - { - for (u32 y = 0; y < shotSize.Height; ++y) - { - for (u32 x = 0; x < shotSize.Width; ++x) - { - newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000); - sP += 4; - } - - sP += lockedRect.Pitch - (4 * shotSize.Width); - } - } - else - { - for (u32 y = 0; y < shotSize.Height; ++y) - { - convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format); - sP += lockedRect.Pitch; - dP += shotSize.Width; - } - } - - newImage->unlock(); - } - - // we can unlock and release the surface - lpSurface->UnlockRect(); - - // release the image surface - lpSurface->Release(); - - // return status of save operation to caller - return newImage; -} - - -//! returns color format -ECOLOR_FORMAT CD3D9Driver::getColorFormat() const -{ - return ColorFormat; -} - - -//! returns color format -D3DFORMAT CD3D9Driver::getD3DColorFormat() const -{ - return D3DColorFormat; -} - - -// returns the current size of the screen or rendertarget -const core::dimension2d& CD3D9Driver::getCurrentRenderTargetSize() const -{ - if ( CurrentRendertargetSize.Width == 0 ) - return ScreenSize; - else - return CurrentRendertargetSize; -} - - -// Set/unset a clipping plane. -bool CD3D9Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) -{ - if (index >= MaxUserClipPlanes) - return false; - - HRESULT ok = pID3DDevice->SetClipPlane(index, (const float*)&(plane.Normal.X)); - if (D3D_OK == ok) - enableClipPlane(index, enable); - return true; -} - - -// Enable/disable a clipping plane. -void CD3D9Driver::enableClipPlane(u32 index, bool enable) -{ - if (index >= MaxUserClipPlanes) - return; - DWORD renderstate; - HRESULT ok = pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); - if (S_OK == ok) - { - if (enable) - renderstate |= (1 << index); - else - renderstate &= ~(1 << index); - ok = pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); - } -} - - -D3DFORMAT CD3D9Driver::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const -{ - switch(format) - { - case ECF_A1R5G5B5: - return D3DFMT_A1R5G5B5; - case ECF_R5G6B5: - return D3DFMT_R5G6B5; - case ECF_R8G8B8: - return D3DFMT_R8G8B8; - case ECF_A8R8G8B8: - return D3DFMT_A8R8G8B8; - - // Floating Point formats. Thanks to Patryk "Nadro" Nadrowski. - case ECF_R16F: - return D3DFMT_R16F; - case ECF_G16R16F: - return D3DFMT_G16R16F; - case ECF_A16B16G16R16F: - return D3DFMT_A16B16G16R16F; - case ECF_R32F: - return D3DFMT_R32F; - case ECF_G32R32F: - return D3DFMT_G32R32F; - case ECF_A32B32G32R32F: - return D3DFMT_A32B32G32R32F; - } - return D3DFMT_UNKNOWN; -} - - -ECOLOR_FORMAT CD3D9Driver::getColorFormatFromD3DFormat(D3DFORMAT format) const -{ - switch(format) - { - case D3DFMT_X1R5G5B5: - case D3DFMT_A1R5G5B5: - return ECF_A1R5G5B5; - case D3DFMT_A8B8G8R8: - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - return ECF_A8R8G8B8; - case D3DFMT_R5G6B5: - return ECF_R5G6B5; - case D3DFMT_R8G8B8: - return ECF_R8G8B8; - - // Floating Point formats. Thanks to Patryk "Nadro" Nadrowski. - case D3DFMT_R16F: - return ECF_R16F; - case D3DFMT_G16R16F: - return ECF_G16R16F; - case D3DFMT_A16B16G16R16F: - return ECF_A16B16G16R16F; - case D3DFMT_R32F: - return ECF_R32F; - case D3DFMT_G32R32F: - return ECF_G32R32F; - case D3DFMT_A32B32G32R32F: - return ECF_A32B32G32R32F; - default: - return (ECOLOR_FORMAT)0; - }; -} - - -void CD3D9Driver::checkDepthBuffer(ITexture* tex) -{ - if (!tex) - return; - const core::dimension2du optSize = tex->getSize().getOptimalSize( - !queryFeature(EVDF_TEXTURE_NPOT), - !queryFeature(EVDF_TEXTURE_NSQUARE), true); - SDepthSurface* depth=0; - core::dimension2du destSize(0x7fffffff, 0x7fffffff); - for (u32 i=0; iSize.Width>=optSize.Width) && - (DepthBuffers[i]->Size.Height>=optSize.Height)) - { - if ((DepthBuffers[i]->Size.WidthSize.HeightSize; - } - } - } - if (!depth) - { - D3DSURFACE_DESC desc; - DepthBuffers[0]->Surface->GetDesc(&desc); - // the multisampling needs to match the RTT - D3DSURFACE_DESC desc2; - ((CD3D9Texture*)tex)->Texture->GetLevelDesc(0,&desc2); - DepthBuffers.push_back(new SDepthSurface()); - HRESULT hr=pID3DDevice->CreateDepthStencilSurface(optSize.Width, - optSize.Height, - desc.Format, - desc2.MultiSampleType, - desc2.MultiSampleQuality, - TRUE, - &(DepthBuffers.getLast()->Surface), - NULL); - if (SUCCEEDED(hr)) - { - depth=DepthBuffers.getLast(); - depth->Surface->GetDesc(&desc); - depth->Size.set(desc.Width, desc.Height); - } - else - { - if (hr == D3DERR_OUTOFVIDEOMEMORY) - os::Printer::log("Could not create DepthBuffer","out of video memory",ELL_ERROR); - else if( hr == E_OUTOFMEMORY ) - os::Printer::log("Could not create DepthBuffer","out of memory",ELL_ERROR); - else - { - char buffer[128]; - sprintf(buffer,"Could not create DepthBuffer of %ix%i",optSize.Width,optSize.Height); - os::Printer::log(buffer,ELL_ERROR); - } - DepthBuffers.erase(DepthBuffers.size()-1); - } - } - else - depth->grab(); - - static_cast(tex)->DepthSurface=depth; -} - - -void CD3D9Driver::removeDepthSurface(SDepthSurface* depth) -{ - for (u32 i=0; iinitDriver(window, pureSoftware)) - { - dx9->drop(); - dx9 = 0; - } - - return dx9; -} -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ - -} // end namespace video -} // end namespace irr - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9Driver.h b/lib/irrlicht/source/Irrlicht/CD3D9Driver.h deleted file mode 100644 index 095ae9d6e..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9Driver.h +++ /dev/null @@ -1,496 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_VIDEO_DIRECTX_9_H_INCLUDED__ -#define __C_VIDEO_DIRECTX_9_H_INCLUDED__ - -#include "IrrCompileConfig.h" - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#ifdef _IRR_WINDOWS_ -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#include "CNullDriver.h" -#include "SIrrCreationParameters.h" -#include "IMaterialRendererServices.h" -#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -#include "irrMath.h" // needed by borland for sqrtf define -#endif -#include - -#ifdef _IRR_COMPILE_WITH_CG_ -#include "Cg/cg.h" -#include "Cg/cgD3D9.h" -#endif - -namespace irr -{ -namespace video -{ - struct SDepthSurface : public IReferenceCounted - { - SDepthSurface() : Surface(0) - { - #ifdef _DEBUG - setDebugName("SDepthSurface"); - #endif - } - virtual ~SDepthSurface() - { - if (Surface) - Surface->Release(); - } - - IDirect3DSurface9* Surface; - core::dimension2du Size; - }; - - class CD3D9Driver : public CNullDriver, IMaterialRendererServices - { - public: - - friend class CD3D9Texture; - - //! constructor - CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io); - - //! destructor - virtual ~CD3D9Driver(); - - //! applications must call this method before performing any rendering. returns false if failed. - virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, - SColor color=SColor(255,0,0,0), - const SExposedVideoData& videoData=SExposedVideoData(), - core::rect* sourceRect=0); - - //! applications must call this method after performing any rendering. returns false if failed. - virtual bool endScene(); - - //! queries the features of the driver, returns true if feature is available - virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const; - - //! sets transformation - virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); - - //! sets a material - virtual void setMaterial(const SMaterial& material); - - //! sets a render target - virtual bool setRenderTarget(video::ITexture* texture, - bool clearBackBuffer=true, bool clearZBuffer=true, - SColor color=video::SColor(0,0,0,0)); - - //! Sets multiple render targets - virtual bool setRenderTarget(const core::array& texture, - bool clearBackBuffer=true, bool clearZBuffer=true, - SColor color=video::SColor(0,0,0,0)); - - //! sets a viewport - virtual void setViewPort(const core::rect& area); - - //! gets the area of the current viewport - virtual const core::rect& getViewPort() const; - - struct SHWBufferLink_d3d9 : public SHWBufferLink - { - SHWBufferLink_d3d9(const scene::IMeshBuffer *_MeshBuffer): - SHWBufferLink(_MeshBuffer), - vertexBuffer(0), indexBuffer(0), - vertexBufferSize(0), indexBufferSize(0) {} - - IDirect3DVertexBuffer9* vertexBuffer; - IDirect3DIndexBuffer9* indexBuffer; - - u32 vertexBufferSize; - u32 indexBufferSize; - }; - - bool updateVertexHardwareBuffer(SHWBufferLink_d3d9 *HWBuffer); - bool updateIndexHardwareBuffer(SHWBufferLink_d3d9 *HWBuffer); - - //! updates hardware buffer if needed - virtual bool updateHardwareBuffer(SHWBufferLink *HWBuffer); - - //! Create hardware buffer from mesh - virtual SHWBufferLink *createHardwareBuffer(const scene::IMeshBuffer* mb); - - //! Delete hardware buffer (only some drivers can) - virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer); - - //! Draw hardware buffer - virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer); - - //! Create occlusion query. - /** Use node for identification and mesh for occlusion test. */ - virtual void addOcclusionQuery(scene::ISceneNode* node, - const scene::IMesh* mesh=0); - - //! Remove occlusion query. - virtual void removeOcclusionQuery(scene::ISceneNode* node); - - //! Run occlusion query. Draws mesh stored in query. - /** If the mesh shall not be rendered visible, use - overrideMaterial to disable the color and depth buffer. */ - virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible=false); - - //! Update occlusion query. Retrieves results from GPU. - /** If the query shall not block, set the flag to false. - Update might not occur in this case, though */ - virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block=true); - - //! Return query result. - /** Return value is the number of visible pixels/fragments. - The value is a safe approximation, i.e. can be larger then the - actual value of pixels. */ - virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const; - - //! draws a vertex primitive list - virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, - const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType); - - //! draws a vertex primitive list in 2d - virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, - const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType); - - //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. - virtual void draw2DImage(const video::ITexture* texture, const core::position2d& destPos, - const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); - - //! Draws a part of the texture into the rectangle. - virtual void draw2DImage(const video::ITexture* texture, const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect = 0, - const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false); - - //! Draws a set of 2d images, using a color and the alpha channel of the texture. - virtual void draw2DImageBatch(const video::ITexture* texture, - const core::array >& positions, - const core::array >& sourceRects, - const core::rect* clipRect=0, - SColor color=SColor(255,255,255,255), - bool useAlphaChannelOfTexture=false); - - //!Draws an 2d rectangle with a gradient. - virtual void draw2DRectangle(const core::rect& pos, - SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, - const core::rect* clip); - - //! Draws a 2d line. - virtual void draw2DLine(const core::position2d& start, - const core::position2d& end, - SColor color=SColor(255,255,255,255)); - - //! Draws a pixel. - virtual void drawPixel(u32 x, u32 y, const SColor & color); - - //! Draws a 3d line. - virtual void draw3DLine(const core::vector3df& start, - const core::vector3df& end, SColor color = SColor(255,255,255,255)); - - //! initialises the Direct3D API - 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". - virtual const wchar_t* getName() const; - - //! deletes all dynamic lights there are - virtual void deleteAllDynamicLights(); - - //! adds a dynamic light, returning an index to the light - //! \param light: the light data to use to create the light - //! \return An index to the light, or -1 if an error occurs - virtual s32 addDynamicLight(const SLight& light); - - //! Turns a dynamic light on or off - //! \param lightIndex: the index returned by addDynamicLight - //! \param turnOn: true to turn the light on, false to turn it off - virtual void turnLightOn(s32 lightIndex, bool turnOn); - - //! returns the maximal amount of dynamic lights the device can handle - virtual u32 getMaximalDynamicLightAmount() const; - - //! Sets the dynamic ambient light color. The default color is - //! (0,0,0,0) which means it is dark. - //! \param color: New color of the ambient light. - virtual void setAmbientLight(const SColorf& color); - - //! Draws a shadow volume into the stencil buffer. - virtual void drawStencilShadowVolume(const core::array& triangles, bool zfail=true, u32 debugDataVisible=0); - - //! Fills the stencil shadow with color. - virtual void drawStencilShadow(bool clearStencilBuffer=false, - video::SColor leftUpEdge = video::SColor(0,0,0,0), - video::SColor rightUpEdge = video::SColor(0,0,0,0), - video::SColor leftDownEdge = video::SColor(0,0,0,0), - video::SColor rightDownEdge = video::SColor(0,0,0,0)); - - //! Returns the maximum amount of primitives (mostly vertices) which - //! the device is able to render with one drawIndexedTriangleList - //! call. - virtual u32 getMaximalPrimitiveCount() const; - - //! Enables or disables a texture creation flag. - virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled); - - //! Sets the fog mode. - virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start, - f32 end, f32 density, bool pixelFog, bool rangeFog); - - //! Only used by the internal engine. Used to notify the driver that - //! the window was resized. - virtual void OnResize(const core::dimension2d& size); - - //! Can be called by an IMaterialRenderer to make its work easier. - virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates); - - //! Returns type of video driver - virtual E_DRIVER_TYPE getDriverType() const; - - //! Returns the transformation set by setTransform - virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const; - - //! Sets a vertex shader constant. - virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); - - //! Sets a pixel shader constant. - virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1); - - //! Sets a constant for the vertex shader based on a name. - virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count); - - //! Bool interface for the above. - virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count); - - //! Int interface for the above. - virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count); - - //! Sets a constant for the pixel shader based on a name. - virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count); - - //! Bool interface for the above. - virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count); - - //! Int interface for the above. - virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count); - - //! Returns a pointer to the IVideoDriver interface. (Implementation for - //! IMaterialRendererServices) - virtual IVideoDriver* getVideoDriver(); - - //! Creates a render target texture. - virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, - const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); - - //! Clears the ZBuffer. - virtual void clearZBuffer(); - - //! Returns an image created from the last rendered frame. - virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER); - - //! Set/unset a clipping plane. - virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false); - - //! Enable/disable a clipping plane. - virtual void enableClipPlane(u32 index, bool enable); - - //! Returns the graphics card vendor name. - virtual core::stringc getVendorInfo() {return VendorName;} - - //! Enable the 2d override material - virtual void enableMaterial2D(bool enable=true); - - //! Check if the driver was recently reset. - virtual bool checkDriverReset() {return DriverWasReset;} - - // removes the depth struct from the DepthSurface array - void removeDepthSurface(SDepthSurface* depth); - - //! Get the current color format of the color buffer - /** \return Color format of the color buffer. */ - virtual ECOLOR_FORMAT getColorFormat() const; - - //! Returns the maximum texture size supported. - virtual core::dimension2du getMaxTextureSize() const; - - //! Get the current color format of the color buffer - /** \return Color format of the color buffer as D3D color value. */ - D3DFORMAT getD3DColorFormat() const; - - //! Get D3D color format from Irrlicht color format. - D3DFORMAT getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const; - - //! Get Irrlicht color format from D3D color format. - ECOLOR_FORMAT getColorFormatFromD3DFormat(D3DFORMAT format) const; - - //! Get Cg context - #ifdef _IRR_COMPILE_WITH_CG_ - const CGcontext& getCgContext(); - #endif - - private: - - //! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates. - enum E_RENDER_MODE - { - ERM_NONE = 0, // no render state has been set yet. - ERM_2D, // 2d drawing rendermode - ERM_3D, // 3d rendering mode - ERM_STENCIL_FILL, // stencil fill mode - ERM_SHADOW_VOLUME_ZFAIL, // stencil volume draw mode - ERM_SHADOW_VOLUME_ZPASS // stencil volume draw mode - }; - - //! sets right vertex shader - void setVertexShader(video::E_VERTEX_TYPE newType); - - //! sets the needed renderstates - bool setRenderStates3DMode(); - - //! sets the needed renderstates - void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel); - - //! sets the needed renderstates - void setRenderStatesStencilFillMode(bool alpha); - - //! sets the needed renderstates - void setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible); - - //! sets the current Texture - bool setActiveTexture(u32 stage, const video::ITexture* texture); - - //! resets the device - bool reset(); - - //! returns a device dependent texture from a software surface (IImage) - //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES - virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0); - - //! returns the current size of the screen or rendertarget - virtual const core::dimension2d& getCurrentRenderTargetSize() const; - - //! Check if a proper depth buffer for the RTT is available, otherwise create it. - void checkDepthBuffer(ITexture* tex); - - //! Adds a new material renderer to the VideoDriver, using pixel and/or - //! vertex shaders to render geometry. - s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram, - IShaderConstantSetCallBack* callback, - E_MATERIAL_TYPE baseMaterial, s32 userData); - - //! Adds a new material renderer to the VideoDriver, based on a high level shading - //! language. - virtual s32 addHighLevelShaderMaterial( - const c8* vertexShaderProgram, - const c8* vertexShaderEntryPointName, - E_VERTEX_SHADER_TYPE vsCompileTarget, - const c8* pixelShaderProgram, - const c8* pixelShaderEntryPointName, - E_PIXEL_SHADER_TYPE psCompileTarget, - const c8* geometryShaderProgram, - const c8* geometryShaderEntryPointName = "main", - E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0, - scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES, - scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP, - u32 verticesOut = 0, - IShaderConstantSetCallBack* callback = 0, - E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, - s32 userData = 0, - E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT); - - void createMaterialRenderers(); - - void draw2D3DVertexPrimitiveList(const void* vertices, - u32 vertexCount, const void* indexList, u32 primitiveCount, - E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, - E_INDEX_TYPE iType, bool is3D); - - D3DTEXTUREADDRESS getTextureWrapMode(const u8 clamp); - - inline D3DCOLORVALUE colorToD3D(const SColor& col) - { - const f32 f = 1.0f / 255.0f; - D3DCOLORVALUE v; - v.r = col.getRed() * f; - v.g = col.getGreen() * f; - v.b = col.getBlue() * f; - v.a = col.getAlpha() * f; - return v; - } - - E_RENDER_MODE CurrentRenderMode; - D3DPRESENT_PARAMETERS present; - - SMaterial Material, LastMaterial; - bool ResetRenderStates; // bool to make all renderstates be reseted if set. - bool Transformation3DChanged; - 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. - - HINSTANCE D3DLibrary; - IDirect3D9* pID3D; - IDirect3DDevice9* pID3DDevice; - - IDirect3DSurface9* PrevRenderTarget; - core::dimension2d CurrentRendertargetSize; - - HWND WindowId; - core::rect* SceneSourceRect; - - D3DCAPS9 Caps; - - SIrrlichtCreationParameters Params; - - E_VERTEX_TYPE LastVertexType; - - SColorf AmbientLight; - - core::stringc VendorName; - u16 VendorID; - - core::array DepthBuffers; - - u32 MaxTextureUnits; - u32 MaxUserClipPlanes; - u32 MaxMRTs; - u32 NumSetMRTs; - f32 MaxLightDistance; - s32 LastSetLight; - - enum E_CACHE_2D_ATTRIBUTES - { - EC2D_ALPHA = 0x1, - EC2D_TEXTURE = 0x2, - EC2D_ALPHA_CHANNEL = 0x4 - }; - - ECOLOR_FORMAT ColorFormat; - D3DFORMAT D3DColorFormat; - bool DeviceLost; - bool DriverWasReset; - bool OcclusionQuerySupport; - bool AlphaToCoverageSupport; - - #ifdef _IRR_COMPILE_WITH_CG_ - CGcontext CgContext; - #endif - }; - - -} // end namespace video -} // end namespace irr - - -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ -#endif // __C_VIDEO_DIRECTX_9_H_INCLUDED__ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp b/lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp deleted file mode 100644 index 131bdf57b..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#include "CD3D9HLSLMaterialRenderer.h" -#include "IShaderConstantSetCallBack.h" -#include "IVideoDriver.h" -#include "os.h" -#include "irrString.h" - -#ifndef _IRR_D3D_NO_SHADER_DEBUGGING -#include -#endif - - -namespace irr -{ -namespace video -{ - - -//! Public constructor -CD3D9HLSLMaterialRenderer::CD3D9HLSLMaterialRenderer(IDirect3DDevice9* d3ddev, - video::IVideoDriver* driver, s32& outMaterialTypeNr, - const c8* vertexShaderProgram, - const c8* vertexShaderEntryPointName, - E_VERTEX_SHADER_TYPE vsCompileTarget, - const c8* pixelShaderProgram, - const c8* pixelShaderEntryPointName, - E_PIXEL_SHADER_TYPE psCompileTarget, - IShaderConstantSetCallBack* callback, - IMaterialRenderer* baseMaterial, - s32 userData) - : CD3D9ShaderMaterialRenderer(d3ddev, driver, callback, baseMaterial, userData), - VSConstantsTable(0), PSConstantsTable(0) -{ - - #ifdef _DEBUG - setDebugName("CD3D9HLSLMaterialRenderer"); - #endif - - outMaterialTypeNr = -1; - - // now create shaders - - if (vsCompileTarget < 0 || vsCompileTarget > EVST_COUNT) - { - os::Printer::log("Invalid HLSL vertex shader compilation target", ELL_ERROR); - return; - } - - if (!createHLSLVertexShader(vertexShaderProgram, - vertexShaderEntryPointName, VERTEX_SHADER_TYPE_NAMES[vsCompileTarget])) - return; - - if (!createHLSLPixelShader(pixelShaderProgram, - pixelShaderEntryPointName, PIXEL_SHADER_TYPE_NAMES[psCompileTarget])) - return; - - // register myself as new material - outMaterialTypeNr = Driver->addMaterialRenderer(this); -} - - -//! Destructor -CD3D9HLSLMaterialRenderer::~CD3D9HLSLMaterialRenderer() -{ - if (VSConstantsTable) - VSConstantsTable->Release(); - - if (PSConstantsTable) - PSConstantsTable->Release(); -} - - -bool CD3D9HLSLMaterialRenderer::createHLSLVertexShader(const char* vertexShaderProgram, - const char* shaderEntryPointName, - const char* shaderTargetName) -{ - if (!vertexShaderProgram) - return true; - - LPD3DXBUFFER buffer = 0; - LPD3DXBUFFER errors = 0; - -#ifdef _IRR_D3D_NO_SHADER_DEBUGGING - - // compile without debug info - HRESULT h = stubD3DXCompileShader( - vertexShaderProgram, - strlen(vertexShaderProgram), - 0, // macros - 0, // no includes - shaderEntryPointName, - shaderTargetName, - 0, // no flags - &buffer, - &errors, - &VSConstantsTable); - -#else - - // compile shader and emitt some debug informations to - // make it possible to debug the shader in visual studio - - static int irr_dbg_hlsl_file_nr = 0; - ++irr_dbg_hlsl_file_nr; - char tmp[32]; - sprintf(tmp, "irr_d3d9_dbg_hlsl_%d.vsh", irr_dbg_hlsl_file_nr); - - FILE* f = fopen(tmp, "wb"); - fwrite(vertexShaderProgram, strlen(vertexShaderProgram), 1, f); - fflush(f); - fclose(f); - - HRESULT h = stubD3DXCompileShaderFromFile( - tmp, - 0, // macros - 0, // no includes - shaderEntryPointName, - shaderTargetName, - D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, - &buffer, - &errors, - &VSConstantsTable); - -#endif - - if (FAILED(h)) - { - os::Printer::log("HLSL vertex shader compilation failed:", ELL_ERROR); - if (errors) - { - os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); - errors->Release(); - if (buffer) - buffer->Release(); - } - return false; - } - - if (errors) - errors->Release(); - - if (buffer) - { - if (FAILED(pID3DDevice->CreateVertexShader((DWORD*)buffer->GetBufferPointer(), - &VertexShader))) - { - os::Printer::log("Could not create hlsl vertex shader.", ELL_ERROR); - buffer->Release(); - return false; - } - - buffer->Release(); - return true; - } - - return false; -} - - -bool CD3D9HLSLMaterialRenderer::createHLSLPixelShader(const char* pixelShaderProgram, - const char* shaderEntryPointName, - const char* shaderTargetName) -{ - if (!pixelShaderProgram) - return true; - - LPD3DXBUFFER buffer = 0; - LPD3DXBUFFER errors = 0; - - DWORD flags = 0; - -#ifdef D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY - if (Driver->queryFeature(video::EVDF_VERTEX_SHADER_2_0) || Driver->queryFeature(video::EVDF_VERTEX_SHADER_3_0)) - // this one's for newer DX SDKs which don't support ps_1_x anymore - // instead they'll silently compile 1_x as 2_x when using this flag - flags |= D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY; -#endif -#if defined(_IRR_D3D_USE_LEGACY_HLSL_COMPILER) && defined(D3DXSHADER_USE_LEGACY_D3DX9_31_DLL) -#ifdef D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY - else -#endif - flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL; -#endif - -#ifdef _IRR_D3D_NO_SHADER_DEBUGGING - - // compile without debug info - HRESULT h = stubD3DXCompileShader( - pixelShaderProgram, - strlen(pixelShaderProgram), - 0, // macros - 0, // no includes - shaderEntryPointName, - shaderTargetName, - flags, - &buffer, - &errors, - &PSConstantsTable); - -#else - - // compile shader and emitt some debug informations to - // make it possible to debug the shader in visual studio - - static int irr_dbg_hlsl_file_nr = 0; - ++irr_dbg_hlsl_file_nr; - char tmp[32]; - sprintf(tmp, "irr_d3d9_dbg_hlsl_%d.psh", irr_dbg_hlsl_file_nr); - - FILE* f = fopen(tmp, "wb"); - fwrite(pixelShaderProgram, strlen(pixelShaderProgram), 1, f); - fflush(f); - fclose(f); - - HRESULT h = stubD3DXCompileShaderFromFile( - tmp, - 0, // macros - 0, // no includes - shaderEntryPointName, - shaderTargetName, - flags | D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION, - &buffer, - &errors, - &PSConstantsTable); - -#endif - - if (FAILED(h)) - { - os::Printer::log("HLSL pixel shader compilation failed:", ELL_ERROR); - if (errors) - { - os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); - errors->Release(); - if (buffer) - buffer->Release(); - } - return false; - } - - if (errors) - errors->Release(); - - if (buffer) - { - if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)buffer->GetBufferPointer(), - &PixelShader))) - { - os::Printer::log("Could not create hlsl pixel shader.", ELL_ERROR); - buffer->Release(); - return false; - } - - buffer->Release(); - return true; - } - - return false; -} - - -bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name, - const f32* floats, int count) -{ - LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; - if (!tbl) - return false; - - // currently we only support top level parameters. - // Should be enough for the beginning. (TODO) - - D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name); - if (!hndl) - { - core::stringc s = "HLSL Variable to set not found: '"; - s += name; - s += "'. Available variables are:"; - os::Printer::log(s.c_str(), ELL_WARNING); - printHLSLVariables(tbl); - return false; - } - - D3DXCONSTANT_DESC Description; - UINT ucount = 1; - tbl->GetConstantDesc(hndl, &Description, &ucount); - - if(Description.RegisterSet != D3DXRS_SAMPLER) - { - HRESULT hr = tbl->SetFloatArray(pID3DDevice, hndl, floats, count); - if (FAILED(hr)) - { - os::Printer::log("Error setting float array for HLSL variable", ELL_WARNING); - return false; - } - } - - return true; -} - - -bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name, - const bool* bools, int count) -{ - LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; - if (!tbl) - return false; - - // currently we only support top level parameters. - // Should be enough for the beginning. (TODO) - - D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name); - if (!hndl) - { - core::stringc s = "HLSL Variable to set not found: '"; - s += name; - s += "'. Available variables are:"; - os::Printer::log(s.c_str(), ELL_WARNING); - printHLSLVariables(tbl); - return false; - } - - D3DXCONSTANT_DESC Description; - UINT ucount = 1; - tbl->GetConstantDesc(hndl, &Description, &ucount); - - if(Description.RegisterSet != D3DXRS_SAMPLER) - { - HRESULT hr = tbl->SetBoolArray(pID3DDevice, hndl, (BOOL*)bools, count); - if (FAILED(hr)) - { - os::Printer::log("Error setting bool array for HLSL variable", ELL_WARNING); - return false; - } - } - - return true; -} - - -bool CD3D9HLSLMaterialRenderer::setVariable(bool vertexShader, const c8* name, - const s32* ints, int count) -{ - LPD3DXCONSTANTTABLE tbl = vertexShader ? VSConstantsTable : PSConstantsTable; - if (!tbl) - return false; - - // currently we only support top level parameters. - // Should be enough for the beginning. (TODO) - - D3DXHANDLE hndl = tbl->GetConstantByName(NULL, name); - if (!hndl) - { - core::stringc s = "HLSL Variable to set not found: '"; - s += name; - s += "'. Available variables are:"; - os::Printer::log(s.c_str(), ELL_WARNING); - printHLSLVariables(tbl); - return false; - } - - D3DXCONSTANT_DESC Description; - UINT ucount = 1; - tbl->GetConstantDesc(hndl, &Description, &ucount); - - if(Description.RegisterSet != D3DXRS_SAMPLER) - { - HRESULT hr = tbl->SetIntArray(pID3DDevice, hndl, ints, count); - if (FAILED(hr)) - { - os::Printer::log("Error setting int array for HLSL variable", ELL_WARNING); - return false; - } - } - - return true; -} - - -bool CD3D9HLSLMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) -{ - if (VSConstantsTable) - VSConstantsTable->SetDefaults(pID3DDevice); - - return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); -} - - -void CD3D9HLSLMaterialRenderer::printHLSLVariables(LPD3DXCONSTANTTABLE table) -{ - // currently we only support top level parameters. - // Should be enough for the beginning. (TODO) - - // print out constant names - D3DXCONSTANTTABLE_DESC tblDesc; - HRESULT hr = table->GetDesc(&tblDesc); - if (!FAILED(hr)) - { - for (int i=0; i<(int)tblDesc.Constants; ++i) - { - D3DXCONSTANT_DESC d; - UINT n = 1; - D3DXHANDLE cHndl = table->GetConstant(NULL, i); - if (!FAILED(table->GetConstantDesc(cHndl, &d, &n))) - { - core::stringc s = " '"; - s += d.Name; - s += "' Registers:[begin:"; - s += (int)d.RegisterIndex; - s += ", count:"; - s += (int)d.RegisterCount; - s += "]"; - os::Printer::log(s.c_str()); - } - } - } -} - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ diff --git a/lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.h deleted file mode 100644 index 2e051b7b3..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D9_HLSL_MATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D9_HLSL_MATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#include "CD3D9ShaderMaterialRenderer.h" -#include "IGPUProgrammingServices.h" - -namespace irr -{ -namespace video -{ - -class IVideoDriver; -class IShaderConstantSetCallBack; -class IMaterialRenderer; - -//! Class for using vertex and pixel shaders via HLSL with D3D9 -class CD3D9HLSLMaterialRenderer : public CD3D9ShaderMaterialRenderer -{ -public: - - //! Public constructor - CD3D9HLSLMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, - const c8* vertexShaderProgram, - const c8* vertexShaderEntryPointName, - E_VERTEX_SHADER_TYPE vsCompileTarget, - const c8* pixelShaderProgram, - const c8* pixelShaderEntryPointName, - E_PIXEL_SHADER_TYPE psCompileTarget, - IShaderConstantSetCallBack* callback, - IMaterialRenderer* baseMaterial, - s32 userData); - - //! Destructor - ~CD3D9HLSLMaterialRenderer(); - - //! sets a variable in the shader. - //! \param vertexShader: True if this should be set in the vertex shader, false if - //! in the pixel shader. - //! \param name: Name of the variable - //! \param floats: Pointer to array of floats - //! \param count: Amount of floats in array. - virtual bool setVariable(bool vertexShader, const c8* name, const f32* floats, int count); - - //! Bool interface for the above. - virtual bool setVariable(bool vertexShader, const c8* name, const bool* bools, int count); - - //! Int interface for the above. - virtual bool setVariable(bool vertexShader, const c8* name, const s32* ints, int count); - - bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); - -protected: - - bool createHLSLVertexShader(const char* vertexShaderProgram, - const char* shaderEntryPointName, - const char* shaderTargetName); - - bool createHLSLPixelShader(const char* pixelShaderProgram, - const char* shaderEntryPointName, - const char* shaderTargetName); - - void printHLSLVariables(LPD3DXCONSTANTTABLE table); - - LPD3DXCONSTANTTABLE VSConstantsTable; - LPD3DXCONSTANTTABLE PSConstantsTable; -}; - - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9MaterialRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D9MaterialRenderer.h deleted file mode 100644 index 16536617e..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9MaterialRenderer.h +++ /dev/null @@ -1,615 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D9_MATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D9_MATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ -#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -#include "irrMath.h" // needed by borland for sqrtf define -#endif -#include - -#include "IMaterialRenderer.h" - -namespace irr -{ -namespace video -{ - -namespace -{ -D3DMATRIX UnitMatrixD3D9; -D3DMATRIX SphereMapMatrixD3D9; -inline void setTextureColorStage(IDirect3DDevice9* dev, DWORD i, - DWORD arg1, DWORD op, DWORD arg2) -{ - dev->SetTextureStageState(i, D3DTSS_COLOROP, op); - dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1); - dev->SetTextureStageState(i, D3DTSS_COLORARG2, arg2); -} -inline void setTextureColorStage(IDirect3DDevice9* dev, DWORD i, DWORD arg1) -{ - dev->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - dev->SetTextureStageState(i, D3DTSS_COLORARG1, arg1); -} - -inline void setTextureAlphaStage(IDirect3DDevice9* dev, DWORD i, - DWORD arg1, DWORD op, DWORD arg2) -{ - dev->SetTextureStageState(i, D3DTSS_ALPHAOP, op); - dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1); - dev->SetTextureStageState(i, D3DTSS_ALPHAARG2, arg2); -} -inline void setTextureAlphaStage(IDirect3DDevice9* dev, DWORD i, DWORD arg1) -{ - dev->SetTextureStageState(i, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - dev->SetTextureStageState(i, D3DTSS_ALPHAARG1, arg1); -} -} // anonymous namespace - -//! Base class for all internal D3D9 material renderers -class CD3D9MaterialRenderer : public IMaterialRenderer -{ -public: - - //! Constructor - CD3D9MaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver) - : pID3DDevice(d3ddev), Driver(driver) - { - } - - //! sets a variable in the shader. - //! \param vertexShader: True if this should be set in the vertex shader, false if - //! in the pixel shader. - //! \param name: Name of the variable - //! \param floats: Pointer to array of floats - //! \param count: Amount of floats in array. - virtual bool setVariable(bool vertexShader, const c8* name, const f32* floats, int count) - { - os::Printer::log("Invalid material to set variable in."); - return false; - } - - //! Bool interface for the above. - virtual bool setVariable(bool vertexShader, const c8* name, const bool* bools, int count) - { - os::Printer::log("Invalid material to set variable in."); - return false; - } - - //! Int interface for the above. - virtual bool setVariable(bool vertexShader, const c8* name, const s32* ints, int count) - { - os::Printer::log("Invalid material to set variable in."); - return false; - } - -protected: - - IDirect3DDevice9* pID3DDevice; - video::IVideoDriver* Driver; -}; - - -//! Solid material renderer -class CD3D9MaterialRenderer_SOLID : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_SOLID(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - } - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } -}; - -//! Generic Texture Blend -class CD3D9MaterialRenderer_ONETEXTURE_BLEND : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_ONETEXTURE_BLEND(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || - material.MaterialTypeParam != lastMaterial.MaterialTypeParam || - resetAllRenderstates) - { - - E_BLEND_FACTOR srcFact,dstFact; - E_MODULATE_FUNC modulate; - u32 alphaSource; - unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam ); - - if (srcFact == EBF_SRC_COLOR && dstFact == EBF_ZERO) - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - else - { - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, getD3DBlend ( srcFact ) ); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, getD3DBlend ( dstFact ) ); - } - - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, getD3DModulate(modulate), D3DTA_DIFFUSE); - - if ( textureBlendFunc_hasAlpha ( srcFact ) || textureBlendFunc_hasAlpha ( dstFact ) ) - { - if (alphaSource==EAS_VERTEX_COLOR) - { - setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); - } - else if (alphaSource==EAS_TEXTURE) - { - setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); - } - else - { - setTextureAlphaStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - } - } - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - } - } - - //! Returns if the material is transparent. - /** The scene management needs to know this for being able to sort the - materials by opaque and transparent. - The return value could be optimized, but we'd need to know the - MaterialTypeParam for it. */ - virtual bool isTransparent() const - { - return true; - } - - private: - - u32 getD3DBlend ( E_BLEND_FACTOR factor ) const - { - u32 r = 0; - switch ( factor ) - { - case EBF_ZERO: r = D3DBLEND_ZERO; break; - case EBF_ONE: r = D3DBLEND_ONE; break; - case EBF_DST_COLOR: r = D3DBLEND_DESTCOLOR; break; - case EBF_ONE_MINUS_DST_COLOR: r = D3DBLEND_INVDESTCOLOR; break; - case EBF_SRC_COLOR: r = D3DBLEND_SRCCOLOR; break; - case EBF_ONE_MINUS_SRC_COLOR: r = D3DBLEND_INVSRCCOLOR; break; - case EBF_SRC_ALPHA: r = D3DBLEND_SRCALPHA; break; - case EBF_ONE_MINUS_SRC_ALPHA: r = D3DBLEND_INVSRCALPHA; break; - case EBF_DST_ALPHA: r = D3DBLEND_DESTALPHA; break; - case EBF_ONE_MINUS_DST_ALPHA: r = D3DBLEND_INVDESTALPHA; break; - case EBF_SRC_ALPHA_SATURATE: r = D3DBLEND_SRCALPHASAT; break; - } - return r; - } - - u32 getD3DModulate ( E_MODULATE_FUNC func ) const - { - u32 r = D3DTOP_MODULATE; - switch ( func ) - { - case EMFN_MODULATE_1X: r = D3DTOP_MODULATE; break; - case EMFN_MODULATE_2X: r = D3DTOP_MODULATE2X; break; - case EMFN_MODULATE_4X: r = D3DTOP_MODULATE4X; break; - } - return r; - } - - bool transparent; - -}; - - - -//! Solid 2 layer material renderer -class CD3D9MaterialRenderer_SOLID_2_LAYER : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_SOLID_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA); - - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } -}; - - -//! Transparent add color material renderer -class CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); - } - } - - //! Returns if the material is transparent. The scene management needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return true; - } -}; - - -//! Transparent vertex alpha material renderer -class CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - } - } - - //! Returns if the material is transparent. The scene managment needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return true; - } -}; - - -//! Transparent alpha channel material renderer -class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates - || material.MaterialTypeParam != lastMaterial.MaterialTypeParam ) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); - setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); - - pID3DDevice->SetRenderState(D3DRS_ALPHAREF, core::floor32(material.MaterialTypeParam * 255.f)); - pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); - pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - } - - //! Returns if the material is transparent. The scene managment needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return true; - } -}; - - - -//! Transparent alpha channel material renderer -class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); - setTextureAlphaStage(pID3DDevice, 0, D3DTA_TEXTURE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - - // 127 is required by EMT_TRANSPARENT_ALPHA_CHANNEL_REF - pID3DDevice->SetRenderState(D3DRS_ALPHAREF, 127); - pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); - pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - } - - //! Returns if the material is transparent. The scene managment needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return false; // this material is not really transparent because it does no blending. - } -}; - - -//! material renderer for all kinds of lightmaps -class CD3D9MaterialRenderer_LIGHTMAP : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_LIGHTMAP(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - if (material.MaterialType >= EMT_LIGHTMAP_LIGHTING) - { - // with lighting - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - } - else - { - setTextureColorStage(pID3DDevice, 0, D3DTA_TEXTURE); - } - - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - - setTextureColorStage(pID3DDevice, 1, - D3DTA_TEXTURE, - (material.MaterialType == EMT_LIGHTMAP_ADD)? - D3DTOP_ADD: - (material.MaterialType == EMT_LIGHTMAP_M4 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M4)? - D3DTOP_MODULATE4X: - (material.MaterialType == EMT_LIGHTMAP_M2 || material.MaterialType == EMT_LIGHTMAP_LIGHTING_M2)? - D3DTOP_MODULATE2X: - D3DTOP_MODULATE, - D3DTA_CURRENT); - - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } -}; - - - -//! material renderer for detail maps -class CD3D9MaterialRenderer_DETAIL_MAP : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_DETAIL_MAP(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - setTextureColorStage(pID3DDevice, 1, - D3DTA_TEXTURE, D3DTOP_ADDSIGNED, D3DTA_CURRENT); - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } -}; - - -//! sphere map material renderer -class CD3D9MaterialRenderer_SPHERE_MAP : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_SPHERE_MAP(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - - pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - - pID3DDevice->SetTransform( D3DTS_TEXTURE0, &SphereMapMatrixD3D9 ); - pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); - pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL ); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - pID3DDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0); - pID3DDevice->SetTransform( D3DTS_TEXTURE0, &UnitMatrixD3D9 ); - } -}; - - -//! reflection 2 layer material renderer -class CD3D9MaterialRenderer_REFLECTION_2_LAYER : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - - setTextureColorStage(pID3DDevice, 1, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); - - pID3DDevice->SetTransform( D3DTS_TEXTURE1, &SphereMapMatrixD3D9 ); - pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); - pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - pID3DDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); - pID3DDevice->SetTransform( D3DTS_TEXTURE1, &UnitMatrixD3D9 ); - } -}; - - -//! reflection 2 layer material renderer -class CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER : public CD3D9MaterialRenderer -{ -public: - - CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(IDirect3DDevice9* p, video::IVideoDriver* d) - : CD3D9MaterialRenderer(p, d) {} - - virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial, - bool resetAllRenderstates, IMaterialRendererServices* services) - { - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); - - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - setTextureColorStage(pID3DDevice, 0, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_DIFFUSE); - setTextureAlphaStage(pID3DDevice, 0, D3DTA_DIFFUSE); - setTextureColorStage(pID3DDevice, 1, - D3DTA_TEXTURE, D3DTOP_MODULATE, D3DTA_CURRENT); - setTextureAlphaStage(pID3DDevice, 1, D3DTA_CURRENT); - - pID3DDevice->SetTransform(D3DTS_TEXTURE1, &SphereMapMatrixD3D9 ); - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); - - pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - } - } - - virtual void OnUnsetMaterial() - { - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - pID3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - pID3DDevice->SetTransform(D3DTS_TEXTURE1, &UnitMatrixD3D9); - } - - //! Returns if the material is transparent. The scene managment needs to know this - //! for being able to sort the materials by opaque and transparent. - virtual bool isTransparent() const - { - return true; - } -}; - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.cpp b/lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.cpp deleted file mode 100644 index eb6f7324d..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.cpp +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#include "CD3D9NormalMapRenderer.h" -#include "IVideoDriver.h" -#include "IMaterialRendererServices.h" -#include "os.h" -#include "SLight.h" - -namespace irr -{ -namespace video -{ - - // 1.1 Shaders with two lights and vertex based attenuation - - // Irrlicht Engine D3D9 render path normal map vertex shader - const char D3D9_NORMAL_MAP_VSH[] = - ";Irrlicht Engine 0.8 D3D9 render path normal map vertex shader\n"\ - "; c0-3: Transposed world matrix \n"\ - "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ - "; c12: Light01 position \n"\ - "; c13: x,y,z: Light01 color; .w: 1/LightRadius˛ \n"\ - "; c14: Light02 position \n"\ - "; c15: x,y,z: Light02 color; .w: 1/LightRadius˛ \n"\ - "vs.1.1\n"\ - "dcl_position v0 ; position \n"\ - "dcl_normal v1 ; normal \n"\ - "dcl_color v2 ; color \n"\ - "dcl_texcoord0 v3 ; texture coord \n"\ - "dcl_texcoord1 v4 ; tangent \n"\ - "dcl_texcoord2 v5 ; binormal \n"\ - "\n"\ - "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ - "\n"\ - "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ - "\n"\ - "m3x3 r5, v4, c0 ; transform tangent U\n"\ - "m3x3 r7, v1, c0 ; transform normal W\n"\ - "m3x3 r6, v5, c0 ; transform binormal V\n"\ - "\n"\ - "m4x4 r4, v0, c0 ; vertex into world position\n"\ - "add r2, c12, -r4 ; vtxpos - lightpos1\n"\ - "add r3, c14, -r4 ; vtxpos - lightpos2\n"\ - "\n"\ - "dp3 r8.x, r5, r2 ; transform the light vector 1 with U, V, W\n"\ - "dp3 r8.y, r6, r2 \n"\ - "dp3 r8.z, r7, r2 \n"\ - "dp3 r9.x, r5, r3 ; transform the light vector 2 with U, V, W\n"\ - "dp3 r9.y, r6, r3 \n"\ - "dp3 r9.z, r7, r3 \n"\ - "\n"\ - "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ - "rsq r8.w, r8.w \n"\ - "mul r8, r8, r8.w \n"\ - "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ - "rsq r9.w, r9.w \n"\ - "mul r9, r9, r9.w \n"\ - "\n"\ - "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ - "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ - "\n"\ - " ; calculate attenuation of light 1 \n"\ - "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x˛ + r2.y˛ + r2.z˛ \n"\ - "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ - "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ - "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ - "\n"\ - " ; calculate attenuation of light 2 \n"\ - "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x˛ + r3.y˛ + r3.z˛ \n"\ - "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ - "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ - "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ - "\n"\ - "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ - "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ - "mov oD0.a, v2.a ; move out original alpha value \n"\ - "\n"; - - // Irrlicht Engine D3D9 render path normal map pixel shader - const char D3D9_NORMAL_MAP_PSH_1_1[] = - ";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\ - ";Input: \n"\ - ";t0: color map texture coord \n"\ - ";t1: normal map texture coords \n"\ - ";t2: light 1 vector in tangent space \n"\ - ";v0: light 1 color \n"\ - ";t3: light 2 vector in tangent space \n"\ - ";v1: light 2 color \n"\ - ";v0.a: vertex alpha value \n"\ - "ps.1.1 \n"\ - "tex t0 ; sample color map \n"\ - "tex t1 ; sample normal map\n"\ - "texcoord t2 ; fetch light vector 1\n"\ - "texcoord t3 ; fetch light vector 2\n"\ - "\n"\ - "dp3_sat r0, t1_bx2, t2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1)\n"\ - "mul r0, r0, v0 ; luminance1 * light color 1 \n"\ - "\n"\ - "dp3_sat r1, t1_bx2, t3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1)\n"\ - "mad r0, r1, v1, r0 ; (luminance2 * light color 2) + luminance 1 \n"\ - "\n"\ - "mul r0.xyz, t0, r0 ; total luminance * base color\n"\ - "+mov r0.a, v0.a ; write interpolated vertex alpha value \n"\ - "\n"\ - ""; - - // Higher-quality normal map pixel shader (requires PS 2.0) - // uses per-pixel normalization for improved accuracy - const char D3D9_NORMAL_MAP_PSH_2_0[] = - ";Irrlicht Engine 0.8 D3D9 render path normal map pixel shader\n"\ - ";Input: \n"\ - ";t0: color map texture coord \n"\ - ";t1: normal map texture coords \n"\ - ";t2: light 1 vector in tangent space \n"\ - ";v0: light 1 color \n"\ - ";t3: light 2 vector in tangent space \n"\ - ";v1: light 2 color \n"\ - ";v0.a: vertex alpha value \n"\ - - "ps_2_0 \n"\ - "def c0, 0, 0, 0, 0\n"\ - "def c1, 1.0, 1.0, 1.0, 1.0\n"\ - "def c2, 2.0, 2.0, 2.0, 2.0\n"\ - "def c3, -.5, -.5, -.5, -.5\n"\ - "dcl t0\n"\ - "dcl t1\n"\ - "dcl t2\n"\ - "dcl t3\n"\ - "dcl v1\n"\ - "dcl v0\n"\ - "dcl_2d s0\n"\ - "dcl_2d s1\n"\ - - "texld r0, t0, s0 ; sample color map into r0 \n"\ - "texld r4, t0, s1 ; sample normal map into r4\n"\ - "add r4, r4, c3 ; bias the normal vector\n"\ - "add r5, t2, c3 ; bias the light 1 vector into r5\n"\ - "add r6, t3, c3 ; bias the light 2 vector into r6\n"\ - - "nrm r1, r4 ; normalize the normal vector into r1\n"\ - "nrm r2, r5 ; normalize the light1 vector into r2\n"\ - "nrm r3, r6 ; normalize the light2 vector into r3\n"\ - - "dp3 r2, r2, r1 ; let r2 = normal DOT light 1 vector\n"\ - "max r2, r2, c0 ; clamp result to positive numbers\n"\ - "mul r2, r2, v0 ; let r2 = luminance1 * light color 1 \n"\ - - "dp3 r3, r3, r1 ; let r3 = normal DOT light 2 vector\n"\ - "max r3, r3, c0 ; clamp result to positive numbers\n"\ - - "mad r2, r3, v1, r2 ; let r2 = (luminance2 * light color 2) + (luminance2 * light color 1) \n"\ - - "mul r2, r2, r0 ; let r2 = total luminance * base color\n"\ - "mov r2.w, v0.w ; write interpolated vertex alpha value \n"\ - - "mov oC0, r2 ; copy r2 to the output register \n"\ - - "\n"\ - ""; - - CD3D9NormalMapRenderer::CD3D9NormalMapRenderer( - IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) - : CD3D9ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial) - { - #ifdef _DEBUG - setDebugName("CD3D9NormalMapRenderer"); - #endif - - // set this as callback. We could have done this in - // the initialization list, but some compilers don't like it. - - CallBack = this; - - // basically, this thing simply compiles the hardcoded shaders - // if the hardware is able to do them, otherwise it maps to the - // base material - - if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) || - !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) - { - // this hardware is not able to do shaders. Fall back to - // base material. - outMaterialTypeNr = driver->addMaterialRenderer(this); - return; - } - - // check if already compiled normal map shaders are there. - - video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID); - if (renderer) - { - // use the already compiled shaders - video::CD3D9NormalMapRenderer* nmr = (video::CD3D9NormalMapRenderer*)renderer; - VertexShader = nmr->VertexShader; - if (VertexShader) - VertexShader->AddRef(); - - PixelShader = nmr->PixelShader; - if (PixelShader) - PixelShader->AddRef(); - - outMaterialTypeNr = driver->addMaterialRenderer(this); - } - else - { - // compile shaders on our own - if (driver->queryFeature(video::EVDF_PIXEL_SHADER_2_0)) - { - init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH_2_0); - } - else - { - init(outMaterialTypeNr, D3D9_NORMAL_MAP_VSH, D3D9_NORMAL_MAP_PSH_1_1); - } - } - // something failed, use base material - if (-1==outMaterialTypeNr) - driver->addMaterialRenderer(this); - } - - - CD3D9NormalMapRenderer::~CD3D9NormalMapRenderer() - { - if (CallBack == this) - CallBack = 0; - } - - - bool CD3D9NormalMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) - { - if (vtxtype != video::EVT_TANGENTS) - { - os::Printer::log("Error: Normal map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); - return false; - } - - return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); - } - - - //! Returns the render capability of the material. - s32 CD3D9NormalMapRenderer::getRenderCapability() const - { - if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) && - Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) - return 0; - - return 1; - } - - - //! Called by the engine when the vertex and/or pixel shader constants - //! for an material renderer should be set. - void CD3D9NormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) - { - video::IVideoDriver* driver = services->getVideoDriver(); - - // set transposed world matrix - services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); - - // set transposed worldViewProj matrix - core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION)); - worldViewProj *= driver->getTransform(video::ETS_VIEW); - worldViewProj *= driver->getTransform(video::ETS_WORLD); - services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); - - // here we've got to fetch the fixed function lights from the - // driver and set them as constants - - u32 cnt = driver->getDynamicLightCount(); - - for (u32 i=0; i<2; ++i) - { - SLight light; - - if (igetDynamicLight(i); - else - { - light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; - } - - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation - - services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); - services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); - } - - // this is not really necessary in d3d9 (used a def instruction), but to be sure: - f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; - services->setVertexShaderConstant(c95, 95, 1); - } - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.h deleted file mode 100644 index 70b4a5ce3..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D9_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D9_NORMAL_MAPMATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ -#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -#include "irrMath.h" // needed by borland for sqrtf define -#endif -#include - -#include "CD3D9ShaderMaterialRenderer.h" -#include "IShaderConstantSetCallBack.h" - -namespace irr -{ -namespace video -{ - -//! Renderer for normal maps -class CD3D9NormalMapRenderer : - public CD3D9ShaderMaterialRenderer, IShaderConstantSetCallBack -{ -public: - - CD3D9NormalMapRenderer( - IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); - - ~CD3D9NormalMapRenderer(); - - //! Called by the engine when the vertex and/or pixel shader constants for an - //! material renderer should be set. - virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); - - virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); - - //! Returns the render capability of the material. - virtual s32 getRenderCapability() const; - -private: - -}; - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp b/lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp deleted file mode 100644 index 954a55204..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp +++ /dev/null @@ -1,410 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#include "CD3D9ParallaxMapRenderer.h" -#include "IMaterialRendererServices.h" -#include "IVideoDriver.h" -#include "os.h" -#include "SLight.h" - -//#define SHADER_EXTERNAL_DEBUG - -#ifdef SHADER_EXTERNAL_DEBUG -#include "CReadFile.h" -#endif - -namespace irr -{ -namespace video -{ - // 1.1/1.4 Shaders with two lights and vertex based attenuation - - // Irrlicht Engine D3D9 render path normal map vertex shader - const char D3D9_PARALLAX_MAP_VSH[] = - ";Irrlicht Engine 0.10 D3D9 render path parallax mapping vertex shader\n"\ - "; c0-3: Transposed world matrix \n"\ - "; c4: Eye position \n"\ - "; c8-11: Transposed worldViewProj matrix (Projection * View * World) \n"\ - "; c12: Light01 position \n"\ - "; c13: x,y,z: Light01 color; .w: 1/LightRadius˛ \n"\ - "; c14: Light02 position \n"\ - "; c15: x,y,z: Light02 color; .w: 1/LightRadius˛ \n"\ - "vs.1.1\n"\ - "dcl_position v0 ; position \n"\ - "dcl_normal v1 ; normal \n"\ - "dcl_color v2 ; color \n"\ - "dcl_texcoord0 v3 ; texture coord \n"\ - "dcl_texcoord1 v4 ; tangent \n"\ - "dcl_texcoord2 v5 ; binormal \n"\ - "\n"\ - "def c95, 0.5, 0.5, 0.5, 0.5 ; used for moving light vector to ps \n"\ - "def c96, -1, 1, 1, 1 ; somewhere I've got a bug. flipping the vectors with this fixes it. \n"\ - "\n"\ - "m4x4 oPos, v0, c8 ; transform position to clip space with worldViewProj matrix\n"\ - "\n"\ - "m3x3 r5, v4, c0 ; transform tangent U\n"\ - "m3x3 r7, v1, c0 ; transform normal W\n"\ - "m3x3 r6, v5, c0 ; transform binormal V\n"\ - "\n"\ - "m4x4 r4, v0, c0 ; vertex into world position\n"\ - "add r2, c12, -r4 ; vtxpos - light1 pos\n"\ - "add r3, c14, -r4 ; vtxpos - light2 pos\n"\ - "add r1, -c4, r4 ; eye - vtxpos \n"\ - "\n"\ - "dp3 r8.x, r5, r2 ; transform the light1 vector with U, V, W\n"\ - "dp3 r8.y, r6, r2 \n"\ - "dp3 r8.z, r7, r2 \n"\ - "dp3 r9.x, r5, r3 ; transform the light2 vector with U, V, W\n"\ - "dp3 r9.y, r6, r3 \n"\ - "dp3 r9.z, r7, r3 \n"\ - "dp3 r10.x, r5, r1 ; transform the eye vector with U, V, W\n"\ - "dp3 r10.y, r6, r1 \n"\ - "dp3 r10.z, r7, r1 \n"\ - "\n"\ - "dp3 r8.w, r8, r8 ; normalize light vector 1 (r8)\n"\ - "rsq r8.w, r8.w \n"\ - "mul r8, r8, r8.w \n"\ - ";mul r8, r8, c96 \n"\ - "dp3 r9.w, r9, r9 ; normalize light vector 2 (r9)\n"\ - "rsq r9.w, r9.w \n"\ - "mul r9, r9, r9.w \n"\ - ";mul r9, r9, c96 \n"\ - "dp3 r10.w, r10, r10 ; normalize eye vector (r10)\n"\ - "rsq r10.w, r10.w \n"\ - "mul r10, r10, r10.w \n"\ - "mul r10, r10, c96 \n"\ - "\n"\ - "\n"\ - "mad oT2.xyz, r8.xyz, c95, c95 ; move light vector 1 from -1..1 into 0..1 \n"\ - "mad oT3.xyz, r9.xyz, c95, c95 ; move light vector 2 from -1..1 into 0..1 \n"\ - "mad oT4.xyz, r10.xyz, c95, c95 ; move eye vector from -1..1 into 0..1 \n"\ - "\n"\ - " ; calculate attenuation of light 1 \n"\ - "dp3 r2.x, r2.xyz, r2.xyz ; r2.x = r2.x˛ + r2.y˛ + r2.z˛ \n"\ - "mul r2.x, r2.x, c13.w ; r2.x * attenutation \n"\ - "rsq r2, r2.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ - "mul oD0, r2, c13 ; resulting light color = lightcolor * attenuation \n"\ - "\n"\ - " ; calculate attenuation of light 2 \n"\ - "dp3 r3.x, r3.xyz, r3.xyz ; r3.x = r3.x˛ + r3.y˛ + r3.z˛ \n"\ - "mul r3.x, r3.x, c15.w ; r2.x * attenutation \n"\ - "rsq r3, r3.x ; r2.xyzw = 1/sqrt(r2.x * attenutation)\n"\ - "mul oD1, r3, c15 ; resulting light color = lightcolor * attenuation \n"\ - "\n"\ - "mov oT0.xy, v3.xy ; move out texture coordinates 1\n"\ - "mov oT1.xy, v3.xy ; move out texture coordinates 2\n"\ - "mov oD0.a, v2.a ; move out original alpha value \n"\ - "\n"; - - - // Irrlicht Engine D3D9 render path normal map pixel shader version 1.4 - const char D3D9_PARALLAX_MAP_PSH[] = - ";Irrlicht Engine 0.10 D3D9 render path parallax mapping pixel shader \n"\ - ";Input: \n"\ - ";t0: color map texture coord \n"\ - ";t1: normal map texture coords \n"\ - ";t2: light 1 vector in tangent space \n"\ - ";t4: eye vector in tangent space \n"\ - ";v0: light 1 color \n"\ - ";t3: light 2 vector in tangent space \n"\ - ";v1: light 2 color \n"\ - ";v0.a: vertex alpha value \n"\ - " \n"\ - "ps.1.4 \n"\ - " \n"\ - ";def c6, 0.02f, 0.02f, 0.02f, 0.0f ; scale factor, now set in callback \n"\ - "def c5, 0.5f, 0.5f, 0.5f, 0.0f ; for specular division \n"\ - " \n"\ - "texld r1, t1 ; sample (normal.x, normal.y, normal.z, height) \n"\ - "texcrd r4.xyz, t4 ; fetch eye vector \n"\ - "texcrd r0.xyz, t0 ; color map \n"\ - " \n"\ - "; original parallax mapping: \n"\ - ";mul r3, r1_bx2.wwww, c6; ; r3 = (height, height, height) * scale \n"\ - ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ - " \n"\ - "; modified parallax mapping to reduce swimming effect: \n"\ - "mul r3, r1_bx2.wwww, r1_bx2.zzzz ; (nh,nh,nh,nh) = (h,h,h,h) * (n.z,n.z,n.z,n.z,) \n"\ - "mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ - "mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ - " \n"\ - "phase \n"\ - " \n"\ - "texld r0, r2 ; load diffuse texture with new tex coord \n"\ - "texld r1, r2 ; sample normal map \n"\ - "texcrd r2.xyz, t2 ; fetch light vector 1 \n"\ - "texcrd r3.xyz, t3 ; fetch light vector 2 \n"\ - " \n"\ - "dp3_sat r5, r1_bx2, r2_bx2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ - "mul r5, r5, v0 ; luminance1 * light color 1 \n"\ - " \n"\ - "dp3_sat r3, r1_bx2, r3_bx2 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ - "mad r3, r3, v1, r5 ; (luminance2 * light color 2) + luminance1 \n"\ - " \n"\ - "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ - "+mov r0.a, v0.a ; write original alpha value \n"\ - "\n"; - - // Irrlicht Engine D3D9 render path normal map pixel shader version 2.0 - const char D3D9_PARALLAX_MAP_PSH_20[] = - ";Irrlicht Engine D3D9 render path parallax mapping pixel shader \n"\ - ";Input: \n"\ - " \n"\ - ";t0: color map texture coord \n"\ - ";t1: normal map texture coords \n"\ - ";t2: light 1 vector in tangent space \n"\ - ";t4: eye vector in tangent space \n"\ - ";v0: light 1 color \n"\ - ";t3: light 2 vector in tangent space \n"\ - ";v1: light 2 color \n"\ - ";v0.a: vertex alpha value \n"\ - " \n"\ - "ps.2.0 \n"\ - " \n"\ - "dcl_2d s0 ; Declare the s0 register to be the sampler for stage 0 \n"\ - "dcl t0.xy ; Declare t0 to have 2D texture coordinates from stage 0 \n"\ - "dcl t1.xy ; Declare t0 to have 2D texture coordinates from stage 0 \n"\ - "dcl_2d s1 ; Declare the s1 register to be the sampler for stage 1 \n"\ - " \n"\ - "dcl t2.xyz ; \n"\ - "dcl t3.xyz ; \n"\ - "dcl t4.xyz ; \n"\ - "dcl v0.xyzw; \n"\ - "dcl v1.xyzw; \n"\ - " \n"\ - "def c0, -1.0f, -1.0f, -1.0f, -1.0f ; for _bx2 emulation \n"\ - "def c1, 2.0f, 2.0f, 2.0f, 2.0f ; for _bx2 emulation \n"\ - "mov r11, c1; \n"\ - " \n"\ - "texld r1, t1, s1 ; sample (normal.x, normal.y, normal.z, height) \n"\ - "mov r4.xyz, t4 ; fetch eye vector \n"\ - "mov r0.xy, t0 ; color map \n"\ - " \n"\ - "; original parallax mapping: \n"\ - "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ - "mad r1.xyz, r1, r11, c0; \n"\ - " \n"\ - "mul r3, r1.wwww, c6; ; r3 = (height, height, height) * scale \n"\ - " \n"\ - "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ - "mad r4.xyz, r4, r11, c0; \n"\ - " \n"\ - "mad r2.xy, r3, r4, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ - " \n"\ - "; modified parallax mapping to avoid swimming: \n"\ - ";mul r3, r1_bx2.wwww, r1_bx2.zzzz ; r3 = (h,h,h,h) * (n.z, n.z, n.z, n.z,) \n"\ - ";mul r3, r3, c6; ; r3 = (nh, nh, nh) * scale \n"\ - ";mad r2.xyz, r3, r4_bx2, r0 ; newTexCoord = height * eye + oldTexCoord \n"\ - " \n"\ - "texld r0, r2, s0 ; load diffuse texture with new tex coord \n"\ - "texld r1, r2, s1 ; sample normal map \n"\ - "mov r2.xyz, t2 ; fetch light vector 1 \n"\ - "mov r3.xyz, t3 ; fetch light vector 2 \n"\ - " \n"\ - "; emulate ps1x _bx2, so substract 0.5f and multiply by 2 \n"\ - "mad r1.xyz, r1, r11, c0; \n"\ - "mad r2.xyz, r2, r11, c0; \n"\ - "mad r3.xyz, r3, r11, c0; \n"\ - " \n"\ - "dp3_sat r2, r1, r2 ; normal dot light 1 (_bx2 because moved into 0..1) \n"\ - "mul r2, r2, v0 ; luminance1 * light color 1 \n"\ - " \n"\ - "dp3_sat r3, r1, r3 ; normal dot light 2 (_bx2 because moved into 0..1) \n"\ - "mad r3, r3, v1, r2 ; (luminance2 * light color 2) + luminance1 \n"\ - " \n"\ - "mul r0.xyz, r0, r3 ; total luminance * base color \n"\ - "mov r0.a, v0.a ; write original alpha value \n"\ - "mov oC0, r0; \n"\ - "\n"; - - CD3D9ParallaxMapRenderer::CD3D9ParallaxMapRenderer( - IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial) - : CD3D9ShaderMaterialRenderer(d3ddev, driver, 0, baseMaterial), - CurrentScale(0.0f) - { - - #ifdef _DEBUG - setDebugName("CD3D9ParallaxMapRenderer"); - #endif - - // set this as callback. We could have done this in - // the initialization list, but some compilers don't like it. - - CallBack = this; - - // basicly, this thing simply compiles these hardcoded shaders if the - // hardware is able to do them, otherwise it maps to the base material - - if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) || - !driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) - { - // this hardware is not able to do shaders. Fall back to - // base material. - outMaterialTypeNr = driver->addMaterialRenderer(this); - return; - } - - // check if already compiled parallax map shaders are there. - - video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID); - if (renderer) - { - // use the already compiled shaders - video::CD3D9ParallaxMapRenderer* nmr = (video::CD3D9ParallaxMapRenderer*)renderer; - VertexShader = nmr->VertexShader; - if (VertexShader) - VertexShader->AddRef(); - - PixelShader = nmr->PixelShader; - if (PixelShader) - PixelShader->AddRef(); - - outMaterialTypeNr = driver->addMaterialRenderer(this); - } - else - { - #ifdef SHADER_EXTERNAL_DEBUG - - // quickly load shader from external file - io::CReadFile* file = new io::CReadFile("parallax.psh"); - s32 sz = file->getSize(); - char* s = new char[sz+1]; - file->read(s, sz); - s[sz] = 0; - - init(outMaterialTypeNr, D3D9_PARALLAX_MAP_VSH, s); - - delete [] s; - file->drop(); - - #else - - // compile shaders on our own - init(outMaterialTypeNr, D3D9_PARALLAX_MAP_VSH, D3D9_PARALLAX_MAP_PSH); - - #endif // SHADER_EXTERNAL_DEBUG - } - // something failed, use base material - if (-1==outMaterialTypeNr) - driver->addMaterialRenderer(this); - } - - - CD3D9ParallaxMapRenderer::~CD3D9ParallaxMapRenderer() - { - if (CallBack == this) - CallBack = 0; - } - - bool CD3D9ParallaxMapRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) - { - if (vtxtype != video::EVT_TANGENTS) - { - os::Printer::log("Error: Parallax map renderer only supports vertices of type EVT_TANGENTS", ELL_ERROR); - return false; - } - - return CD3D9ShaderMaterialRenderer::OnRender(service, vtxtype); - } - - - void CD3D9ParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material, - const video::SMaterial& lastMaterial, - bool resetAllRenderstates, video::IMaterialRendererServices* services) - { - CD3D9ShaderMaterialRenderer::OnSetMaterial(material, lastMaterial, - resetAllRenderstates, services); - - CurrentScale = material.MaterialTypeParam; - } - - - //! Returns the render capability of the material. - s32 CD3D9ParallaxMapRenderer::getRenderCapability() const - { - if (Driver->queryFeature(video::EVDF_PIXEL_SHADER_1_4) && - Driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) - return 0; - - return 1; - } - - - //! Called by the engine when the vertex and/or pixel shader constants - //! for an material renderer should be set. - void CD3D9ParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData) - { - video::IVideoDriver* driver = services->getVideoDriver(); - - // set transposed world matrix - services->setVertexShaderConstant(driver->getTransform(video::ETS_WORLD).getTransposed().pointer(), 0, 4); - - // set eye position - - // The viewpoint is at (0., 0., 0.) in eye space. - // Turning this into a vector [0 0 0 1] and multiply it by - // the inverse of the view matrix, the resulting vector is the - // object space location of the camera. - - f32 floats[4] = {0,0,0,1}; - core::matrix4 minv = driver->getTransform(video::ETS_VIEW); - minv.makeInverse(); - minv.multiplyWith1x4Matrix(floats); - services->setVertexShaderConstant(floats, 4, 1); - - // set transposed worldViewProj matrix - core::matrix4 worldViewProj; - worldViewProj = driver->getTransform(video::ETS_PROJECTION); - worldViewProj *= driver->getTransform(video::ETS_VIEW); - worldViewProj *= driver->getTransform(video::ETS_WORLD); - services->setVertexShaderConstant(worldViewProj.getTransposed().pointer(), 8, 4); - - // here we've got to fetch the fixed function lights from the - // driver and set them as constants - - const u32 cnt = driver->getDynamicLightCount(); - - for (u32 i=0; i<2; ++i) - { - SLight light; - - if (igetDynamicLight(i); - else - { - light.DiffuseColor.set(0,0,0); // make light dark - light.Radius = 1.0f; - } - - light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation - - services->setVertexShaderConstant(reinterpret_cast(&light.Position), 12+(i*2), 1); - services->setVertexShaderConstant(reinterpret_cast(&light.DiffuseColor), 13+(i*2), 1); - } - - // this is not really necessary in d3d9 (used a def instruction), but to be sure: - f32 c95[] = {0.5f, 0.5f, 0.5f, 0.5f}; - services->setVertexShaderConstant(c95, 95, 1); - f32 c96[] = {-1, 1, 1, 1}; - services->setVertexShaderConstant(c96, 96, 1); - - // set scale factor - f32 factor = 0.02f; // default value - if (CurrentScale != 0) - factor = CurrentScale; - - f32 c6[] = {factor, factor, factor, 0}; - services->setPixelShaderConstant(c6, 6, 1); - } - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.h deleted file mode 100644 index 94010cd73..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D9_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D9_PARALLAX_MAPMATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ -#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -#include "irrMath.h" // needed by borland for sqrtf define -#endif -#include - -#include "CD3D9ShaderMaterialRenderer.h" -#include "IShaderConstantSetCallBack.h" - -namespace irr -{ -namespace video -{ - -//! Renderer for normal maps using parallax mapping -class CD3D9ParallaxMapRenderer : - public CD3D9ShaderMaterialRenderer, IShaderConstantSetCallBack -{ -public: - - CD3D9ParallaxMapRenderer( - IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial); - - ~CD3D9ParallaxMapRenderer(); - - //! Called by the engine when the vertex and/or pixel shader constants for an - //! material renderer should be set. - virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData); - - virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); - - //! Returns the render capability of the material. - virtual s32 getRenderCapability() const; - - virtual void OnSetMaterial(const SMaterial& material) { } - virtual void OnSetMaterial(const video::SMaterial& material, - const video::SMaterial& lastMaterial, - bool resetAllRenderstates, video::IMaterialRendererServices* services); - -private: - - f32 CurrentScale; - -}; - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp b/lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp deleted file mode 100644 index 7d2f76e6b..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp +++ /dev/null @@ -1,540 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#include "CD3D9ShaderMaterialRenderer.h" -#include "IShaderConstantSetCallBack.h" -#include "IMaterialRendererServices.h" -#include "IVideoDriver.h" -#include "os.h" -#include "irrString.h" - -#ifndef _IRR_D3D_NO_SHADER_DEBUGGING -#include -#endif - - -namespace irr -{ -namespace video -{ - -//! Public constructor -CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, - IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData) -: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), - VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) -{ - #ifdef _DEBUG - setDebugName("CD3D9ShaderMaterialRenderer"); - #endif - - if (BaseMaterial) - BaseMaterial->grab(); - - if (CallBack) - CallBack->grab(); - - init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram); -} - - -//! constructor only for use by derived classes who want to -//! create a fall back material for example. -CD3D9ShaderMaterialRenderer::CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, - video::IVideoDriver* driver, - IShaderConstantSetCallBack* callback, - IMaterialRenderer* baseMaterial, s32 userData) -: pID3DDevice(d3ddev), Driver(driver), CallBack(callback), BaseMaterial(baseMaterial), - VertexShader(0), OldVertexShader(0), PixelShader(0), UserData(userData) -{ - #ifdef _DEBUG - setDebugName("CD3D9ShaderMaterialRenderer"); - #endif - - if (BaseMaterial) - BaseMaterial->grab(); - - if (CallBack) - CallBack->grab(); -} - - -void CD3D9ShaderMaterialRenderer::init(s32& outMaterialTypeNr, - const c8* vertexShaderProgram, const c8* pixelShaderProgram) -{ - outMaterialTypeNr = -1; - - // create vertex shader - if (!createVertexShader(vertexShaderProgram)) - return; - - // create pixel shader - if (!createPixelShader(pixelShaderProgram)) - return; - - // register myself as new material - outMaterialTypeNr = Driver->addMaterialRenderer(this); -} - - -//! Destructor -CD3D9ShaderMaterialRenderer::~CD3D9ShaderMaterialRenderer() -{ - if (CallBack) - CallBack->drop(); - - if (VertexShader) - VertexShader->Release(); - - if (PixelShader) - PixelShader->Release(); - - if (BaseMaterial) - BaseMaterial->drop(); -} - - -bool CD3D9ShaderMaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) -{ - // call callback to set shader constants - if (CallBack && (VertexShader || PixelShader)) - CallBack->OnSetConstants(service, UserData); - - return true; -} - - -void CD3D9ShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, - bool resetAllRenderstates, video::IMaterialRendererServices* services) -{ - if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates) - { - if (VertexShader) - { - // save old vertex shader - pID3DDevice->GetVertexShader(&OldVertexShader); - - // set new vertex shader - if (FAILED(pID3DDevice->SetVertexShader(VertexShader))) - os::Printer::log("Could not set vertex shader.", ELL_WARNING); - } - - // set new pixel shader - if (PixelShader) - { - if (FAILED(pID3DDevice->SetPixelShader(PixelShader))) - os::Printer::log("Could not set pixel shader.", ELL_WARNING); - } - - if (BaseMaterial) - BaseMaterial->OnSetMaterial(material, material, true, services); - } - - //let callback know used material - if (CallBack) - CallBack->OnSetMaterial(material); - - services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); -} - - -void CD3D9ShaderMaterialRenderer::OnUnsetMaterial() -{ - if (VertexShader) - pID3DDevice->SetVertexShader(OldVertexShader); - - if (PixelShader) - pID3DDevice->SetPixelShader(0); - - if (BaseMaterial) - BaseMaterial->OnUnsetMaterial(); -} - - -//! Returns if the material is transparent. The scene managment needs to know this -//! for being able to sort the materials by opaque and transparent. -bool CD3D9ShaderMaterialRenderer::isTransparent() const -{ - return BaseMaterial ? BaseMaterial->isTransparent() : false; -} - - -bool CD3D9ShaderMaterialRenderer::createPixelShader(const c8* pxsh) -{ - if (!pxsh) - return true; - - // compile shader - - LPD3DXBUFFER code = 0; - LPD3DXBUFFER errors = 0; - - #ifdef _IRR_D3D_NO_SHADER_DEBUGGING - - // compile shader without debug info - stubD3DXAssembleShader(pxsh, (UINT)strlen(pxsh), 0, 0, 0, &code, &errors); - #else - - // compile shader and emitt some debug informations to - // make it possible to debug the shader in visual studio - - static int irr_dbg_file_nr = 0; - ++irr_dbg_file_nr; - char tmp[32]; - sprintf(tmp, "irr_d3d9_dbg_shader_%d.psh", irr_dbg_file_nr); - - FILE* f = fopen(tmp, "wb"); - fwrite(pxsh, strlen(pxsh), 1, f); - fflush(f); - fclose(f); - - stubD3DXAssembleShaderFromFile(tmp, 0, 0, D3DXSHADER_DEBUG, &code, &errors); - - #endif - - - if (errors) - { - // print out compilation errors. - os::Printer::log("Pixel shader compilation failed:", ELL_ERROR); - os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); - - if (code) - code->Release(); - - errors->Release(); - return false; - } - - if (FAILED(pID3DDevice->CreatePixelShader((DWORD*)code->GetBufferPointer(), &PixelShader))) - { - os::Printer::log("Could not create pixel shader.", ELL_ERROR); - code->Release(); - return false; - } - - code->Release(); - return true; -} - - -bool CD3D9ShaderMaterialRenderer::createVertexShader(const char* vtxsh) -{ - if (!vtxsh) - return true; - - // compile shader - - LPD3DXBUFFER code = 0; - LPD3DXBUFFER errors = 0; - - #ifdef _IRR_D3D_NO_SHADER_DEBUGGING - - // compile shader without debug info - stubD3DXAssembleShader(vtxsh, (UINT)strlen(vtxsh), 0, 0, 0, &code, &errors); - - #else - - // compile shader and emitt some debug informations to - // make it possible to debug the shader in visual studio - - static int irr_dbg_file_nr = 0; - ++irr_dbg_file_nr; - char tmp[32]; - sprintf(tmp, "irr_d3d9_dbg_shader_%d.vsh", irr_dbg_file_nr); - - FILE* f = fopen(tmp, "wb"); - fwrite(vtxsh, strlen(vtxsh), 1, f); - fflush(f); - fclose(f); - - stubD3DXAssembleShaderFromFile(tmp, 0, 0, D3DXSHADER_DEBUG, &code, &errors); - - #endif - - if (errors) - { - // print out compilation errors. - os::Printer::log("Vertex shader compilation failed:", ELL_ERROR); - os::Printer::log((c8*)errors->GetBufferPointer(), ELL_ERROR); - - if (code) - code->Release(); - - errors->Release(); - return false; - } - - if (!code || FAILED(pID3DDevice->CreateVertexShader((DWORD*)code->GetBufferPointer(), &VertexShader))) - { - os::Printer::log("Could not create vertex shader.", ELL_ERROR); - if (code) - code->Release(); - return false; - } - - code->Release(); - return true; -} - - -HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader(LPCSTR pSrcData, - UINT SrcDataLen, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, - LPD3DXBUFFER* ppErrorMsgs) -{ - // Because Irrlicht needs to be able to start up even without installed d3d dlls, it - // needs to load external d3d dlls manually. examples for the dlls are: - // SDK dll name D3DX_SDK_VERSION - // Summer 2004: no dll 22 - // February 2005: d3dx9_24.dll 24 - // April 2005: d3dx9_25.dll 25 - // June 2005: d3dx9_26.dll 26 - // August 2005: d3dx9_27.dll 27 - // October 2005, - // December 2005: d3dx9_28.dll 28 - - #if ( D3DX_SDK_VERSION < 24 ) - // directly link functions, old d3d sdks didn't try to load external dlls - // when linking to the d3dx9.lib - #ifdef _MSC_VER - #pragma comment (lib, "d3dx9.lib") - #endif - - // invoke static linked function - return D3DXAssembleShader(pSrcData, SrcDataLen, pDefines, pInclude, - Flags, ppShader, ppErrorMsgs); - #else - { - // try to load shader functions from the dll and print error if failed. - - // D3DXAssembleShader signature - typedef HRESULT (WINAPI *AssembleShaderFunction)(LPCSTR pSrcData, UINT SrcDataLen, - CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, - DWORD Flags, LPD3DXBUFFER* ppShader, - LPD3DXBUFFER* ppErrorMsgs); - - static bool LoadFailed = false; - static AssembleShaderFunction pFn = 0; - - if (!pFn && !LoadFailed) - { - // try to load dll - io::path strDllName = "d3dx9_"; - strDllName += (int)D3DX_SDK_VERSION; - strDllName += ".dll"; - - HMODULE hMod = LoadLibrary(strDllName.c_str()); - if (hMod) - pFn = (AssembleShaderFunction)GetProcAddress(hMod, "D3DXAssembleShader"); - - if (!pFn) - { - LoadFailed = true; - os::Printer::log("Could not load shader function D3DXAssembleShader from dll, shaders disabled", - strDllName.c_str(), ELL_ERROR); - } - } - - if (pFn) - { - // call already loaded function - return (*pFn)(pSrcData, SrcDataLen, pDefines, pInclude, Flags, ppShader, ppErrorMsgs); - } - } - #endif // D3DX_SDK_VERSION < 24 - - return 0; -} - - -HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShaderFromFile(LPCSTR pSrcFile, - CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, - LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs) -{ - // wondering what I'm doing here? - // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() - - #if ( D3DX_SDK_VERSION < 24 ) - // directly link functions, old d3d sdks didn't try to load external dlls - // when linking to the d3dx9.lib - #ifdef _MSC_VER - #pragma comment (lib, "d3dx9.lib") - #endif - - // invoke static linked function - return D3DXAssembleShaderFromFileA(pSrcFile, pDefines, pInclude, Flags, - ppShader, ppErrorMsgs); - #else - { - // try to load shader functions from the dll and print error if failed. - - // D3DXAssembleShaderFromFileA signature - typedef HRESULT (WINAPI *AssembleShaderFromFileFunction)(LPCSTR pSrcFile, - CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, - LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs); - - static bool LoadFailed = false; - static AssembleShaderFromFileFunction pFn = 0; - - if (!pFn && !LoadFailed) - { - // try to load dll - io::path strDllName = "d3dx9_"; - strDllName += (int)D3DX_SDK_VERSION; - strDllName += ".dll"; - - HMODULE hMod = LoadLibrary(strDllName.c_str()); - if (hMod) - pFn = (AssembleShaderFromFileFunction)GetProcAddress(hMod, "D3DXAssembleShaderFromFileA"); - - if (!pFn) - { - LoadFailed = true; - os::Printer::log("Could not load shader function D3DXAssembleShaderFromFileA from dll, shaders disabled", - strDllName.c_str(), ELL_ERROR); - } - } - - if (pFn) - { - // call already loaded function - return (*pFn)(pSrcFile, pDefines, pInclude, Flags, ppShader, ppErrorMsgs); - } - } - #endif // D3DX_SDK_VERSION < 24 - - return 0; -} - - -HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, - LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, - LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable) -{ - // wondering what I'm doing here? - // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() - - #if ( D3DX_SDK_VERSION < 24 ) - // directly link functions, old d3d sdks didn't try to load external dlls - // when linking to the d3dx9.lib - #ifdef _MSC_VER - #pragma comment (lib, "d3dx9.lib") - #endif - - // invoke static linked function - return D3DXCompileShader(pSrcData, SrcDataLen, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); - #else - { - // try to load shader functions from the dll and print error if failed. - - // D3DXCompileShader - typedef HRESULT (WINAPI *D3DXCompileShaderFunction)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, - LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, - LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable); - - static bool LoadFailed = false; - static D3DXCompileShaderFunction pFn = 0; - - if (!pFn && !LoadFailed) - { - // try to load dll - io::path strDllName = "d3dx9_"; - strDllName += (int)D3DX_SDK_VERSION; - strDllName += ".dll"; - - HMODULE hMod = LoadLibrary(strDllName.c_str()); - if (hMod) - pFn = (D3DXCompileShaderFunction)GetProcAddress(hMod, "D3DXCompileShader"); - - if (!pFn) - { - LoadFailed = true; - os::Printer::log("Could not load shader function D3DXCompileShader from dll, shaders disabled", - strDllName.c_str(), ELL_ERROR); - } - } - - if (pFn) - { - // call already loaded function - return (*pFn)(pSrcData, SrcDataLen, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); - } - } - #endif // D3DX_SDK_VERSION < 24 - - return 0; -} - -HRESULT CD3D9ShaderMaterialRenderer::stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, - LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, - LPD3DXCONSTANTTABLE* ppConstantTable) -{ - // wondering what I'm doing here? - // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() - - #if ( D3DX_SDK_VERSION < 24 ) - // directly link functions, old d3d sdks didn't try to load external dlls - // when linking to the d3dx9.lib - #ifdef _MSC_VER - #pragma comment (lib, "d3dx9.lib") - #endif - - // invoke static linked function - return D3DXCompileShaderFromFileA(pSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); - #else - { - // try to load shader functions from the dll and print error if failed. - - // D3DXCompileShaderFromFileA - typedef HRESULT (WINAPI *D3DXCompileShaderFromFileFunction)(LPCSTR pSrcFile, - CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, - LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, - LPD3DXCONSTANTTABLE* ppConstantTable); - - static bool LoadFailed = false; - static D3DXCompileShaderFromFileFunction pFn = 0; - - if (!pFn && !LoadFailed) - { - // try to load dll - io::path strDllName = "d3dx9_"; - strDllName += (int)D3DX_SDK_VERSION; - strDllName += ".dll"; - - HMODULE hMod = LoadLibrary(strDllName.c_str()); - if (hMod) - pFn = (D3DXCompileShaderFromFileFunction)GetProcAddress(hMod, "D3DXCompileShaderFromFileA"); - - if (!pFn) - { - LoadFailed = true; - os::Printer::log("Could not load shader function D3DXCompileShaderFromFileA from dll, shaders disabled", - strDllName.c_str(), ELL_ERROR); - } - } - - if (pFn) - { - // call already loaded function - return (*pFn)(pSrcFile, pDefines, pInclude, pFunctionName, pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable); - } - } - #endif // D3DX_SDK_VERSION < 24 - - return 0; -} - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ diff --git a/lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.h b/lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.h deleted file mode 100644 index 2c2bb19ab..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_D3D9_SHADER_MATERIAL_RENDERER_H_INCLUDED__ -#define __C_D3D9_SHADER_MATERIAL_RENDERER_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_WINDOWS_ - -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ -#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -#include "irrMath.h" // needed by borland for sqrtf define -#endif -#include - -#include "IMaterialRenderer.h" - -namespace irr -{ -namespace video -{ - -class IVideoDriver; -class IShaderConstantSetCallBack; -class IMaterialRenderer; - -//! Class for using vertex and pixel shaders with D3D9 -class CD3D9ShaderMaterialRenderer : public IMaterialRenderer -{ -public: - - //! Public constructor - CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, video::IVideoDriver* driver, - s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, - IShaderConstantSetCallBack* callback, IMaterialRenderer* baseMaterial, s32 userData); - - //! Destructor - ~CD3D9ShaderMaterialRenderer(); - - virtual void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial, - bool resetAllRenderstates, video::IMaterialRendererServices* services); - - virtual void OnUnsetMaterial(); - - virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype); - - //! Returns if the material is transparent. - virtual bool isTransparent() const; - -protected: - - //! constructor only for use by derived classes who want to - //! create a fall back material for example. - CD3D9ShaderMaterialRenderer(IDirect3DDevice9* d3ddev, - video::IVideoDriver* driver, - IShaderConstantSetCallBack* callback, - IMaterialRenderer* baseMaterial, - s32 userData=0); - - void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram); - bool createPixelShader(const c8* pxsh); - bool createVertexShader(const char* vtxsh); - - HRESULT stubD3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen, - CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, - DWORD Flags, LPD3DXBUFFER* ppShader, - LPD3DXBUFFER* ppErrorMsgs); - - HRESULT stubD3DXAssembleShaderFromFile(LPCSTR pSrcFile, - CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, - LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs); - - HRESULT stubD3DXCompileShader(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, - LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, - LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable); - - HRESULT stubD3DXCompileShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, - LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, - LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, - LPD3DXCONSTANTTABLE* ppConstantTable); - - IDirect3DDevice9* pID3DDevice; - video::IVideoDriver* Driver; - IShaderConstantSetCallBack* CallBack; - IMaterialRenderer* BaseMaterial; - - IDirect3DVertexShader9* VertexShader; - IDirect3DVertexShader9* OldVertexShader; - IDirect3DPixelShader9* PixelShader; - s32 UserData; -}; - - -} // end namespace video -} // end namespace irr - -#endif -#endif -#endif - diff --git a/lib/irrlicht/source/Irrlicht/CD3D9Texture.cpp b/lib/irrlicht/source/Irrlicht/CD3D9Texture.cpp deleted file mode 100644 index 122ee2a67..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9Texture.cpp +++ /dev/null @@ -1,699 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE -#include "CD3D9Texture.h" -#include "CD3D9Driver.h" -#include "os.h" - -#include - -#ifndef _IRR_COMPILE_WITH_DIRECT3D_8_ -// The D3DXFilterTexture function seems to get linked wrong when -// compiling with both D3D8 and 9, causing it not to work in the D3D9 device. -// So mipmapgeneration is replaced with my own bad generation in d3d 8 when -// compiling with both D3D 8 and 9. -// #define _IRR_USE_D3DXFilterTexture_ -#endif // _IRR_COMPILE_WITH_DIRECT3D_8_ - -#ifdef _IRR_USE_D3DXFilterTexture_ -#pragma comment(lib, "d3dx9.lib") -#endif - -namespace irr -{ -namespace video -{ - -//! rendertarget constructor -CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d& size, - const io::path& name, const ECOLOR_FORMAT format) -: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0), - TextureSize(size), ImageSize(size), Pitch(0), ColorFormat(ECF_UNKNOWN), - HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(true) -{ - #ifdef _DEBUG - setDebugName("CD3D9Texture"); - #endif - - Device=driver->getExposedVideoData().D3D9.D3DDev9; - if (Device) - Device->AddRef(); - - createRenderTarget(format); -} - - -//! constructor -CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, - u32 flags, const io::path& name, void* mipmapData) -: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0), - TextureSize(0,0), ImageSize(0,0), Pitch(0), ColorFormat(ECF_UNKNOWN), - HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false) -{ - #ifdef _DEBUG - setDebugName("CD3D9Texture"); - #endif - - HasMipMaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); - - Device=driver->getExposedVideoData().D3D9.D3DDev9; - if (Device) - Device->AddRef(); - - if (image) - { - if (createTexture(flags, image)) - { - if (copyTexture(image)) - { - regenerateMipMapLevels(mipmapData); - } - } - else - os::Printer::log("Could not create DIRECT3D9 Texture.", ELL_WARNING); - } -} - - -//! destructor -CD3D9Texture::~CD3D9Texture() -{ - if (Texture) - Texture->Release(); - - if (RTTSurface) - RTTSurface->Release(); - - // if this texture was the last one using the depth buffer - // we can release the surface. We only use the value of the pointer - // hence it is safe to use the dropped pointer... - if (DepthSurface) - { - if (DepthSurface->drop()) - Driver->removeDepthSurface(DepthSurface); - } - - if (Device) - Device->Release(); -} - - -void CD3D9Texture::createRenderTarget(const ECOLOR_FORMAT format) -{ - // are texture size restrictions there ? - if(!Driver->queryFeature(EVDF_TEXTURE_NPOT)) - { - if (TextureSize != ImageSize) - os::Printer::log("RenderTarget size has to be a power of two", ELL_INFORMATION); - } - TextureSize = TextureSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); - - D3DFORMAT d3dformat = Driver->getD3DColorFormat(); - - if(ColorFormat == ECF_UNKNOWN) - { - // get irrlicht format from backbuffer - // (This will get overwritten by the custom format if it is provided, else kept.) - ColorFormat = Driver->getColorFormat(); - setPitch(d3dformat); - - // Use color format if provided. - if(format != ECF_UNKNOWN) - { - ColorFormat = format; - d3dformat = Driver->getD3DFormatFromColorFormat(format); - setPitch(d3dformat); // This will likely set pitch to 0 for now. - } - } - else - { - d3dformat = Driver->getD3DFormatFromColorFormat(ColorFormat); - } - - // create texture - HRESULT hr; - - hr = Device->CreateTexture( - TextureSize.Width, - TextureSize.Height, - 1, // mip map level count, we don't want mipmaps here - D3DUSAGE_RENDERTARGET, - d3dformat, - D3DPOOL_DEFAULT, - &Texture, - NULL); - - if (FAILED(hr)) - { - if (D3DERR_INVALIDCALL == hr) - os::Printer::log("Could not create render target texture", "Invalid Call"); - else - if (D3DERR_OUTOFVIDEOMEMORY == hr) - os::Printer::log("Could not create render target texture", "Out of Video Memory"); - else - if (E_OUTOFMEMORY == hr) - os::Printer::log("Could not create render target texture", "Out of Memory"); - else - os::Printer::log("Could not create render target texture"); - } -} - - -bool CD3D9Texture::createMipMaps(u32 level) -{ - if (level==0) - return true; - - if (HardwareMipMaps && Texture) - { - // generate mipmaps in hardware - Texture->GenerateMipSubLevels(); - return true; - } - - // manual mipmap generation - IDirect3DSurface9* upperSurface = 0; - IDirect3DSurface9* lowerSurface = 0; - - // get upper level - HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface); - if (FAILED(hr) || !upperSurface) - { - os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING); - return false; - } - - // get lower level - hr = Texture->GetSurfaceLevel(level, &lowerSurface); - if (FAILED(hr) || !lowerSurface) - { - os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING); - upperSurface->Release(); - return false; - } - - D3DSURFACE_DESC upperDesc, lowerDesc; - upperSurface->GetDesc(&upperDesc); - lowerSurface->GetDesc(&lowerDesc); - - D3DLOCKED_RECT upperlr; - D3DLOCKED_RECT lowerlr; - - // lock upper surface - if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0))) - { - upperSurface->Release(); - lowerSurface->Release(); - os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING); - return false; - } - - // lock lower surface - if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0))) - { - upperSurface->UnlockRect(); - upperSurface->Release(); - lowerSurface->Release(); - os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING); - return false; - } - - if (upperDesc.Format != lowerDesc.Format) - { - os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING); - } - else - { - if ((upperDesc.Format == D3DFMT_A1R5G5B5) || (upperDesc.Format == D3DFMT_R5G6B5)) - copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, - lowerDesc.Width, lowerDesc.Height, - upperlr.Pitch, lowerlr.Pitch); - else - if (upperDesc.Format == D3DFMT_A8R8G8B8) - copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, - lowerDesc.Width, lowerDesc.Height, - upperlr.Pitch, lowerlr.Pitch); - else - os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING); - } - - bool result=true; - // unlock - if (FAILED(upperSurface->UnlockRect())) - result=false; - if (FAILED(lowerSurface->UnlockRect())) - result=false; - - // release - upperSurface->Release(); - lowerSurface->Release(); - - if (!result || (upperDesc.Width <= 3 && upperDesc.Height <= 3)) - return result; // stop generating levels - - // generate next level - return createMipMaps(level+1); -} - - -//! creates the hardware texture -bool CD3D9Texture::createTexture(u32 flags, IImage * image) -{ - ImageSize = image->getDimension(); - - core::dimension2d optSize = ImageSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); - - D3DFORMAT format = D3DFMT_A1R5G5B5; - - switch(getTextureFormatFromFlags(flags)) - { - case ETCF_ALWAYS_16_BIT: - format = D3DFMT_A1R5G5B5; break; - case ETCF_ALWAYS_32_BIT: - format = D3DFMT_A8R8G8B8; break; - case ETCF_OPTIMIZED_FOR_QUALITY: - { - switch(image->getColorFormat()) - { - case ECF_R8G8B8: - case ECF_A8R8G8B8: - format = D3DFMT_A8R8G8B8; break; - case ECF_A1R5G5B5: - case ECF_R5G6B5: - format = D3DFMT_A1R5G5B5; break; - } - } - break; - case ETCF_OPTIMIZED_FOR_SPEED: - format = D3DFMT_A1R5G5B5; - break; - default: - break; - } - if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL)) - { - if (format == D3DFMT_A8R8G8B8) - format = D3DFMT_R8G8B8; - else if (format == D3DFMT_A1R5G5B5) - format = D3DFMT_R5G6B5; - } - - const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); - - DWORD usage = 0; - - // This enables hardware mip map generation. - if (mipmaps && Driver->queryFeature(EVDF_MIP_MAP_AUTO_UPDATE)) - { - LPDIRECT3D9 intf = Driver->getExposedVideoData().D3D9.D3D9; - D3DDISPLAYMODE d3ddm; - intf->GetAdapterDisplayMode(Driver->Params.DisplayAdapter, &d3ddm); - - if (D3D_OK==intf->CheckDeviceFormat(Driver->Params.DisplayAdapter,D3DDEVTYPE_HAL,d3ddm.Format,D3DUSAGE_AUTOGENMIPMAP,D3DRTYPE_TEXTURE,format)) - { - usage = D3DUSAGE_AUTOGENMIPMAP; - HardwareMipMaps = true; - } - } - - HRESULT hr = Device->CreateTexture(optSize.Width, optSize.Height, - mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) - usage, // usage - format, D3DPOOL_MANAGED , &Texture, NULL); - - if (FAILED(hr)) - { - // try brute force 16 bit - HardwareMipMaps = false; - if (format == D3DFMT_A8R8G8B8) - format = D3DFMT_A1R5G5B5; - else if (format == D3DFMT_R8G8B8) - format = D3DFMT_R5G6B5; - else - return false; - - hr = Device->CreateTexture(optSize.Width, optSize.Height, - mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) - 0, format, D3DPOOL_MANAGED, &Texture, NULL); - } - - ColorFormat = Driver->getColorFormatFromD3DFormat(format); - setPitch(format); - return (SUCCEEDED(hr)); -} - - -//! copies the image to the texture -bool CD3D9Texture::copyTexture(IImage * image) -{ - if (Texture && image) - { - D3DSURFACE_DESC desc; - Texture->GetLevelDesc(0, &desc); - - TextureSize.Width = desc.Width; - TextureSize.Height = desc.Height; - - D3DLOCKED_RECT rect; - HRESULT hr = Texture->LockRect(0, &rect, 0, 0); - if (FAILED(hr)) - { - os::Printer::log("Texture data not copied", "Could not LockRect D3D9 Texture.", ELL_ERROR); - return false; - } - - Pitch = rect.Pitch; - image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); - - hr = Texture->UnlockRect(0); - if (FAILED(hr)) - { - os::Printer::log("Texture data not copied", "Could not UnlockRect D3D9 Texture.", ELL_ERROR); - return false; - } - } - - return true; -} - - -//! lock function -void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) -{ - if (!Texture) - return 0; - - MipLevelLocked=mipmapLevel; - HRESULT hr; - D3DLOCKED_RECT rect; - if(!IsRenderTarget) - { - hr = Texture->LockRect(mipmapLevel, &rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); - if (FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); - return 0; - } - } - else - { - if (!RTTSurface) - { - // Make RTT surface large enough for all miplevels (including 0) - D3DSURFACE_DESC desc; - Texture->GetLevelDesc(0, &desc); - hr = Device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &RTTSurface, 0); - if (FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D9 Texture", "Offscreen surface creation failed.", ELL_ERROR); - return 0; - } - } - - IDirect3DSurface9 *surface = 0; - hr = Texture->GetSurfaceLevel(mipmapLevel, &surface); - if (FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D9 Texture", "Could not get surface.", ELL_ERROR); - return 0; - } - hr = Device->GetRenderTargetData(surface, RTTSurface); - surface->Release(); - if(FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D9 Texture", "Data copy failed.", ELL_ERROR); - return 0; - } - hr = RTTSurface->LockRect(&rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); - if(FAILED(hr)) - { - os::Printer::log("Could not lock DIRECT3D9 Texture", "LockRect failed.", ELL_ERROR); - return 0; - } - } - return rect.pBits; -} - - -//! unlock function -void CD3D9Texture::unlock() -{ - if (!Texture) - return; - - if (!IsRenderTarget) - Texture->UnlockRect(MipLevelLocked); - else if (RTTSurface) - RTTSurface->UnlockRect(); -} - - -//! Returns original size of the texture. -const core::dimension2d& CD3D9Texture::getOriginalSize() const -{ - return ImageSize; -} - - -//! Returns (=size) of the texture. -const core::dimension2d& CD3D9Texture::getSize() const -{ - return TextureSize; -} - - -//! returns driver type of texture (=the driver, who created the texture) -E_DRIVER_TYPE CD3D9Texture::getDriverType() const -{ - return EDT_DIRECT3D9; -} - - -//! returns color format of texture -ECOLOR_FORMAT CD3D9Texture::getColorFormat() const -{ - return ColorFormat; -} - - -//! returns pitch of texture (in bytes) -u32 CD3D9Texture::getPitch() const -{ - return Pitch; -} - - -//! returns the DIRECT3D9 Texture -IDirect3DBaseTexture9* CD3D9Texture::getDX9Texture() const -{ - return Texture; -} - - -//! returns if texture has mipmap levels -bool CD3D9Texture::hasMipMaps() const -{ - return HasMipMaps; -} - - -void CD3D9Texture::copy16BitMipMap(char* src, char* tgt, - s32 width, s32 height, - s32 pitchsrc, s32 pitchtgt) const -{ - for (s32 y=0; y1) - size.Width /=2; - if (size.Height>1) - size.Height /=2; - ++level; - IDirect3DSurface9* mipSurface = 0; - HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface); - if (FAILED(hr) || !mipSurface) - { - os::Printer::log("Could not get mipmap level", ELL_WARNING); - return; - } - D3DSURFACE_DESC mipDesc; - mipSurface->GetDesc(&mipDesc); - D3DLOCKED_RECT miplr; - - // lock mipmap surface - if (FAILED(mipSurface->LockRect(&miplr, NULL, 0))) - { - mipSurface->Release(); - os::Printer::log("Could not lock texture", ELL_WARNING); - return; - } - - memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width); - mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width; - // unlock - mipSurface->UnlockRect(); - // release - mipSurface->Release(); - } while (size.Width != 1 || size.Height != 1); - } - else if (HasMipMaps) - { - // create mip maps. -#ifdef _IRR_USE_D3DXFilterTexture_ - // The D3DXFilterTexture function seems to get linked wrong when - // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. - // So mipmapgeneration is replaced with my own bad generation - HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_DEFAULT); - if (FAILED(hr)) -#endif - createMipMaps(); - } -} - - -//! returns if it is a render target -bool CD3D9Texture::isRenderTarget() const -{ - return IsRenderTarget; -} - - -//! Returns pointer to the render target surface -IDirect3DSurface9* CD3D9Texture::getRenderTargetSurface() -{ - if (!IsRenderTarget) - return 0; - - IDirect3DSurface9 *pRTTSurface = 0; - if (Texture) - Texture->GetSurfaceLevel(0, &pRTTSurface); - - if (pRTTSurface) - pRTTSurface->Release(); - - return pRTTSurface; -} - - -void CD3D9Texture::setPitch(D3DFORMAT d3dformat) -{ - switch(d3dformat) - { - case D3DFMT_X1R5G5B5: - case D3DFMT_A1R5G5B5: - Pitch = TextureSize.Width * 2; - break; - case D3DFMT_A8B8G8R8: - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - Pitch = TextureSize.Width * 4; - break; - case D3DFMT_R5G6B5: - Pitch = TextureSize.Width * 2; - break; - case D3DFMT_R8G8B8: - Pitch = TextureSize.Width * 3; - break; - default: - Pitch = 0; - }; -} - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ diff --git a/lib/irrlicht/source/Irrlicht/CD3D9Texture.h b/lib/irrlicht/source/Irrlicht/CD3D9Texture.h deleted file mode 100644 index 812aa714d..000000000 --- a/lib/irrlicht/source/Irrlicht/CD3D9Texture.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (C) 2002-2012 Nikolaus Gebhardt -// This file is part of the "Irrlicht Engine". -// For conditions of distribution and use, see copyright notice in irrlicht.h - -#ifndef __C_DIRECTX9_TEXTURE_H_INCLUDED__ -#define __C_DIRECTX9_TEXTURE_H_INCLUDED__ - -#include "IrrCompileConfig.h" -#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ - -#include "ITexture.h" -#include "IImage.h" -#if defined(__BORLANDC__) || defined (__BCPLUSPLUS__) -#include "irrMath.h" // needed by borland for sqrtf define -#endif -#include - -namespace irr -{ -namespace video -{ - -class CD3D9Driver; -// forward declaration for RTT depth buffer handling -struct SDepthSurface; -/*! - interface for a Video Driver dependent Texture. -*/ -class CD3D9Texture : public ITexture -{ -public: - - //! constructor - CD3D9Texture(IImage* image, CD3D9Driver* driver, - u32 flags, const io::path& name, void* mipmapData=0); - - //! rendertarget constructor - CD3D9Texture(CD3D9Driver* driver, const core::dimension2d& size, const io::path& name, - const ECOLOR_FORMAT format = ECF_UNKNOWN); - - //! destructor - virtual ~CD3D9Texture(); - - //! lock function - virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0); - - //! unlock function - virtual void unlock(); - - //! Returns original size of the texture. - virtual const core::dimension2d& getOriginalSize() const; - - //! Returns (=size) of the texture. - virtual const core::dimension2d& getSize() const; - - //! returns driver type of texture (=the driver, who created the texture) - virtual E_DRIVER_TYPE getDriverType() const; - - //! returns color format of texture - virtual ECOLOR_FORMAT getColorFormat() const; - - //! returns pitch of texture (in bytes) - virtual u32 getPitch() const; - - //! returns the DIRECT3D9 Texture - IDirect3DBaseTexture9* getDX9Texture() const; - - //! returns if texture has mipmap levels - bool hasMipMaps() const; - - //! Regenerates the mip map levels of the texture. Useful after locking and - //! modifying the texture - virtual void regenerateMipMapLevels(void* mipmapData=0); - - //! returns if it is a render target - virtual bool isRenderTarget() const; - - //! Returns pointer to the render target surface - IDirect3DSurface9* getRenderTargetSurface(); - -private: - friend class CD3D9Driver; - - void createRenderTarget(const ECOLOR_FORMAT format = ECF_UNKNOWN); - - //! creates the hardware texture - bool createTexture(u32 flags, IImage * image); - - //! copies the image to the texture - bool copyTexture(IImage * image); - - //! Helper function for mipmap generation. - bool createMipMaps(u32 level=1); - - //! Helper function for mipmap generation. - void copy16BitMipMap(char* src, char* tgt, - s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; - - //! Helper function for mipmap generation. - void copy32BitMipMap(char* src, char* tgt, - s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const; - - //! set Pitch based on the d3d format - void setPitch(D3DFORMAT d3dformat); - - IDirect3DDevice9* Device; - IDirect3DTexture9* Texture; - IDirect3DSurface9* RTTSurface; - CD3D9Driver* Driver; - SDepthSurface* DepthSurface; - core::dimension2d TextureSize; - core::dimension2d ImageSize; - s32 Pitch; - u32 MipLevelLocked; - ECOLOR_FORMAT ColorFormat; - - bool HasMipMaps; - bool HardwareMipMaps; - bool IsRenderTarget; -}; - - -} // end namespace video -} // end namespace irr - -#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ - -#endif // __C_DIRECTX9_TEXTURE_H_INCLUDED__ - -