Add DirectX 9 driver
This commit is contained in:
parent
b6d58f55c4
commit
b9b5ac2fec
@ -27,6 +27,10 @@ endif()
|
|||||||
|
|
||||||
option(USE_SWITCH "Build targetting switch" OFF)
|
option(USE_SWITCH "Build targetting switch" OFF)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
option(USE_DIRECTX "Build DirectX 9 driver (requires DirectX SDK)" OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(SERVER_ONLY "Create a server only (i.e. no graphics or sound)" OFF)
|
option(SERVER_ONLY "Create a server only (i.e. no graphics or sound)" OFF)
|
||||||
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
|
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
|
||||||
option(USE_SYSTEM_ANGELSCRIPT "Use system angelscript instead of built-in angelscript. If you enable this option, make sure to use a compatible version." OFF)
|
option(USE_SYSTEM_ANGELSCRIPT "Use system angelscript instead of built-in angelscript. If you enable this option, make sure to use a compatible version." OFF)
|
||||||
@ -158,6 +162,10 @@ if(WIN32)
|
|||||||
include_directories(${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/include)
|
include_directories(${PROJECT_SOURCE_DIR}/${DEPENDENCIES}/include)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WIN32 AND NOT USE_DIRECTX)
|
||||||
|
add_definitions(-DNO_IRR_COMPILE_WITH_DIRECT3D_9_)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(USE_GLES2)
|
if(USE_GLES2)
|
||||||
add_definitions(-DUSE_GLES2)
|
add_definitions(-DUSE_GLES2)
|
||||||
if (NOT IOS)
|
if (NOT IOS)
|
||||||
|
@ -187,6 +187,19 @@ source/Irrlicht/Irrlicht.cpp
|
|||||||
source/Irrlicht/irrXML.cpp
|
source/Irrlicht/irrXML.cpp
|
||||||
source/Irrlicht/os.cpp
|
source/Irrlicht/os.cpp
|
||||||
source/Irrlicht/COpenGLNormalMapRenderer.cpp
|
source/Irrlicht/COpenGLNormalMapRenderer.cpp
|
||||||
|
source/Irrlicht/CD3D9Driver.cpp
|
||||||
|
source/Irrlicht/CD3D9Driver.h
|
||||||
|
source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp
|
||||||
|
source/Irrlicht/CD3D9HLSLMaterialRenderer.h
|
||||||
|
source/Irrlicht/CD3D9MaterialRenderer.h
|
||||||
|
source/Irrlicht/CD3D9NormalMapRenderer.cpp
|
||||||
|
source/Irrlicht/CD3D9NormalMapRenderer.h
|
||||||
|
source/Irrlicht/CD3D9ParallaxMapRenderer.cpp
|
||||||
|
source/Irrlicht/CD3D9ParallaxMapRenderer.h
|
||||||
|
source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp
|
||||||
|
source/Irrlicht/CD3D9ShaderMaterialRenderer.h
|
||||||
|
source/Irrlicht/CD3D9Texture.cpp
|
||||||
|
source/Irrlicht/CD3D9Texture.h
|
||||||
source/Irrlicht/CAnimatedMeshSceneNode.h
|
source/Irrlicht/CAnimatedMeshSceneNode.h
|
||||||
source/Irrlicht/CAttributeImpl.h
|
source/Irrlicht/CAttributeImpl.h
|
||||||
source/Irrlicht/CAttributes.h
|
source/Irrlicht/CAttributes.h
|
||||||
|
@ -157,7 +157,11 @@ If not defined, Windows Multimedia library is used, which offers also broad supp
|
|||||||
|
|
||||||
//! Only define _IRR_COMPILE_WITH_DIRECT3D_8_ if you have an appropriate DXSDK, e.g. Summer 2004
|
//! Only define _IRR_COMPILE_WITH_DIRECT3D_8_ if you have an appropriate DXSDK, e.g. Summer 2004
|
||||||
// #define _IRR_COMPILE_WITH_DIRECT3D_8_
|
// #define _IRR_COMPILE_WITH_DIRECT3D_8_
|
||||||
|
#ifdef NO_IRR_COMPILE_WITH_DIRECT3D_9_
|
||||||
#undef _IRR_COMPILE_WITH_DIRECT3D_9_
|
#undef _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||||
|
#else
|
||||||
|
#define _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
3633
lib/irrlicht/source/Irrlicht/CD3D9Driver.cpp
Normal file
3633
lib/irrlicht/source/Irrlicht/CD3D9Driver.cpp
Normal file
File diff suppressed because it is too large
Load Diff
496
lib/irrlicht/source/Irrlicht/CD3D9Driver.h
Normal file
496
lib/irrlicht/source/Irrlicht/CD3D9Driver.h
Normal file
@ -0,0 +1,496 @@
|
|||||||
|
// 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 <windows.h>
|
||||||
|
#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 <d3d9.h>
|
||||||
|
|
||||||
|
#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<s32>* 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<video::IRenderTarget>& texture,
|
||||||
|
bool clearBackBuffer=true, bool clearZBuffer=true,
|
||||||
|
SColor color=video::SColor(0,0,0,0));
|
||||||
|
|
||||||
|
//! sets a viewport
|
||||||
|
virtual void setViewPort(const core::rect<s32>& area);
|
||||||
|
|
||||||
|
//! gets the area of the current viewport
|
||||||
|
virtual const core::rect<s32>& 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<s32>& destPos,
|
||||||
|
const core::rect<s32>& sourceRect, const core::rect<s32>* 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<s32>& destRect,
|
||||||
|
const core::rect<s32>& sourceRect, const core::rect<s32>* 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<core::position2d<s32> >& positions,
|
||||||
|
const core::array<core::rect<s32> >& sourceRects,
|
||||||
|
const core::rect<s32>* 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<s32>& pos,
|
||||||
|
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
|
||||||
|
const core::rect<s32>* clip);
|
||||||
|
|
||||||
|
//! Draws a 2d line.
|
||||||
|
virtual void draw2DLine(const core::position2d<s32>& start,
|
||||||
|
const core::position2d<s32>& 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<core::vector3df>& 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<u32>& 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<u32>& size,
|
||||||
|
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN, const bool useStencil = false);
|
||||||
|
|
||||||
|
//! 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<u32>& 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<u32> CurrentRendertargetSize;
|
||||||
|
|
||||||
|
HWND WindowId;
|
||||||
|
core::rect<s32>* SceneSourceRect;
|
||||||
|
|
||||||
|
D3DCAPS9 Caps;
|
||||||
|
|
||||||
|
SIrrlichtCreationParameters Params;
|
||||||
|
|
||||||
|
E_VERTEX_TYPE LastVertexType;
|
||||||
|
|
||||||
|
SColorf AmbientLight;
|
||||||
|
|
||||||
|
core::stringc VendorName;
|
||||||
|
u16 VendorID;
|
||||||
|
|
||||||
|
core::array<SDepthSurface*> 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__
|
||||||
|
|
429
lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp
Normal file
429
lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
// 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_D3D_NO_SHADER_DEBUGGING 1
|
||||||
|
#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 <stdio.h>
|
||||||
|
#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_
|
85
lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.h
Normal file
85
lib/irrlicht/source/Irrlicht/CD3D9HLSLMaterialRenderer.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// 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
|
||||||
|
|
615
lib/irrlicht/source/Irrlicht/CD3D9MaterialRenderer.h
Normal file
615
lib/irrlicht/source/Irrlicht/CD3D9MaterialRenderer.h
Normal file
@ -0,0 +1,615 @@
|
|||||||
|
// 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 <d3d9.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
306
lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.cpp
Normal file
306
lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.cpp
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
// 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 (i<cnt)
|
||||||
|
light = driver->getDynamicLight(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<const f32*>(&light.Position), 12+(i*2), 1);
|
||||||
|
services->setVertexShaderConstant(reinterpret_cast<const f32*>(&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_
|
||||||
|
|
56
lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.h
Normal file
56
lib/irrlicht/source/Irrlicht/CD3D9NormalMapRenderer.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// 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 <d3d9.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
410
lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp
Normal file
410
lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.cpp
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
// 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 (i<cnt)
|
||||||
|
light = driver->getDynamicLight(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<const f32*>(&light.Position), 12+(i*2), 1);
|
||||||
|
services->setVertexShaderConstant(reinterpret_cast<const f32*>(&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_
|
||||||
|
|
63
lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.h
Normal file
63
lib/irrlicht/source/Irrlicht/CD3D9ParallaxMapRenderer.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// 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 <d3d9.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
541
lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp
Normal file
541
lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp
Normal file
@ -0,0 +1,541 @@
|
|||||||
|
// 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_D3D_NO_SHADER_DEBUGGING 1
|
||||||
|
|
||||||
|
#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 <stdio.h>
|
||||||
|
#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 = LoadLibraryA(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 = LoadLibraryA(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 = LoadLibraryA(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 = LoadLibraryA(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_
|
102
lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.h
Normal file
102
lib/irrlicht/source/Irrlicht/CD3D9ShaderMaterialRenderer.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// 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 <d3dx9shader.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
699
lib/irrlicht/source/Irrlicht/CD3D9Texture.cpp
Normal file
699
lib/irrlicht/source/Irrlicht/CD3D9Texture.cpp
Normal file
@ -0,0 +1,699 @@
|
|||||||
|
// 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 <d3dx9tex.h>
|
||||||
|
|
||||||
|
#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<u32>& 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<u32> 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<u32>& CD3D9Texture::getOriginalSize() const
|
||||||
|
{
|
||||||
|
return ImageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Returns (=size) of the texture.
|
||||||
|
const core::dimension2d<u32>& 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; y<height; ++y)
|
||||||
|
{
|
||||||
|
for (s32 x=0; x<width; ++x)
|
||||||
|
{
|
||||||
|
u32 a=0, r=0, g=0, b=0;
|
||||||
|
|
||||||
|
for (s32 dy=0; dy<2; ++dy)
|
||||||
|
{
|
||||||
|
const s32 tgy = (y*2)+dy;
|
||||||
|
for (s32 dx=0; dx<2; ++dx)
|
||||||
|
{
|
||||||
|
const s32 tgx = (x*2)+dx;
|
||||||
|
|
||||||
|
SColor c;
|
||||||
|
if (ColorFormat == ECF_A1R5G5B5)
|
||||||
|
c = A1R5G5B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
|
||||||
|
else
|
||||||
|
c = R5G6B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
|
||||||
|
|
||||||
|
a += c.getAlpha();
|
||||||
|
r += c.getRed();
|
||||||
|
g += c.getGreen();
|
||||||
|
b += c.getBlue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a /= 4;
|
||||||
|
r /= 4;
|
||||||
|
g /= 4;
|
||||||
|
b /= 4;
|
||||||
|
|
||||||
|
u16 c;
|
||||||
|
if (ColorFormat == ECF_A1R5G5B5)
|
||||||
|
c = RGBA16(r,g,b,a);
|
||||||
|
else
|
||||||
|
c = A8R8G8B8toR5G6B5(SColor(a,r,g,b).color);
|
||||||
|
*(u16*)(&tgt[(x*2)+(y*pitchtgt)]) = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
|
||||||
|
s32 width, s32 height,
|
||||||
|
s32 pitchsrc, s32 pitchtgt) const
|
||||||
|
{
|
||||||
|
for (s32 y=0; y<height; ++y)
|
||||||
|
{
|
||||||
|
for (s32 x=0; x<width; ++x)
|
||||||
|
{
|
||||||
|
u32 a=0, r=0, g=0, b=0;
|
||||||
|
SColor c;
|
||||||
|
|
||||||
|
for (s32 dy=0; dy<2; ++dy)
|
||||||
|
{
|
||||||
|
const s32 tgy = (y*2)+dy;
|
||||||
|
for (s32 dx=0; dx<2; ++dx)
|
||||||
|
{
|
||||||
|
const s32 tgx = (x*2)+dx;
|
||||||
|
|
||||||
|
c = *(u32*)(&src[(tgx*4)+(tgy*pitchsrc)]);
|
||||||
|
|
||||||
|
a += c.getAlpha();
|
||||||
|
r += c.getRed();
|
||||||
|
g += c.getGreen();
|
||||||
|
b += c.getBlue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a /= 4;
|
||||||
|
r /= 4;
|
||||||
|
g /= 4;
|
||||||
|
b /= 4;
|
||||||
|
|
||||||
|
c.set(a, r, g, b);
|
||||||
|
*(u32*)(&tgt[(x*4)+(y*pitchtgt)]) = c.color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Regenerates the mip map levels of the texture. Useful after locking and
|
||||||
|
//! modifying the texture
|
||||||
|
void CD3D9Texture::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;
|
||||||
|
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_
|
132
lib/irrlicht/source/Irrlicht/CD3D9Texture.h
Normal file
132
lib/irrlicht/source/Irrlicht/CD3D9Texture.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// 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 <d3d9.h>
|
||||||
|
|
||||||
|
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<u32>& 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<u32>& getOriginalSize() const;
|
||||||
|
|
||||||
|
//! Returns (=size) of the texture.
|
||||||
|
virtual const core::dimension2d<u32>& 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();
|
||||||
|
|
||||||
|
u64 getTextureHandler() const { return (u64)Texture; }
|
||||||
|
|
||||||
|
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<u32> TextureSize;
|
||||||
|
core::dimension2d<u32> 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__
|
||||||
|
|
||||||
|
|
@ -33,7 +33,10 @@ namespace irr
|
|||||||
io::IFileSystem* io, CIrrDeviceSDL* device);
|
io::IFileSystem* io, CIrrDeviceSDL* device);
|
||||||
IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params,
|
IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params,
|
||||||
io::IFileSystem* io, CIrrDeviceSDL* device, u32 default_fb);
|
io::IFileSystem* io, CIrrDeviceSDL* device, u32 default_fb);
|
||||||
|
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||||
|
IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params,
|
||||||
|
io::IFileSystem* io, HWND window);
|
||||||
|
#endif
|
||||||
} // end namespace video
|
} // end namespace video
|
||||||
|
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
@ -577,6 +580,16 @@ void CIrrDeviceSDL::createDriver()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case video::EDT_DIRECT3D9:
|
||||||
|
{
|
||||||
|
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
|
||||||
|
VideoDriver = video::createDirectX9Driver(CreationParams, FileSystem, Info.info.win.window);
|
||||||
|
#else
|
||||||
|
os::Printer::log("No DirectX 9 support compiled in.", ELL_ERROR);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case video::EDT_NULL:
|
case video::EDT_NULL:
|
||||||
VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
|
VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user