Purging DirectX libraries (3D, sound, input).

This commit is contained in:
Isilin 2019-04-13 13:53:22 +02:00
parent edb19ee4d8
commit 790e55bf0c
211 changed files with 1346 additions and 31376 deletions

View file

@ -1055,7 +1055,7 @@ Windows client build:
- find codebis -type f -name "*.rc" -exec unix2dos {} \;
- mkdir -p build
- cd build
- wine cmake.exe -DWITH_RYZOM_CUSTOM_PATCH_SERVER=ON -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_PATCH=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_TOOLS=OFF -DWITH_TOOLS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_LUA53=ON -DWITH_LUA51=OFF -DWITH_STLPORT=OFF -DWITH_DRIVER_DSOUND=ON -G "NMake Makefiles JOM" -DWITH_STATIC=ON -DWITH_STATIC_DRIVERS=ON -DWITH_DRIVER_OPENAL=OFF -DWITH_DRIVER_DSOUND=ON -DWITH_DRIVER_XAUDIO2=ON -DWITH_DRIVER_FMOD=ON -DWITH_DRIVER_DIRECT3D=ON ../codebis
- wine cmake.exe -DWITH_RYZOM_CUSTOM_PATCH_SERVER=ON -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_PATCH=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_TOOLS=OFF -DWITH_TOOLS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_LUA53=ON -DWITH_LUA51=OFF -DWITH_STLPORT=OFF -G "NMake Makefiles JOM" -DWITH_STATIC=ON -DWITH_STATIC_DRIVERS=ON -DWITH_DRIVER_OPENAL=OFF -DWITH_DRIVER_FMOD=ON ../codebis
- wine jom.exe
artifacts:
name: "khanat-client-windows-$CI_COMMIT_REF_NAME"

View file

@ -10,10 +10,6 @@ MACRO(NL_CONFIGURE_CHECKS)
SET(NL_OPENGLES_AVAILABLE 1)
ENDIF()
IF(WITH_DRIVER_DIRECT3D)
SET(NL_DIRECT3D_AVAILABLE 1)
ENDIF()
# sound drivers
IF(WITH_DRIVER_FMOD)
SET(NL_FMOD_AVAILABLE 1)
@ -23,14 +19,6 @@ MACRO(NL_CONFIGURE_CHECKS)
SET(NL_OPENAL_AVAILABLE 1)
ENDIF()
IF(WITH_DRIVER_DSOUND)
SET(NL_DSOUND_AVAILABLE 1)
ENDIF()
IF(WITH_DRIVER_XAUDIO2)
SET(NL_XAUDIO2_AVAILABLE 1)
ENDIF()
IF(NOT RYZOM_VERSION_MAJOR)
SET(RYZOM_VERSION_MAJOR ${NL_VERSION_MAJOR})
SET(RYZOM_VERSION_MINOR ${NL_VERSION_MINOR})

View file

@ -1,6 +1,3 @@
# - Find DirectInput
# Find the DirectSound includes and libraries
#
# MAXSDK_DIR - 3DSMAX SDK root directory
# MAXSDK_INCLUDE_DIR - where to find baseinterface.h
# MAXSDK_LIBRARIES - List of libraries when using 3DSMAX.

View file

@ -1,36 +0,0 @@
# - Find DirectSound
# Find the DirectSound includes and libraries
#
# DSOUND_INCLUDE_DIR - where to find dsound.h
# DSOUND_LIBRARIES - List of libraries when using dsound.
# DSOUND_FOUND - True if dsound found.
if(DSOUND_INCLUDE_DIR)
# Already in cache, be silent
set(DSOUND_FIND_QUIETLY TRUE)
ENDIF()
find_path(DSOUND_INCLUDE_DIR dsound.h
"$ENV{DXSDK_DIR}"
"$ENV{DXSDK_DIR}/Include"
)
find_library(DSOUND_LIBRARY dsound
"$ENV{DXSDK_DIR}"
"$ENV{DXSDK_DIR}/Lib"
"$ENV{DXSDK_DIR}/Lib/x86"
)
# Handle the QUIETLY and REQUIRED arguments and set DSOUND_FOUND to TRUE if
# all listed variables are TRUE.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(DSOUND DEFAULT_MSG
DSOUND_INCLUDE_DIR DSOUND_LIBRARY)
if(DSOUND_FOUND)
set(DSOUND_LIBRARIES ${DSOUND_LIBRARY})
ELSE()
set(DSOUND_LIBRARIES)
ENDIF()
mark_as_advanced(DSOUND_INCLUDE_DIR DSOUND_LIBRARY)

View file

@ -1,69 +0,0 @@
# - Find DirectX
# Find the DirectX includes and libraries
#
# DXSDK_INCLUDE_DIR - where to find baseinterface.h
# DXSDK_LIBRARIES - List of libraries when using 3DSMAX.
# DXSDK_FOUND - True if MAX SDK found.
IF(DXSDK_DIR)
# Already in cache, be silent
SET(DXSDK_FIND_QUIETLY TRUE)
ENDIF()
FIND_PATH(DXSDK_DIR
"Include/dxsdkver.h"
PATHS
"$ENV{DXSDK_DIR}"
"C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)"
"C:/Program Files/Microsoft DirectX SDK (June 2010)"
"C:/Program Files (x86)/Microsoft DirectX SDK (February 2010)"
"C:/Program Files/Microsoft DirectX SDK (February 2010)"
"C:/Program Files (x86)/Microsoft DirectX SDK (November 2007)"
"C:/Program Files/Microsoft DirectX SDK (November 2007)"
"C:/Program Files (x86)/Microsoft DirectX SDK"
"C:/Program Files/Microsoft DirectX SDK"
)
MACRO(FIND_DXSDK_LIBRARY MYLIBRARY MYLIBRARYNAME)
FIND_LIBRARY(${MYLIBRARY}
NAMES ${MYLIBRARYNAME}
HINTS
"${DXSDK_LIBRARY_DIR}"
)
ENDMACRO()
IF(DXSDK_DIR)
SET(DXSDK_INCLUDE_DIR "${DXSDK_DIR}/Include")
IF(TARGET_X64)
SET(DXSDK_LIBRARY_DIRS ${DXSDK_DIR}/Lib/x64 ${DXSDK_DIR}/lib/amd64)
ELSE()
SET(DXSDK_LIBRARY_DIRS ${DXSDK_DIR}/Lib/x86 ${DXSDK_DIR}/lib)
ENDIF()
FIND_PATH(DXSDK_LIBRARY_DIR
dxguid.lib
PATHS
${DXSDK_LIBRARY_DIRS})
FIND_DXSDK_LIBRARY(DXSDK_GUID_LIBRARY dxguid)
FIND_DXSDK_LIBRARY(DXSDK_DINPUT_LIBRARY dinput8)
FIND_DXSDK_LIBRARY(DXSDK_DSOUND_LIBRARY dsound)
FIND_DXSDK_LIBRARY(DXSDK_XAUDIO_LIBRARY x3daudio)
FIND_DXSDK_LIBRARY(DXSDK_D3DX9_LIBRARY d3dx9)
FIND_DXSDK_LIBRARY(DXSDK_D3D9_LIBRARY d3d9)
ENDIF()
# Handle the QUIETLY and REQUIRED arguments and set DXSDK_FOUND to TRUE if
# all listed variables are TRUE.
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DirectXSDK DEFAULT_MSG DXSDK_DIR DXSDK_GUID_LIBRARY DXSDK_DINPUT_LIBRARY)
MARK_AS_ADVANCED(DXSDK_INCLUDE_DIR
DXSDK_GUID_LIBRARY
DXSDK_DINPUT_LIBRARY
DXSDK_DSOUND_LIBRARY
DXSDK_XAUDIO_LIBRARY
DXSDK_D3DX9_LIBRARY
DXSDK_D3D9_LIBRARY)

View file

@ -30,12 +30,16 @@ ELSE()
FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES libmysql mysqlclient
PATHS
$ENV{ProgramFiles}/MySQL/*/lib/opt
$ENV{SystemDrive}/MySQL/*/lib/opt)
$ENV{SystemDrive}/MySQL/*/lib/opt
$ENV{ProgramFiles}/MySQL/*/lib
$ENV{SystemDrive}/MySQL/*/lib)
FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES libmysqld mysqlclientd
PATHS
$ENV{ProgramFiles}/MySQL/*/lib/opt
$ENV{SystemDrive}/MySQL/*/lib/opt)
$ENV{SystemDrive}/MySQL/*/lib/opt
$ENV{ProgramFiles}/MySQL/*/lib
$ENV{SystemDrive}/MySQL/*/lib)
ELSE()
FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient
PATHS

View file

@ -122,12 +122,6 @@ ENDMACRO(NL_ADD_RUNTIME_FLAGS)
MACRO(NL_ADD_STATIC_VID_DRIVERS name)
IF(WITH_STATIC_DRIVERS)
IF(WIN32)
IF(WITH_DRIVER_DIRECT3D)
TARGET_LINK_LIBRARIES(${name} nel_drv_direct3d_win)
ENDIF()
ENDIF()
IF(WITH_DRIVER_OPENGL)
IF(WIN32)
TARGET_LINK_LIBRARIES(${name} nel_drv_opengl_win)
@ -149,14 +143,6 @@ ENDMACRO(NL_ADD_STATIC_VID_DRIVERS)
MACRO(NL_ADD_STATIC_SND_DRIVERS name)
IF(WITH_STATIC_DRIVERS)
IF(WIN32)
IF(WITH_DRIVER_DSOUND)
TARGET_LINK_LIBRARIES(${name} nel_drv_dsound_win)
ENDIF()
IF(WITH_DRIVER_XAUDIO2)
TARGET_LINK_LIBRARIES(${name} nel_drv_xaudio2_win)
ENDIF()
IF(WITH_DRIVER_OPENAL)
TARGET_LINK_LIBRARIES(${name} nel_drv_openal_win)
ENDIF()
@ -299,11 +285,8 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
###
OPTION(WITH_DRIVER_OPENGL "Build OpenGL Driver (3D)" ON )
OPTION(WITH_DRIVER_OPENGLES "Build OpenGL ES Driver (3D)" OFF)
OPTION(WITH_DRIVER_DIRECT3D "Build Direct3D Driver (3D)" OFF)
OPTION(WITH_DRIVER_OPENAL "Build OpenAL Driver (Sound)" ON )
OPTION(WITH_DRIVER_FMOD "Build FMOD Driver (Sound)" OFF)
OPTION(WITH_DRIVER_DSOUND "Build DirectSound Driver (Sound)" OFF)
OPTION(WITH_DRIVER_XAUDIO2 "Build XAudio2 Driver (Sound)" OFF)
###
# Optional support
@ -1198,14 +1181,6 @@ MACRO(SETUP_EXTERNAL)
INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR})
ENDIF()
IF(WIN32)
# Must include DXSDK before WINSDK
FIND_PACKAGE(DirectXSDK REQUIRED)
# IF(DXSDK_INCLUDE_DIR)
# INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR})
# ENDIF()
ENDIF()
IF(MSVC)
FIND_PACKAGE(MSVC REQUIRED)
FIND_PACKAGE(WindowsSDK REQUIRED)

View file

@ -3,12 +3,9 @@
#cmakedefine NL_OPENGL_AVAILABLE ${NL_OPENGL_AVAILABLE}
#cmakedefine NL_OPENGLES_AVAILABLE ${NL_OPENGLES_AVAILABLE}
#cmakedefine NL_DIRECT3D_AVAILABLE ${NL_DIRECT3D_AVAILABLE}
#cmakedefine NL_FMOD_AVAILABLE ${NL_FMOD_AVAILABLE}
#cmakedefine NL_OPENAL_AVAILABLE ${NL_OPENAL_AVAILABLE}
#cmakedefine NL_DSOUND_AVAILABLE ${NL_DSOUND_AVAILABLE}
#cmakedefine NL_XAUDIO2_AVAILABLE ${NL_XAUDIO2_AVAILABLE}
#cmakedefine NL_STEREO_AVAILABLE ${NL_STEREO_AVAILABLE}

View file

@ -37,7 +37,7 @@ class CTextureUser;
//---------------------------------------- CBloomEffect -----------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
// CBloomEffect class apply a bloom effect on the whole scene. The whole scene is rendered in a
// render target (a Frame Buffer Object on OpengL, the normal back buffer in Direct3D) which is stretched
// render target (a Frame Buffer Object on OpengL) which is stretched
// in a 256*256 another render target.
// We apply a horizontal blur on this 256*256 render target, then a vertical blur on the result of this first pass.
// The final blurred render target is blend with the initial render target of scene, with a dest + src - dest*src
@ -93,7 +93,6 @@ public:
// to keep Z tests correct.
// This method is called at the end of interfaces display in the main loop, to display final render target
// (with added interfaces) in the color frame buffer.
// NB : In Direct3D, the final render target is displayed at the end of endBloom call.
// void endInterfacesDisplayBloom();
private:

View file

@ -188,9 +188,6 @@ public:
/// Before rendering via a driver in a thread, must activate() (per thread).
virtual bool activate() = 0;
// Test if the device is lost. Can only happen with D3D.
// The calling application may skip some part of its rendering when it is the case (this is not a requirement, but may save cpu for other applications)
virtual bool isLost() const = 0;
/// Return true if driver is still active. Return false else. If he user close the window, must return false.
virtual bool isActive() = 0;
@ -437,8 +434,7 @@ public:
virtual uint getNbTextureStages() const = 0;
/** Get max number of per stage constant that can be used simultaneously.
* This will usually match the number of texture stages, but with a D3D driver, this feature is not available most of the time
* so it is emulated. If pixel shaders are available this will be fully supported.
* This will usually match the number of texture stages. If pixel shaders are available this will be fully supported.
* Under OpenGL this simply returns the maximum number of texture stages (getNbTextureStages) in both return values.
*/
virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0;
@ -1363,7 +1359,7 @@ public:
*/
virtual bool setAdapter(uint adapter) = 0;
/** Tell if the vertex color memory format is RGBA (openGL) or BGRA (directx)
/** Tell if the vertex color memory format is RGBA (openGL) or BGRA
* BGRA :
* *****************************************************************
* Offset: * 0 * 1 * 2 * 3 *
@ -1446,4 +1442,3 @@ private:
}
#endif // NL_DRV_H

View file

@ -133,8 +133,6 @@ public:
virtual ~CDriverUser();
// @}
virtual bool isLost() const;
/// \name Window / driver management.
// @{

View file

@ -27,11 +27,9 @@
#if defined (NL_COMP_MINGW)
# define NL3D_GL_DLL_NAME "libnel_drv_opengl_win"
# define NL3D_GLES_DLL_NAME "libnel_drv_opengles_win"
# define NL3D_D3D_DLL_NAME "libnel_drv_direct3d_win"
#elif defined (NL_OS_WINDOWS)
# define NL3D_GL_DLL_NAME "nel_drv_opengl_win"
# define NL3D_GLES_DLL_NAME "nel_drv_opengles_win"
# define NL3D_D3D_DLL_NAME "nel_drv_direct3d_win"
#elif defined (NL_OS_UNIX)
# define NL3D_GL_DLL_NAME "nel_drv_opengl"
# define NL3D_GLES_DLL_NAME "nel_drv_opengles"
@ -100,34 +98,6 @@ struct EDruOpenglEsDriverCantCreateDriver : public EDru
EDruOpenglEsDriverCantCreateDriver() : EDru( NL3D_GLES_DLL_NAME " can't create driver" ) {}
};
#ifdef NL_OS_WINDOWS
// Direct3D
struct EDruDirect3dDriverNotFound : public EDru
{
EDruDirect3dDriverNotFound() : EDru( NL3D_D3D_DLL_NAME " not found" ) {}
};
struct EDruDirect3dDriverCorrupted : public EDru
{
EDruDirect3dDriverCorrupted() : EDru( "Can't get NL3D_createIDriverInstance from " NL3D_D3D_DLL_NAME " (Bad dll?)" ) {}
};
struct EDruDirect3dDriverOldVersion : public EDru
{
EDruDirect3dDriverOldVersion() : EDru( NL3D_D3D_DLL_NAME " is a too old version. Ask for a more recent file" ) {}
};
struct EDruDirect3dDriverUnknownVersion : public EDru
{
EDruDirect3dDriverUnknownVersion() : EDru( NL3D_D3D_DLL_NAME " is more recent than the application" ) {}
};
struct EDruDirect3dDriverCantCreateDriver : public EDru
{
EDruDirect3dDriverCantCreateDriver() : EDru( NL3D_D3D_DLL_NAME " can't create driver" ) {}
};
#endif // NL_OS_WINDOWS
/// The driver Utilities class of static.
class CDRU
{
@ -139,11 +109,6 @@ public:
/// Portable Function which create a GL ES Driver (using gl dll...).
static IDriver *createGlEsDriver() throw(EDru);
#ifdef NL_OS_WINDOWS
/// Windows Function which create a Direct3d Driver.
static IDriver *createD3DDriver() throw(EDru);
#endif // NL_OS_WINDOWS
/// \name 2D render.
// @{
/// Draw a bitmap 2D. Warning: this is slow...

View file

@ -223,8 +223,7 @@ public:
/** \name Texture Addressing Modes. They are valid only with the normal texture shader.
* All modes are not supported everywhere, so you should check for it in the driver.
* The modes are similar to those introduced with DirectX 8.0 Pixel Shaders and OpenGL
* TEXTURE_SHADERS_NV
* The modes are similar to those introduced with OpenGL TEXTURE_SHADERS_NV
*/
// @{
enum TTexAddressingMode {
@ -416,7 +415,7 @@ public:
*
* For compatibility problems:
* - no scaling is allowed (some cards do not implement this well).
* - Texture can be the source only for Arg0 (DirectX restriction). nlassert...
* - Texture can be the source only for Arg0. nlassert...
*
* NB: for Alpha Aguments, only operands SrcAlpha and InvSrcAlpha are valid (nlassert..).
*/

View file

@ -64,7 +64,7 @@ public:
*
* You can access the driver with CNELU::Driver.
*/
static bool initDriver(uint w, uint h, uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen=false, bool direct3d=false) throw(EDru);
static bool initDriver(uint w, uint h, uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen=false) throw(EDru);
/** Init all that we need for a Scene.
* - register scene basics models,
@ -108,7 +108,7 @@ public:
* - initScene();
* - initEventServer();
*/
static bool init(uint w, uint h, CViewport viewport=CViewport(), uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen = false, bool direct3d = false) throw(EDru);
static bool init(uint w, uint h, CViewport viewport=CViewport(), uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen = false) throw(EDru);
/** Delete all:
* - releaseEventServer();

View file

@ -148,22 +148,6 @@ public:
// nel - 0x31,type,bitfield
nelvp = 0x31010001, // VP supported by CVertexProgramParser, similar to arbvp1, can be translated to vs_1_1
// direct3d - 0xD9,type,major,minor
// vertex programs
vs_1_1 = 0xD9010101,
vs_2_0 = 0xD9010200,
// vs_2_sw = 0xD9010201, // not sure...
// vs_2_x = 0xD9010202, // not sure...
// vs_3_0 = 0xD9010300, // not supported
// pixel programs
ps_1_1 = 0xD9020101,
ps_1_2 = 0xD9020102,
ps_1_3 = 0xD9020103,
ps_1_4 = 0xD9020104,
ps_2_0 = 0xD9020200,
// ps_2_x = 0xD9020201, // not sure...
// ps_3_0 = 0xD9020300, // not supported
// opengl - 0x61,type,bitfield
// vertex programs
// vp20 = 0x61010001, // NV_vertex_program1_1, outdated
@ -227,7 +211,7 @@ public:
inline size_t addSource(CSource *source) { nlassert(!m_Source); m_Sources.push_back(source); return (m_Sources.size() - 1); }
inline void removeSource(size_t i) { nlassert(!m_Source); m_Sources.erase(m_Sources.begin() + i); }
// Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0
// Get the idx of a parameter (ogl: uniform, etcetera) by name. Invalid name returns ~0
inline uint getUniformIndex(const char *name) const { return m_DrvInfo->getUniformIndex(name); };
inline uint getUniformIndex(const std::string &name) const { return m_DrvInfo->getUniformIndex(name.c_str()); };
inline uint getUniformIndex(CProgramIndex::TName name) const { return m_Index.Indices[name]; }

View file

@ -287,7 +287,7 @@ public:
// misc
// used by colors only : set the internal color format. useful to write in vertex buffer (format differs between D3D & OpenGL)
// used by colors only : set the internal color format. useful to write in vertex buffer
virtual void setColorType(CVertexBuffer::TVertexColorType /* type */) {}
protected:

View file

@ -470,7 +470,7 @@ public:
/** See if filter mode or wrap mode have been touched.
* If this is the case, the driver should resetup them for that texture (If driver stores filter & wrap mode
* per texture (OpenGL) rather than globally (D3D))
* per texture (OpenGL))
*/
bool filterOrWrapModeTouched() const { return _FilterOrWrapModeTouched; }

View file

@ -140,7 +140,7 @@ public:
enum TStencilFunc { never = 0, less, lessequal, equal, notequal, greaterequal, greater, always};
// Existing drivers
enum TDriver { Direct3d = 0, OpenGl, OpenGlEs };
enum TDriver { OpenGl = 1, OpenGlEs };
public:
/// The EventServer of this driver. Init after setDisplay()!!
@ -157,10 +157,6 @@ public:
virtual ~UDriver();
// @}
// Test if the device is lost. Can only happen with D3D.
// The calling application may skip some part of its rendering when it is the case (this is not a requirement, but may save cpu for other applications)
virtual bool isLost() const = 0;
/// \name Disable Hardware Feature
/** Disable some Feature that may be supported by the Hardware
@ -200,7 +196,6 @@ public:
virtual void showWindow(bool show = true)=0;
/* Pass in dialog box mode. After having called this method, you can use normal GUI.
* In fullscreen under direct3d, the main 3d window is minimized.
*
* \code
* Driver->beginDialogMode();
@ -215,7 +210,6 @@ public:
virtual void beginDialogMode() =0;
/* Leave the dialog box mode. After having called this method, you can't use normal GUI anymore.
* In fullscreen under direct3d, the main 3d window is maximized.
*/
virtual void endDialogMode() =0;
@ -841,7 +835,7 @@ public:
/**
* This is the static function which build a UDriver, the root for all 3D functions.
*/
static UDriver *createDriver(uintptr_t windowIcon = 0, bool direct3d = false, emptyProc exitFunc = 0);
static UDriver *createDriver(uintptr_t windowIcon = 0, emptyProc exitFunc = 0);
static UDriver *createDriver(uintptr_t windowIcon, TDriver driver, emptyProc exitFunc = 0);
/**

View file

@ -178,7 +178,7 @@ public:
/**
* Value type, there is 13 kind of value type as in DirectX8 and gl_vertex_program used in exteneded mode
* Value type, there is 13 kind of value type as in gl_vertex_program used in exteneded mode
*/
enum TType
{
@ -1267,24 +1267,3 @@ inline void CVertexBuffer::unlock () const
#endif // NL_VERTEX_BUFFER_H
/* End of vertex_buffer.h */

View file

@ -24,10 +24,10 @@
/**
* This class is a vertex program.
*
* D3D / OPENGL compatibility notes:
* OPENGL compatibility notes:
* ---------------------------------
*
* To make your program compatible with D3D and OPENGL nel drivers, please follow thoses directives to write your vertex programs
* To make your program compatible with OPENGL nel drivers, please follow thoses directives to write your vertex programs
*
* - Use only v[0], v[1] etc.. syntax for input registers. Don't use v0, v1 or v[OPOS] etc..
* - Use only c[0], c[1] etc.. syntax for constant registers. Don't use c0, c1 etc..
@ -39,11 +39,6 @@
* - Don't use macros.
*
* -> Thoses programs work without any change under OpenGL.
* -> Direct3D driver implementation will have to modify the syntax on the fly before the setup like this:
* - "v[0]" must be changed in "v0" etc..
* - "o[HPOS]" must be changed in oPos etc..
* - Semicolon must be changed in line return character.
* - ARL instruction must be changed in MOV.
*
* Behaviour of LOG may change depending on implementation: You can only expect to have dest.z = log2(abs(src.w)).
* LIT may or may not clamp the specular exponent to [-128, 128] (not done when EXT_vertex_shader is used for example ..)
@ -166,7 +161,7 @@ struct CVPInstruction
enum EOpcode
{
MOV = 0,
ARL, // in D3D, is equivalent to MOV
ARL,
MUL,
ADD,
MAD,
@ -266,4 +261,3 @@ private:
#endif

View file

@ -46,7 +46,6 @@ public:
/// Standard PCM format.
FormatPcm = 1,
/// Intel/DVI ADPCM format, only available for 1 channel at 16 bits per sample, encoded at 4 bits per sample.
/// This is only implemented in the DSound and XAudio2 driver.
FormatDviAdpcm = 11,
/// No format set. Used when a TBufferFormat value has not been set to any value yet.
FormatNotSet = (~0),

View file

@ -64,16 +64,12 @@ public:
/// Driver Creation Choice
enum TDriver
{
/// DriverAuto automatically picks the most awesome driver (picks first available in this order: FMod, OpenAl, XAudio2, DSound).
/// DriverAuto automatically picks the most awesome driver (picks first available in this order: FMod, OpenAl).
DriverAuto = 0,
/// DriverFMod is a driver that runs on FMod, nice quality, but not fully implemented.
DriverFMod,
/// DriverOpenAl is the recommended driver, especially if you have hardware sound acceleration.
DriverOpenAl,
/// DriverDSound is deprecated.
DriverDSound,
/// DriverXAudio2 runs on a fully software-based audio processing API without artificial limits.
DriverXAudio2,
NumDrivers
};
@ -84,11 +80,11 @@ public:
OptionEnvironmentEffects = 0x01,
/// Allow the user to use the ADPCM encoding. (verify availability with getOption)
OptionAllowADPCM = 0x02,
/// Force software buffering (always true for XAudio2).
/// Force software buffering.
OptionSoftwareBuffer = 0x04,
/**
* Configuration to use manual or API (directx or open AL) rolloff factor.
* 0 => API (directx, open AL, etc) rollOff control.
* Configuration to use manual or API (open AL) rolloff factor.
* 0 => API (open AL, etc) rollOff control.
* ISource::setAlpha() will fail.
* IListener::setRollOffFactor() works
* 1 => Manual rollOff control

View file

@ -59,9 +59,7 @@
/**
* The maximum allowed pitch is specified as 8.0f.
* Tests indicate that with OpenAL the pitch can be set to 8.0f,
* and with FMod to somewhere around 9.0f. The XAudio2 implementation
* uses this value directly to configure the maximum pitch, which can
* technically be as high as XAUDIO2_MAX_FREQ_RATIO which is 1024.0f.
* and with FMod to somewhere around 9.0f.
* If you pass a value outside the minimum and maximum bounds,
* it will automatically be clamped between them.
* \brief Maximum allowed pitch.

View file

@ -82,8 +82,6 @@ public:
DriverAuto = 0,
DriverFMod,
DriverOpenAl,
DriverDSound,
DriverXAudio2,
NumDrivers
};

View file

@ -108,9 +108,8 @@ int main(int argc, char **argv)
#ifdef NL_OS_WINDOWS
icon = (uint)LoadIcon(ghInstance,MAKEINTRESOURCE(IDI_ICON1));
#endif
bool useD3D = false;
#ifdef NL_INDEX_BUFFER_H //new 3d
NL3D::UDriver *driver = NL3D::UDriver::createDriver(icon,useD3D);
NL3D::UDriver *driver = NL3D::UDriver::createDriver(icon);
#else
driver = NL3D::UDriver::createDriver(icon);
#endif
@ -328,5 +327,3 @@ bool handleCheck(const CEGUI::EventArgs& e)
return true;
}

View file

@ -54,7 +54,7 @@ int main(int argc, char **argv)
#endif
{
// look at 3dinit example
CNELU::init (800, 600, CViewport(), 32, true, 0, false, false);
CNELU::init (800, 600, CViewport(), 32, true, 0, false);
NLMISC::CPath::addSearchPath(FONT_DIR);

View file

@ -78,17 +78,8 @@ void CGraphicsViewport::init(CGraphicsConfig *graphicsConfig)
// create the driver
nlassert(!m_Driver);
m_Direct3D = false;
std::string driver = m_GraphicsConfig->getGraphicsDriver();
if (driver == "Direct3D") m_Direct3D = true; //m_Driver = Direct3D;
else if (driver == "OpenGL") m_Direct3D = false; //m_Driver = OpenGL;
else
{
nlwarning("Invalid driver specified, defaulting to OpenGL");
//m_Configuration->getConfigFile().getVar("GraphicsDriver").forceAsString("OpenGL");
//m_Driver = OpenGL;
}
m_Driver = UDriver::createDriver(NULL, m_Direct3D, NULL);
m_Driver = UDriver::createDriver(NULL, NULL);
nlassert(m_Driver);
// initialize the window with config file values
@ -221,13 +212,12 @@ void CGraphicsViewport::saveScreenshot(const string &name, bool jpg, bool png, b
void CGraphicsViewport::resizeEvent(QResizeEvent *resizeEvent)
{
QWidget::resizeEvent(resizeEvent);
if (m_Driver && !m_Direct3D)
if (m_Driver)
{
m_Driver->setMode(UDriver::CMode(resizeEvent->size().width(), resizeEvent->size().height(), 32));
}
// The OpenGL driver does not resize automatically.
// The Direct3D driver breaks the window mode to include window borders when calling setMode windowed.
// Resizing the window after switching drivers a few times becomes slow.
// There is probably something inside the drivers not being released properly.

View file

@ -91,8 +91,6 @@ private:
NL3D::UTextContext *m_TextContext;
NL3D::UScene *m_Scene;
bool m_Direct3D;
private:
CGraphicsViewport(const CGraphicsViewport &);
CGraphicsViewport &operator=(const CGraphicsViewport &);

View file

@ -55,9 +55,9 @@ LoginBackground = "login_background.dds";
// Graphics //////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Use OpenGL or Direct3D (Windows)
// Use OpenGL (Windows)
GraphicsEnabled = 1;
GraphicsDrivers = { "OpenGL", "Direct3D" };
GraphicsDrivers = { "OpenGL" };
GraphicsDriver = "OpenGL";
// Resolution of the screen
@ -134,9 +134,9 @@ FpsSmoothing = 64;
// Sound /////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// The sound driver, choose between "Auto", "FMod", "DSound" and "OpenAl"
// The sound driver, choose between "Auto", "FMod" and "OpenAl"
SoundEnabled = 1;
SoundDrivers = { "Auto", "OpenAL", "XAudio2", "FMod", "DSound" };
SoundDrivers = { "Auto", "OpenAL", "FMod" };
SoundDriver = "OpenAL";
SoundDevice = "";
SoundMaxTrack = 48;

View file

@ -67,8 +67,6 @@ void Init()
printf("Select NLSOUND Driver:\n");
printf(" [1] FMod\n");
printf(" [2] OpenAl\n");
printf(" [3] DSound\n");
printf(" [4] XAudio2\n");
printf("> ");
int selection = getchar();
printf("\n");

View file

@ -78,8 +78,6 @@ static void initSample()
printf("Select NLSOUND Driver:\n");
printf(" [1] FMod\n");
printf(" [2] OpenAl\n");
printf(" [3] DSound\n");
printf(" [4] XAudio2\n");
printf("> ");
int selection = getchar(); getchar();
printf("\n");

View file

@ -70,8 +70,6 @@ static void initSample()
printf("Select NLSOUND Driver:\n");
printf(" [1] FMod\n");
printf(" [2] OpenAl\n");
printf(" [3] DSound\n");
printf(" [4] XAudio2\n");
printf("> ");
int selection = getchar(); getchar();
printf("\n");

View file

@ -120,7 +120,7 @@ void CCoarseMeshManager::flushRender (IDriver *drv)
H_AUTO( NL3D_StaticLod_Render );
if (_Meshs.empty()) return;
// if the driver is BGRA (Direct3D), then invert color format
// if the driver is BGRA, then invert color format
if(!_VBuffer.isResident() && drv->getVertexColorFormat()==CVertexBuffer::TBGRA)
{
// since actually empty, no need to swap current memory

View file

@ -5,9 +5,3 @@ ENDIF()
IF(WITH_DRIVER_OPENGLES)
ADD_SUBDIRECTORY(opengles)
ENDIF()
IF(WIN32)
IF(WITH_DRIVER_DIRECT3D)
ADD_SUBDIRECTORY(direct3d)
ENDIF()
ENDIF()

View file

@ -1,24 +0,0 @@
FILE(GLOB SRC *.cpp *.h *.def *.rc)
NL_TARGET_DRIVER(nel_drv_direct3d_win ${SRC})
INCLUDE_DIRECTORIES(BEFORE ${DXSDK_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(nel_drv_direct3d_win nel3d nelmisc ${DXSDK_D3DX9_LIBRARY} ${DXSDK_D3D9_LIBRARY})
NL_DEFAULT_PROPS(nel_drv_direct3d_win "NeL, Driver, Video: Direct3D")
NL_ADD_RUNTIME_FLAGS(nel_drv_direct3d_win)
NL_ADD_LIB_SUFFIX(nel_drv_direct3d_win)
ADD_DEFINITIONS(-DRIVER_DIRECT3D_EXPORTS)
IF(WITH_PCH)
ADD_NATIVE_PRECOMPILED_HEADER(nel_drv_direct3d_win ${CMAKE_CURRENT_SOURCE_DIR}/stddirect3d.h ${CMAKE_CURRENT_SOURCE_DIR}/stddirect3d.cpp)
ENDIF()
IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS)
INSTALL(TARGETS nel_drv_direct3d_win LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION ${NL_LIB_PREFIX} RUNTIME DESTINATION ${NL_DRIVER_PREFIX} COMPONENT drivers3d)
IF(WITH_MAXPLUGIN)
INSTALL(TARGETS nel_drv_direct3d_win RUNTIME DESTINATION maxplugin COMPONENT drivers3d)
ENDIF()
ENDIF()

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
EXPORTS
NL3D_createIDriverInstance
NL3D_interfaceVersion

File diff suppressed because it is too large Load diff

View file

@ -1,515 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "nel/3d/index_buffer.h"
#include "nel/3d/light.h"
#include "nel/misc/rect.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// ***************************************************************************
CIBDrvInfosD3D::CIBDrvInfosD3D(CDriverD3D *drv, ItIBDrvInfoPtrList it, CIndexBuffer *ib) : IIBDrvInfos(drv, it, ib)
{
H_AUTO_D3D(CIBDrvInfosD3D_CIBDrvInfosD3D)
Driver = drv;
IndexBuffer = NULL;
VolatileIndexBuffer = NULL;
}
// ***************************************************************************
uint indexCount=0;
CIBDrvInfosD3D::~CIBDrvInfosD3D()
{
H_AUTO_D3D(CIBDrvInfosD3D_CIBDrvInfosD3DDtor);
// Restore non resident memory
if (IndexBufferPtr)
{
IndexBufferPtr->setLocation(CIndexBuffer::NotResident);
IndexBufferPtr= NULL;
}
// release index buffer
if (IndexBuffer && !Volatile)
{
if (Driver)
{
if (Driver->_IndexBufferCache.IndexBuffer == IndexBuffer)
{
Driver->_IndexBufferCache.IndexBuffer = NULL;
Driver->touchRenderVariable(&Driver->_IndexBufferCache);
}
}
indexCount--;
IndexBuffer->Release();
}
}
// ***************************************************************************
void *CIBDrvInfosD3D::lock (uint first, uint last, bool readOnly)
{
H_AUTO_D3D(CIBDrvInfosD3D_lock);
nlassert (first != last);
CDriverD3D *driver = static_cast<CDriverD3D*>(_Driver);
if (driver->getMaxVertexIndex() <= 0xffff && getFormat() != CIndexBuffer::Indices16)
{
nlassert(getFormat() == CIndexBuffer::Indices32);
// 32-bit index not supported -> uses RAM mirror
nlassert(!RamVersion.empty());
return &RamVersion[0];
}
else
{
if (Volatile)
{
// Lock the good buffer
CVolatileIndexBuffer **buffer = NULL;
if (getFormat() == CIndexBuffer::Indices16)
{
buffer = VolatileRAM ? (&driver->_VolatileIndexBuffer16RAM[driver->_CurrentRenderPass&1]):(&driver->_VolatileIndexBuffer16AGP[driver->_CurrentRenderPass&1]);
}
else if (getFormat() == CIndexBuffer::Indices32)
{
buffer = VolatileRAM ? (&driver->_VolatileIndexBuffer32RAM[driver->_CurrentRenderPass&1]):(&driver->_VolatileIndexBuffer32AGP[driver->_CurrentRenderPass&1]);
}
else
{
nlassert(0);
}
void *ptr = (*buffer)->lock ((last-first)*getIndexNumBytes(), Offset);
if (!ptr)
{
// buffer full, swap them
CVolatileIndexBuffer **bufferOther;
if (getFormat() == CIndexBuffer::Indices16)
{
bufferOther = VolatileRAM ? (&driver->_VolatileIndexBuffer16RAM[(driver->_CurrentRenderPass + 1) &1]):(&driver->_VolatileIndexBuffer16AGP[(driver->_CurrentRenderPass + 1 ) &1]);
}
else
{
bufferOther = VolatileRAM ? (&driver->_VolatileIndexBuffer32RAM[(driver->_CurrentRenderPass + 1) &1]):(&driver->_VolatileIndexBuffer32AGP[(driver->_CurrentRenderPass + 1 ) &1]);
}
std::swap(*buffer, *bufferOther);
(*buffer)->reset();
ptr = (*buffer)->lock ((last-first)*getIndexNumBytes(), Offset);
nlassert(ptr);
}
nlassert(!VolatileIndexBuffer);
VolatileIndexBuffer = *buffer;
IndexBuffer = (*buffer)->IndexBuffer;
ptr = (uint8 *) ptr - first * getIndexNumBytes();
// Current lock time
VolatileLockTime = driver->_CurrentRenderPass;
// Touch the index buffer
driver->touchRenderVariable (&driver->_IndexBufferCache);
return ptr;
}
else
{
nlassert (IndexBuffer);
// Lock Profile?
TTicks beforeLock = 0;
if(driver->_IBProfiling /*&& Hardware*/)
{
beforeLock= CTime::getPerformanceTime();
}
void *pbData;
HRESULT result = IndexBuffer->Lock ( first*getIndexNumBytes(), (last-first)*getIndexNumBytes(), &pbData, readOnly?D3DLOCK_READONLY:0);
nlassert(result == D3D_OK);
// Lock Profile?
if(driver->_IBProfiling /*&& Hardware*/)
{
TTicks afterLock;
afterLock= CTime::getPerformanceTime();
driver->appendIBLockProfile(afterLock-beforeLock, IndexBufferPtr);
}
if (result == D3D_OK) return pbData;
}
}
return NULL;
}
// ***************************************************************************
void CIBDrvInfosD3D::unlock (uint /* first */, uint /* last */)
{
H_AUTO_D3D(CIBDrvInfosD3D_unlock)
CDriverD3D *driver = static_cast<CDriverD3D*>(_Driver);
if (driver->getMaxVertexIndex() > 0xffff || getFormat() == CIndexBuffer::Indices16)
{
if (Volatile)
{
nlassert(VolatileIndexBuffer);
VolatileIndexBuffer->unlock ();
VolatileIndexBuffer = NULL;
}
else
{
if (IndexBuffer) IndexBuffer->Unlock ();
}
}
}
// ***************************************************************************
DWORD RemapIndexBufferUsage[CIndexBuffer::LocationCount]=
{
D3DUSAGE_DYNAMIC, // RAMResident
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, // AGPResident
D3DUSAGE_WRITEONLY, // VRAMResident
0, // Not used
};
// ***************************************************************************
D3DPOOL RemapIndexBufferPool[CIndexBuffer::LocationCount]=
{
D3DPOOL_SYSTEMMEM, // RAMResident
D3DPOOL_DEFAULT, // AGPResident
D3DPOOL_DEFAULT, // VRAMResident
D3DPOOL_DEFAULT, // Not used
};
// ***************************************************************************
bool CDriverD3D::activeIndexBuffer(CIndexBuffer& IB)
{
H_AUTO_D3D(CDriverD3D_activeIndexBuffer)
// Must not be locked
nlassert (!IB.isLocked());
// Must not be empty
if (IB.capacity() == 0)
return false;
const bool touched = (IB.getTouchFlags() & (CIndexBuffer::TouchedReserve|CIndexBuffer::TouchedIndexFormat)) != 0;
CIBDrvInfosD3D *info = static_cast<CIBDrvInfosD3D*>(static_cast<IIBDrvInfos*>(IB.DrvInfos));
// Volatile buffers must be filled at each pass (exception if emulated)
if (_MaxVertexIndex > 0xffff)
{
nlassertex (!info || !info->Volatile || IB.getKeepLocalMemory() || (info->VolatileLockTime == _CurrentRenderPass), ("Volatile buffers must be filled at each pass"));
}
// Build the driver info
if (touched)
{
// Delete previous index buffer info
if (IB.DrvInfos)
{
delete IB.DrvInfos;
nlassert (IB.DrvInfos == NULL);
}
// Rebuild it
_IBDrvInfos.push_front (NULL);
ItIBDrvInfoPtrList ite = _IBDrvInfos.begin();
info = new CIBDrvInfosD3D(this, ite, &IB);
*ite = info;
// Create the index buffer
const uint size = (uint)IB.capacity();
uint preferredMemory = 0;
if (_DisableHardwareIndexArrayAGP)
{
preferredMemory = CIndexBuffer::RAMResident;
info->Volatile = false;
}
else
{
switch (IB.getPreferredMemory ())
{
case CIndexBuffer::RAMPreferred:
preferredMemory = CIndexBuffer::RAMResident;
info->Volatile = false;
break;
case CIndexBuffer::AGPPreferred:
preferredMemory = CIndexBuffer::AGPResident;
info->Volatile = false;
break;
case CIndexBuffer::StaticPreferred:
if (getStaticMemoryToVRAM())
preferredMemory = CIndexBuffer::VRAMResident;
else
preferredMemory = CIndexBuffer::AGPResident;
info->Volatile = false;
break;
case CIndexBuffer::RAMVolatile:
preferredMemory = CIndexBuffer::RAMResident;
info->Volatile = true;
break;
case CIndexBuffer::AGPVolatile:
preferredMemory = CIndexBuffer::AGPResident;
info->Volatile = true;
break;
}
}
// if 32 bit index not supported, the index buffer will be reformated so return a RAM mirror
// Real index buffer will be allocated if indices are not modified (e.g a single lock is used to update the content)
if (_MaxVertexIndex <= 0xffff && IB.getFormat() == CIndexBuffer::Indices32)
{
info->RamVersion.resize(size);
info->IndexBuffer = NULL;
}
else
{
// Volatile index buffer
if (info->Volatile)
{
nlassert (info->IndexBuffer == NULL);
info->VolatileRAM = preferredMemory == CIndexBuffer::RAMResident;
}
else
{
// Offset will be 0
info->Offset = 0;
bool success = false;
do
{
success = _DeviceInterface->CreateIndexBuffer(size*IB.getIndexNumBytes(),
RemapIndexBufferUsage[preferredMemory],
IB.getFormat() == CIndexBuffer::Indices32 ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
RemapIndexBufferPool[preferredMemory],
&(info->IndexBuffer), NULL) == D3D_OK;
if (success)
break;
}
while (preferredMemory--);
if (!success)
return false;
++indexCount;
}
// Force the vertex buffer update
touchRenderVariable (&_IndexBufferCache);
}
// Release the local index buffer
IB.DrvInfos = info;
IB.setLocation((CIndexBuffer::TLocation)preferredMemory);
}
// Set the current index buffer
nlassert (info);
_LastIndexBufferInfo = info;
// Fill the buffer if in local memory
IB.fillBuffer ();
_CurrIndexBufferFormat = IB.getFormat();
// Set the index buffer
if (_MaxVertexIndex > 0xffff || IB.getFormat() == CIndexBuffer::Indices16)
{
setIndexBuffer (info->IndexBuffer, info->Offset);
}
return true;
}
// ***************************************************************************
bool CDriverD3D::supportIndexBufferHard() const
{
H_AUTO_D3D(CDriverD3D_supportIndexBufferHard);
return !_DisableHardwareIndexArrayAGP;
}
// ***************************************************************************
void CDriverD3D::disableHardwareIndexArrayAGP()
{
H_AUTO_D3D(CDriverD3D_disableHardwareIndexArrayAGP)
_DisableHardwareIndexArrayAGP = true;
}
// ***************************************************************************
// CVolatileIndexBuffer
// ***************************************************************************
CVolatileIndexBuffer::CVolatileIndexBuffer()
{
H_AUTO_D3D(CVolatileIndexBuffer_CVolatileIndexBuffer);
IndexBuffer = NULL;
Locked = false;
}
// ***************************************************************************
CVolatileIndexBuffer::~CVolatileIndexBuffer()
{
H_AUTO_D3D(CVolatileIndexBuffer_CVolatileIndexBufferDtor);
release ();
}
// ***************************************************************************
void CVolatileIndexBuffer::release ()
{
H_AUTO_D3D(CVolatileIndexBuffer_release);
if (IndexBuffer)
IndexBuffer->Release();
IndexBuffer = NULL;
}
// ***************************************************************************
void CVolatileIndexBuffer::init (CIndexBuffer::TLocation location, uint sizeInBytes, uint maxSize, CDriverD3D *driver, CIndexBuffer::TFormat format)
{
H_AUTO_D3D(CVolatileIndexBuffer_init);
release();
if (maxSize < sizeInBytes) maxSize = sizeInBytes;
// Init the buffer
Location = location;
Size = sizeInBytes;
MaxSize = maxSize;
Driver = driver;
nlassert(format == CIndexBuffer::Indices16 || format == CIndexBuffer::Indices32);
if (format == CIndexBuffer::Indices32)
{
// device must support 32 bits indices
nlassert(driver->_MaxVertexIndex > 0xffff);
}
D3DFORMAT d3dFormat = format == CIndexBuffer::Indices16 ? D3DFMT_INDEX16 : D3DFMT_INDEX32;
// Allocate the vertex buffer
if (Driver->_DeviceInterface->CreateIndexBuffer(sizeInBytes, RemapIndexBufferUsage[location],
d3dFormat, RemapIndexBufferPool[location], &IndexBuffer, NULL) != D3D_OK)
{
// Location in RAM must not failed
nlassert (location != CIndexBuffer::RAMResident);
// Allocate in RAM
nlverify (Driver->_DeviceInterface->CreateIndexBuffer(sizeInBytes, RemapIndexBufferUsage[CIndexBuffer::RAMResident],
d3dFormat, RemapIndexBufferPool[CIndexBuffer::RAMResident], &IndexBuffer, NULL) != D3D_OK);
Location = CIndexBuffer::RAMResident;
}
Format = format;
}
// ***************************************************************************
void *CVolatileIndexBuffer::lock (uint size, uint &offset)
{
nlassertex(!Locked, ("Volatile buffer usage should follow an atomic lock/unlock/render sequence"));
H_AUTO_D3D(CVolatileIndexBuffer_lock);
/* If not enough room to allocate this buffer, resise the buffer to Size+Size/2 but do not reset CurrentIndex
* to be sure the buffer will be large enough next pass. */
// Enough room for this index ?
if (CurrentIndex+size > Size)
{
if (CurrentIndex+size > MaxSize && CurrentIndex != 0)
{
return NULL; // max size exceeded -> can reallocate only if we are at start of block
}
// No, reallocate
init (Location, std::max (std::min(Size+Size/2, MaxSize), CurrentIndex+size), MaxSize, Driver, Format);
}
// Lock Profile?
TTicks beforeLock = 0;
if(Driver->_IBProfiling /*&& Hardware*/)
{
beforeLock= CTime::getPerformanceTime();
}
// Lock the buffer, noblocking lock here if not the first allocation since a reset
VOID *pbData;
if (CurrentIndex==0)
{
nlverify (IndexBuffer->Lock (0, size, &pbData, 0) == D3D_OK);
}
else
{
nlverify (IndexBuffer->Lock (CurrentIndex, size, &pbData, D3DLOCK_NOOVERWRITE) == D3D_OK);
}
if(Driver->_IBProfiling /*&& Hardware*/)
{
TTicks afterLock;
afterLock= CTime::getPerformanceTime();
Driver->_VolatileIBLockTime += afterLock - beforeLock;
}
// Old buffer position
offset = CurrentIndex / (Format == CIndexBuffer::Indices32 ? sizeof(uint32) : sizeof(uint16));
// New buffer position
CurrentIndex += size;
Locked = true;
return pbData;
}
// ***************************************************************************
void CVolatileIndexBuffer::unlock ()
{
H_AUTO_D3D(CVolatileIndexBuffer_unlock);
nlassertex(Locked, ("Volatile buffer usage should follow an atomic lock/unlock/render sequence"));
nlverify (IndexBuffer->Unlock () == D3D_OK);
Locked = false;
}
// ***************************************************************************
void CVolatileIndexBuffer::reset ()
{
H_AUTO_D3D(CVolatileIndexBuffer_reset);
CurrentIndex = 0;
}
// ***************************************************************************
bool CDriverD3D::buildQuadIndexBuffer()
{
// this code will becomes useless when 16 bits buffer are really supported
nlassert(!_QuadIB);
uint numQuads = std::min(MAX_NUM_QUADS, (uint) (_MaxPrimitiveCount * 2)); // 2 primitives for each quads
HRESULT r = _DeviceInterface->CreateIndexBuffer(sizeof(uint16) * 6 * numQuads, D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &_QuadIB, NULL);
if (r != D3D_OK) return false;
void *datas;
r = _QuadIB->Lock(0, sizeof(uint16) * 6 * numQuads, &datas, 0);
if (r != D3D_OK) return false;
fillQuadIndexes((uint16 *) datas, 0, 6 * numQuads);
_QuadIB->Unlock();
return true;
}
// ***************************************************************************
} // NL3D

View file

@ -1,475 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// *************************************************************************************
CDriverD3D::CCursor::CCursor() : ColorDepth(CDriverD3D::ColorDepth32),
OrigHeight(32),
HotspotScale(1.f),
HotspotOffsetX(0),
HotspotOffsetY(0),
HotSpotX(0),
HotSpotY(0),
Cursor(EmptyCursor),
Col(CRGBA::White),
Rot(0)
{
}
// *************************************************************************************
CDriverD3D::CCursor::~CCursor()
{
reset();
}
// *************************************************************************************
void CDriverD3D::CCursor::reset()
{
if (Cursor != EmptyCursor)
{
DestroyIcon(Cursor);
}
}
// *************************************************************************************
CDriverD3D::CCursor& CDriverD3D::CCursor::operator= (const CDriverD3D::CCursor& from)
{
if (&from == this)
return *this;
Src = from.Src; // requires more than a surface copy
OrigHeight = from.OrigHeight;
HotspotScale = from.HotspotScale;
HotspotOffsetX = from.HotspotOffsetX;
HotspotOffsetY = from.HotspotOffsetY;
HotSpotX = from.HotSpotX;
HotSpotY = from.HotSpotY;
Cursor = from.Cursor;
Col = from.Col;
Rot = from.Rot;
return *this;
}
// *************************************************************************************
bool CDriverD3D::isAlphaBlendedCursorSupported()
{
if (!_AlphaBlendedCursorSupportRetrieved)
{
// Support starts with windows 2000 (not only from XP as seen in most docs)
// NB : Additionnaly, could query D3D caps to know if
// color hardware cursor is supported, not only emulated,
// but can't be sure that using the win32 api 'SetCursor' uses the same resources
// So far, seems to be supported on any modern card used by the game anyway ...
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osvi))
{
_AlphaBlendedCursorSupported = (osvi.dwMajorVersion >= 5);
}
_AlphaBlendedCursorSupportRetrieved = true;
}
return _AlphaBlendedCursorSupported;
}
// *************************************************************************************
void CDriverD3D::addCursor(const std::string &name, const NLMISC::CBitmap &cursorBitmap)
{
if (!isAlphaBlendedCursorSupported()) return;
nlassert(cursorBitmap.getWidth() != 0);
nlassert(cursorBitmap.getHeight() != 0);
// find used part base on alpha, to avoid too much shrinking
const CRGBA *pixels = (const CRGBA *) &cursorBitmap.getPixels()[0];
uint minX, maxX, minY, maxY;
uint width = cursorBitmap.getWidth();
uint height = cursorBitmap.getHeight();
//
minX = 0;
for (uint x = 0; x < width; ++x)
{
bool stop = false;
minX = x;
for (uint y = 0; y < height; ++y)
{
if(pixels[x + y * width].A != 0)
{
stop = true;
break;
}
}
if (stop) break;
}
//
maxX = width - 1;
for (sint x = width - 1; x >= 0; --x)
{
bool stop = false;
maxX = (uint) x;
for (uint y = 0; y < height; ++y)
{
if(pixels[x + y * width].A != 0)
{
stop = true;
break;
}
}
if (stop) break;
}
//
minY = 0;
for (uint y = 0; y < height; ++y)
{
bool stop = false;
minY = y;
for (uint x = 0; x < width; ++x)
{
if(pixels[x + y * width].A != 0)
{
stop = true;
break;
}
}
if (stop) break;
}
//
maxY = height - 1;
for (sint y = height - 1; y >= 0; --y)
{
bool stop = false;
maxY = (uint) y;
for (uint x = 0; x < width; ++x)
{
if(pixels[x + y * width].A != 0)
{
stop = true;
break;
}
}
if (stop) break;
}
//
CCursor &curs = _Cursors[name];
curs = CCursor(); // erase possible previous cursor
uint destWidth = GetSystemMetrics(SM_CXCURSOR);
uint destHeight = GetSystemMetrics(SM_CYCURSOR);
// build a square bitmap
uint tmpSize = std::max(maxX - minX + 1, maxY - minY + 1);
curs.Src.resize(tmpSize, tmpSize);
// blit at top left corner
curs.Src.blit(cursorBitmap, minX, minY, maxX - minX + 1, maxY - minY + 1, 0, 0);
curs.OrigHeight = cursorBitmap.getHeight();
curs.HotspotOffsetX = minX;
curs.HotspotOffsetY = minY;
//
curs.HotspotScale = _CursorScale;
clamp(curs.HotspotScale, 0.f, 1.f);
// first resampling, same for all cursors
tmpSize = (uint) (tmpSize * curs.HotspotScale);
if (tmpSize == 0) tmpSize = 1;
if (curs.HotspotScale < 1.f)
{
curs.Src.resample(tmpSize, tmpSize);
}
// shrink if necessary
if (tmpSize > destWidth || tmpSize > destHeight) // need to shrink ?
{
// constraint proportions
curs.HotspotScale *= std::min(float(destWidth) / tmpSize, float(destHeight) / tmpSize);
curs.Src.resample(destWidth, destHeight);
}
else
{
CBitmap final;
final.resize(destWidth, destHeight);
final.blit(&curs.Src, 0, 0);
curs.Src.swap(final);
}
if (name == _CurrName)
{
updateCursor();
}
}
// *************************************************************************************
void CDriverD3D::createCursors()
{
_DefaultCursor = LoadCursor(NULL, IDC_ARROW);
}
// *************************************************************************************
void CDriverD3D::releaseCursors()
{
SetClassLongPtr(_HWnd, GCLP_HCURSOR, 0);
_Cursors.clear();
}
// *************************************************************************************
void CDriverD3D::updateCursor(bool forceRebuild)
{
setCursor(_CurrName, _CurrCol, _CurrRot, _CurrHotSpotX, _CurrHotSpotY, forceRebuild);
}
// *************************************************************************************
void CDriverD3D::setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild)
{
// don't update cursor if it's hidden or if custom cursors are not suppported
if (!isAlphaBlendedCursorSupported() || _CurrName == "none") return;
_CurrName = name;
_CurrCol = col;
_CurrRot = rot;
_CurrHotSpotX = hotSpotX;
_CurrHotSpotY = hotSpotY;
// cursor has to be changed next time
if (_CurrName.empty()) return;
if (rot > 3) rot = 3; // same than 'CViewRenderer::drawRotFlipBitmapTiled
TCursorMap::iterator it = _Cursors.find(name);
nlCursor cursorHandle = _DefaultCursor;
if (it != _Cursors.end())
{
// Update cursor if modified or not already built
CCursor &curs = it->second;
hotSpotX = (sint) (curs.HotspotScale * (hotSpotX - curs.HotspotOffsetX));
hotSpotY = (sint) (curs.HotspotScale * ((curs.OrigHeight - hotSpotY) - curs.HotspotOffsetY));
if (curs.Cursor == EmptyCursor ||
curs.HotSpotX != hotSpotX ||
curs.HotSpotY != hotSpotY ||
curs.Col != col ||
curs.Rot != rot ||
curs.ColorDepth != _ColorDepth ||
forceRebuild
)
{
curs.reset();
curs.Cursor = buildCursor(curs.Src, col, rot, hotSpotX, hotSpotY);
curs.Col = col;
curs.Rot = rot;
curs.HotSpotX = hotSpotX;
curs.HotSpotY = hotSpotY;
curs.ColorDepth = _ColorDepth;
}
cursorHandle = curs.Cursor ? curs.Cursor : _DefaultCursor;
}
if (isSystemCursorInClientArea() || isSystemCursorCaptured() || forceRebuild)
{
// if (CInputHandlerManager::getInstance()->hasFocus())
{
::SetCursor(cursorHandle);
SetClassLongPtr(_HWnd, GCLP_HCURSOR, (LONG_PTR) cursorHandle); // set default mouse icon to the last one
}
}
}
// *************************************************************************************
void CDriverD3D::setCursorScale(float scale)
{
_CursorScale = scale;
}
// *************************************************************************************
nlCursor CDriverD3D::buildCursor(const CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY)
{
nlassert(isAlphaBlendedCursorSupported());
uint mouseW = GetSystemMetrics(SM_CXCURSOR);
uint mouseH = GetSystemMetrics(SM_CYCURSOR);
CBitmap rotSrc = src;
if (rot > 3) rot = 3; // mimic behavior of 'CViewRenderer::drawRotFlipBitmapTiled' (why not rot & 3 ??? ...)
switch(rot)
{
case 0: break;
case 1: rotSrc.rot90CW(); break;
case 2: rotSrc.rot90CW(); rotSrc.rot90CW(); break;
case 3: rotSrc.rot90CCW(); break;
}
// create a cursor from bitmap
nlCursor result = NULL;
convertBitmapToCursor(rotSrc, result, mouseW, mouseH, _ColorDepth == ColorDepth16 ? 16:32, col, hotSpotX, hotSpotY);
return result;
}
// *************************************************************************************
void CDriverD3D::setSystemArrow()
{
H_AUTO_D3D(CDriverD3D_setSystemArrow);
if (isSystemCursorInClientArea() || isSystemCursorCaptured())
{
SetCursor(_DefaultCursor);
}
// set default mouse icon to the default one
SetClassLongPtr(_HWnd, GCLP_HCURSOR, (LONG_PTR) _DefaultCursor);
}
// ***************************************************************************
void CDriverD3D::showCursor(bool b)
{
H_AUTO_D3D(CDriverD3D_showCursor);
if (_HWnd == EmptyWindow)
return;
if (b)
{
// update current hardware icon to avoid to have the plain arrow
updateCursor(true);
while (ShowCursor(b) < 0)
;
}
else
{
while (ShowCursor(b) >= 0)
;
}
}
// ***************************************************************************
void CDriverD3D::setMousePos(float x, float y)
{
H_AUTO_D3D(CDriverD3D_setMousePos);
if (_HWnd == EmptyWindow)
return;
// convert position size from float to pixels
sint x1 = (sint)((float)_CurrentMode.Width*x);
sint y1 = (sint)((float)_CurrentMode.Height*(1.0f-y));
// NeL window coordinate to MSWindows coordinates
POINT pt;
pt.x = x1;
pt.y = y1;
ClientToScreen (_HWnd, &pt);
SetCursorPos(pt.x, pt.y);
}
// ***************************************************************************
void CDriverD3D::setCapture (bool b)
{
H_AUTO_D3D(CDriverD3D_setCapture);
if (b && isSystemCursorInClientArea() && !isSystemCursorCaptured())
{
SetCapture(_HWnd);
}
else if (!b && isSystemCursorCaptured())
{
// if hardware mouse and not in client area, then force to update its aspect by updating its pos
if (!isSystemCursorInClientArea())
{
// force update
showCursor(true);
}
ReleaseCapture();
}
}
// ***************************************************************************
bool CDriverD3D::isSystemCursorInClientArea()
{
if (_FullScreen /* || !IsMouseCursorHardware() */)
{
return IsWindowVisible(_HWnd) != FALSE;
}
else
{
POINT cursPos;
// the mouse should be in the client area of the window
if (!GetCursorPos(&cursPos))
{
return false;
}
HWND wnd = WindowFromPoint(cursPos);
if (wnd != _HWnd)
{
return false; // not the same window
}
// want that the mouse be in the client area
RECT clientRect;
if (!GetClientRect(_HWnd, &clientRect))
{
return false;
}
POINT tl, br;
tl.x = clientRect.left;
tl.y = clientRect.top;
br.x = clientRect.right;
br.y = clientRect.bottom;
if (!ClientToScreen(_HWnd, &tl))
{
return false;
}
if (!ClientToScreen(_HWnd, &br))
{
return false;
}
if ((cursPos.x < tl.x) || (cursPos.x >= br.x) || (cursPos.y < tl.y) || (cursPos.y >= br.y))
{
return false;
}
}
return true;
}
// ***************************************************************************
bool CDriverD3D::isSystemCursorCaptured()
{
H_AUTO_D3D(CDriverD3D_isSystemCursorCaptured);
return GetCapture() == _HWnd;
}
bool CDriverD3D::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY)
{
return convertBitmapToIcon(bitmap, cursor, iconWidth, iconHeight, iconDepth, col, hotSpotX, hotSpotY, true);
}
} // NL3D

View file

@ -1,213 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "nel/3d/vertex_buffer.h"
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// ***************************************************************************
const D3DLIGHTTYPE RemapLightTypeNeL2D3D[3]=
{
D3DLIGHT_DIRECTIONAL, // CLight::DirectionalLight
D3DLIGHT_POINT, // CLight::PointLight
D3DLIGHT_SPOT, // CLight::SpotLight
};
// ***************************************************************************
void CDriverD3D::setLight (uint8 index, const CLight &light)
{
H_AUTO_D3D(CDriverD3D_setLight);
// bkup real light, for lightmap dynamic lighting purpose
if(index==0)
{
_UserLight0= light;
// because the D3D setup change, must dirt lightmap rendering
_LightMapDynamicLightDirty= true;
}
setLightInternal(index, light);
}
// ***************************************************************************
void CDriverD3D::enableLight (uint8 index, bool enable)
{
H_AUTO_D3D(CDriverD3D_enableLight);
// User call => set the User flag
if(index<MaxLight)
{
_UserLightEnable[index]= enable;
}
// enable the light in D3D
enableLightInternal(index, enable);
// because the D3D setup has changed, must dirt lightmap rendering
_LightMapDynamicLightDirty= true;
}
static const float sqrtFLT_MAX = (float) sqrtf(FLT_MAX);
// ***************************************************************************
void CDriverD3D::setLightInternal (uint8 index, const CLight &light)
{
H_AUTO_D3D(CDriverD3D_setLightInternal);
nlassert (_DeviceInterface);
if (index<MaxLight)
{
// Ref on the state
D3DLIGHT9 &lightRef = _LightCache[index].Light;
lightRef.Type = RemapLightTypeNeL2D3D[light.getMode ()];
NL_D3DCOLORVALUE_RGBA(lightRef.Diffuse, light.getDiffuse());
NL_D3DCOLORVALUE_RGBA(lightRef.Specular, light.getSpecular());
NL_D3DCOLORVALUE_RGBA(lightRef.Ambient, light.getAmbiant());
CVector vect = light.getPosition();
NL_D3DVECTOR_VECTOR (lightRef.Position, vect);
vect = light.getDirection();
NL_D3DVECTOR_VECTOR (lightRef.Direction, vect);
lightRef.Range = sqrtFLT_MAX;
lightRef.Falloff = 1;
lightRef.Attenuation0 = light.getConstantAttenuation();
lightRef.Attenuation1 = light.getLinearAttenuation();
lightRef.Attenuation2 = light.getQuadraticAttenuation();
if (lightRef.Type == D3DLIGHT_SPOT)
{
lightRef.Phi = light.getCutoff();
float divid=light.getExponent();
if (divid==0.f)
divid=0.0001f;
float hotSpotAngle = (float)acos(exp(log (0.9)/divid));
lightRef.Theta = hotSpotAngle;
}
else
{
lightRef.Phi = (float) NLMISC::Pi * 0.5f;
lightRef.Theta = (float) NLMISC::Pi * 0.25f;
}
// Settings touched
_LightCache[index].SettingsTouched = true;
// Touch only if enabled
if (_LightCache[index].Enabled)
touchRenderVariable (&_LightCache[index]);
}
}
// ***************************************************************************
void CDriverD3D::enableLightInternal (uint8 index, bool enable)
{
H_AUTO_D3D(CDriverD3D_enableLightInternal);
nlassert (_DeviceInterface);
if (index<MaxLight)
{
if (_LightCache[index].Enabled != enable)
{
_LightCache[index].Enabled = enable;
_LightCache[index].EnabledTouched = true;
touchRenderVariable (&_LightCache[index]);
}
}
}
// ***************************************************************************
uint CDriverD3D::getMaxLight () const
{
H_AUTO_D3D(CDriverD3D_getMaxLight);
return _MaxLight;
}
// ***************************************************************************
void CDriverD3D::setAmbientColor (CRGBA color)
{
H_AUTO_D3D(CDriverD3D_setAmbientColor);
setRenderState(D3DRS_AMBIENT, NL_D3DCOLOR_RGBA(color));
}
// ***************************************************************************
void CDriverD3D::setLightMapDynamicLight (bool enable, const CLight& light)
{
H_AUTO_D3D(CDriverD3D_setLightMapDynamicLight);
// just store, for future setup in lightmap material rendering
_LightMapDynamicLightEnabled= enable;
_LightMapDynamicLight= light;
_LightMapDynamicLightDirty= true;
}
// ***************************************************************************
void CDriverD3D::setupLightMapDynamicLighting(bool enable)
{
H_AUTO_D3D(CDriverD3D_setupLightMapDynamicLighting);
// start lightmap dynamic lighting
if(enable)
{
// disable all lights but the 0th.
for(uint i=1;i<_MaxLight;++i)
enableLightInternal(uint8(i), false);
// if the dynamic light is really enabled
if(_LightMapDynamicLightEnabled)
{
// then setup and enable
setLightInternal(0, _LightMapDynamicLight);
enableLightInternal(0, true);
}
// else just disable also the light 0
else
{
enableLightInternal(0, false);
}
// ok it has been setup
_LightMapDynamicLightDirty= false;
}
// restore old lighting
else
{
// restore the light 0
setLightInternal(0, _UserLight0);
// restore all standard light enable states
for(uint i=0;i<_MaxLight;++i)
enableLightInternal(uint8(i), _UserLightEnable[i]);
}
}
} // NL3D

File diff suppressed because it is too large Load diff

View file

@ -1,445 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "nel/3d/vertex_buffer.h"
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// ***************************************************************************
void CDriverD3D::updateMatrices ()
{
H_AUTO_D3D(CDriver3D_updateMatrices );
// Update view model matrix
D3DXMatrixMultiply (&_D3DModelView, &(_MatrixCache[remapMatrixIndex (D3DTS_WORLD)].Matrix), &(_MatrixCache[remapMatrixIndex (D3DTS_VIEW)].Matrix));
// Update view model projection matrix
_D3DModelViewProjection = _D3DModelView;
D3DXMatrixMultiply (&_D3DModelViewProjection, &_D3DModelViewProjection, &(_MatrixCache[remapMatrixIndex (D3DTS_PROJECTION)].Matrix));
// Update the inverted view model matrix
D3DXMatrixInverse (&_D3DInvModelView, NULL, &_D3DModelView);
// Update the normalize state
setRenderState (D3DRS_NORMALIZENORMALS, (_UserViewMtx.hasScalePart() || _UserModelMtx.hasScalePart() || _ForceNormalize)?TRUE:FALSE);
}
// ***************************************************************************
void CDriverD3D::updateProjectionMatrix ()
{
H_AUTO_D3D(CDriver3D_updateProjectionMatrix );
float left = _FrustumLeft;
float right = _FrustumRight;
float top = _FrustumTop;
float bottom = _FrustumBottom;
if (_RenderTarget.Texture)
swap (bottom, top);
// Get the render target size
uint32 clientWidth;
uint32 clientHeight;
getRenderTargetSize (clientWidth, clientHeight);
// In D3D, the center of the first screen pixel is [0.0,0.0]. Is NeL it is [0.5,0.5]
const float addW = (right-left)/(2*(_Viewport.getWidth() * (float)clientWidth));
const float addH = (bottom-top)/(2*(_Viewport.getHeight() * (float)clientHeight));
left += addW;
right += addW;
top += addH;
bottom += addH;
D3DXMATRIX projection;
if (_FrustumPerspective)
{
D3DXMatrixPerspectiveOffCenterLH (&projection, left, right, bottom, top, _FrustumZNear, _FrustumZFar);
}
else
{
D3DXMatrixOrthoOffCenterLH (&projection, left, right, bottom, top, _FrustumZNear, _FrustumZFar);
}
setMatrix (D3DTS_PROJECTION, projection);
// Backup znear and zfar for zbias setup
_OODeltaZ = 1 / (_FrustumZFar - _FrustumZNear);
updateMatrices ();
}
// ***************************************************************************
void CDriverD3D::setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective)
{
H_AUTO_D3D(CDriverD3D_setFrustum)
_FrustumLeft = left;
_FrustumRight = right;
_FrustumTop = top;
_FrustumBottom = bottom;
_FrustumZNear = znear;
_FrustumZFar = zfar;
_FrustumPerspective = perspective;
updateProjectionMatrix ();
}
// ***************************************************************************
void CDriverD3D::setFrustumMatrix(CMatrix &frustumMatrix)
{
H_AUTO_D3D(CDriverD3D_setFrustum)
frustumMatrix.transpose();
setMatrix (D3DTS_PROJECTION, D3DXMATRIX(frustumMatrix.get()));
}
// ***************************************************************************
CMatrix CDriverD3D::getFrustumMatrix()
{
H_AUTO_D3D(CDriverD3D_getFrustum)
CMatrix frustumMatrix;
frustumMatrix.set((float *)_MatrixCache[D3DTS_PROJECTION].Matrix.m);
frustumMatrix.transpose();
return frustumMatrix;
}
// ***************************************************************************
void CDriverD3D::setupViewMatrix(const CMatrix& mtx)
{
H_AUTO_D3D(CDriverD3D_setupViewMatrix)
// Remember the view matrix
_UserViewMtx= mtx;
_PZBCameraPos= CVector::Null;
// Set the driver matrix
D3DXMATRIX view;
NL_D3D_MATRIX (view, mtx);
// Pass to directx matrix basis
swap (view._12, view._13);
swap (view._22, view._23);
swap (view._32, view._33);
swap (view._42, view._43);
setMatrix (D3DTS_VIEW, view);
// Set the spacular matrix
CMatrix specularTex;
specularTex = mtx;
specularTex.setPos(CVector(0.0f,0.0f,0.0f));
specularTex.invert();
NL_D3D_MATRIX (_D3DSpecularWorldTex, specularTex);
updateMatrices ();
}
// ***************************************************************************
void CDriverD3D::setupViewMatrixEx(const CMatrix& mtx, const CVector &cameraPos)
{
H_AUTO_D3D(CDriverD3D_setupViewMatrixEx)
// Remeber the view matrix
_UserViewMtx= mtx;
_PZBCameraPos= cameraPos;
// Set the driver matrix
D3DXMATRIX view;
NL_D3D_MATRIX (view, mtx);
// Pass to directx matrix basis
swap (view._12, view._13);
swap (view._22, view._23);
swap (view._32, view._33);
swap (view._42, view._43);
// Reset the viewMtx position.
view._41 = 0;
view._42 = 0;
view._43 = 0;
setMatrix (D3DTS_VIEW, view);
// Set the spacular matrix
CMatrix specularTex;
specularTex = mtx;
NL_D3D_MATRIX (_D3DSpecularWorldTex, specularTex);
swap (_D3DSpecularWorldTex._12, _D3DSpecularWorldTex._13);
swap (_D3DSpecularWorldTex._22, _D3DSpecularWorldTex._23);
swap (_D3DSpecularWorldTex._32, _D3DSpecularWorldTex._33);
swap (_D3DSpecularWorldTex._42, _D3DSpecularWorldTex._43);
_D3DSpecularWorldTex._41 = 0;
_D3DSpecularWorldTex._42 = 0;
_D3DSpecularWorldTex._43 = 0;
D3DXMatrixInverse ( &_D3DSpecularWorldTex, NULL, &_D3DSpecularWorldTex);
swap (_D3DSpecularWorldTex._12, _D3DSpecularWorldTex._13);
swap (_D3DSpecularWorldTex._22, _D3DSpecularWorldTex._23);
swap (_D3DSpecularWorldTex._32, _D3DSpecularWorldTex._33);
swap (_D3DSpecularWorldTex._42, _D3DSpecularWorldTex._43);
updateMatrices ();
}
// ***************************************************************************
void CDriverD3D::setupModelMatrix(const CMatrix& mtx)
{
H_AUTO_D3D(CDriverD3D_setupModelMatrix)
// Stats
_NbSetupModelMatrixCall++;
// Remeber the model matrix
_UserModelMtx= mtx;
D3DXMATRIX world;
NL_D3D_MATRIX (world, mtx);
// Remove from position the camera position
world._41 -= _PZBCameraPos.x;
world._42 -= _PZBCameraPos.y;
world._43 -= _PZBCameraPos.z;
setMatrix (D3DTS_WORLD, world);
updateMatrices ();
}
// ***************************************************************************
CMatrix CDriverD3D::getViewMatrix() const
{
H_AUTO_D3D(CDriverD3D_getViewMatrix)
return _UserViewMtx;
}
// ***************************************************************************
void CDriverD3D::forceNormalize(bool normalize)
{
H_AUTO_D3D(CDriverD3D_forceNormalize)
_ForceNormalize = normalize;
updateMatrices ();
}
// ***************************************************************************
bool CDriverD3D::isForceNormalize() const
{
H_AUTO_D3D(CDriverD3D_isForceNormalize)
return _RenderStateCache[D3DRS_NORMALIZENORMALS].Value != FALSE;
}
// ***************************************************************************
void CDriverD3D::setupScissor (const class CScissor& scissor)
{
H_AUTO_D3D(CDriverD3D_setupScissor )
if (!_ScissorTouched &&
_Scissor.X == scissor.X &&
_Scissor.Y == scissor.Y &&
_Scissor.Width == scissor.Width &&
_Scissor.Height == scissor.Height
) return;
nlassert (_DeviceInterface);
// Get viewport
_ScissorTouched = false;
float x= scissor.X;
float width= scissor.Width;
float height= scissor.Height;
if(x==0 && x==0 && width==1 && height==1)
{
setRenderState (D3DRS_SCISSORTESTENABLE, FALSE);
}
else
{
float y= scissor.Y;
if (_HWnd)
{
// Get the render target size
uint32 clientWidth;
uint32 clientHeight;
getRenderTargetSize (clientWidth, clientHeight);
// Setup d3d scissor
RECT rect;
rect.left=(int)floor((float)clientWidth * x + 0.5f);
clamp (rect.left, 0, (int)clientWidth);
if (_RenderTarget.Texture)
rect.top=(int)floor((float)clientHeight* y + 0.5f);
else
rect.top=(int)floor((float)clientHeight* (1-y-height) + 0.5f);
clamp (rect.top, 0, (int)clientHeight);
rect.right=(int)floor((float)clientWidth * (x+width) + 0.5f );
clamp (rect.right, 0, (int)clientWidth);
if (_RenderTarget.Texture)
rect.bottom=(int)floor((float)clientHeight* (y+height) + 0.5f);
else
rect.bottom=(int)floor((float)clientHeight* (1-y) + 0.5f);
clamp (rect.bottom, 0, (int)clientHeight);
{
H_AUTO_D3D(CDriverD3D_setupScissorDevice )
_DeviceInterface->SetScissorRect (&rect);
}
setRenderState (D3DRS_SCISSORTESTENABLE, TRUE);
}
}
// Backup the scissor
_Scissor = scissor;
}
// ***************************************************************************
void CDriverD3D::setupViewport (const class CViewport& viewport)
{
H_AUTO_D3D(CDriverD3D_setupViewport )
if (_HWnd == NULL)
return;
// Get the render target size
uint32 clientWidth;
uint32 clientHeight;
getRenderTargetSize (clientWidth, clientHeight);
// Get viewport
float x;
float y;
float width;
float height;
viewport.getValues (x, y, width, height);
// Get integer values
int ix=(int)((float)clientWidth*x);
clamp (ix, 0, (int)clientWidth);
int iy;
if (_RenderTarget.Texture)
iy=(int)((float)clientHeight*y);
else
iy=(int)((float)clientHeight*(1.f-(y+height)));
clamp (iy, 0, (int)clientHeight);
int iwidth=(int)((float)clientWidth*width);
clamp (iwidth, 0, (int)clientWidth-ix);
int iheight=(int)((float)clientHeight*height);
clamp (iheight, 0, (int)clientHeight-iy);
// Setup D3D viewport
_D3DViewport.X = ix;
_D3DViewport.Y = iy;
_D3DViewport.Width = iwidth;
_D3DViewport.Height = iheight;
_D3DViewport.MinZ = _DepthRangeNear;
_D3DViewport.MaxZ = _DepthRangeFar;
_DeviceInterface->SetViewport (&_D3DViewport);
// Backup the viewport
_Viewport = viewport;
updateProjectionMatrix ();
}
// ***************************************************************************
void CDriverD3D::setDepthRange(float znear, float zfar)
{
H_AUTO_D3D(CDriverD3D_setDepthRange)
nlassert(znear != zfar);
if (_HWnd == NULL)
return;
#ifdef NL_D3D_USE_RENDER_STATE_CACHE
NL_D3D_CACHE_TEST(CacheTest_DepthRange, znear != _DepthRangeNear || zfar != _DepthRangeFar)
#endif
{
_DepthRangeNear = znear;
_DepthRangeFar = zfar;
_D3DViewport.MinZ = _DepthRangeNear;
_D3DViewport.MaxZ = _DepthRangeFar;
_DeviceInterface->SetViewport (&_D3DViewport);
}
}
// ***************************************************************************
void CDriverD3D::getDepthRange(float &znear, float &zfar) const
{
H_AUTO_D3D(CDriverD3D_getDepthRange)
znear = _DepthRangeNear;
zfar = _DepthRangeFar;
}
// ***************************************************************************
void CDriverD3D::getViewport(CViewport &viewport)
{
H_AUTO_D3D(CDriverD3D_getViewport)
viewport = _Viewport;
}
// ***************************************************************************
} // NL3D

View file

@ -1,157 +0,0 @@
/** \file driver_direct3d_pixel_program.cpp
* Direct 3d driver implementation
*
* $Id: driver_direct3d_pixel_program.cpp,v 1.1.2.4 2007/07/09 15:26:35 legallo Exp $
*
* \todo manage better the init/release system (if a throw occurs in the init, we must release correctly the driver)
*/
/* Copyright, 2000 Nevrax Ltd.
*
* This file is part of NEVRAX NEL.
* NEVRAX NEL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
* NEVRAX NEL is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with NEVRAX NEL; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "stddirect3d.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// ***************************************************************************
CPixelProgramDrvInfosD3D::CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it) : IProgramDrvInfos (drv, it)
{
H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgamDrvInfosD3D)
Shader = NULL;
}
// ***************************************************************************
CPixelProgramDrvInfosD3D::~CPixelProgramDrvInfosD3D()
{
H_AUTO_D3D(CPixelProgramDrvInfosD3D_CPixelProgramDrvInfosD3DDtor)
if (Shader)
Shader->Release();
}
// ***************************************************************************
bool CDriverD3D::supportPixelProgram (CPixelProgram::TProfile profile) const
{
H_AUTO_D3D(CDriverD3D_supportPixelProgram_profile)
return ((profile & 0xFFFF0000) == 0xD9020000)
&& (_PixelProgramVersion >= (uint16)(profile & 0x0000FFFF));
}
// ***************************************************************************
bool CDriverD3D::compilePixelProgram(CPixelProgram *program)
{
// Program setuped ?
if (program->m_DrvInfo==NULL)
{
// Find a supported pixel program profile
IProgram::CSource *source = NULL;
for (uint i = 0; i < program->getSourceNb(); ++i)
{
if (supportPixelProgram(program->getSource(i)->Profile))
{
source = program->getSource(i);
}
}
if (!source)
{
nlwarning("No supported source profile for pixel program");
return false;
}
_GPUPrgDrvInfos.push_front (NULL);
ItGPUPrgDrvInfoPtrList itPix = _GPUPrgDrvInfos.begin();
CPixelProgramDrvInfosD3D *drvInfo;
*itPix = drvInfo = new CPixelProgramDrvInfosD3D(this, itPix);
// Create a driver info structure
program->m_DrvInfo = *itPix;
LPD3DXBUFFER pShader;
LPD3DXBUFFER pErrorMsgs;
if (D3DXAssembleShader(source->SourcePtr, source->SourceLen, NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK)
{
if (_DeviceInterface->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), &(getPixelProgramD3D(*program)->Shader)) != D3D_OK)
return false;
}
else
{
nlwarning ("Can't assemble pixel program:");
nlwarning ((const char*)pErrorMsgs->GetBufferPointer());
return false;
}
// Set parameters for assembly programs
drvInfo->ParamIndices = source->ParamIndices;
// Build the feature info
program->buildInfo(source);
}
return true;
}
// ***************************************************************************
bool CDriverD3D::activePixelProgram(CPixelProgram *program)
{
H_AUTO_D3D(CDriverD3D_activePixelProgram )
if (_DisableHardwarePixelProgram)
return false;
// Set the pixel program
if (program)
{
if (!CDriverD3D::compilePixelProgram(program)) return false;
CPixelProgramDrvInfosD3D *info = static_cast<CPixelProgramDrvInfosD3D *>((IProgramDrvInfos*)program->m_DrvInfo);
_PixelProgramUser = program;
setPixelShader(info->Shader);
}
else
{
setPixelShader(NULL);
_PixelProgramUser = NULL;
}
return true;
}
// ***************************************************************************
void CDriverD3D::disableHardwarePixelProgram()
{
H_AUTO_D3D(CDriverD3D_disableHardwarePixelProgram)
_DisableHardwarePixelProgram = true;
_PixelProgram = false;
}
} // NL3D

View file

@ -1,358 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "driver_direct3d.h"
#include "nel/misc/hierarchical_timer.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// ***************************************************************************
void CDriverD3D::profileRenderedPrimitives(CPrimitiveProfile &pIn, CPrimitiveProfile &pOut)
{
pIn= _PrimitiveProfileIn;
pOut= _PrimitiveProfileOut;
}
// ***************************************************************************
uint32 CDriverD3D::profileAllocatedTextureMemory()
{
return _AllocatedTextureMemory;
}
// ***************************************************************************
uint32 CDriverD3D::profileSetupedMaterials() const
{
return _NbSetupMaterialCall;
}
// ***************************************************************************
uint32 CDriverD3D::profileSetupedModelMatrix() const
{
return _NbSetupModelMatrixCall;
}
// ***************************************************************************
void CDriverD3D::enableUsedTextureMemorySum (bool enable)
{
if (enable)
nlinfo ("PERFORMANCE INFO: enableUsedTextureMemorySum has been set to true in CDriverD3D\n");
_SumTextureMemoryUsed=enable;
}
// ***************************************************************************
uint32 CDriverD3D::getUsedTextureMemory() const
{
// Sum memory used
uint32 memory=0;
// For each texture used
set<CTextureDrvInfosD3D*>::const_iterator ite=_TextureUsed.begin();
while (ite!=_TextureUsed.end())
{
// Get the d3d texture
CTextureDrvInfosD3D* d3dtext;
d3dtext= (*ite);
// Sum the memory used by this texture
memory+=d3dtext->TextureMemory;
// Next texture
ite++;
}
// Return the count
return memory;
}
// ***************************************************************************
void CDriverD3D::startProfileVBHardLock()
{
if(_VBHardProfiling)
return;
// start
_VBHardProfiles.clear();
_VBHardProfiles.reserve(50);
_VBHardProfiling= true;
_CurVBHardLockCount= 0;
_NumVBHardProfileFrame= 0;
_VolatileVBLockTime = 0;
}
// ***************************************************************************
void CDriverD3D::endProfileVBHardLock(std::vector<std::string> &result)
{
if(!_VBHardProfiling)
return;
// Fill infos.
result.clear();
result.resize(_VBHardProfiles.size() + 2);
float total= 0;
for(uint i=0;i<_VBHardProfiles.size();i++)
{
const uint tmpSize= 256;
char tmp[tmpSize];
CVBHardProfile &vbProf= _VBHardProfiles[i];
const char *vbName;
if(vbProf.VBHard && !vbProf.VBHard->getName().empty())
{
vbName= vbProf.VBHard->getName().c_str();
}
else
{
vbName= "????";
}
// Display in ms.
float timeLock= (float)CTime::ticksToSecond(vbProf.AccumTime)*1000 / max(_NumVBHardProfileFrame,1U);
smprintf(tmp, tmpSize, "%16s%c: %2.3f ms", vbName, vbProf.Change?'*':' ', timeLock );
total+= timeLock;
result[i]= tmp;
}
result[_VBHardProfiles.size()]= toString("Total: %2.3f", total);
// float volatileVBTimeLock = (float)CTime::ticksToSecond(_VolatileVBLockTime)*1000 / max(_NumVBHardProfileFrame,1U);
result[_VBHardProfiles.size() + 1]= toString("Volatile Vertex Buffer lock time = %2.3f", _VolatileVBLockTime);
// clear.
_VBHardProfiling= false;
contReset(_VBHardProfiles);
}
// ***************************************************************************
void CDriverD3D::appendVBHardLockProfile(NLMISC::TTicks time, CVertexBuffer *vb)
{
// must allocate a new place?
if(_CurVBHardLockCount>=_VBHardProfiles.size())
{
_VBHardProfiles.resize(_VBHardProfiles.size()+1);
// set the original VBHard
_VBHardProfiles[_CurVBHardLockCount].VBHard= vb;
}
// Accumulate.
_VBHardProfiles[_CurVBHardLockCount].AccumTime+= time;
// if change of VBHard for this chrono place
if(_VBHardProfiles[_CurVBHardLockCount].VBHard != vb)
{
// flag, and set new
_VBHardProfiles[_CurVBHardLockCount].VBHard= vb;
_VBHardProfiles[_CurVBHardLockCount].Change= true;
}
// next!
_CurVBHardLockCount++;
}
// ***************************************************************************
void CDriverD3D::startProfileIBLock()
{
if(_IBProfiling)
return;
// start
_IBProfiles.clear();
_IBProfiles.reserve(50);
_IBProfiling= true;
_CurIBLockCount= 0;
_NumIBProfileFrame= 0;
_VolatileIBLockTime = 0;
}
// ***************************************************************************
void CDriverD3D::endProfileIBLock(std::vector<std::string> &result)
{
if(!_IBProfiling)
return;
// Fill infos.
result.clear();
result.resize(_IBProfiles.size() + 2);
float total= 0;
for(uint i=0;i<_IBProfiles.size();i++)
{
const uint tmpSize= 256;
char tmp[tmpSize];
CIBProfile &ibProf= _IBProfiles[i];
const char *ibName;
if(ibProf.IB && !ibProf.IB->getName().empty())
{
ibName= ibProf.IB->getName().c_str();
}
else
{
ibName= "????";
}
// Display in ms.
float timeLock= (float)CTime::ticksToSecond(ibProf.AccumTime)*1000 / max(_NumIBProfileFrame,1U);
smprintf(tmp, tmpSize, "%16s%c: %2.3f ms", ibName, ibProf.Change?'*':' ', timeLock );
total+= timeLock;
result[i]= tmp;
}
result[_IBProfiles.size()]= toString("Total: %2.3f", total);
float volatileIBTimeLock = (float)CTime::ticksToSecond(_VolatileIBLockTime)*1000 / max(_NumIBProfileFrame,1U);
result[_IBProfiles.size() + 1]= toString("Volatile Index Buffer lock time = %2.3f", volatileIBTimeLock);
nlwarning("IB lock time = %2.3f", total);
nlwarning("Volatile IB lock time = %2.3f", volatileIBTimeLock);
// clear.
_IBProfiling= false;
contReset(_IBProfiles);
}
// ***************************************************************************
void CDriverD3D::appendIBLockProfile(NLMISC::TTicks time, CIndexBuffer *ib)
{
// must allocate a new place?
if(_CurIBLockCount>=_IBProfiles.size())
{
_IBProfiles.resize(_IBProfiles.size()+1);
_IBProfiles[_CurIBLockCount].IB= ib;
}
// Accumulate.
_IBProfiles[_CurIBLockCount].AccumTime+= time;
// if change of VBHard for this chrono place
if(_IBProfiles[_CurIBLockCount].IB != ib)
{
// flag, and set new
_IBProfiles[_CurIBLockCount].IB= ib;
_IBProfiles[_CurIBLockCount].Change= true;
}
// next!
_CurIBLockCount++;
}
// ***************************************************************************
void CDriverD3D::profileVBHardAllocation(std::vector<std::string> &result)
{
result.clear();
result.reserve(1000);
result.push_back(toString("Memory Allocated: %4d Ko in AGP / %4d Ko in VRAM",
getAvailableVertexAGPMemory()/1000, getAvailableVertexVRAMMemory()/1000 ));
result.push_back(toString("Num VBHard: %d", _VertexBufferHardSet.size()));
uint totalMemUsed= 0;
set<CVBDrvInfosD3D*>::iterator it;
for(it= _VertexBufferHardSet.begin(); it!=_VertexBufferHardSet.end(); it++)
{
CVBDrvInfosD3D *vbHard= *it;
if(vbHard)
{
uint vSize= vbHard->VertexBufferPtr->getVertexSize();
uint numVerts= vbHard->VertexBufferPtr->getNumVertices();
totalMemUsed+= vSize*numVerts;
}
}
result.push_back(toString("Mem Used: %4d Ko", totalMemUsed/1000) );
for(it= _VertexBufferHardSet.begin(); it!=_VertexBufferHardSet.end(); it++)
{
CVBDrvInfosD3D *vbHard= *it;
if(vbHard)
{
uint vSize= vbHard->VertexBufferPtr->getVertexSize();
uint numVerts= vbHard->VertexBufferPtr->getNumVertices();
result.push_back(toString(" %16s: %4d ko (format: %d / numVerts: %d)",
vbHard->VertexBufferPtr->getName().c_str(), vSize*numVerts/1000, vSize, numVerts ));
}
}
}
// ***************************************************************************
void CDriverD3D::profileIBAllocation(std::vector<std::string> &result)
{
result.clear();
result.reserve(1000);
result.push_back(toString("Memory Allocated: %4d Ko in AGP / %4d Ko in VRAM",
getAvailableVertexAGPMemory()/1000, getAvailableVertexVRAMMemory()/1000 ));
result.push_back(toString("Num Index buffers : %d", _IBDrvInfos.size()));
uint totalMemUsed= 0;
for(TIBDrvInfoPtrList::iterator it = _IBDrvInfos.begin(); it != _IBDrvInfos.end(); ++it)
{
CIBDrvInfosD3D *ib = NLMISC::safe_cast<CIBDrvInfosD3D *>(*it);
if(ib)
{
uint numIndex= ib->IndexBufferPtr->getNumIndexes();
totalMemUsed+= sizeof(uint32)*numIndex;
}
}
result.push_back(toString("Mem Used: %4d Ko", totalMemUsed/1000) );
for(TIBDrvInfoPtrList::iterator it = _IBDrvInfos.begin(); it != _IBDrvInfos.end(); ++it)
{
CIBDrvInfosD3D *ib = NLMISC::safe_cast<CIBDrvInfosD3D *>(*it);
if(ib)
{
uint numIndex= ib->IndexBufferPtr->getNumIndexes();
result.push_back(toString(" %16s: %4d ko ",
ib->IndexBufferPtr->getName().c_str(), sizeof(uint32) * numIndex));
}
}
}
// ***************************************************************************
void CDriverD3D::startBench (bool wantStandardDeviation, bool quick, bool reset)
{
CHTimer::startBench (wantStandardDeviation, quick, reset);
}
// ***************************************************************************
void CDriverD3D::endBench ()
{
CHTimer::endBench ();
}
// ***************************************************************************
void CDriverD3D::displayBench (class NLMISC::CLog *log)
{
// diplay
CHTimer::displayHierarchicalByExecutionPathSorted(log, CHTimer::TotalTime, true, 48, 2);
CHTimer::displayHierarchical(log, true, 48, 2);
CHTimer::displayByExecutionPath(log, CHTimer::TotalTime);
CHTimer::display(log, CHTimer::TotalTime);
CHTimer::display(log, CHTimer::TotalTimeWithoutSons);
}
// ***************************************************************************
} // NL3D

View file

@ -1,468 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "nel/3d/vertex_buffer.h"
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/misc/fast_mem.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// convert 32 bit indices to 16 bit indices on devices that don't have 32 bit indices
// ***************************************************************************
void CDriverD3D::convertToIndices16(uint firstIndex, uint numIndices)
{
nlassert(numIndices > 0);
// Lock the good buffer
uint offset;
CVolatileIndexBuffer *&buffer = _VolatileIndexBuffer16RAM[_CurrentRenderPass&1];
uint16 *ptr = (uint16*)buffer->lock (numIndices*sizeof(uint16), offset);
if (!ptr)
{
// index buffer full, swap with other buffer
CVolatileIndexBuffer *&bufferOther = _VolatileIndexBuffer16RAM[(_CurrentRenderPass + 1) &1];
std::swap(buffer, bufferOther);
buffer->reset();
ptr = (uint16*)buffer->lock (numIndices*sizeof(uint16), offset);
}
const uint32 *currIndex = &_LastIndexBufferInfo->RamVersion[firstIndex];
const uint32 *indexEnd = currIndex + numIndices;
do
{
#ifdef NL_DEBUG
nlassertex(*currIndex < _MaxVertexIndex, ("In this implementation, only 16 bit indices are supported"));
#endif
*ptr++ = (uint16&) (*currIndex++);
}
while (currIndex != indexEnd);
buffer->unlock();
setIndexBuffer(buffer->IndexBuffer, offset);
}
// ***************************************************************************
#ifndef NL_DEBUG
inline
#endif
bool CDriverD3D::renderPrimitives(D3DPRIMITIVETYPE primitiveType, uint /* numVertexPerPrim */, CMaterial& mat, uint firstVertex, uint32 nPrims)
{
// Setup material
if ( !setupMaterial(mat) )
return false;
if (nPrims == 0)
return false;
nlassertex(nPrims < _MaxPrimitiveCount, ("Number of max primitive at each calls limited in this implementation on current hradware"));
if (_VertexBufferCache.VertexBuffer)
{
uint pass;
beginMultiPass ();
for (pass=0; pass<_CurrentShaderPassCount; pass++)
{
// Active the pass
activePass (pass);
HRESULT r = _DeviceInterface->DrawPrimitive (primitiveType, firstVertex + _VertexBufferOffset, nPrims);
nlassert(r == D3D_OK);
}
endMultiPass ();
}
return true;
}
// ***************************************************************************
#ifndef NL_DEBUG
inline
#endif
bool CDriverD3D::renderIndexedPrimitives(D3DPRIMITIVETYPE primitiveType, uint numVertexPerPrim, CMaterial& mat, uint32 firstIndex, uint32 nPrims, uint indexOffset /*= 0*/)
{
// Setup material
if ( !setupMaterial(mat) )
return false;
if (nPrims == 0)
return false;
nlassertex(nPrims < _MaxPrimitiveCount, ("Number of max primitive at each calls limited in this implementation on current hardware"));
nlassert(_CurrIndexBufferFormat != CIndexBuffer::IndicesUnknownFormat);
if (_MaxVertexIndex <= 0xffff && _CurrIndexBufferFormat == CIndexBuffer::Indices32)
{
convertToIndices16(firstIndex, numVertexPerPrim * nPrims);
firstIndex = 0;
}
if (_VertexBufferCache.VertexBuffer && _IndexBufferCache.IndexBuffer)
{
uint pass;
beginMultiPass ();
for (pass=0; pass< _CurrentShaderPassCount; pass++)
{
// Active the pass
activePass (pass);
// NB : indexOffset is actually a constant added to each index in the current index buffer (actually may be implemented
// by moving vertex pointer in the driver ...), whereas _IndexBufferOffset+firstIndex gives an offset into the index buffer
HRESULT r = _DeviceInterface->DrawIndexedPrimitive (primitiveType, _VertexBufferOffset + indexOffset, 0, _VertexBufferSize,
firstIndex+_IndexBufferOffset, nPrims);
nlassert(r == D3D_OK);
}
endMultiPass ();
}
return true;
}
// ***************************************************************************
#ifndef NL_DEBUG
inline
#endif
bool CDriverD3D::renderSimpleIndexedPrimitives(D3DPRIMITIVETYPE primitiveType, uint numVertexPerPrim, uint32 firstIndex, uint32 nPrims, uint indexOffset /*= 0*/)
{
if (nPrims == 0)
return false;
nlassertex(nPrims < _MaxPrimitiveCount, ("Number of max primitive at each calls limited in this implementation on current hardware"));
nlassert(_CurrIndexBufferFormat != CIndexBuffer::IndicesUnknownFormat);
if (_MaxVertexIndex <= 0xffff && _CurrIndexBufferFormat == CIndexBuffer::Indices32)
{
convertToIndices16(firstIndex, numVertexPerPrim * nPrims);
firstIndex = 0;
}
if (_VertexBufferCache.VertexBuffer && _IndexBufferCache.IndexBuffer)
{
updateRenderVariablesInternal();
//fixVB(nPrims, numVertexPerPrim);
// NB : indexOffset is actually a constant added to each index in the current index buffer (actually may be implemented
// by moving vertex pointer in the driver ...), whereas _IndexBufferOffset+firstIndex gives an offset into the index buffer
HRESULT r = _DeviceInterface->DrawIndexedPrimitive (primitiveType, _VertexBufferOffset + indexOffset, 0, _VertexBufferSize,
firstIndex+_IndexBufferOffset, nPrims);
nlassert(r == D3D_OK);
}
return true;
}
// ***************************************************************************
bool CDriverD3D::renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines)
{
H_AUTO_D3D(CDriverD3D_renderLines)
if (!renderIndexedPrimitives(D3DPT_LINELIST, 2, mat, firstIndex, nlines)) return false;
// Stats
_PrimitiveProfileIn.NLines += nlines;
_PrimitiveProfileOut.NLines += nlines*_CurrentShaderPassCount;
return true;
}
// ***************************************************************************
bool CDriverD3D::renderTriangles(CMaterial& mat, uint32 firstIndex, uint32 ntris)
{
H_AUTO_D3D(CDriverD3D_renderTriangles)
if (!renderIndexedPrimitives(D3DPT_TRIANGLELIST, 3, mat, firstIndex, ntris)) return false;
// Stats
_PrimitiveProfileIn.NTriangles += ntris;
_PrimitiveProfileOut.NTriangles += ntris*_CurrentShaderPassCount;
return true;
}
// ***************************************************************************
bool CDriverD3D::renderSimpleTriangles(uint32 firstIndex, uint32 ntris)
{
H_AUTO_D3D(CDriverD3D_renderSimpleTriangles)
nlassert (ntris != 0);
nlassert (_VertexBufferCache.VertexBuffer);
nlassert (_IndexBufferCache.IndexBuffer);
if (!renderSimpleIndexedPrimitives(D3DPT_TRIANGLELIST, 3, firstIndex, ntris)) return false;
// Stats
_PrimitiveProfileIn.NTriangles += ntris;
_PrimitiveProfileOut.NTriangles += ntris;
return true;
}
// ***************************************************************************
bool CDriverD3D::renderLinesWithIndexOffset(CMaterial& mat, uint32 firstIndex, uint32 nlines, uint indexOffset)
{
H_AUTO_D3D(CDriverD3D_renderLinesWithIndexOffset)
if (!renderIndexedPrimitives(D3DPT_LINELIST, 2, mat, firstIndex, nlines, indexOffset)) return false;
// Stats
_PrimitiveProfileIn.NLines += nlines;
_PrimitiveProfileOut.NLines += nlines*_CurrentShaderPassCount;
return true;
}
// ***************************************************************************
bool CDriverD3D::renderTrianglesWithIndexOffset(CMaterial& mat, uint32 firstIndex, uint32 ntris, uint indexOffset)
{
H_AUTO_D3D(CDriverD3D_renderTrianglesWithIndexOffset)
if (!renderIndexedPrimitives(D3DPT_TRIANGLELIST, 3, mat, firstIndex, ntris, indexOffset)) return false;
// Stats
_PrimitiveProfileIn.NTriangles += ntris;
_PrimitiveProfileOut.NTriangles += ntris*_CurrentShaderPassCount;
return true;
}
// ***************************************************************************
bool CDriverD3D::renderSimpleTrianglesWithIndexOffset(uint32 firstIndex, uint32 ntris, uint indexOffset)
{
H_AUTO_D3D(CDriverD3D_renderSimpleTrianglesWithIndexOffset)
nlassert (ntris != 0);
nlassert (_VertexBufferCache.VertexBuffer);
nlassert (_IndexBufferCache.IndexBuffer);
if (!renderSimpleIndexedPrimitives(D3DPT_TRIANGLELIST, 3, firstIndex, ntris, indexOffset)) return false;
// Stats
_PrimitiveProfileIn.NTriangles += ntris;
_PrimitiveProfileOut.NTriangles += ntris;
return true;
}
// ***************************************************************************
bool CDriverD3D::renderRawPoints(CMaterial& mat, uint32 firstIndex, uint32 numPoints)
{
H_AUTO_D3D(CDriverD3D_renderRawPoints);
if (!renderPrimitives(D3DPT_POINTLIST, 1, mat, firstIndex, numPoints))
// Stats
_PrimitiveProfileIn.NPoints += numPoints;
_PrimitiveProfileOut.NPoints += numPoints*_CurrentShaderPassCount;
return true;
}
// ***************************************************************************
bool CDriverD3D::renderRawLines(CMaterial& mat, uint32 firstIndex, uint32 numLines)
{
H_AUTO_D3D(CDriverD3D_renderRawLines);
if (!renderPrimitives(D3DPT_LINELIST, 2, mat, firstIndex, numLines)) return false;
// Stats
_PrimitiveProfileIn.NLines += numLines;
_PrimitiveProfileOut.NLines += numLines*_CurrentShaderPassCount;
return true;
}
// ***************************************************************************
bool CDriverD3D::renderRawTriangles(CMaterial& mat, uint32 firstIndex, uint32 numTris)
{
H_AUTO_D3D(CDriverD3D_renderRawTriangles)
if (!renderPrimitives(D3DPT_TRIANGLELIST, 3, mat, 3 * firstIndex, numTris)) return false;
// Stats
_PrimitiveProfileIn.NTriangles += numTris;
_PrimitiveProfileOut.NTriangles += numTris*_CurrentShaderPassCount;
return true;
}
// ***************************************************************************
// 32 bits version
void fillQuadIndexes (uint32 *indexes, uint first, uint last)
{
H_AUTO_D3D(fillQuadIndexes)
uint firstQuad = (first / 6) * 4;
for (;first<last; first+=6, firstQuad+=4)
{
indexes[first+0] = firstQuad+0;
indexes[first+1] = firstQuad+1;
indexes[first+2] = firstQuad+2;
indexes[first+3] = firstQuad+0;
indexes[first+4] = firstQuad+2;
indexes[first+5] = firstQuad+3;
}
}
// ***************************************************************************
// 16 bits version
void fillQuadIndexes (uint16 *indexes, uint first, uint last)
{
H_AUTO_D3D(fillQuadIndexes)
uint16 firstQuad = (uint16) ((first / 6) * 4);
for (;first<last; first+=6, firstQuad+=4)
{
indexes[first+0] = firstQuad+0;
indexes[first+1] = firstQuad+1;
indexes[first+2] = firstQuad+2;
indexes[first+3] = firstQuad+0;
indexes[first+4] = firstQuad+2;
indexes[first+5] = firstQuad+3;
}
}
// ***************************************************************************
void CDriverD3D::setDebugMaterial()
{
H_AUTO_D3D(CDriverD3D_setDebugMaterial)
_DeviceInterface->SetRenderState (D3DRS_ALPHABLENDENABLE, FALSE);
_DeviceInterface->SetRenderState (D3DRS_SRCBLEND, D3DBLEND_ONE);
_DeviceInterface->SetRenderState (D3DRS_DESTBLEND, D3DBLEND_ZERO);
_DeviceInterface->SetRenderState (D3DRS_ALPHATESTENABLE, FALSE);
_DeviceInterface->SetRenderState (D3DRS_ALPHAREF, 128);
_DeviceInterface->SetRenderState (D3DRS_ALPHAFUNC, D3DCMP_GREATER);
_DeviceInterface->SetRenderState (D3DRS_LIGHTING, FALSE);
_DeviceInterface->SetRenderState (D3DRS_TEXTUREFACTOR, NL_D3DCOLOR_RGBA(CRGBA(255,0,255,255)));
_DeviceInterface->SetRenderState (D3DRS_CULLMODE, D3DCULL_CW);
_DeviceInterface->SetRenderState (D3DRS_COLORVERTEX, FALSE);
_DeviceInterface->SetRenderState (D3DRS_ZWRITEENABLE, TRUE);
_DeviceInterface->SetRenderState (D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
_DeviceInterface->SetRenderState (D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
_DeviceInterface->SetRenderState (D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
_DeviceInterface->SetRenderState (D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
_DeviceInterface->SetRenderState (D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
_DeviceInterface->SetTexture (0, NULL);
_DeviceInterface->SetTexture (1, NULL);
_DeviceInterface->SetTexture (2, NULL);
_DeviceInterface->SetTexture (3, NULL);
_DeviceInterface->SetTexture (4, NULL);
_DeviceInterface->SetTexture (5, NULL);
_DeviceInterface->SetTexture (6, NULL);
_DeviceInterface->SetTexture (7, NULL);
_DeviceInterface->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
_DeviceInterface->SetTextureStageState (0, D3DTSS_COLORARG0, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
_DeviceInterface->SetTextureStageState (0, D3DTSS_ALPHAARG0, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
// _DeviceInterface->SetTextureStageState (0, D3DTSS_CONSTANT, 0x0);
uint i;
for (i=1; i<8; i++)
{
_DeviceInterface->SetTextureStageState (i, D3DTSS_COLOROP, D3DTOP_DISABLE);
_DeviceInterface->SetTextureStageState (i, D3DTSS_COLORARG0, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (i, D3DTSS_COLORARG1, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (i, D3DTSS_COLORARG2, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (i, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
_DeviceInterface->SetTextureStageState (i, D3DTSS_ALPHAARG0, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (i, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
_DeviceInterface->SetTextureStageState (i, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
// _DeviceInterface->SetTextureStageState (i, D3DTSS_CONSTANT, 0x0);
}
}
// ***************************************************************************
bool CDriverD3D::renderRawQuads(CMaterial& mat, uint32 startIndex, uint32 numQuads)
{
H_AUTO_D3D(CDriverD3D_renderRawQuads)
if (numQuads == 0) return false;
else
if (_VertexBufferCache.VertexBuffer)
{
// Num of indexes needed
const uint numQuadsNeeded = numQuads*6;
nlassert(numQuads < MAX_NUM_QUADS); // this limitation should suffice for now
{
if (_MaxVertexIndex <= 0xffff)
{
nlassert(_QuadIB);
setIndexBuffer(_QuadIB, 0);
_CurrIndexBufferFormat = CIndexBuffer::Indices16; // must set the format because we don't call activeIndexBuffer
}
else
{
const uint IB_RESIZE_STRIDE = 6 * 256;
nlctassert(IB_RESIZE_STRIDE % 6 == 0);
// Need to resize the quad indexes array ?
if (_QuadIndexes.getNumIndexes() < numQuadsNeeded)
{
// Resize it
uint32 numIndexResize = IB_RESIZE_STRIDE * ((numQuadsNeeded + (IB_RESIZE_STRIDE - 1)) / IB_RESIZE_STRIDE);
_QuadIndexes.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT);
_QuadIndexes.setNumIndexes(numIndexResize); // snap to nearest size
// Fill the index buffer in VRAM
CIndexBufferReadWrite iba;
_QuadIndexes.lock (iba);
if (_QuadIndexes.getFormat() == CIndexBuffer::Indices32)
{
fillQuadIndexes ((uint32 *) iba.getPtr(), 0, numIndexResize);
}
else
{
fillQuadIndexes ((uint16 *) iba.getPtr(), 0, numIndexResize);
}
}
activeIndexBuffer (_QuadIndexes);
}
// Setup material
if ( !setupMaterial(mat) )
return false;
uint pass;
beginMultiPass ();
for (pass=0; pass<_CurrentShaderPassCount; pass++)
{
// Active the pass
activePass (pass);
//fixVB(numQuads, 4);
_DeviceInterface->DrawIndexedPrimitive (D3DPT_TRIANGLELIST, _VertexBufferOffset + startIndex, 0, numQuads * 4,
0, numQuads*2);
}
endMultiPass ();
}
}
// Stats
_PrimitiveProfileIn.NTriangles += numQuads*2;
_PrimitiveProfileOut.NTriangles += numQuads*2*_CurrentShaderPassCount;
return true;
}
// ***************************************************************************
} // NL3D

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,246 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
void CDriverD3D::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3)
{
H_AUTO_D3D(CDriverD3D_setUniform4f);
const float tabl[4] = { f0, f1, f2, f3 };
switch (program)
{
case VertexProgram:
if (_VertexProgram)
{
setVertexProgramConstant(index, tabl);
}
break;
case PixelProgram:
if (_PixelProgram)
{
setPixelShaderConstant(index, tabl);
}
break;
}
}
void CDriverD3D::setUniform4fv(TProgram program, uint index, size_t num, const float *src)
{
H_AUTO_D3D(CDriverD3D_setUniform4fv);
switch (program)
{
case VertexProgram:
if (_VertexProgram)
{
for (uint i = 0; i < num; ++i)
{
setVertexProgramConstant(index + i, src + (i * 4));
}
}
break;
case PixelProgram:
if (_PixelProgram)
{
for (uint i = 0; i < num; ++i)
{
setPixelShaderConstant(index + i, src + (i * 4));
}
}
break;
}
}
void CDriverD3D::setUniform1f(TProgram program, uint index, float f0)
{
CDriverD3D::setUniform4f(program, index, f0, 0.f, 0.f, 0.f);
}
void CDriverD3D::setUniform2f(TProgram program, uint index, float f0, float f1)
{
CDriverD3D::setUniform4f(program, index, f0, f1, 0.f, 0.f);
}
void CDriverD3D::setUniform3f(TProgram program, uint index, float f0, float f1, float f2)
{
CDriverD3D::setUniform4f(program, index, f0, f1, f2, 0.0f);
}
void CDriverD3D::setUniform1i(TProgram program, uint index, sint32 i0)
{
}
void CDriverD3D::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1)
{
}
void CDriverD3D::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2)
{
}
void CDriverD3D::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3)
{
}
void CDriverD3D::setUniform1ui(TProgram program, uint index, uint32 ui0)
{
}
void CDriverD3D::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1)
{
}
void CDriverD3D::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2)
{
}
void CDriverD3D::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3)
{
}
void CDriverD3D::setUniform3f(TProgram program, uint index, const NLMISC::CVector& v)
{
CDriverD3D::setUniform4f(program, index, v.x, v.y, v.z, 0.f);
}
void CDriverD3D::setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3)
{
CDriverD3D::setUniform4f(program, index, v.x, v.y, v.z, f3);
}
void CDriverD3D::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba)
{
CDriverD3D::setUniform4fv(program, index, 1, &rgba.R);
}
void CDriverD3D::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m)
{
H_AUTO_D3D(CDriverD3D_setUniform4x4f);
// TODO: Verify this!
NLMISC::CMatrix mat = m;
mat.transpose();
const float *md = mat.get();
CDriverD3D::setUniform4fv(program, index, 4, md);
}
void CDriverD3D::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src)
{
}
void CDriverD3D::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src)
{
}
void CDriverD3D::setUniformMatrix(NL3D::IDriver::TProgram program, uint index, NL3D::IDriver::TMatrix matrix, NL3D::IDriver::TTransform transform)
{
H_AUTO_D3D(CDriverD3D_setUniformMatrix);
D3DXMATRIX mat;
D3DXMATRIX *matPtr = NULL;
switch (matrix)
{
case IDriver::ModelView:
matPtr = &_D3DModelView;
break;
case IDriver::Projection:
matPtr = &(_MatrixCache[remapMatrixIndex(D3DTS_PROJECTION)].Matrix);
break;
case IDriver::ModelViewProjection:
matPtr = &_D3DModelViewProjection;
break;
}
if (transform != IDriver::Identity)
{
switch (transform)
{
case IDriver::Inverse:
D3DXMatrixInverse(&mat, NULL, matPtr);
break;
case IDriver::Transpose:
D3DXMatrixTranspose(&mat, matPtr);
break;
case IDriver::InverseTranspose:
D3DXMatrixInverse(&mat, NULL, matPtr);
D3DXMatrixTranspose(&mat, &mat);
break;
}
matPtr = &mat;
}
D3DXMatrixTranspose(&mat, matPtr);
CDriverD3D::setUniform4fv(program, index, 4, &mat.m[0][0]);
}
void CDriverD3D::setUniformFog(NL3D::IDriver::TProgram program, uint index)
{
H_AUTO_D3D(CDriverD3D_setUniformFog)
/* "oFog" must always be between [1, 0] what ever you set in D3DRS_FOGSTART and D3DRS_FOGEND (1 for no fog, 0 for full fog).
The Geforce4 TI 4200 (drivers 53.03 and 45.23) doesn't accept other values for "oFog". */
const float delta = _FogEnd - _FogStart;
CDriverD3D::setUniform4f(program, index,
-_D3DModelView._13 / delta,
-_D3DModelView._23 / delta,
-_D3DModelView._33 / delta,
1 - (_D3DModelView._43 - _FogStart) / delta);
}
bool CDriverD3D::setUniformDriver(TProgram program)
{
// todo
return true;
}
bool CDriverD3D::setUniformMaterial(TProgram program, CMaterial &material)
{
// todo
return true;
}
void CDriverD3D::setUniformParams(TProgram program, CGPUProgramParams &params)
{
// todo
}
} // NL3D

View file

@ -1,943 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "nel/3d/vertex_buffer.h"
#include "nel/3d/light.h"
#include "nel/3d/index_buffer.h"
#include "nel/misc/rect.h"
#include "nel/3d/viewport.h"
#include "nel/3d/scissor.h"
#include "nel/3d/u_driver.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
// 500K min.
#define NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE (20*1024)
namespace NL3D
{
// ***************************************************************************
CVBDrvInfosD3D::CVBDrvInfosD3D(CDriverD3D *drv, ItVBDrvInfoPtrList it, CVertexBuffer *vb) : IVBDrvInfos(drv, it, vb)
{
H_AUTO_D3D(CVBDrvInfosD3D_CVBDrvInfosD3D)
VertexDecl = NULL;
VertexDeclAliasDiffuseToSpecular = NULL;
ColorOffset = 0;
VertexBuffer = NULL;
Usage = 0;
VolatileVertexBuffer = NULL;
VertexDeclNoDiffuse = NULL;
#ifdef NL_DEBUG
Locked = false;
#endif
Driver = drv;
}
// ***************************************************************************
uint vertexCount=0;
CVBDrvInfosD3D::~CVBDrvInfosD3D()
{
H_AUTO_D3D(CVBDrvInfosD3D_CVBDrvInfosD3D)
CDriverD3D *driver = static_cast<CDriverD3D*>(_Driver);
// Restore non resident memory
if (VertexBufferPtr)
{
VertexBufferPtr->setLocation(CVertexBuffer::NotResident);
VertexBufferPtr = NULL;
}
// Don't release VertexDecl, it is release by the driver
if (VertexBuffer && !Volatile)
{
if (Driver)
{
if (Driver->_VertexBufferCache.VertexBuffer == VertexBuffer)
{
Driver->_VertexBufferCache.VertexBuffer = NULL;
Driver->touchRenderVariable(&Driver->_VertexBufferCache);
}
}
vertexCount--;
VertexBuffer->Release();
}
// Stats
if (Hardware)
driver->_VertexBufferHardSet.erase(this);
#ifdef NL_DEBUG
if (Locked)
{
nlinfo("VBuffer %s is still locked at destruction", VertexBufferPtr->getName().c_str()) ;
CDriverD3D *drv = NLMISC::safe_cast<CDriverD3D *>(_Driver);
drv->_LockedBuffers.erase(this);
}
#endif
}
// ***************************************************************************
uint8 *CVBDrvInfosD3D::lock (uint begin, uint end, bool readOnly)
{
H_AUTO_D3D(CVBDrvInfosD3D_lock)
nlassert (begin != end);
CDriverD3D *driver = static_cast<CDriverD3D*>(_Driver);
//nlinfo("lock from %s", VertexBufferPtr->getName().c_str());
#ifdef NL_DEBUG
nlassert(!Locked);
driver->_LockedBuffers.insert(this);
Locked = true;
static volatile bool dumpLockedBuffers = false;
if (dumpLockedBuffers)
{
nlinfo("Num locked buffers = %d", (int) driver->_LockedBuffers.size());
for(std::set<CVBDrvInfosD3D *>::iterator it = driver->_LockedBuffers.begin(); it != driver->_LockedBuffers.end(); ++it)
{
if (!(*it)->VertexBufferPtr)
{
nlinfo("Empty buffer");
}
else
{
nlinfo("Buffer %s at %p is Locked", (*it)->VertexBufferPtr->getName().c_str(), *it);
}
}
}
#endif
if (Volatile)
{
// Lock the good buffer
CVolatileVertexBuffer *&buffer = VolatileRAM ? (driver->_VolatileVertexBufferRAM[driver->_CurrentRenderPass&1]):
(driver->_VolatileVertexBufferAGP[driver->_CurrentRenderPass&1]);
uint8 *ptr = (uint8*)buffer->lock (end-begin, Stride, Offset);
if (!ptr)
{
// buffer full, swap them
CVolatileVertexBuffer *&bufferOther = VolatileRAM ? (driver->_VolatileVertexBufferRAM[(driver->_CurrentRenderPass + 1) &1]):
(driver->_VolatileVertexBufferAGP[(driver->_CurrentRenderPass + 1) &1]);
std::swap(buffer, bufferOther);
buffer->reset();
ptr = (uint8*)buffer->lock (end-begin, Stride, Offset);
nlassert(ptr);
}
nlassert(!VolatileVertexBuffer);
VolatileVertexBuffer = buffer;
VertexBuffer = buffer->VertexBuffer;
ptr -= begin;
// Current lock time
VolatileLockTime = driver->_CurrentRenderPass;
// Touch the vertex buffer
driver->touchRenderVariable (&driver->_VertexBufferCache);
return ptr;
}
else
{
nlassert (VertexBuffer);
// Lock Profile?
TTicks beforeLock = 0;
if(driver->_VBHardProfiling /*&& Hardware*/)
{
beforeLock= CTime::getPerformanceTime();
}
void *pbData;
if (VertexBuffer->Lock ( begin, end-begin, &pbData, readOnly?D3DLOCK_READONLY:0) != D3D_OK)
return NULL;
// Lock Profile?
if(driver->_VBHardProfiling /*&& Hardware*/)
{
TTicks afterLock;
afterLock= CTime::getPerformanceTime();
driver->appendVBHardLockProfile(afterLock-beforeLock, VertexBufferPtr);
}
return (uint8*)pbData;
}
}
// ***************************************************************************
void CVBDrvInfosD3D::unlock (uint /* begin */, uint /* end */)
{
H_AUTO_D3D(CVBDrvInfosD3D_unlock )
CDriverD3D *drv = NLMISC::safe_cast<CDriverD3D *>(_Driver);
#ifdef NL_DEBUG
nlassert(Locked);
drv->_LockedBuffers.erase(this);
Locked = false;
#endif
//nlinfo("unlock from %s", VertexBufferPtr->getName().c_str());
if (Volatile)
{
nlassert(VolatileVertexBuffer);
VolatileVertexBuffer->unlock ();
VolatileVertexBuffer = NULL;
}
else
VertexBuffer->Unlock ();
}
// ***************************************************************************
const D3DDECLTYPE RemapVertexBufferTypeNeL2D3D[CVertexBuffer::NumType]=
{
D3DDECLTYPE_UNUSED, // Double1,
D3DDECLTYPE_FLOAT1, // Float1,
D3DDECLTYPE_UNUSED, // Short1,
D3DDECLTYPE_UNUSED, // Double2,
D3DDECLTYPE_FLOAT2, // Float2,
D3DDECLTYPE_SHORT2, // Short2,
D3DDECLTYPE_UNUSED, // Double3,
D3DDECLTYPE_FLOAT3, // Float3,
D3DDECLTYPE_UNUSED, // Short3,
D3DDECLTYPE_UNUSED, // Double4,
D3DDECLTYPE_FLOAT4, // Float4,
D3DDECLTYPE_SHORT4, // Short4,
D3DDECLTYPE_D3DCOLOR, // UChar4,
};
// ***************************************************************************
const D3DDECLUSAGE RemapVertexBufferUsageNeL2D3D[CVertexBuffer::NumValue]=
{
D3DDECLUSAGE_POSITION, // Position
D3DDECLUSAGE_NORMAL, // Normal
D3DDECLUSAGE_TEXCOORD, // TexCoord0
D3DDECLUSAGE_TEXCOORD, // TexCoord1
D3DDECLUSAGE_TEXCOORD, // TexCoord2
D3DDECLUSAGE_TEXCOORD, // TexCoord3
D3DDECLUSAGE_TEXCOORD, // TexCoord4
D3DDECLUSAGE_TEXCOORD, // TexCoord5
D3DDECLUSAGE_TEXCOORD, // TexCoord6
D3DDECLUSAGE_TEXCOORD, // TexCoord7
D3DDECLUSAGE_COLOR, // PrimaryColor
D3DDECLUSAGE_COLOR, // SecondaryColor
D3DDECLUSAGE_BLENDWEIGHT, // Weight
D3DDECLUSAGE_BLENDINDICES, // PaletteSkin
D3DDECLUSAGE_FOG, // Fog
};
// ***************************************************************************
const uint RemapVertexBufferIndexNeL2D3D[CVertexBuffer::NumValue]=
{
0, // Position
0, // Normal
0, // TexCoord0
1, // TexCoord1
2, // TexCoord2
3, // TexCoord3
4, // TexCoord4
5, // TexCoord5
6, // TexCoord6
7, // TexCoord7
0, // PrimaryColor
1, // SecondaryColor
0, // Weight
0, // PaletteSkin
0, // Fog
};
// ***************************************************************************
DWORD RemapVertexBufferUsage[CVertexBuffer::LocationCount]=
{
D3DUSAGE_DYNAMIC, // RAMResident
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, // AGPResident
D3DUSAGE_WRITEONLY, // VRAMResident
0, // Not used
};
// ***************************************************************************
D3DPOOL RemapVertexBufferPool[CVertexBuffer::LocationCount]=
{
D3DPOOL_SYSTEMMEM, // RAMResident
D3DPOOL_DEFAULT, // AGPResident
D3DPOOL_DEFAULT, // VRAMResident
D3DPOOL_DEFAULT, // Not used
};
// ***************************************************************************
bool CDriverD3D::activeVertexBuffer(CVertexBuffer& VB)
{
H_AUTO_D3D(CDriverD3D_activeVertexBuffer)
// Must not be locked
nlassert (!VB.isLocked());
// Must not be empty
if (VB.capacity() == 0)
return false;
const bool touched = (VB.getTouchFlags() & (CVertexBuffer::TouchedReserve|CVertexBuffer::TouchedVertexFormat)) != 0;
CVBDrvInfosD3D *info = static_cast<CVBDrvInfosD3D*>(static_cast<IVBDrvInfos*>(VB.DrvInfos));
// Volatile buffers must be filled at each pass
nlassertex (!info || !info->Volatile || VB.getKeepLocalMemory() || (info->VolatileLockTime == _CurrentRenderPass), ("Volatile buffers must be filled at each pass"));
// Build the driver info
if (touched)
{
// Delete previous vertex buffer info
if (VB.DrvInfos)
{
delete VB.DrvInfos;
nlassert (VB.DrvInfos == NULL);
}
// Force the vertex color format to BGRA
VB.setVertexColorFormat (CVertexBuffer::TBGRA);
// Rebuild it
_VBDrvInfos.push_front (NULL);
ItVBDrvInfoPtrList ite = _VBDrvInfos.begin();
info = new CVBDrvInfosD3D(this, ite, &VB);
*ite = info;
// Use vertex color ?
info->UseVertexColor = (VB.getVertexFormat()&CVertexBuffer::PrimaryColorFlag) != 0;
info->Stride = (uint8)VB.getVertexSize();
// Create the vertex declaration
if (!createVertexDeclaration (VB.getVertexFormat(), VB.getValueTypePointer(), &(info->VertexDecl), info->ColorOffset, false, false))
return false;
info->VertexDeclAliasDiffuseToSpecular = NULL;
info->VertexDeclNoDiffuse = NULL;
if (VB.hasValueEx(CVertexBuffer::PrimaryColor) && !VB.hasValueEx(CVertexBuffer::SecondaryColor))
{
uint colorOffset2;
if (!createVertexDeclaration (VB.getVertexFormat(), VB.getValueTypePointer(), &(info->VertexDeclAliasDiffuseToSpecular), colorOffset2, true, false))
return false;
nlassert(colorOffset2 == info->ColorOffset); // should be the same value
}
if (_NbNeLTextureStages == 3 && info->UseVertexColor)
{
// Fix for radeon 7xxx -> if vertex color is not used it should not be declared (example : lighted material + vertex color but, no vertexColorLighted)
uint colorOffset2;
if (!createVertexDeclaration (VB.getVertexFormat(), VB.getValueTypePointer(), &(info->VertexDeclNoDiffuse), colorOffset2, false, true))
return false;
}
// Create the vertex buffer
const uint size = VB.capacity()*VB.getVertexSize();
uint preferredMemory = 0;
if (_DisableHardwareVertexArrayAGP)
{
preferredMemory = CVertexBuffer::RAMResident;
info->Volatile = false;
}
else
{
switch (VB.getPreferredMemory ())
{
case CVertexBuffer::RAMPreferred:
preferredMemory = CVertexBuffer::RAMResident;
info->Volatile = false;
break;
case CVertexBuffer::AGPPreferred:
preferredMemory = CVertexBuffer::AGPResident;
info->Volatile = false;
break;
case CVertexBuffer::StaticPreferred:
if (getStaticMemoryToVRAM())
preferredMemory = CVertexBuffer::VRAMResident;
else
preferredMemory = CVertexBuffer::AGPResident;
info->Volatile = false;
break;
case CVertexBuffer::RAMVolatile:
preferredMemory = CVertexBuffer::RAMResident;
info->Volatile = true;
break;
case CVertexBuffer::AGPVolatile:
preferredMemory = CVertexBuffer::AGPResident;
info->Volatile = true;
break;
}
}
// Volatile vertex buffer
if (info->Volatile)
{
nlassert (info->VertexBuffer == NULL);
info->Hardware = false;
info->VolatileRAM = preferredMemory == CVertexBuffer::RAMResident;
}
else
{
// Offset will be 0
info->Offset = 0;
bool success;
do
{
success = _DeviceInterface->CreateVertexBuffer(size, RemapVertexBufferUsage[preferredMemory],
0, RemapVertexBufferPool[preferredMemory], &(info->VertexBuffer), NULL) == D3D_OK;
if (success)
break;
}
while (preferredMemory--);
if (!success)
return false;
++vertexCount;
// Hardware ?
info->Hardware = preferredMemory != CVertexBuffer::RAMResident;
// Stats
if (info->Hardware)
_VertexBufferHardSet.insert(info);
}
// Release the local vertex buffer
VB.DrvInfos = info;
VB.setLocation ((CVertexBuffer::TLocation)preferredMemory);
// Force the vertex buffer update
touchRenderVariable (&_VertexDeclCache);
touchRenderVariable (&_VertexBufferCache);
}
// Set the current vertex buffer
nlassert (info);
// Fill the buffer if in local memory
VB.fillBuffer ();
setVertexDecl (info->VertexDecl, info->VertexDeclAliasDiffuseToSpecular, info->VertexDeclNoDiffuse, info->Stride);
//setVertexBuffer (info->VertexBuffer, info->Offset, info->Stride, info->UseVertexColor, VB.getNumVertices(), VB.getPreferredMemory(), info->Usage, info->ColorOffset);
setVertexBuffer (info->VertexBuffer, info->Offset, info->Stride, info->UseVertexColor, VB.getNumVertices(), VB.getPreferredMemory(), info->Usage, info->ColorOffset);
// Set UVRouting
const uint8 *uvRouting = VB.getUVRouting();
uint i;
for (i=0; i<MaxTexture; i++)
setTextureIndexUV (i, uvRouting[i]);
// backup uv-routing, because some shader may change the routing
// For example, if the same vb is used for lightmap, then for standard shader, then uv routing will be wrong
std::copy(uvRouting, uvRouting + MaxTexture, _CurrentUVRouting);
/* Hulud test : read in a "write only" vertex buffer. Seams to work well. */
/*
// Read the vertex buffer
CVBDrvInfosD3D *info = static_cast<CVBDrvInfosD3D*>(static_cast<IVBDrvInfos*>(VB.DrvInfos));
static vector<uint8> temp;
uint size = VB.capacity()*VB.getVertexSize();
// No special flag for the lock, the driver should return a valid vertex buffer pointer with previous values.
uint8 *out = info->lock (0, 0, false);
nlassert (out);
{
temp.resize (size);
memcpy (&(temp[0]), out, size);
}
info->unlock (0, 0);
out = info->lock (0, 0, false);
nlassert (out);
{
memcpy (out, &(temp[0]), size);
}
info->unlock (0, 0);
*/
return true;
}
// ***************************************************************************
bool CDriverD3D::createVertexDeclaration (uint16 vertexFormat, const uint8 *typeArray,
IDirect3DVertexDeclaration9 **vertexDecl,
uint &colorOffset,
bool aliasDiffuseToSpecular,
bool bypassDiffuse,
uint *stride)
{
H_AUTO_D3D(CDriverD3D_createVertexDeclaration)
CVertexDeclaration declaration;
if (aliasDiffuseToSpecular)
{
// there should be a single color stream : diffuse
nlassert(vertexFormat & CVertexBuffer::PrimaryColorFlag); // diffuse required
nlassert(!(vertexFormat & CVertexBuffer::SecondaryColorFlag)); // specular should not be used
}
// Set the vertex format
uint i;
uint j = 0;
uint offset = 0;
colorOffset = 0;
for (i=0; i<CVertexBuffer::NumValue; i++)
{
// Slot used ?
if (vertexFormat & (1<<i))
{
if ((i != CVertexBuffer::Weight && i != CVertexBuffer::PaletteSkin) || _PixelShaderVersion != D3DPS_VERSION(1, 4)) // fix for radeon 8500/9000/9200 : hand when this is declared and not used
// don't let gap for other cards else render bug on some ...
{
D3DVERTEXELEMENT9 &vertexElement = declaration.VertexElements[j];
vertexElement.Stream = 0;
vertexElement.Type = BYTE(RemapVertexBufferTypeNeL2D3D[(uint)typeArray[i]]);
vertexElement.Offset = WORD(offset);
vertexElement.Method = D3DDECLMETHOD_DEFAULT;
vertexElement.Usage = BYTE(RemapVertexBufferUsageNeL2D3D[(uint)i]);
if (aliasDiffuseToSpecular && i == CVertexBuffer::PrimaryColor)
{
vertexElement.UsageIndex = 1; // Map to specular stream -> this free PrimaryColor to build a constant
// Ueful to emulate per stage constant (which we can do on 2 stages only)
}
else
{
vertexElement.UsageIndex = BYTE(RemapVertexBufferIndexNeL2D3D[(uint)i]);
}
// nico : Fix for Radeon 7xxx series
// Vertex declaration doesn't work when the vertex layout has vertex color defined after tex coord.
// For example, the following layout (Position/TexCoord0/Diffuse) will silently be converted into (Position/Diffuse/TexCoord0)
// It seems that the driver tries to map the vertex declaration to the matching FVF. FVF has a prefined order and requires Diffuse to appear
// before texture coordinates in the vertex. Don't know if it is a limitation of D3D related to the 7xxx sries of if it is a driver bug.
// The D3D debug dll doesn't issue a warning about it.
// To solve this 2 vertex streams are declared :
// - First streams contains Position/Normal/Texcoord
// - When vertex color are used, second stream contains Diffuse/Specular vertex component(s)
// In fact the 2 streams map to the same vertex buffer, but the 2nd stream has an added offset to point on the color component
// I tried to add this offset directly into the vertex declaration, but D3D complains about it...
// If the following field contains a non 0 value, then a second stream must be used for diffuse/specular with the given offset
if (_NbNeLTextureStages == 3)
{
if (vertexElement.Usage == D3DDECLUSAGE_COLOR)
{
if (bypassDiffuse)
{
continue;
}
vertexElement.Stream = 1;
if (colorOffset == 0)
{
vertexElement.Offset = 0;
colorOffset = offset;
}
else
{
vertexElement.Offset = 4;
}
}
}
j++;
}
offset += CVertexBuffer::SizeType[typeArray[i]];
}
}
// Set the stride ?
if (stride)
*stride = offset;
// End
D3DVERTEXELEMENT9 end = D3DDECL_END();
declaration.VertexElements[j] = end;
// Look for the same vertex declaration
std::list<CVertexDeclaration>::iterator ite = _VertexDeclarationList.begin();
while (ite != _VertexDeclarationList.end())
{
for (i=0; i<=j; i++)
{
const D3DVERTEXELEMENT9 &vertexElementNew = declaration.VertexElements[i];
const D3DVERTEXELEMENT9 &vertexElementOld = ite->VertexElements[i];
if ( (vertexElementNew.Stream != vertexElementOld.Stream) ||
(vertexElementNew.Type != vertexElementOld.Type) ||
(vertexElementNew.Offset != vertexElementOld.Offset) ||
(vertexElementNew.Method != vertexElementOld.Method) ||
(vertexElementNew.Usage != vertexElementOld.Usage) ||
(vertexElementNew.UsageIndex != vertexElementOld.UsageIndex))
{
break;
}
}
// All is good ?
if (i == (j+1))
{
// It is the same vertex declaration
*vertexDecl = ite->VertexDecl;
return true;
}
ite++;
}
// Not found, create the vertex declaration
if (_DeviceInterface->CreateVertexDeclaration (declaration.VertexElements, &(declaration.VertexDecl)) != D3D_OK)
{
return false;
}
// Add the vertex declaration
_VertexDeclarationList.push_back (declaration);
// Set the final declaration pointer
*vertexDecl = declaration.VertexDecl;
return true;
}
// ***************************************************************************
bool CDriverD3D::supportVertexBufferHard() const
{
H_AUTO_D3D(CDriverD3D_supportVertexBufferHard)
return !_DisableHardwareVertexArrayAGP;
}
// ***************************************************************************
bool CDriverD3D::supportVolatileVertexBuffer() const
{
H_AUTO_D3D(CDriverD3D_supportVolatileVertexBuffer)
return true;
}
// ***************************************************************************
void CDriverD3D::disableHardwareVertexArrayAGP()
{
H_AUTO_D3D(CDriverD3D_disableHardwareVertexArrayAGP)
_DisableHardwareVertexArrayAGP = true;
}
// ***************************************************************************
uint CDriverD3D::getMaxVerticesByVertexBufferHard() const
{
H_AUTO_D3D(CDriverD3D_getMaxVerticesByVertexBufferHard)
return _MaxVerticesByVertexBufferHard;
}
// ***************************************************************************
uint32 CDriverD3D::getAvailableVertexAGPMemory ()
{
H_AUTO_D3D(CDriverD3D_getAvailableVertexAGPMemory )
return _AGPMemoryAllocated;
}
// ***************************************************************************
uint32 CDriverD3D::getAvailableVertexVRAMMemory ()
{
H_AUTO_D3D(CDriverD3D_getAvailableVertexVRAMMemory )
return _VRAMMemoryAllocated;
}
// ***************************************************************************
bool CDriverD3D::initVertexBufferHard(uint agpMem, uint vramMem)
{
H_AUTO_D3D(CDriverD3D_initVertexBufferHard)
if(!supportVertexBufferHard())
return false;
// First, reset any VBHard created.
bool ok= true;
// Try to allocate AGPMemory.
_AGPMemoryAllocated = agpMem;
if(_AGPMemoryAllocated>0)
{
_AGPMemoryAllocated&= ~15; // ensure 16-bytes aligned mem count (maybe useful :) ).
_AGPMemoryAllocated= max(_AGPMemoryAllocated, (uint32)NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE);
while(_AGPMemoryAllocated >= NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
{
IDirect3DVertexBuffer9 *vb;
if (_DeviceInterface->CreateVertexBuffer (_AGPMemoryAllocated, D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, 0,
D3DPOOL_DEFAULT, &vb, NULL) == D3D_OK)
{
D3DVERTEXBUFFER_DESC desc;
nlverify (vb->GetDesc (&desc) == D3D_OK);
if (((desc.Usage&(D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC)) == (D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC)) &&
(desc.Pool == D3DPOOL_DEFAULT))
{
nlinfo("%.d vertices supported", _MaxVerticesByVertexBufferHard);
nlinfo("Success to allocate %.1f Mo of AGP VAR Ram", _AGPMemoryAllocated / 1000000.f);
vb->Release();
break;
}
else
vb->Release();
}
else
{
_AGPMemoryAllocated/=2;
_AGPMemoryAllocated &=~15;
}
}
if(_AGPMemoryAllocated< NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
{
nlwarning("%.d vertices supported", _MaxVerticesByVertexBufferHard);
nlwarning("Failed to allocate %.1f Mo of AGP VAR Ram", NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE / 1000000.f);
ok= false;
}
}
// Try to allocate VRAMMemory.
_VRAMMemoryAllocated = vramMem;
if(_VRAMMemoryAllocated>0)
{
_VRAMMemoryAllocated&= ~15; // ensure 16-bytes aligned mem count (maybe useful :) ).
_VRAMMemoryAllocated= max(_VRAMMemoryAllocated, (uint32)NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE);
while(_VRAMMemoryAllocated>= NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
{
IDirect3DVertexBuffer9 *vb;
if (_DeviceInterface->CreateVertexBuffer (_VRAMMemoryAllocated, D3DUSAGE_WRITEONLY, 0,
D3DPOOL_DEFAULT, &vb, NULL) == D3D_OK)
{
vb->Release();
break;
}
else
{
_VRAMMemoryAllocated/=2;
_VRAMMemoryAllocated &=~15;
}
}
if(_VRAMMemoryAllocated< NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
{
ok= false;
}
}
return ok;
}
// ***************************************************************************
void CDriverD3D::mapTextureStageToUV(uint stage, uint uv)
{
H_AUTO_D3D(CDriverD3D_mapTextureStageToUV)
setTextureIndexUV (stage, uv);
}
// ***************************************************************************
// CVolatileVertexBuffer
// ***************************************************************************
CVolatileVertexBuffer::CVolatileVertexBuffer()
{
H_AUTO_D3D(CVolatileVertexBuffer_CVolatileVertexBuffer)
VertexBuffer = NULL;
Locked = false;
}
// ***************************************************************************
CVolatileVertexBuffer::~CVolatileVertexBuffer()
{
H_AUTO_D3D(CVolatileVertexBuffer_CVolatileVertexBufferDtor)
release ();
}
// ***************************************************************************
void CVolatileVertexBuffer::release ()
{
H_AUTO_D3D(CVolatileVertexBuffer_release )
if (VertexBuffer)
VertexBuffer->Release();
VertexBuffer = NULL;
}
// ***************************************************************************
void CVolatileVertexBuffer::init (CVertexBuffer::TLocation location, uint size, uint maxSize, CDriverD3D *driver)
{
H_AUTO_D3D(CVolatileVertexBuffer_init )
release();
if (maxSize < size) maxSize = size;
MaxSize = maxSize;
// Init the buffer
Location = location;
Size = size;
Driver = driver;
// Allocate the vertex buffer
if (Driver->_DeviceInterface->CreateVertexBuffer(size, RemapVertexBufferUsage[location],
0, RemapVertexBufferPool[location], &VertexBuffer, NULL) != D3D_OK)
{
// Location in RAM must not failed
nlassert (location != CVertexBuffer::RAMResident);
// Allocate in RAM
nlverify (Driver->_DeviceInterface->CreateVertexBuffer(size, RemapVertexBufferUsage[CVertexBuffer::RAMResident],
0, RemapVertexBufferPool[CVertexBuffer::RAMResident], &VertexBuffer, NULL) != D3D_OK);
Location = CVertexBuffer::RAMResident;
}
}
// ***************************************************************************
//volatile int callCount = 0;
//volatile int callStop = 17700;
void *CVolatileVertexBuffer::lock (uint size, uint stride, uint &offset)
{
nlassertex(!Locked, ("Volatile buffer usage should follow an atomic lock/unlock/render sequence"));
H_AUTO_D3D(CVolatileVertexBuffer_lock)
/* If not enough room to allocate this buffer, resise the buffer to Size+Size/2 but do not reset CurrentIndex
* to be sure the buffer will be large enough next pass. */
//if (callCount == callStop)
// nlstop;
//callCount++;
// Align the index
uint mod = CurrentIndex / stride;
if (CurrentIndex != (mod*stride))
CurrentIndex = (mod+1)*stride;
// Enough room for this vertex ?
if (CurrentIndex+size+stride > Size)
{
if (CurrentIndex+size > MaxSize && CurrentIndex != 0)
{
reset();
if (size > MaxSize)
{
init (Location, std::max (std::min(Size+Size/2, MaxSize), size), MaxSize, Driver);
}
}
else
{
// Max size not reached, so reallocate
init (Location, std::max (std::min(Size+Size/2, MaxSize), CurrentIndex+size), MaxSize, Driver);
reset(); // reallocate will cause a cpu stall anyway ...
}
}
// Lock Profile?
TTicks beforeLock = 0;
if(Driver->_VBHardProfiling)
{
beforeLock= CTime::getPerformanceTime();
}
// Lock the buffer, noblocking lock here if not the first allocation since a reset
VOID *pbData;
if (CurrentIndex==0)
{
nlverify (VertexBuffer->Lock (0, Size, &pbData, D3DLOCK_DISCARD) == D3D_OK);
}
else
{
nlverify (VertexBuffer->Lock (CurrentIndex, size, &pbData, D3DLOCK_NOOVERWRITE) == D3D_OK);
}
if(Driver->_VBHardProfiling)
{
TTicks afterLock;
afterLock= CTime::getPerformanceTime();
Driver->_VolatileVBLockTime += afterLock - beforeLock;
}
// Old buffer position
offset = CurrentIndex/stride;
// New buffer position
CurrentIndex += size;
Locked = true;
return pbData;
}
// ***************************************************************************
void CVolatileVertexBuffer::unlock ()
{
H_AUTO_D3D(CVolatileVertexBuffer_unlock )
nlassertex(Locked, ("Volatile buffer usage should follow an atomic lock/unlock/render sequence"));
nlverify (VertexBuffer->Unlock () == D3D_OK);
Locked = false;
}
// ***************************************************************************
void CVolatileVertexBuffer::reset ()
{
H_AUTO_D3D(CVolatileVertexBuffer_reset )
CurrentIndex = 0;
// callCount = 0;
}
// ***************************************************************************
} // NL3D

View file

@ -1,439 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"
#include "driver_direct3d.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace std;
using namespace NLMISC;
namespace NL3D
{
// ***************************************************************************
CVertexProgamDrvInfosD3D::CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it) : IProgramDrvInfos (drv, it)
{
H_AUTO_D3D(CVertexProgamDrvInfosD3D_CVertexProgamDrvInfosD3D)
Shader = NULL;
}
// ***************************************************************************
CVertexProgamDrvInfosD3D::~CVertexProgamDrvInfosD3D()
{
H_AUTO_D3D(CVertexProgamDrvInfosD3D_CVertexProgamDrvInfosD3DDtor)
if (Shader)
Shader->Release();
}
// ***************************************************************************
bool CDriverD3D::supportVertexProgram (CVertexProgram::TProfile profile) const
{
H_AUTO_D3D(CDriverD3D_supportVertexProgram )
return (profile == CVertexProgram::nelvp) && _VertexProgram;
}
// ***************************************************************************
bool CDriverD3D::isVertexProgramEmulated () const
{
H_AUTO_D3D(CDriverD3D_isVertexProgramEmulated )
// Pure HAL driver, no emulation available
return false;
}
// ***************************************************************************
static const char *instrToName[] =
{
"mov ",
"mov ",
"mul ",
"add ",
"mad ",
"rsq ",
"dp3 ",
"dp4 ",
"dst ",
"lit ",
"min ",
"max ",
"slt ",
"sge ",
"expp ",
"log ",
"rcp "
};
// ***************************************************************************
static const char *outputRegisterToName[] =
{
"Pos",
"D0",
"D1",
"BFC0",
"BFC1",
"Fog",
"Pts",
"T0",
"T1",
"T2",
"T3",
"T4",
"T5",
"T6",
"T7"
};
// ***************************************************************************
void dumpWriteMask(uint mask, std::string &out)
{
H_AUTO_D3D(dumpWriteMask)
if (mask == 0xf)
{
out.clear();
return;
}
out = ".";
if (mask & 1) out +="x";
if (mask & 2) out +="y";
if (mask & 4) out +="z";
if (mask & 8) out +="w";
}
// ***************************************************************************
void dumpSwizzle(const CVPSwizzle &swz, std::string &out)
{
H_AUTO_D3D(dumpSwizzle)
if (swz.isIdentity())
{
out.clear();
return;
}
out = ".";
for(uint k = 0; k < 4; ++k)
{
switch(swz.Comp[k])
{
case CVPSwizzle::X: out += "x"; break;
case CVPSwizzle::Y: out += "y"; break;
case CVPSwizzle::Z: out += "z"; break;
case CVPSwizzle::W: out += "w"; break;
default:
nlassert(0);
break;
}
if (swz.isScalar() && k == 0) break;
}
}
// ***************************************************************************
void dumpOperand(const CVPOperand &op, bool destOperand, std::string &out, set<uint> &inputs)
{
H_AUTO_D3D(dumpOperand)
out = op.Negate ? " -" : " ";
switch(op.Type)
{
case CVPOperand::Variable: out += "r" + NLMISC::toString(op.Value.VariableValue); break;
case CVPOperand::Constant:
out += "c[";
if (op.Indexed)
{
out += "a0.x + ";
}
out += NLMISC::toString(op.Value.ConstantValue) + "]";
break;
case CVPOperand::InputRegister:
out += "v" + NLMISC::toString((uint) op.Value.InputRegisterValue);
inputs.insert (op.Value.InputRegisterValue);
break;
case CVPOperand::OutputRegister:
nlassert(op.Value.OutputRegisterValue < CVPOperand::OutputRegisterCount);
out += "o" + std::string(outputRegisterToName[op.Value.OutputRegisterValue]);
break;
case CVPOperand::AddressRegister:
out += "a0.x";
break;
}
std::string suffix;
if (destOperand)
{
// No mask for the fog value
if (op.Value.OutputRegisterValue != CVPOperand::OFogCoord)
dumpWriteMask(op.WriteMask, suffix);
}
else
{
dumpSwizzle(op.Swizzle, suffix);
}
out += suffix;
}
// ***************************************************************************
void dumpInstr(const CVPInstruction &instr, std::string &out, set<uint> &inputs)
{
H_AUTO_D3D(dumpInstr)
nlassert(instr.Opcode < CVPInstruction::OpcodeCount);
out = instrToName[instr.Opcode];
uint nbOp = instr.getNumUsedSrc();
std::string destOperand;
dumpOperand(instr.Dest, true, destOperand, inputs);
out += destOperand;
for(uint k = 0; k < nbOp; ++k)
{
out += ", ";
std::string srcOperand;
dumpOperand(instr.getSrc(k), false, srcOperand, inputs);
out += srcOperand;
}
out +="; \n";
}
// ***************************************************************************
static const char *inputToDecl[CVPOperand::InputRegisterCount] =
{
"dcl_position v0",
"dcl_blendweight v1",
"dcl_normal v2",
"dcl_color0 v3",
"dcl_color1 v4",
"dcl_fog v5",
"dcl_blendindices v6",
"",
"dcl_texcoord0 v8",
"dcl_texcoord1 v9",
"dcl_texcoord2 v10",
"dcl_texcoord3 v11",
"dcl_texcoord4 v12",
"dcl_texcoord5 v13",
"dcl_texcoord6 v14",
"dcl_texcoord7 v15",
};
// ***************************************************************************
void dump(const CVPParser::TProgram &prg, std::string &dest)
{
H_AUTO_D3D(dump)
// Set of input registers used
set<uint> inputs;
string program;
for(uint k = 0; k < prg.size(); ++k)
{
std::string instr;
dumpInstr(prg[k], instr, inputs);
program += instr;
}
// Write the header
dest = "vs.1.1\n";
set<uint>::iterator ite = inputs.begin();
while (ite != inputs.end())
{
dest += inputToDecl[*ite] + string("\n");
ite++;
}
dest += program;
}
// ***************************************************************************
bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program)
{
// Program setuped ?
if (program->m_DrvInfo == NULL)
{
// Find nelvp
IProgram::CSource *source = NULL;
for (uint i = 0; i < program->getSourceNb(); ++i)
{
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
{
source = program->getSource(i);
}
}
if (!source)
{
nlwarning("Direct3D driver only supports 'nelvp' profile, vertex program cannot be used");
return false;
}
_GPUPrgDrvInfos.push_front (NULL);
ItGPUPrgDrvInfoPtrList itTex = _GPUPrgDrvInfos.begin();
CVertexProgamDrvInfosD3D *drvInfo;
*itTex = drvInfo = new CVertexProgamDrvInfosD3D(this, itTex);
// Create a driver info structure
program->m_DrvInfo = *itTex;
/** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..).
* There are some incompatibilities.
*/
CVPParser parser;
CVPParser::TProgram parsedProgram;
std::string errorOutput;
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
if (!result)
{
nlwarning("Unable to parse a vertex program :");
nlwarning(errorOutput.c_str());
#ifdef NL_DEBUG_D3D
nlassert(0);
#endif // NL_DEBUG_D3D
return false;
}
// tmp fix for Radeon 8500/9000/9200
// Currently they hang when PaletteSkin / SkinWeight are present in the vertex declaration, but not used
// so disable them in the vertex declaration
// We don't use these component in vertex programs currently..
#ifdef NL_DEBUG
for(uint k = 0; k < parsedProgram.size(); ++k)
{
for(uint l = 0; l < parsedProgram[k].getNumUsedSrc(); ++l)
{
const CVPOperand &op = parsedProgram[k].getSrc(l);
if (op.Type == CVPOperand::InputRegister)
{
nlassert(op.Value.InputRegisterValue != CVPOperand::IWeight);
nlassert(op.Value.InputRegisterValue != CVPOperand::IPaletteSkin);
}
}
}
#endif
// Dump the vertex program
std::string dest;
dump(parsedProgram, dest);
#ifdef NL_DEBUG_D3D
nlinfo("Assemble Vertex Shader : ");
string::size_type lineBegin = 0;
string::size_type lineEnd;
while ((lineEnd = dest.find('\n', lineBegin)) != string::npos)
{
nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str());
lineBegin = lineEnd+1;
}
nlinfo(dest.substr (lineBegin, lineEnd-lineBegin).c_str());
#endif // NL_DEBUG_D3D
LPD3DXBUFFER pShader;
LPD3DXBUFFER pErrorMsgs;
if (D3DXAssembleShader (dest.c_str(), (UINT)dest.size(), NULL, NULL, 0, &pShader, &pErrorMsgs) == D3D_OK)
{
if (_DeviceInterface->CreateVertexShader((DWORD*)pShader->GetBufferPointer(), &(getVertexProgramD3D(*program)->Shader)) != D3D_OK)
return false;
}
else
{
nlwarning ("Can't assemble vertex program:");
nlwarning ((const char*)pErrorMsgs->GetBufferPointer());
return false;
}
// Set parameters for assembly programs
drvInfo->ParamIndices = source->ParamIndices;
// Build the feature info
program->buildInfo(source);
}
return true;
}
// ***************************************************************************
bool CDriverD3D::activeVertexProgram (CVertexProgram *program)
{
H_AUTO_D3D(CDriverD3D_activeVertexProgram )
if (_DisableHardwareVertexProgram)
return false;
// Set the vertex program
if (program)
{
if (!CDriverD3D::compileVertexProgram(program)) return false;
CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast<CVertexProgamDrvInfosD3D *>((IProgramDrvInfos*)program->m_DrvInfo);
_VertexProgramUser = program;
setVertexProgram (info->Shader, program);
/* D3DRS_FOGSTART and D3DRS_FOGEND must be set with [1, 0] else the fog doesn't work properly on VertexShader and non-VertexShader objects
(random fog flicking) with Geforce4 TI 4200 (drivers 53.03 and 45.23). The other cards seam to interpret the "oFog"'s values using D3DRS_FOGSTART,
D3DRS_FOGEND.
Related to setUniformFog().
*/
float z = 0;
float o = 1;
setRenderState (D3DRS_FOGSTART, *((DWORD*) (&o)));
setRenderState (D3DRS_FOGEND, *((DWORD*) (&z)));
}
else
{
setVertexProgram (NULL, NULL);
_VertexProgramUser = NULL;
// Set the old fog range
setRenderState (D3DRS_FOGSTART, *((DWORD*) (&_FogStart)));
setRenderState (D3DRS_FOGEND, *((DWORD*) (&_FogEnd)));
}
return true;
}
// ***************************************************************************
void CDriverD3D::enableVertexProgramDoubleSidedColor(bool /* doubleSided */)
{
H_AUTO_D3D(CDriverD3D_enableVertexProgramDoubleSidedColor)
}
// ***************************************************************************
bool CDriverD3D::supportVertexProgramDoubleSidedColor() const
{
H_AUTO_D3D(CDriverD3D_supportVertexProgramDoubleSidedColor)
// Not supported under D3D
return false;
}
// ***************************************************************************
void CDriverD3D::disableHardwareVertexProgram()
{
H_AUTO_D3D(CDriverD3D_disableHardwareVertexProgram)
_DisableHardwareVertexProgram = true;
_VertexProgram = false;
}
// ***************************************************************************
} // NL3D

View file

@ -1,37 +0,0 @@
#include <windows.h>
#include "config.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION NL_VERSION_RC
PRODUCTVERSION NL_VERSION_RC
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "NeL Direct3D driver"
VALUE "FileVersion", NL_VERSION
VALUE "LegalCopyright", COPYRIGHT
#ifdef _DEBUG
VALUE "OriginalFilename", "nel_drv_direct3d_win_d.dll"
#else
VALUE "OriginalFilename", "nel_drv_direct3d_win_r.dll"
#endif
VALUE "ProductName", "Ryzom Core"
VALUE "ProductVersion", NL_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END

View file

@ -1,17 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddirect3d.h"

View file

@ -1,72 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef STDDIRECT3D_H
#define STDDIRECT3D_H
#if defined(_MSC_VER) && defined(_DEBUG)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
// System includes
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <algorithm>
#include <sstream>
#include <exception>
#include <utility>
#include <deque>
#include <limits>
// Default NeL includes
#include "nel/misc/types_nl.h"
#ifdef NL_DEBUG
// add Direct3D debug infos
#define D3D_DEBUG_INFO
#endif
// NeL includes
#include "nel/misc/common.h"
#include "nel/misc/debug.h"
#include "nel/misc/stream.h"
#include "nel/misc/mem_stream.h"
#include "nel/misc/time_nl.h"
#include "nel/misc/command.h"
#ifdef NL_OS_WINDOWS
# define WIN32_LEAN_AND_MEAN
# ifndef NL_COMP_MINGW
# define NOMINMAX
# endif
# include <windows.h>
#endif
// Directx includes
#include <d3d9.h>
#include <d3dx9math.h>
#endif

View file

@ -320,11 +320,6 @@ EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
#endif
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
#endif
#ifndef EGL_NV_coverage_sample_resolve
#define EGL_NV_coverage_sample_resolve 1
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
@ -435,11 +430,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, E
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
#endif
#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
#define EGL_ANGLE_d3d_share_handle_client_buffer 1
/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */
#endif
#ifndef EGL_KHR_create_context
#define EGL_KHR_create_context 1
#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION

View file

@ -2883,7 +2883,7 @@ IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType()
nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_NV, &result);
OcclusionType = result != 0 ? NotOccluded : Occluded;
VisibleCount = (uint) result;
// Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation (Direct3D ...)
// Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation ...
}
}
else

View file

@ -440,7 +440,7 @@ public:
virtual bool supportCloudRenderSinglePass() const;
virtual bool supportIndexOffset() const { return false; /* feature only supported in D3D for now */ }
virtual bool supportIndexOffset() const { return false; }
virtual bool slowUnlockVertexBufferHard() const;
@ -1006,7 +1006,6 @@ private:
bool setScreenMode(const GfxMode &mode);
// Test if cursor is in the client area. always true when software cursor is used and window visible
// (displayed in software when DirectInput is used)
bool isSystemCursorInClientArea();
// Check if RGBA cursors are supported

View file

@ -113,10 +113,6 @@ bool CDriverGL::isAlphaBlendedCursorSupported()
{
#ifdef NL_OS_WINDOWS
// Support starts with windows 2000 (not only from XP as seen in most docs)
// NB : Additionnaly, could query D3D caps to know if
// color hardware cursor is supported, not only emulated,
// but can't be sure that using the win32 api 'SetCursor' uses the same resources
// So far, seems to be supported on any modern card used by the game anyway ...
OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osvi))

View file

@ -88,9 +88,9 @@ void UDriver::setMatrixMode2D43()
}
// ***************************************************************************
UDriver *UDriver::createDriver(uintptr_t windowIcon, bool direct3d, emptyProc exitFunc)
UDriver *UDriver::createDriver(uintptr_t windowIcon, emptyProc exitFunc)
{
return new CDriverUser (windowIcon, direct3d ? CDriverUser::Direct3d:CDriverUser::OpenGl, exitFunc);
return new CDriverUser (windowIcon, CDriverUser::OpenGl, exitFunc);
}
// ***************************************************************************
@ -128,12 +128,6 @@ CDriverUser::CDriverUser (uintptr_t windowIcon, TDriver driver, emptyProc exitFu
_Driver = NULL;
// Create/Init Driver.
#if defined(NL_OS_WINDOWS)
if (driver == Direct3d)
_Driver= CDRU::createD3DDriver();
#endif
if (!_Driver && driver == OpenGl)
_Driver= CDRU::createGlDriver();
@ -1840,13 +1834,6 @@ UDriver::TCullMode CDriverUser::getCullMode() const
return (TCullMode) _Driver->getCullMode();
}
// ***************************************************************************
bool CDriverUser::isLost() const
{
NL3D_HAUTO_UI_DRIVER
return _Driver->isLost();
}
// ***************************************************************************
void CDriverUser::beginDialogMode()
{

View file

@ -29,9 +29,6 @@
# include "config.h"
#else
# define NL_OPENGL_AVAILABLE
# ifdef NL_OS_WINDOWS
# define NL_DIRECT3D_AVAILABLE
# endif
#endif // HAVE_CONFIG_H
#ifdef NL_OS_WINDOWS
@ -66,10 +63,6 @@ const char *IDRV_VERSION_PROC_NAME = "NL3D_interfaceVersion";
extern IDriver* createGlDriverInstance ();
#endif
#if defined(NL_OS_WINDOWS) && defined(NL_DIRECT3D_AVAILABLE)
extern IDriver* createD3DDriverInstance ();
#endif
#ifdef NL_OPENGLES_AVAILABLE
extern IDriver* createGlEsDriverInstance ();
#endif
@ -186,60 +179,6 @@ IDriver *CDRU::createGlEsDriver() throw (EDru)
// ***************************************************************************
#ifdef NL_OS_WINDOWS
IDriver *CDRU::createD3DDriver() throw (EDru)
{
#ifdef NL_STATIC
#ifdef NL_DIRECT3D_AVAILABLE
return createD3DDriverInstance ();
#else
return NULL;
#endif // NL_DIRECT3D_AVAILABLE
#else
IDRV_CREATE_PROC createDriver = NULL;
IDRV_VERSION_PROC versionDriver = NULL;
CLibrary driverLib;
if (!driverLib.loadLibrary(NL3D_D3D_DLL_NAME, true, true, false))
{
throw EDruDirect3dDriverNotFound();
}
nlinfo ("Using the library '" NL3D_D3D_DLL_NAME "' that is in the directory: '%s'", driverLib.getLibFileName().c_str());
createDriver = (IDRV_CREATE_PROC) driverLib.getSymbolAddress(IDRV_CREATE_PROC_NAME);
if (createDriver == NULL)
{
throw EDruDirect3dDriverCorrupted();
}
versionDriver = (IDRV_VERSION_PROC) driverLib.getSymbolAddress(IDRV_VERSION_PROC_NAME);
if (versionDriver != NULL)
{
if (versionDriver()<IDriver::InterfaceVersion)
throw EDruDirect3dDriverOldVersion();
else if (versionDriver()>IDriver::InterfaceVersion)
throw EDruDirect3dDriverUnknownVersion();
}
IDriver *ret= createDriver();
if (ret == NULL)
{
throw EDruDirect3dDriverCantCreateDriver();
}
return ret;
#endif
}
#endif // NL_OS_WINDOWS
// ***************************************************************************
void CDRU::drawBitmap (float x, float y, float width, float height, ITexture& texture, IDriver& driver, CViewport viewport, bool blend)
{
CMatrix mtx;

View file

@ -78,14 +78,6 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_VP(NULL), m_PP(NULL),
source->setSourcePtr(a_arbfp1);
m_PP->addSource(source);
}
// ps_2_0
{
IProgram::CSource *source = new IProgram::CSource();
source->Features.MaterialFlags = CProgramFeatures::TextureStages;
source->Profile = IProgram::ps_2_0;
source->setSourcePtr(a_ps_2_0);
m_PP->addSource(source);
}
if (!drv->compilePixelProgram(m_PP))
{
nlwarning("3D: No supported pixel program for FXAA effect");

View file

@ -105,7 +105,6 @@ void CFarVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb, bool forVertexP
if(VertexFormat & CVertexBuffer::PrimaryColorFlag)
{
ColorOff= vb.getColorOff();
// todo hulud d3d vertex color RGBA / BGRA
ColorPointer= Accessor.getColorPointer();
}
else

View file

@ -133,7 +133,7 @@ void CLight::setupAttenuation (float farAttenuationBegin, float farAttenuationEn
const float quadratic= 10.0f;
/*
With GL/D3D 'att=1/(c+l*r+q*r2)' formula, I think it is impossible to simulate correctly
With GL 'att=1/(c+l*r+q*r2)' formula, I think it is impossible to simulate correctly
farAttenuationBegin (very big decrase if for instance farAttenuationBegin is near farAttenuationEnd),
hence I simulate it very badly by multiplying the farAttenuationEnd by some factor
*/

View file

@ -444,7 +444,6 @@ bool CLodCharacterManager::addRenderCharacterKey(CLodCharacterInstance &instan
_LockDone= true;
}
// After lock, For D3D, the VertexColor may be in BGRA format
if(_VertexStream.isBRGA())
{
// then swap only the B and R (no cpu cycle added per vertex)

View file

@ -580,7 +580,6 @@ bool CMaterial::isSupportedByDriver(IDriver &drv, bool forceBaseCaps) const
{
uint numTexStages = drv.getNbTextureStages();
// special case for radeon : though 3 stages are supported, do as if there were only 2, because of the texEnvColor feature
// not managed in Direct3D : emulation is provided, but for no more than 2 constants (and if diffuse is not used)
if (numTexStages == 3) numTexStages = 2;
if (forceBaseCaps) numTexStages = std::min(numTexStages, (uint) 2);
switch(getShader())
@ -628,4 +627,3 @@ bool CMaterial::isSupportedByDriver(IDriver &drv, bool forceBaseCaps) const
}
}

View file

@ -196,7 +196,6 @@ void CMeshMorpher::update (std::vector<CAnimatedMorph> *pBSFactor)
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
if (!rBS.deltaCol.empty())
{
// todo hulud d3d vertex color RGBA / BGRA
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
CRGBAF rgbf(*pRGBA);
rgbf.R += rBS.deltaCol[j].R * rFactor;
@ -324,7 +323,6 @@ void CMeshMorpher::updateSkinned (std::vector<CAnimatedMorph> *pBSFactor)
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
if (!rBS.deltaCol.empty())
{
// todo hulud d3d vertex color RGBA / BGRA
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
CRGBAF rgbf(*pRGBA);
rgbf.R += rBS.deltaCol[j].R * rFactor;
@ -440,13 +438,3 @@ void CMeshMorpher::updateRawSkin (CVertexBuffer *vbOri,
} // NL3D

View file

@ -76,8 +76,7 @@ static const char* WindTreeVPCodeEnd=
DP4 o[HPOS].z, c[2], R5; \n\
DP4 o[HPOS].w, c[3], R5; \n\
MOV o[TEX0], v[8]; \n\
# hulud : remove this line for the moment because it doesn't work under d3d, if it is needed, we will have to create 2 CVertexProgram objects.\n\
#MOV o[TEX1], v[9]; \n\
MOV o[TEX1], v[9]; \n\
DP4 o[FOGC].x, c[6], R5; \n\
END \n\
";

View file

@ -51,7 +51,7 @@ CEventServer CNELU::EventServer;
CEventListenerAsync CNELU::AsyncListener;
bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen, bool direct3d) throw(EDru)
bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen) throw(EDru)
{
// Init debug system
// NLMISC::InitDebug();
@ -61,13 +61,6 @@ bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow syst
CNELU::Driver = NULL;
// Init driver.
#ifdef NL_OS_WINDOWS
if (direct3d)
{
CNELU::Driver= CDRU::createD3DDriver();
}
#endif
if (!CNELU::Driver)
{
CNELU::Driver= CDRU::createGlDriver();
@ -183,10 +176,10 @@ void CNELU::releaseDriver()
}
}
bool CNELU::init (uint w, uint h, CViewport viewport, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen, bool direct3d) throw(EDru)
bool CNELU::init (uint w, uint h, CViewport viewport, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen) throw(EDru)
{
NL3D::registerSerial3d();
if (initDriver(w,h,bpp,windowed,systemWindow,offscreen,direct3d))
if (initDriver(w,h,bpp,windowed,systemWindow,offscreen))
{
initScene(viewport);
initEventServer();

View file

@ -185,7 +185,6 @@ void CNoise3d::render2passes (CQuadUV &qc, float wpos, float alpha)
uint8 finalAlpha = (uint8)(255*alphaPos*alpha);
// todo hulud d3d vertex color RGBA / BGRA
uint8 *pColA = (uint8*)vba.getColorPointer(_NbVertices) + 3;
*pColA = finalAlpha; pColA = ((uint8*)pColA) + nVSize;
*pColA = finalAlpha; pColA = ((uint8*)pColA) + nVSize;
@ -260,7 +259,6 @@ void CNoise3d::render (CQuadUV &qc, float wpos, float intensity)
pUV = (CUV*)( ((uint8*)pUV) + nVSize );
*pUV = CUV(qc.Uv3.U*_ScaleW+_OffS[nSlice2].U, qc.Uv3.V*_ScaleH+_OffS[nSlice2].V);
// todo hulud d3d vertex color RGBA / BGRA
uint8 *pColA = (uint8*)vba.getColorPointer(_NbVertices) + 3;
*pColA = nAlphaPos; pColA = ((uint8*)pColA) + nVSize;
*pColA = nAlphaPos; pColA = ((uint8*)pColA) + nVSize;
@ -306,7 +304,6 @@ void CNoise3d::renderGrid (uint32 nbw, uint32 nbh, uint32 w, uint32 h,
pVertices = vba.getVertexCoordPointer(0);
pUV0 = vba.getTexCoordPointer (0, 0);
pUV1 = vba.getTexCoordPointer (0, 1);
// todo hulud d3d vertex color RGBA / BGRA
pColA = (uint8*)vba.getColorPointer(0) + 3;
for (j = 0; j < nbh; ++j)
@ -374,7 +371,6 @@ void CNoise3d::renderGrid2passes (uint32 nbw, uint32 nbh, uint32 w, uint32 h,
pVertices = vba.getVertexCoordPointer(0);
pUV0 = vba.getTexCoordPointer (0, 0);
// todo hulud d3d vertex color RGBA / BGRA
pColA = (uint8*)vba.getColorPointer(0) + 3;
for (j = 0; j < nbh; ++j)
@ -471,4 +467,3 @@ uint32 CNoise3d::getDepth ()
}
} // namespace NL3D

View file

@ -1952,7 +1952,6 @@ void CPSConstraintMesh::computeColors(CVertexBuffer &outVB, const CVertexBuffer
// TODO: optimisation : avoid to duplicate colors...
_ColorScheme->makeN(_Owner, startIndex, vba.getColorPointer(), outVB.getVertexSize(), toProcess, inVB.getNumVertices(), srcStep);
// modulate from the source mesh
// todo hulud d3d vertex color RGBA / BGRA
uint8 *vDest = (uint8 *) vba.getColorPointer();
uint8 *vSrc = (uint8 *) vbaIn.getColorPointer();
const uint vSize = outVB.getVertexSize();

View file

@ -485,7 +485,6 @@ void CPSQuad::updateVbColNUVForRender(CVertexBuffer &vb, uint32 startIndex, uint
if (_ColorScheme)
{
// compute the colors, each color is replicated 4 times
// todo hulud d3d vertex color RGBA / BGRA
_ColorScheme->make4(_Owner, startIndex, vba.getColorPointer(), vb.getVertexSize(), size, srcStep);
}

View file

@ -102,7 +102,6 @@ void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender, bool
nlwarning("Render trave begin");
#endif
H_AUTO( NL3D_TravRender );
if (getDriver()->isLost()) return; // device is lost so no need to render anything
CTravCameraScene::update();
// Bind to Driver.
setupDriverCamera();

View file

@ -179,7 +179,6 @@ CShadowMapManager::CShadowMapManager()
_ReceiveShadowMaterial.setTexCoordGen(0, true);
_ReceiveShadowMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace);
// Setup the stage so we interpolate ShadowColor and White (according to shadowmap alpha)
// nico : with D3D driver, limitation of the number of per stage constant (Only 1 if diffuse is used), so do a blend between inv diffuse & black (instead of diffuse & white), which resolve to a modulate between
// source alpha & inverse diffuse. then invert result at subsequent stage
_ReceiveShadowMaterial.texEnvOpRGB(0, CMaterial::Modulate);
_ReceiveShadowMaterial.texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::InvSrcColor);
@ -1242,4 +1241,3 @@ void CShadowMapManager::garbageShadowTextures(CScene *scene)
} // NL3D

View file

@ -1335,7 +1335,6 @@ void CVegetableManager::addInstance(CVegetableInstanceGroup *ig,
uint dstBendOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_BENDINFO);
uint dstCenterOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_CENTER);
// For D3D, If the VertexBuffer is in BGRA mode
if(allocator->isBGRA())
{
// then swap only the B and R (no cpu cycle added per vertex)
@ -2666,7 +2665,6 @@ uint CVegetableManager::updateInstanceLighting(CVegetableInstanceGroup *ig, uin
uint dstColor0Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR0);
uint dstColor1Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR1);
// For D3D, If the VertexBuffer is in BGRA mode
if(allocator->isBGRA())
{
// then swap only the B and R (no cpu cycle added per vertex)

View file

@ -153,7 +153,6 @@ void CVegetableShape::build(CVegetableShapeBuild &vbuild)
CUV *dstUVBend= vbaOut.getTexCoordPointer(i, 1);
if(bendFromColor)
{
// todo hulud d3d vertex color RGBA / BGRA
const CRGBA *srcColor= (const CRGBA*)vba.getColorPointer(i);
// Copy and scale by MaxBendWeight
dstUVBend->U= (srcColor->R / 255.f) * vbuild.MaxBendWeight;

View file

@ -56,7 +56,6 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence)
{
if (whence == SEEK_CUR && offset == 0)
{
// nlwarning(NLSOUND_XAUDIO2_PREFIX "This seek call doesn't do a damn thing, wtf.");
return 0; // ooookkaaaaaayyy
}
@ -75,7 +74,6 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence)
origin = NLMISC::IStream::end;
break;
default:
// nlwarning(NLSOUND_XAUDIO2_PREFIX "Seeking to fake origin.");
return -1;
}
@ -153,7 +151,6 @@ uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 m
getBitsPerSample() == 8 ? 1 : 2,
getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1.
&current_section);
// nlinfo(NLSOUND_XAUDIO2_PREFIX "current_section: %i", current_section);
if (br > 0)
{
bytes_read += (uint32)br;

View file

@ -374,9 +374,7 @@ void CAudioMixerUser::initDriver(const std::string &driverName)
ISoundDriver::TDriver driverType;
if (dn == "auto") driverType = ISoundDriver::DriverAuto;
else if (dn == "fmod") driverType = ISoundDriver::DriverFMod;
else if (dn == "dsound") driverType = ISoundDriver::DriverDSound;
else if (dn == "openal") driverType = ISoundDriver::DriverOpenAl;
else if (dn == "xaudio2") driverType = ISoundDriver::DriverXAudio2;
else
{
driverType = ISoundDriver::DriverAuto;
@ -2833,5 +2831,3 @@ NLMISC_CATEGORISED_COMMAND(nel, displaySoundProfile, "Display information on sou
} // NLSOUND

View file

@ -590,10 +590,10 @@ void CClusteredSound::soundTraverse(const std::vector<CCluster *> &clusters, CSo
CClusterSoundStatus css;
css.Gain = travContext.Gain;
CVector soundDir = (nearPos - travContext.ListenerPos).normed();
/* ****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
/* ****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
TStringId occId = portal->getOcclusionModelId();
TStringIntMap::iterator it(_IdToMaterial.find(occId));
****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
#if EAX_AVAILABLE == 1 // EAX_AVAILABLE no longer used => TODO: implement with EFX and remove when new implementation OK.
if (it != _IdToMaterial.end())
@ -612,14 +612,14 @@ void CClusteredSound::soundTraverse(const std::vector<CCluster *> &clusters, CSo
css.OcclusionRoomRatio = travContext.OcclusionRoomRatio;
}
#else // EAX_AVAILABLE
/* ****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
/* ****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
if (it != _IdToMaterial.end())
{
// found an occlusion material for this portal
uint matId = it->second;
css.Gain *= EAX_MATERIAL_PARAM[matId];
}
****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
#endif // EAX_AVAILABLE
/* if (portal->getOcclusionModel() == "wood door")
{

View file

@ -25,11 +25,3 @@ ENDIF()
IF(WITH_DRIVER_FMOD)
ADD_SUBDIRECTORY(fmod)
ENDIF()
IF(WITH_DRIVER_DSOUND)
ADD_SUBDIRECTORY(dsound)
ENDIF()
IF(WITH_DRIVER_XAUDIO2)
ADD_SUBDIRECTORY(xaudio2)
ENDIF()

View file

@ -1,21 +0,0 @@
FILE(GLOB SRC *.cpp *.h *.def *.rc)
NL_TARGET_DRIVER(nel_drv_dsound_win ${SRC})
INCLUDE_DIRECTORIES(BEFORE ${DXSDK_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(nel_drv_dsound_win nelmisc nelsnd_lowlevel ${DXSDK_DSOUND_LIBRARY})
NL_DEFAULT_PROPS(nel_drv_dsound_win "NeL, Driver, Sound: DirectSound")
NL_ADD_RUNTIME_FLAGS(nel_drv_dsound_win)
NL_ADD_LIB_SUFFIX(nel_drv_dsound_win)
IF(WITH_PCH)
ADD_NATIVE_PRECOMPILED_HEADER(nel_drv_dsound_win ${CMAKE_CURRENT_SOURCE_DIR}/stddsound.h ${CMAKE_CURRENT_SOURCE_DIR}/stddsound.cpp)
ENDIF()
IF((WITH_INSTALL_LIBRARIES AND WITH_STATIC_DRIVERS) OR NOT WITH_STATIC_DRIVERS)
INSTALL(TARGETS nel_drv_dsound_win RUNTIME DESTINATION ${NL_DRIVER_PREFIX} LIBRARY DESTINATION ${NL_DRIVER_PREFIX} ARCHIVE DESTINATION ${NL_LIB_PREFIX} COMPONENT driverssound)
IF(WITH_MAXPLUGIN)
INSTALL(TARGETS nel_drv_dsound_win RUNTIME DESTINATION maxplugin COMPONENT driverssound)
ENDIF()
ENDIF()

View file

@ -1,271 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddsound.h"
#include "buffer_dsound.h"
#include "sound_driver_dsound.h"
#define NOMINMAX
#include <windows.h>
#include <mmsystem.h>
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace NLMISC;
using namespace std;
namespace NLSOUND {
static const std::string EmptyString;
// Custom mutimedia IO proc.
/*LRESULT NelIOProc(LPSTR lpmmioinfo, UINT uMsg, LONG lParam1, LONG lParam2)
{
MMIOINFO *mmioinfo = (MMIOINFO*) lpmmioinfo;
switch (uMsg)
{
case MMIOM_OPEN:
{
// do some validity checking.
nlassert((mmioinfo->dwFlags & MMIO_CREATE) == 0);
char *fileName = (char*)lParam1;
std::string fullName = NLMISC::CPath::lookup(fileName, false);
if (fullName.empty())
{
mmioinfo->adwInfo[0] = NULL;
return MMIOERR_CANNOTOPEN;
}
NLMISC::CIFile *pfile = new NLMISC::CIFile(fullName);
mmioinfo->adwInfo[0] = (DWORD)pfile;
return MMSYSERR_NOERROR ;
}
break;
case MMIOM_CLOSE:
{
NLMISC::CIFile *file = (NLMISC::CIFile *)mmioinfo->adwInfo[0];
delete file;
return 0;
}
break;
case MMIOM_READ:
{
uint8 *pdst = (uint8*) lParam1;
uint bytes = (uint) lParam2;
nlassert(mmioinfo->adwInfo[0] != NULL);
NLMISC::CIFile *file = (NLMISC::CIFile *)mmioinfo->adwInfo[0];
bytes = std::min(uint(file->getFileSize() - file->getPos()), bytes);
file->serialBufferWithSize(pdst, bytes);
mmioinfo->lBufOffset = file->getPos();
return bytes;
}
break;
case MMIOM_SEEK:
{
uint newPos = (uint) lParam1;
uint seekMode = lParam2;
nlassert(mmioinfo->adwInfo[0] != NULL);
NLMISC::CIFile *file = (NLMISC::CIFile *)mmioinfo->adwInfo[0];
switch(seekMode)
{
case SEEK_CUR:
file->seek(newPos, NLMISC::IStream::current);
break;
case SEEK_END:
file->seek(newPos, NLMISC::IStream::end);
break;
case SEEK_SET:
file->seek(newPos, NLMISC::IStream::begin);
break;
}
mmioinfo->lBufOffset = file->getPos();
return mmioinfo->lBufOffset;
}
break;
case MMIOM_WRITE:
nlassert("Mutimedia IO write is not supported !");
break;
case MMIOM_WRITEFLUSH:
nlassert("Mutimedia IO write is not supported !");
break;
}
}
*/
CBufferDSound::CBufferDSound() : _Data(NULL), _Capacity(0), _Size(0)
{
_Name = CStringMapper::map(EmptyString);
_Format = Mono16;
_Freq = 0;
}
CBufferDSound::~CBufferDSound()
{
// nldebug("Destroying DirectSound buffer %s (%p)", CSoundDriverDSound::instance()->getStringMapper()->unmap(_Name).c_str(), this);
if (_Data)
{
delete[] _Data;
_Data = NULL;
}
}
void CBufferDSound::setName(NLMISC::TStringId bufferName)
{
_Name = bufferName;
}
/// Set the sample format. (channels = 1, 2, ...; bitsPerSample = 8, 16; frequency = samples per second, 44100, ...)
void CBufferDSound::setFormat(TBufferFormat format, uint8 channels, uint8 bitsPerSample, uint32 frequency)
{
bufferFormatToSampleFormat(format, channels, bitsPerSample, _Format);
_Freq = frequency;
}
/// Get a writable pointer to the buffer of specified size. Returns NULL in case of failure. It is only guaranteed that the original data is still available when using StorageSoftware and the specified size is not larger than the available data. Call setStorageMode() and setFormat() first.
uint8 *CBufferDSound::lock(uint capacity)
{
if (_Data)
{
if (capacity > _Capacity)
{
delete[] _Data;
_Data = NULL;
}
}
if (!_Data)
{
_Data = new uint8[capacity];
_Capacity = capacity;
if (_Size > capacity)
_Size = capacity;
}
return _Data;
}
/// Notify that you are done writing to this buffer, so it can be copied over to hardware if needed. Returns true if ok.
bool CBufferDSound::unlock(uint size)
{
if (size > _Capacity)
{
_Size = _Capacity;
return false;
}
else
{
_Size = size;
return true;
}
}
/// Copy the data with specified size into the buffer. A readable local copy is only guaranteed when OptionLocalBufferCopy is set. Returns true if ok.
bool CBufferDSound::fill(const uint8 *src, uint size)
{
uint8 *dest = lock(size);
if (dest == NULL) return false;
CFastMem::memcpy(dest, src, size);
return unlock(size);
}
/// Return the sample format information.
void CBufferDSound::getFormat(TBufferFormat &format, uint8 &channels, uint8 &bitsPerSample, uint32 &frequency) const
{
sampleFormatToBufferFormat(_Format, format, channels, bitsPerSample);
frequency = _Freq;
}
/// Return the size of the buffer, in bytes.
uint CBufferDSound::getSize() const
{
return _Size;
}
float CBufferDSound::getDuration() const
{
float frames = (float) _Size;
switch (_Format)
{
case Mono8:
break;
case Mono16ADPCM:
frames *= 2.0f;
break;
case Mono16:
frames /= 2.0f;
break;
case Stereo8:
frames /= 2.0f;
break;
case Stereo16:
frames /= 4.0f;
break;
}
return 1000.0f * frames / (float) _Freq;
}
bool CBufferDSound::isStereo() const
{
return (_Format == Stereo8) || (_Format == Stereo16);
}
/// Return the name of this buffer
NLMISC::TStringId CBufferDSound::getName() const
{
return _Name;
}
/// Return true if the buffer is loaded. Used for async load/unload.
bool CBufferDSound::isBufferLoaded() const
{
return _Data != NULL;
}
/// Set the storage mode of this buffer, call before filling this buffer. Storage mode is always software if OptionSoftwareBuffer is enabled. Default is auto.
void CBufferDSound::setStorageMode(TStorageMode /* storageMode */)
{
// software buffering, no hardware storage mode available
}
/// Get the storage mode of this buffer.
IBuffer::TStorageMode CBufferDSound::getStorageMode()
{
// always uses software buffers
return IBuffer::StorageSoftware;
}
} // NLSOUND

View file

@ -1,102 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_BUFFER_DSOUND_H
#define NL_BUFFER_DSOUND_H
#include "nel/sound/driver/buffer.h"
namespace NLSOUND {
/**
* Buffer for the DSound implementation of the audio driver.
*
* A buffer represents a sound file loaded in RAM.
*
* \author Peter Hanappe, Olivier Cado
* \author Nevrax France
* \date 2002
*/
class CBufferDSound : public IBuffer
{
public:
/// Constructor
CBufferDSound();
/// Destructor
virtual ~CBufferDSound();
/// Return a pointer to the sample data
inline const uint8 *getData() const { return _Data; }
/** Preset the name of the buffer. Used for async loading to give a name
* before the buffer is effectivly loaded.
* If the name after loading of the buffer doesn't match the preset name,
* the load will assert.
*/
virtual void setName(NLMISC::TStringId bufferName);
/// Return the name of this buffer
virtual NLMISC::TStringId getName() const;
/// Set the sample format. (channels = 1, 2, ...; bitsPerSample = 8, 16; frequency = samples per second, 44100, ...)
virtual void setFormat(TBufferFormat format, uint8 channels, uint8 bitsPerSample, uint32 frequency);
/// Return the sample format information.
virtual void getFormat(TBufferFormat &format, uint8 &channels, uint8 &bitsPerSample, uint32 &frequency) const;
/// Set the storage mode of this buffer, call before filling this buffer. Storage mode is always software if OptionSoftwareBuffer is enabled. Default is auto.
virtual void setStorageMode(TStorageMode storageMode = IBuffer::StorageAuto);
/// Get the storage mode of this buffer.
virtual TStorageMode getStorageMode();
/// Get a writable pointer to the buffer of specified size. Use capacity to specify the required bytes. Returns NULL in case of failure. It is only guaranteed that the original data is still available when using StorageSoftware and the specified size is not larger than the size specified in the last lock. Call setStorageMode() and setFormat() first.
virtual uint8 *lock(uint capacity);
/// Notify that you are done writing to this buffer, so it can be copied over to hardware if needed. Set size to the number of bytes actually written to the buffer. Returns true if ok.
virtual bool unlock(uint size);
/// Copy the data with specified size into the buffer. A readable local copy is only guaranteed when OptionLocalBufferCopy is set. Returns true if ok.
virtual bool fill(const uint8 *src, uint size);
/// Return the size of the buffer, in bytes.
virtual uint getSize() const;
/// Return the duration (in ms) of the sample in the buffer.
virtual float getDuration() const;
/// Return true if the buffer is stereo (multi-channel), false if mono.
virtual bool isStereo() const;
/// Return true if the buffer is loaded. Used for async load/unload.
virtual bool isBufferLoaded() const;
private:
NLMISC::TStringId _Name;
/// The sample data in this buffer.
uint8 *_Data;
/// The capacity of the buffer
uint _Capacity;
/// The size of the data in the buffer
uint _Size;
TSampleFormat _Format;
uint _Freq;
#if USE_LOCDEFER
LPDIRECTSOUNDBUFFER _SecondaryBuffer;
LPDIRECTSOUND3DBUFFER _3DBuffer;
#endif
};
} // NLSOUND
#endif // NL_BUFFER_DSOUND_H

View file

@ -1,4 +0,0 @@
EXPORTS NLSOUND_createISoundDriverInstance
EXPORTS NLSOUND_interfaceVersion
EXPORTS NLSOUND_outputProfile
EXPORTS NLSOUND_getDriverType

View file

@ -1,376 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddsound.h"
#include "listener_dsound.h"
#include "sound_driver_dsound.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace NLMISC;
namespace NLSOUND {
// The instance of the singleton
CListenerDSound *CListenerDSound::_Instance = NULL;
/*
* Constructor
*/
CListenerDSound::CListenerDSound(LPDIRECTSOUND3DLISTENER dsoundListener) //: IListener()
: _Pos(CVector::Null)
{
#if EAX_AVAILABLE == 1
_EAXListener = 0;
#endif
if ( _Instance == NULL )
{
_Instance = this;
_Listener = dsoundListener;
if (CSoundDriverDSound::instance()->getOption(ISoundDriver::OptionManualRolloff))
{
// Manual RollOff => disable API rollOff
if ( !_Listener || FAILED(_Listener->SetRolloffFactor(DS3D_MINROLLOFFFACTOR, DS3D_DEFERRED)))
{
nlwarning("SetRolloffFactor failed");
}
}
}
else
{
//nlerror( "Listener singleton instanciated twice" );
}
}
CListenerDSound::~CListenerDSound()
{
nldebug("Destroying DirectSound listener");
release();
_Instance = NULL;
}
/*
* Release all DirectSound resources
*/
void CListenerDSound::release()
{
if (_Listener != NULL)
{
_Listener->Release();
_Listener = NULL;
}
#if EAX_AVAILABLE == 1
if (_EAXListener != NULL)
{
_EAXListener->Release();
_EAXListener = NULL;
}
#endif
}
/*
* Set the position vector (default: (0,0,0)) (3D mode only)
*/
void CListenerDSound::setPos( const NLMISC::CVector& pos )
{
_Pos = pos;
// Coordinate system: conversion from NeL to OpenAL/GL:
if (_Listener != NULL)
{
if (FAILED(_Listener->SetPosition(pos.x, pos.z, pos.y, DS3D_DEFERRED)))
{
nlwarning("SetPosition failed");
}
else
{
//nlwarning ("set listener NEL(p:%.2f/%.2f/%.2f) DS(p:%.2f/%.2f/%.2f)", pos.x, pos.y, pos.z, pos.x, pos.z, pos.y);
}
}
}
/** Get the position vector.
* See setPos() for details.
*/
const NLMISC::CVector &CListenerDSound::getPos() const
{
return _Pos;
/* return;
// Coordinate system: conversion from NeL to OpenAL/GL:
if (_Listener != NULL)
{
D3DVECTOR v;
if (FAILED(_Listener->GetPosition(&v)))
{
nlwarning("GetPosition failed");
pos.set(0.0f, 0.0f, 0.0f);
}
else
{
pos.set(v.x, v.z, v.y);
}
}
else
{
pos.set(0, 0, 0);
}
*/
}
/*
* Set the velocity vector (3D mode only)
*/
void CListenerDSound::setVelocity( const NLMISC::CVector& vel )
{
if (_Listener != NULL)
{
if (FAILED(_Listener->SetVelocity(vel.x, vel.z, vel.y, DS3D_DEFERRED)))
{
nlwarning("SetVelocity failed");
}
}
}
/*
* Get the velocity vector
*/
void CListenerDSound::getVelocity( NLMISC::CVector& vel ) const
{
if (_Listener != NULL)
{
D3DVECTOR v;
if (FAILED(_Listener->GetVelocity(&v)))
{
nlwarning("GetVelocity failed");
vel.set(0.0f, 0.0f, 0.0f);
}
else
{
vel.set(v.x, v.z, v.y);
}
}
else
{
vel.set(0, 0, 0);
}
}
/*
* Set the orientation vectors (3D mode only)
*/
void CListenerDSound::setOrientation( const NLMISC::CVector& front, const NLMISC::CVector& up )
{
if (_Listener != NULL)
{
if (FAILED(_Listener->SetOrientation(front.x, front.z, front.y, up.x, up.z, up.y, DS3D_DEFERRED)))
{
nlwarning("SetOrientation failed");
}
else
{
//nlwarning ("NLSOUND: set listener orientation NEL(f:%.2f/%.2f/%.2f up:%.2f/%.2f/%.2f) DS(f:%.2f/%.2f/%.2f up:%.2f/%.2f/%.2f)", front.x, front.y, front.z, up.x, up.y, up.z, front.x, front.z, front.y, up.x, up.z, up.y);
}
}
}
/*
* Get the orientation vectors
*/
void CListenerDSound::getOrientation( NLMISC::CVector& front, NLMISC::CVector& up ) const
{
if (_Listener != NULL)
{
D3DVECTOR vfront, vtop;
if (FAILED(_Listener->GetOrientation(&vfront, &vtop)))
{
nlwarning("GetOrientation failed");
front.set(0.0f, 0.0f, 1.0f);
up.set(0.0f, 1.0f, 0.0f);
}
else
{
front.set(vfront.x, vfront.z, vfront.y);
up.set(vtop.x, vtop.z, vtop.y);
}
}
else
{
front.set(0, 0, 1);
up.set(0, 1, 0);
}
}
/* Set the gain (volume value inside [0 , 1]). (default: 1)
* 0.0 -> silence
* 0.5 -> -6dB
* 1.0 -> no attenuation
* values > 1 (amplification) not supported by most drivers
*/
void CListenerDSound::setGain( float gain )
{
CSoundDriverDSound::instance()->setGain(gain);
}
/*
* Get the gain
*/
float CListenerDSound::getGain() const
{
return CSoundDriverDSound::instance()->getGain();
}
/*
* Set the doppler factor (default: 1) to exaggerate or not the doppler effect
*/
void CListenerDSound::setDopplerFactor( float f )
{
if (_Listener != NULL)
{
if (f > DS3D_MAXDOPPLERFACTOR)
{
f = DS3D_MAXDOPPLERFACTOR;
}
else if (f < DS3D_MINDOPPLERFACTOR)
{
f = DS3D_MINDOPPLERFACTOR;
}
if (FAILED(_Listener->SetDopplerFactor(f, DS3D_DEFERRED)))
{
nlwarning("SetDopplerFactor failed");
}
}
}
/*
* Set the rolloff factor (default: 1) to scale the distance attenuation effect
*/
void CListenerDSound::setRolloffFactor( float f )
{
// Works only in API rolloff mode
nlassert(!CSoundDriverDSound::instance()->getOption(ISoundDriver::OptionManualRolloff));
if (!CSoundDriverDSound::instance()->getOption(ISoundDriver::OptionManualRolloff))
{
if (_Listener != NULL)
{
clamp(f, DS3D_MINROLLOFFFACTOR, DS3D_MAXROLLOFFFACTOR);
if (FAILED(_Listener->SetRolloffFactor(f, DS3D_DEFERRED)))
{
nlwarning("SetRolloffFactor failed");
}
}
}
}
float CListenerDSound::getRolloffFactor()
{
// Works only in API rolloff mode
nlassert(!CSoundDriverDSound::instance()->instance()->getOption(ISoundDriver::OptionManualRolloff));
if (!CSoundDriverDSound::instance()->instance()->getOption(ISoundDriver::OptionManualRolloff))
{
if (_Listener != NULL)
{
float f;
_Listener->GetRolloffFactor(&f);
return f;
}
}
return 1.f;
}
void CListenerDSound::commit3DChanges()
{
if (_Listener != NULL)
{
_Listener->CommitDeferredSettings();
}
}
/*
* Set DSPROPERTY_EAXLISTENER_ENVIRONMENT and DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE if EAX available (see EAX listener properties)
*/
#if EAX_AVAILABLE == 1
void CListenerDSound::setEnvironment(uint env, float size)
{
if (_EAXListener == NULL)
{
_EAXListener = CSoundDriverDSound::instance()->createPropertySet(NULL);
}
if ( _EAXListener != NULL )
{
HRESULT res = _EAXListener->Set( DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, NULL, 0, &env, sizeof(unsigned long) );
if (res != S_OK)
nlwarning("Setting EAX environment #%u fail : %x", env, res);
res = _EAXListener->Set( DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE, NULL, 0, &size, sizeof(float) );
if (res != S_OK)
nlwarning("Setting EAX environment size %f fail : %x", size, res);
}
#else
void CListenerDSound::setEnvironment(uint /* env */, float /* size */)
{
#endif
}
/*
* Set any EAX listener property if EAX available
*/
#if EAX_AVAILABLE
void CListenerDSound::setEAXProperty(uint prop, void *value, uint valuesize)
{
if (_EAXListener == NULL)
{
_EAXListener = CSoundDriverDSound::instance()->createPropertySet(NULL);
}
if ( _EAXListener != NULL )
{
HRESULT res = _EAXListener->Set(DSPROPSETID_EAX_ListenerProperties, prop, NULL, 0, value, valuesize );
if (res != S_OK)
nlwarning("Setting EAX listener prop #%d fail : %x", prop, res);
}
#else
void CListenerDSound::setEAXProperty(uint /* prop */, void * /* value */, uint /* valuesize */)
{
#endif
}
} // NLSOUND

View file

@ -1,132 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_LISTENER_DSOUND_H
#define NL_LISTENER_DSOUND_H
#include "nel/sound/driver/listener.h"
namespace NLSOUND {
/**
* DirectSound listener.
*
* For arguments as 3D vectors, use the NeL vector coordinate system
* (not OpenAL/OpenGL's one).
*
* \author Peter Hanappe, Olivier Cado
* \author Nevrax France
* \date 2002
*/
class CListenerDSound : public IListener
{
friend class CSoundDriverDSound;
public:
/// Constructor
CListenerDSound(LPDIRECTSOUND3DLISTENER dsoundListener);
/// Deconstructor
virtual ~CListenerDSound();
/// Return the instance of the singleton
static CListenerDSound* instance() { return _Instance; }
/// \name Listener properties
//@{
/// Set the position vector (default: (0,0,0)) (3D mode only)
virtual void setPos( const NLMISC::CVector& pos );
/** Get the position vector.
* See setPos() for details.
*/
virtual const NLMISC::CVector &getPos() const;
/// Set the velocity vector (3D mode only) (default: (0,0,0))
virtual void setVelocity( const NLMISC::CVector& vel );
/// Get the velocity vector
virtual void getVelocity( NLMISC::CVector& vel ) const;
/// Set the orientation vectors (3D mode only) (default: (0,1,0), (0,0,1))
virtual void setOrientation( const NLMISC::CVector& front, const NLMISC::CVector& up );
/// Get the orientation vectors
virtual void getOrientation( NLMISC::CVector& front, NLMISC::CVector& up ) const;
/** Set the gain (volume value inside [0 , 1]). (default: 1)
* 0.0 -> silence
* 0.5 -> -6dB
* 1.0 -> no attenuation
* values > 1 (amplification) not supported by most drivers
*/
virtual void setGain( float gain );
/// Get the gain
virtual float getGain() const;
//@}
/// \name Global properties
//@{
/// Set the doppler factor (default: 1) to exaggerate or not the doppler effect
virtual void setDopplerFactor( float f );
/// Set the rolloff factor (default: 1) to scale the distance attenuation effect
virtual void setRolloffFactor( float f );
/// Return the rolloff factor
virtual float getRolloffFactor();
/// Set DSPROPERTY_EAXLISTENER_ENVIRONMENT and DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE if EAX available (see EAX listener properties)
virtual void setEnvironment( uint env, float size=7.5f );
/// Set any EAX listener property if EAX available
virtual void setEAXProperty( uint prop, void *value, uint valuesize );
//@}
/// Commit any changes to the 3D environment
void commit3DChanges();
private:
/// Release all DirectSound resources
void release();
/// The instance of the singleton
static CListenerDSound *_Instance;
/// The DirectSound listener interface
LPDIRECTSOUND3DLISTENER _Listener;
// TMP : TEST
NLMISC::CVector _Pos;
#if EAX_AVAILABLE == 1
LPKSPROPERTYSET _EAXListener;
#endif
};
} // NLSOUND
#endif // NL_LISTENER_DSOUND_H

View file

@ -1,37 +0,0 @@
#include <windows.h>
#include "config.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION NL_VERSION_RC
PRODUCTVERSION NL_VERSION_RC
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "NeL DirectSound driver"
VALUE "FileVersion", NL_VERSION
VALUE "LegalCopyright", COPYRIGHT
#ifdef _DEBUG
VALUE "OriginalFilename", "nel_drv_dsound_win_d.dll"
#else
VALUE "OriginalFilename", "nel_drv_dsound_win_r.dll"
#endif
VALUE "ProductName", "Ryzom Core"
VALUE "ProductVersion", NL_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END

File diff suppressed because it is too large Load diff

View file

@ -1,214 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_SOUND_DRIVER_DSOUND_H
#define NL_SOUND_DRIVER_DSOUND_H
#include "nel/sound/driver/sound_driver.h"
#include "source_dsound.h"
#include "buffer_dsound.h"
namespace NLSOUND {
class IListener;
class ISource;
class IBuffer;
class CListenerDSound;
class CSourceDSound;
class CBufferDSound;
class CSoundDriverDSound : public ISoundDriver
{
public:
/// Constructor
CSoundDriverDSound(ISoundDriver::IStringMapperProvider *stringMapper);
virtual ~CSoundDriverDSound();
/// Return the instance of the singleton
static CSoundDriverDSound *instance() { return _Instance; }
/// Return a list of available devices for the user. The value at index 0 is empty, and is used for automatic device selection.
virtual void getDevices(std::vector<std::string> &devices);
/// Initialize the driver with a user selected device. If device.empty(), the default or most appropriate device is used.
virtual void initDevice(const std::string &device, TSoundOptions options);
/// Return options that are enabled (including those that cannot be disabled on this driver).
virtual TSoundOptions getOptions();
/// Return if an option is enabled (including those that cannot be disabled on this driver).
virtual bool getOption(TSoundOptions option);
/// Create the listener instance
virtual IListener *createListener();
/// Create a sound buffer
virtual IBuffer *createBuffer();
// Source management
/// Create a source
virtual ISource *createSource();
/// Commit all the changes made to 3D settings of listener and sources
virtual void commit3DChanges();
/// Return the maximum number of sources that can created
virtual uint countMaxSources();
/// Count the number of available hardware streaming 3D buffers
uint countHw3DBuffers();
/// Count the number of available hardware streaming 2D buffers
uint countHw2DBuffers();
/// Count the number of sources that are actually playing.
uint countPlayingSources();
/// Update all the driver and its sources. To be called only by the timer callback.
void update();
/// Write information about the driver to the output stream.
void writeProfile(std::string& out);
/** Set the gain (volume value inside [0 , 1]). (default: 1)
* 0.0 -> silence
* 0.5 -> -6dB
* 1.0 -> no attenuation
* values > 1 (amplification) not supported by most drivers
*/
void setGain( float gain );
/// Get the gain
float getGain();
/// Return the string mapper
IStringMapperProvider *getStringMapper() {return _StringMapper;}
#if EAX_AVAILABLE == 1
LPKSPROPERTYSET createPropertySet(CSourceDSound *source);
#endif
/// Create a music channel, destroy with destroyMusicChannel
virtual IMusicChannel *createMusicChannel() { return NULL; }
/// Destroy a music channel
virtual void destroyMusicChannel(IMusicChannel * /* musicChannel */) { nlassert(false); }
/** Get music info. Returns false if the song is not found or the function is not implemented.
* If the song has no name, result is filled with the filename.
* \param filepath path to file, CPath::lookup done by driver
* \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available)
*/
virtual bool getMusicInfo(const std::string & /* filepath */, std::string &artist, std::string &title, float &length) { artist.clear(); title.clear(); length = 0.f; return false; }
private:
// The callback for the multimedia timer
static void CALLBACK TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
// The refence to the singleton.
static CSoundDriverDSound* _Instance;
// The period of the timer.
static uint32 _TimerPeriod;
friend CBufferDSound::~CBufferDSound();
friend CSourceDSound::~CSourceDSound();
/// Remove a buffer (should be called by the friend destructor of the buffer class)
virtual void removeBuffer(IBuffer *buffer);
/// Remove a source (should be called by the friend destructor of the source class)
virtual void removeSource(ISource *source);
virtual void startBench();
virtual void endBench();
virtual void displayBench(NLMISC::CLog *log);
/// Get audio/container extensions that are supported natively by the driver implementation.
virtual void getMusicExtensions(std::vector<std::string> & /* extensions */) const { }
/// Return if a music extension is supported by the driver's music channel.
virtual bool isMusicExtensionSupported(const std::string & /* extension */) const { return false; }
// The DirectSound object
LPDIRECTSOUND _DirectSound;
// The application-wide primary buffer
LPDIRECTSOUNDBUFFER _PrimaryBuffer;
// The capabilities of the driver
DSCAPS _Caps;
// Array with the allocated sources
//CSourceDSound** _Sources;
std::set<CSourceDSound*> _Sources;
// The number of allocated sources
uint _SourceCount;
// The Windows ID of the multimedia timer used in the update.
UINT _TimerID;
// The timer resolution.
uint32 _TimerResolution;
/// The EAX support is requested and accepted (ie, there is enougth hardware 3D buffer)
bool _UseEAX;
/// The string mapper provided by client code
IStringMapperProvider *_StringMapper;
/// Driver options
TSoundOptions _Options;
#if NLSOUND_PROFILE
protected:
uint _TimerInterval[1024];
uint _TimerIntervalCount;
NLMISC::TTicks _TimerDate;
double _TotalTime;
double _TotalUpdateTime;
uint32 _UpdateCount;
uint32 _UpdateSources;
uint32 _UpdateExec;
public:
void printDriverInfo(FILE* fp);
uint countTimerIntervals();
uint getTimerIntervals(uint index);
void addTimerInterval(uint32 dt);
double getCPULoad();
double getTotalTime() { return _TotalTime; };
double getAverageUpdateTime() { return (_UpdateCount) ? _TotalUpdateTime / _UpdateCount : 0.0; }
uint32 getAverageUpdateSources() { return (_UpdateExec) ? _UpdateSources / _UpdateExec : 0; }
double getUpdatePercentage() { return (_UpdateCount) ? (double) _UpdateExec / (double) _UpdateCount: 0; }
#endif
};
} // NLSOUND
#endif // NL_SOUND_DRIVER_DSOUND_H

File diff suppressed because it is too large Load diff

View file

@ -1,517 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_SOURCE_DSOUND_H
#define NL_SOURCE_DSOUND_H
#include "nel/sound/driver/source.h"
#include "nel/sound/driver/sound_driver.h"
#include "nel/sound/driver/buffer.h"
namespace NLSOUND {
class CBufferDSound;
/** Keep trace of following states of the DirectSound buffer:
* - the buffer is being filled with samples (filling),
* - the buffer still contains samples but silence is being written (silencing),
* - the buffer contains no samples but only silence (silenced)
*/
/*enum TSourceDSoundBufferState
{
/// The buffer is being filled with samples (filling),
NL_DSOUND_FILLING,
/// The buffer still contains samples but silence is being written (silencing),
NL_DSOUND_SILENCING,
/// The buffer contains no samples but only silence (silenced)
NL_DSOUND_SILENCED
} ;
/*
/** The state of the source as experienced by the user: playing, paused, and stopped. */
/*
enum TSourceDSoundUserState
{
/// The buffer is playing.
NL_DSOUND_PLAYING,
/// The buffer is paused.
NL_DSOUND_PAUSED,
/// The buffer is stopped.
NL_DSOUND_STOPPED
};
*/
/** To figger out whether the sound device has played all the samples in the buffer,
* the position of the play cursor is traced relatively to the position of the last
* sample in the buffer.
*/
/*
enum TSourceDSoundEndState
{
NL_DSOUND_TAIL1,
NL_DSOUND_TAIL2,
NL_DSOUND_ENDED
};
*/
/**
* DirectSound sound source
*
* For arguments as 3D vectors, use the NeL vector coordinate system
*
* \author Peter Hanappe
* \author Nevrax France
* \date 2002
*/
class CSourceDSound : public ISource
{
friend class CSoundDriverDSound;
public:
/// Constructor
CSourceDSound(uint sourcename = 0);
/// Destructor
virtual ~CSourceDSound();
/// Initialize the DirectSound buffers. Called by the sound driver only.
void init(LPDIRECTSOUND directSound, bool useEax);
/// \name Initialization
//@{
/// Enable or disable streaming mode. Source must be stopped to call this.
virtual void setStreaming(bool streaming);
/** Set the buffer that will be played (no streaming)
* If the buffer is stereo, the source mode becomes stereo and the source relative mode is on,
* otherwise the source is considered as a 3D source. Use submitStreamingBuffer for streaming.
*/
virtual void setStaticBuffer(IBuffer *buffer);
/// Return the buffer, or NULL if streaming is used. Not available for streaming.
virtual IBuffer *getStaticBuffer();
/// Add a buffer to the streaming queue. A buffer of 100ms length is optimal for streaming.
/// Should be called by a thread which checks countStreamingBuffers every 100ms.
virtual void submitStreamingBuffer(IBuffer *buffer);
/// Return the amount of buffers in the queue (playing and waiting). 3 buffers is optimal.
virtual uint countStreamingBuffers() const;
//@}
/// \name Playback control
//@{
/// Set looping on/off for future playbacks (default: off), not available for streaming
virtual void setLooping(bool l);
/// Return the looping state
virtual bool getLooping() const;
/** Play the static buffer (or stream in and play).
* This method can return false if the sample for this sound is unloaded.
*/
virtual bool play();
/// Stop playing
virtual void stop();
/// Pause. Call play() to resume.
virtual void pause();
/// Return true if play() or pause(), false if stop().
virtual bool isPlaying() const;
/// Return true if playing is finished or stop() has been called.
virtual bool isStopped() const;
/// Return true if the playing source is paused
virtual bool isPaused() const;
/// Returns the number of milliseconds the source has been playing
virtual uint32 getTime();
//@}
/// \name Source properties
//@{
/** Set the position vector (default: (0,0,0)).
* 3D mode -> 3D position
* st mode -> x is the pan value (from left (-1) to right (1)), set y and z to 0
*/
virtual void setPos(const NLMISC::CVector& pos, bool deffered = true);
/** Get the position vector.
* See setPos() for details.
*/
virtual const NLMISC::CVector &getPos() const;
/// Set the velocity vector (3D mode only, ignored in stereo mode) (default: (0,0,0))
virtual void setVelocity(const NLMISC::CVector& vel, bool deferred = true);
/// Get the velocity vector
virtual void getVelocity(NLMISC::CVector& vel) const;
/// Set the direction vector (3D mode only, ignored in stereo mode) (default: (0,0,0) as non-directional)
virtual void setDirection(const NLMISC::CVector& dir);
/// Get the direction vector
virtual void getDirection(NLMISC::CVector& dir) const;
/** Set the gain (volume value inside [0 , 1]). (default: 1)
* 0.0 -> silence
* 0.5 -> -6dB
* 1.0 -> no attenuation
* values > 1 (amplification) not supported by most drivers
*/
virtual void setGain(float gain);
/// Get the gain
virtual float getGain() const;
/** Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift
* of one octave. 0 is not a legal value.
*/
virtual void setPitch(float pitch);
/// Get the pitch
virtual float getPitch() const;
/// Set the source relative mode. If true, positions are interpreted relative to the listener position
virtual void setSourceRelativeMode(bool mode);
/// Get the source relative mode
virtual bool getSourceRelativeMode() const;
/// Set the min and max distances (default: 1, MAX_FLOAT) (3D mode only)
virtual void setMinMaxDistances(float mindist, float maxdist, bool deferred = true);
/// Get the min and max distances
virtual void getMinMaxDistances(float& mindist, float& maxdist) const;
/// Set the cone angles (in radian) and gain (in [0 , 1]) (default: 2PI, 2PI, 0)
virtual void setCone(float innerAngle, float outerAngle, float outerGain);
/// Get the cone angles (in radian)
virtual void getCone(float& innerAngle, float& outerAngle, float& outerGain) const;
/** Set the alpha value for the volume-distance curve
*
* Useful only with OptionManualRolloff. value from -1 to 1 (default 0)
*
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
* is the default used by DirectSound/OpenAL
*
* For any other value of alpha, an interpolation is be done between the two
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
* the linear dB curve and the linear amplitude curve.
*/
virtual void setAlpha(double a);
//@}
/// \name Direct output
//@{
/// Enable or disable direct output [true/false], default: true
virtual void setDirect(bool enable = true);
/// Return if the direct output is enabled
virtual bool getDirect() const;
/// Set the gain for the direct path
virtual void setDirectGain(float gain);
/// Get the gain for the direct path
virtual float getDirectGain() const;
/// Enable or disable the filter for the direct channel
virtual void enableDirectFilter(bool enable = true);
/// Check if the filter on the direct channel is enabled
virtual bool isDirectFilterEnabled() const;
/// Set the filter parameters for the direct channel
virtual void setDirectFilter(TFilter filter, float lowFrequency, float highFrequency, float passGain);
/// Get the filter parameters for the direct channel
virtual void getDirectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const;
/// Set the direct filter gain
virtual void setDirectFilterPassGain(float passGain);
/// Get the direct filter gain
virtual float getDirectFilterPassGain() const;
//@}
/// \name Effect output
//@{
/// Set the effect send for this source, NULL to disable. [IEffect], default: NULL
virtual void setEffect(IReverbEffect *reverbEffect);
/// Get the effect send for this source
virtual IEffect *getEffect() const;
/// Set the gain for the effect path
virtual void setEffectGain(float gain);
/// Get the gain for the effect path
virtual float getEffectGain() const;
/// Enable or disable the filter for the effect channel
virtual void enableEffectFilter(bool enable = true);
/// Check if the filter on the effect channel is enabled
virtual bool isEffectFilterEnabled() const;
/// Set the filter parameters for the effect channel
virtual void setEffectFilter(TFilter filter, float lowFrequency, float highFrequency, float passGain);
/// Get the filter parameters for the effect channel
virtual void getEffectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const;
/// Set the effect filter gain
virtual void setEffectFilterPassGain(float passGain);
/// Get the effect filter gain
virtual float getEffectFilterPassGain() const;
//@}
/// Return the OpenAL source name
uint sourceName() { return _SourceName; }
/// Returns the buffer associated with this source.
IBuffer *getBuffer();
/// Reset the source before reuse
void reset();
/// Update the source (e.g. continue to stream the data in)
bool update();
/// Update the source's volume according to its distance and fade out curve.
/// It takes the current position of the listener as argument.
void updateVolume(const NLMISC::CVector& listener);
private:
void copySampleTo16BitsTrack(void *dst, void *src, uint nbSample, TSampleFormat sourceFormat);
enum TSourceState
{
source_stopped,
source_playing,
source_silencing,
source_swap_pending
};
/// Release all DirectSound resources
void release();
// The minimum size of available space in the DS buffer for update
static const uint32 _UpdateCopySize;
// The size of the samples that are copied when buffers are swapped
static const uint32 _SwapCopySize;
// The number of channels
static const uint _DefaultChannels;
// The default sample rate
static const uint _DefaultSampleRate;
// The default sample size
static const uint _DefaultSampleSize;
// The length of the crossfade, in samples
static const uint32 _XFadeSize;
/// The play and write cursors
struct TCursors
{
uint32 PlayCursor;
uint32 WriteCursor;
uint32 WriteSize;
};
/// A locked buffer info.
struct TLockedBufferInfo
{
// First locked part.
sint16 *Ptr1;
uint32 Size1;
// second locked part (or 0 if none)
sint16 *Ptr2;
uint32 Size2;
};
// Utility function that locks the DirectSound buffer and restores it if it was lost.
// bool lock(uint32 writePos, uint32 size, uint8* &ptr1, DWORD &bytes1, uint8* &ptr2, DWORD &bytes2);
bool lock(uint32 writePos, uint32 size, TLockedBufferInfo &lockedInfo);
// Utility function that unlocks the DirectSound buffer
// bool unlock(uint8* ptr1, DWORD bytes1, uint8* ptr2, DWORD bytes2);
bool unlock(const TLockedBufferInfo &lockedInfo);
void getCursors(TCursors &cursors);
uint32 checkFillCursor();
void fillData(const TLockedBufferInfo &lbi, int nbSample);
void fillData(sint16 *dst, uint nbSample);
void fillSilence(const TLockedBufferInfo &lbi, int nbSample);
void xfade(const TLockedBufferInfo &lbi, sint16 *src);
void fadeOut(const TLockedBufferInfo &lbi);
void fadeIn(const TLockedBufferInfo &lbi);
void advanceFill(TLockedBufferInfo &lbi, uint nbSample);
// Replace the current buffer with the swap buffer
void swap();
// getFadeOutSize() calculates how many samples have been written after the
// write cursor in the DirectSound buffer. This value is returned in the
// writtenTooMuch variable. The xfadeSize contains the number of samples over
// which to do a xfade or fade out, and in1 points to the sample in the sample
// buffer where to start the fade.
// void getFadeOutSize(uint32 writePos, uint32& xfadeSize, sint16* &in1, uint32 &writtenTooMuch);
// Fill the buffer with fresh samples. Should be called inside the critical zone.
bool fill();
// Fill the buffer with sparkling silence. Should be called inside the critical zone.
bool silence();
// Do a cross fade between the current buffer and the buffer stored in the _SwapBuffer
// variable. Call inside the critical zone.
void crossFade();
// Fade out the current buffer. Call inside the critical zone.
void fadeOut();
// Fade in the current buffer. Call inside the critical zone.
void fadeIn();
/// Check whether the play position has advanced enough to require an update
bool needsUpdate();
// Source name
uint _SourceName;
TSourceState _State;
// uint32 _FillCursor;
// The size of the sound buffer, in bytes
// uint32 _BufferSize;
IBuffer *_Sample;
// Size of the buffer in sample
uint _SampleSize;
// Position in the buffer in sample.
uint _SampleOffset;
// The number of sample realy played (depend on play cursor).
uint32 _PlayOffset;
TSampleFormat _Format;
uint _SampleFreq;
// The frequency of the source [0,10], i.e. slowed down or accelerated
float _Freq;
// The sample rate of the source (= _Freq * _Buffer sample rate)
uint32 _SampleRate;
IBuffer *_NextSample;
uint32 _LastPlayPos;
uint32 _FillOffset;
uint32 _SilenceWriten;
// The next sound buffer
// IBuffer *_SwapBuffer;
// To loop or not to loop
bool _Loop;
// The state of the source (playing, paused, stopped)
// TSourceDSoundUserState _UserState;
// DirectSound secondary buffer
LPDIRECTSOUNDBUFFER _SecondaryBuffer;
// The byte size of the DirectSound secondary buffers
static const uint32 _SecondaryBufferSize;
// The mask for the buffer size
static const uint32 _SizeMask;
// 3D interface of the secondary buffer.
LPDIRECTSOUND3DBUFFER _3DBuffer;
// The critial section object to protect the swap and update functions
CRITICAL_SECTION _CriticalSection;
// The state for ADPCM decompression.
IBuffer::TADPCMState _ADPCMState;
// The state of the DirectSound buffer (filling, silencing, silenced)
// TSourceDSoundBufferState _SecondaryBufferState;
// The next position in the DirectSound buffer where we should write next
// uint32 _NextWritePos;
// The total number of bytes written from the current sound buffer
// uint32 _BytesWritten;
// The amount of silence written (in bytes) after the end of the current sound buffer
// uint32 _SilenceWritten;
// The position of the last audio sample written.
// uint32 _EndPosition;
// The state of the buffer to reach the end of the audio samples. To flag the buffer as
// STOPPED, we have to make sure all the samples in the buffer are played. The play
// cursor in the DirectSound buffer is inspected and when it crosses the position of
// the last sample written (_EndPosition) the buffer is flagged as stopped. The _EndState
// field is used to keep a trace of the whereabouts of the play cursor.
// TSourceDSoundEndState _EndState;
// Has this source been handed out.
/* bool _IsUsed;
// Set the 'used' state of the source. Managed by the driver.
void setUsed(bool v) { _IsUsed = v; }
// Return the 'used' state of the source
bool isUsed() { return _IsUsed; }
*/
sint32 _Volume;
float _Gain;
double _Alpha;
NLMISC::CVector _Pos;
bool _PosRelative;
#if EAX_AVAILABLE == 1
LPKSPROPERTYSET _EAXSource;
#endif
#if NLSOUND_PROFILE
public:
static double _LastSwapTime;
static double _TotalSwapTime;
static double _MaxSwapTime;
static double _MinSwapTime;
static uint32 _SwapCount;
static double _TotalUpdateTime;
static double _MaxUpdateTime;
static double _MinUpdateTime;
static uint32 _UpdateCount;
static uint32 _TotalUpdateSize;
static double _PosTime;
static double _LockTime;
static double _CopyTime;
static double _UnlockTime;
static uint32 _CopyCount;
public:
static double getTestLast() { return 1000.0f * _LastSwapTime; };
static double getTestMax() { return 1000.0f * _MaxSwapTime; };
static double getTestMin() { return 1000.0f * _MinSwapTime; };
static double getTestAverage() { return (_SwapCount > 0) ? 1000.0f * _TotalSwapTime / _SwapCount : 0.0; };
static double getAveragePosTime() { return (_CopyCount > 0) ? 1000.0f * _PosTime / _CopyCount : 0.0; };
static double getAverageLockTime() { return (_CopyCount > 0) ? 1000.0f * _LockTime / _CopyCount : 0.0; };
static double getAverageCopyTime() { return (_CopyCount > 0) ? 1000.0f * _CopyTime / _CopyCount : 0.0; };
static double getAverageUnlockTime() { return (_CopyCount > 0) ? 1000.0f * _UnlockTime / _CopyCount : 0.0; };
static double getAverageCumulTime() { return (_CopyCount > 0) ? 1000.0f * (_PosTime + _LockTime + _CopyTime + _UnlockTime) / _CopyCount : 0.0; };
static uint getAverageUpdateSize() { return (_CopyCount > 0) ? (uint) (_TotalUpdateSize / _CopyCount) : 0; };
static double getMaxUpdateTime() { return 1000.0f * _MaxUpdateTime; };
static double getMinUpdateTime() { return 1000.0f * _MinUpdateTime; };
static double getAverageUpdateTime() { return (_UpdateCount > 0) ? 1000.0f * _TotalUpdateTime / _UpdateCount : 0.0; };
static double getTotalUpdateTime() { return 1000.0f * _TotalUpdateTime; };
static double getUpdateBytesPerMsec() { return (_UpdateCount > 0) ? _TotalUpdateSize / _TotalUpdateTime / 1000.0 : 0.0; }
#endif
};
} // NLSOUND
#endif // NL_SOURCE_DSOUND_H
/* End of source_al.h */

View file

@ -1,17 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stddsound.h"

View file

@ -1,58 +0,0 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef STDDSOUND_H
#define STDDSOUND_H
#if defined(_MSC_VER) && defined(_DEBUG)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
#include "nel/misc/types_nl.h"
#define EAX_AVAILABLE 0
#if EAX_AVAILABLE
# include <eax.h>
#endif
#include <initguid.h>
#include <dsound.h>
#include <iostream>
#include <algorithm>
#include <cmath>
#include "nel/misc/common.h"
#include "nel/misc/time_nl.h"
#include "nel/misc/fast_mem.h"
#include "nel/misc/debug.h"
#include "nel/misc/vector.h"
#include "nel/misc/path.h"
#include "nel/misc/file.h"
#include "nel/misc/log.h"
#include "nel/misc/hierarchical_timer.h"
#include "nel/sound/driver/sound_driver.h"
#include "nel/sound/driver/buffer.h"
#include "nel/sound/driver/source.h"
#include "nel/sound/driver/listener.h"
#endif
/* end of file */

View file

@ -131,7 +131,6 @@ void CListenerFMod::setDopplerFactor( float f )
if( !CSoundDriverFMod::getInstance()->fmodOk() )
return;
// clamp as in DSound.
clamp(f, 0.f, 10.f);
// set
@ -150,7 +149,6 @@ void CListenerFMod::setRolloffFactor( float f )
if(!CSoundDriverFMod::getInstance()->fmodOk())
return;
// clamp as in DSound (FMod requirement)
clamp(f, 0.f, 10.f);
_RolloffFactor = f;

View file

@ -105,7 +105,7 @@ public:
private:
/// Release all DirectSound resources
/// Release all FMOD resources
void release();
// Nel Basis
@ -128,4 +128,3 @@ private:
#endif // NL_LISTENER_FMOD_H

View file

@ -199,9 +199,6 @@ void CSoundDriverFMod::initDevice(const std::string &device, TSoundOptions optio
_Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions);
uint initFlags = 0;
#ifdef NL_OS_WINDOWS
initFlags = FSOUND_INIT_DSOUND_DEFERRED;
#endif
// Init with 32 channels, and deferred sound
if (!FSOUND_Init(22050, 32, initFlags))

View file

@ -35,7 +35,7 @@ namespace NLSOUND {
- EAX is not supported (setEnvironnement() / setEAXProperty() no-op)
- ADPCM is not supported (decompressed and the format change internaly )
- deffered param on ISource::setPos() etc... does not work. Always deffered.
- No cooperative level change in FMod as in DSOUND (default???)
- No cooperative level change in FMod (default???)
*/

View file

@ -495,7 +495,7 @@ void CSourceFMod::getCone( float& /* innerAngle */, float& /* outerAngle */, flo
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
* is the default used by DirectSound/OpenAL
* is the default used by OpenAL
*
* For any other value of alpha, an interpolation is be done between the two
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between

View file

@ -25,11 +25,11 @@ namespace NLSOUND {
class CBufferFMod;
// TODO: Doc comments in FMod driver are wrong.
// Bad copy pastes from DSound & OpenAL drivers.
// Bad copy pastes from OpenAL drivers.
// Fix drivername, author and date (2004?)!
/**
* DirectSound sound source
* FMOD sound source
*
* For arguments as 3D vectors, use the NeL vector coordinate system
@ -48,7 +48,7 @@ public:
/// Destructor
virtual ~CSourceFMod();
/// Initialize the DirectSound buffers. Called by the sound driver only.
/// Initialize the FMOD buffers. Called by the sound driver only.
void init();
/// \name Initialization
@ -147,7 +147,7 @@ public:
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
* is the default used by DirectSound/OpenAL
* is the default used by OpenAL
*
* For any other value of alpha, an interpolation is be done between the two
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
@ -236,7 +236,7 @@ private:
source_swap_pending
};
/// Release all DirectSound resources
/// Release all FMod resources
void release();
// Source name

View file

@ -357,7 +357,7 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
}
}
// Choose the I3DL2 model (same as DirectSound3D if not manual)
// Choose the I3DL2 model
if (getOption(OptionManualRolloff)) alDistanceModel(AL_NONE);
else alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
alTestError();

View file

@ -584,7 +584,7 @@ void CSourceAL::getCone( float& innerAngle, float& outerAngle, float& outerGain
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
* is the default used by DirectSound/OpenAL
* is the default used by OpenAL
*
* For any other value of alpha, an interpolation is be done between the two
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between

Some files were not shown because too many files have changed in this diff Show more