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

@ -22,7 +22,7 @@
# gitlab-runner exec docker --timeout=3600 'Linux client debian_amd64_strech build' # gitlab-runner exec docker --timeout=3600 'Linux client debian_amd64_strech build'
# gitlab-runner exec docker --timeout=3600 'Linux client_static debian_amd64_strech build' # gitlab-runner exec docker --timeout=3600 'Linux client_static debian_amd64_strech build'
# gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Linux client build' # gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Linux client build'
# gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Linux client archlinux build' # gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Linux client archlinux build'
# gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Linux client fedora_amd64_27 build' # gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Linux client fedora_amd64_27 build'
# gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Linux client ubuntu_amd64_17_10 build' # gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Linux client ubuntu_amd64_17_10 build'
# gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Windows client build' # gitlab-runner exec docker --kubernetes-memory-limit='10g' --timeout=3600 'Windows client build'
@ -1055,7 +1055,7 @@ Windows client build:
- find codebis -type f -name "*.rc" -exec unix2dos {} \; - find codebis -type f -name "*.rc" -exec unix2dos {} \;
- mkdir -p build - mkdir -p build
- cd 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 - wine jom.exe
artifacts: artifacts:
name: "khanat-client-windows-$CI_COMMIT_REF_NAME" name: "khanat-client-windows-$CI_COMMIT_REF_NAME"
@ -1104,7 +1104,7 @@ Linux client test:
- ./khanat-$(echo $CI_BUILD_REF | head -c 7 )-$CI_PIPELINE_ID-Linux-x86_64.run - ./khanat-$(echo $CI_BUILD_REF | head -c 7 )-$CI_PIPELINE_ID-Linux-x86_64.run
dependencies: dependencies:
- Linux client build - Linux client build
.OSX client test: .OSX client test:
stage: test stage: test
only: only:
@ -1120,7 +1120,7 @@ Linux client test:
##DEPLOYEMENT TO STAGING (TEST SERVER) ##DEPLOYEMENT TO STAGING (TEST SERVER)
# Job de déploiment vers le staging. Inutilisé pour le moment, il pourrait servir à l'avenir pour déployer automatiquement les nouvelles versions du client/serveur vers l'environnement de staging (zone de test) # Job de déploiment vers le staging. Inutilisé pour le moment, il pourrait servir à l'avenir pour déployer automatiquement les nouvelles versions du client/serveur vers l'environnement de staging (zone de test)
.Deploy to Staging: .Deploy to Staging:
stage: staging stage: staging
environment: Staging environment: Staging
@ -1138,9 +1138,9 @@ Linux client test:
- OSX client test - OSX client test
when: manual when: manual
##DEPLOYEMENT TO PRODUCTION ##DEPLOYEMENT TO PRODUCTION
# Job de déploiment vers la production. Inutilisé pour le moment, il pourrait servir à l'avenir pour déployer automatiquement les nouvelles versions du client/serveur vers l'environnement de production # Job de déploiment vers la production. Inutilisé pour le moment, il pourrait servir à l'avenir pour déployer automatiquement les nouvelles versions du client/serveur vers l'environnement de production
.Release to Production: .Release to Production:
stage: production stage: production
environment: Production environment: Production

View file

@ -10,10 +10,6 @@ MACRO(NL_CONFIGURE_CHECKS)
SET(NL_OPENGLES_AVAILABLE 1) SET(NL_OPENGLES_AVAILABLE 1)
ENDIF() ENDIF()
IF(WITH_DRIVER_DIRECT3D)
SET(NL_DIRECT3D_AVAILABLE 1)
ENDIF()
# sound drivers # sound drivers
IF(WITH_DRIVER_FMOD) IF(WITH_DRIVER_FMOD)
SET(NL_FMOD_AVAILABLE 1) SET(NL_FMOD_AVAILABLE 1)
@ -23,14 +19,6 @@ MACRO(NL_CONFIGURE_CHECKS)
SET(NL_OPENAL_AVAILABLE 1) SET(NL_OPENAL_AVAILABLE 1)
ENDIF() 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) IF(NOT RYZOM_VERSION_MAJOR)
SET(RYZOM_VERSION_MAJOR ${NL_VERSION_MAJOR}) SET(RYZOM_VERSION_MAJOR ${NL_VERSION_MAJOR})
SET(RYZOM_VERSION_MINOR ${NL_VERSION_MINOR}) 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_DIR - 3DSMAX SDK root directory
# MAXSDK_INCLUDE_DIR - where to find baseinterface.h # MAXSDK_INCLUDE_DIR - where to find baseinterface.h
# MAXSDK_LIBRARIES - List of libraries when using 3DSMAX. # 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 FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES libmysql mysqlclient
PATHS PATHS
$ENV{ProgramFiles}/MySQL/*/lib/opt $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 FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES libmysqld mysqlclientd
PATHS PATHS
$ENV{ProgramFiles}/MySQL/*/lib/opt $ENV{ProgramFiles}/MySQL/*/lib/opt
$ENV{SystemDrive}/MySQL/*/lib/opt) $ENV{SystemDrive}/MySQL/*/lib/opt
$ENV{ProgramFiles}/MySQL/*/lib
$ENV{SystemDrive}/MySQL/*/lib)
ELSE() ELSE()
FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient
PATHS PATHS

View file

@ -122,12 +122,6 @@ ENDMACRO(NL_ADD_RUNTIME_FLAGS)
MACRO(NL_ADD_STATIC_VID_DRIVERS name) MACRO(NL_ADD_STATIC_VID_DRIVERS name)
IF(WITH_STATIC_DRIVERS) 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(WITH_DRIVER_OPENGL)
IF(WIN32) IF(WIN32)
TARGET_LINK_LIBRARIES(${name} nel_drv_opengl_win) 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) MACRO(NL_ADD_STATIC_SND_DRIVERS name)
IF(WITH_STATIC_DRIVERS) IF(WITH_STATIC_DRIVERS)
IF(WIN32) 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) IF(WITH_DRIVER_OPENAL)
TARGET_LINK_LIBRARIES(${name} nel_drv_openal_win) TARGET_LINK_LIBRARIES(${name} nel_drv_openal_win)
ENDIF() ENDIF()
@ -299,11 +285,8 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
### ###
OPTION(WITH_DRIVER_OPENGL "Build OpenGL Driver (3D)" ON ) OPTION(WITH_DRIVER_OPENGL "Build OpenGL Driver (3D)" ON )
OPTION(WITH_DRIVER_OPENGLES "Build OpenGL ES Driver (3D)" OFF) 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_OPENAL "Build OpenAL Driver (Sound)" ON )
OPTION(WITH_DRIVER_FMOD "Build FMOD Driver (Sound)" OFF) 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 # Optional support
@ -665,7 +648,7 @@ MACRO(NL_SETUP_BUILD)
IF(APPLE) IF(APPLE)
SET(OBJC_FLAGS -fobjc-abi-version=2 -fobjc-legacy-dispatch -fobjc-weak) SET(OBJC_FLAGS -fobjc-abi-version=2 -fobjc-legacy-dispatch -fobjc-weak)
IF(NOT XCODE) IF(NOT XCODE)
IF(CMAKE_OSX_ARCHITECTURES) IF(CMAKE_OSX_ARCHITECTURES)
SET(TARGETS_COUNT 0) SET(TARGETS_COUNT 0)
@ -1198,14 +1181,6 @@ MACRO(SETUP_EXTERNAL)
INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR})
ENDIF() 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) IF(MSVC)
FIND_PACKAGE(MSVC REQUIRED) FIND_PACKAGE(MSVC REQUIRED)
FIND_PACKAGE(WindowsSDK REQUIRED) FIND_PACKAGE(WindowsSDK REQUIRED)

View file

@ -3,12 +3,9 @@
#cmakedefine NL_OPENGL_AVAILABLE ${NL_OPENGL_AVAILABLE} #cmakedefine NL_OPENGL_AVAILABLE ${NL_OPENGL_AVAILABLE}
#cmakedefine NL_OPENGLES_AVAILABLE ${NL_OPENGLES_AVAILABLE} #cmakedefine NL_OPENGLES_AVAILABLE ${NL_OPENGLES_AVAILABLE}
#cmakedefine NL_DIRECT3D_AVAILABLE ${NL_DIRECT3D_AVAILABLE}
#cmakedefine NL_FMOD_AVAILABLE ${NL_FMOD_AVAILABLE} #cmakedefine NL_FMOD_AVAILABLE ${NL_FMOD_AVAILABLE}
#cmakedefine NL_OPENAL_AVAILABLE ${NL_OPENAL_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} #cmakedefine NL_STEREO_AVAILABLE ${NL_STEREO_AVAILABLE}

View file

@ -37,7 +37,7 @@ class CTextureUser;
//---------------------------------------- CBloomEffect ----------------------------------------------------- //---------------------------------------- CBloomEffect -----------------------------------------------------
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
// CBloomEffect class apply a bloom effect on the whole scene. The whole scene is rendered in a // 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. // 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. // 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 // 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. // to keep Z tests correct.
// This method is called at the end of interfaces display in the main loop, to display final render target // 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. // (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(); // void endInterfacesDisplayBloom();
private: private:

View file

@ -188,9 +188,6 @@ public:
/// Before rendering via a driver in a thread, must activate() (per thread). /// Before rendering via a driver in a thread, must activate() (per thread).
virtual bool activate() = 0; 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. /// Return true if driver is still active. Return false else. If he user close the window, must return false.
virtual bool isActive() = 0; virtual bool isActive() = 0;
@ -437,8 +434,7 @@ public:
virtual uint getNbTextureStages() const = 0; virtual uint getNbTextureStages() const = 0;
/** Get max number of per stage constant that can be used simultaneously. /** 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 * This will usually match the number of texture stages. If pixel shaders are available this will be fully supported.
* so it is emulated. 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. * 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; virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0;
@ -1363,7 +1359,7 @@ public:
*/ */
virtual bool setAdapter(uint adapter) = 0; 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 : * BGRA :
* ***************************************************************** * *****************************************************************
* Offset: * 0 * 1 * 2 * 3 * * Offset: * 0 * 1 * 2 * 3 *
@ -1446,4 +1442,3 @@ private:
} }
#endif // NL_DRV_H #endif // NL_DRV_H

View file

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

View file

@ -27,11 +27,9 @@
#if defined (NL_COMP_MINGW) #if defined (NL_COMP_MINGW)
# define NL3D_GL_DLL_NAME "libnel_drv_opengl_win" # define NL3D_GL_DLL_NAME "libnel_drv_opengl_win"
# define NL3D_GLES_DLL_NAME "libnel_drv_opengles_win" # define NL3D_GLES_DLL_NAME "libnel_drv_opengles_win"
# define NL3D_D3D_DLL_NAME "libnel_drv_direct3d_win"
#elif defined (NL_OS_WINDOWS) #elif defined (NL_OS_WINDOWS)
# define NL3D_GL_DLL_NAME "nel_drv_opengl_win" # define NL3D_GL_DLL_NAME "nel_drv_opengl_win"
# define NL3D_GLES_DLL_NAME "nel_drv_opengles_win" # define NL3D_GLES_DLL_NAME "nel_drv_opengles_win"
# define NL3D_D3D_DLL_NAME "nel_drv_direct3d_win"
#elif defined (NL_OS_UNIX) #elif defined (NL_OS_UNIX)
# define NL3D_GL_DLL_NAME "nel_drv_opengl" # define NL3D_GL_DLL_NAME "nel_drv_opengl"
# define NL3D_GLES_DLL_NAME "nel_drv_opengles" # 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" ) {} 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. /// The driver Utilities class of static.
class CDRU class CDRU
{ {
@ -139,11 +109,6 @@ public:
/// Portable Function which create a GL ES Driver (using gl dll...). /// Portable Function which create a GL ES Driver (using gl dll...).
static IDriver *createGlEsDriver() throw(EDru); 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. /// \name 2D render.
// @{ // @{
/// Draw a bitmap 2D. Warning: this is slow... /// 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. /** \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. * 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 * The modes are similar to those introduced with OpenGL TEXTURE_SHADERS_NV
* TEXTURE_SHADERS_NV
*/ */
// @{ // @{
enum TTexAddressingMode { enum TTexAddressingMode {
@ -416,7 +415,7 @@ public:
* *
* For compatibility problems: * For compatibility problems:
* - no scaling is allowed (some cards do not implement this well). * - 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..). * 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. * 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. /** Init all that we need for a Scene.
* - register scene basics models, * - register scene basics models,
@ -108,7 +108,7 @@ public:
* - initScene(); * - initScene();
* - initEventServer(); * - 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: /** Delete all:
* - releaseEventServer(); * - releaseEventServer();

View file

@ -6,20 +6,20 @@
* IProgram * IProgram
*/ */
/* /*
* Copyright (C) 2013 by authors * Copyright (C) 2013 by authors
* *
* This file is part of NL3D. * This file is part of NL3D.
* NL3D is free software: you can redistribute it and/or modify it * NL3D is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as * under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the * published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version. * License, or (at your option) any later version.
* *
* NL3D is distributed in the hope that it will be useful, but WITHOUT * NL3D is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
* Public License for more details. * Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public * You should have received a copy of the GNU Affero General Public
* License along with NL3D. If not, see * License along with NL3D. If not, see
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
@ -61,7 +61,7 @@ public:
}; };
// Features exposed by a program. Used to set builtin parameters on user provided shaders. // Features exposed by a program. Used to set builtin parameters on user provided shaders.
// This is only used for user provided shaders, not for builtin shaders, // This is only used for user provided shaders, not for builtin shaders,
// as it is a slow method which has to go through all of the options every time. // as it is a slow method which has to go through all of the options every time.
// Builtin shaders should set all flags to 0. // Builtin shaders should set all flags to 0.
// Example: // Example:
@ -81,18 +81,18 @@ struct CProgramFeatures
enum TDriverFlags enum TDriverFlags
{ {
// Matrices // Matrices
Matrices = 0x00000001, Matrices = 0x00000001,
// Fog // Fog
Fog = 0x00000002, Fog = 0x00000002,
}; };
uint32 DriverFlags; uint32 DriverFlags;
enum TMaterialFlags enum TMaterialFlags
{ {
/// Use the CMaterial texture stages as the textures for a Pixel Program /// Use the CMaterial texture stages as the textures for a Pixel Program
TextureStages = 0x00000001, TextureStages = 0x00000001,
TextureMatrices = 0x00000002, TextureMatrices = 0x00000002,
}; };
// Material builtin parameters // Material builtin parameters
uint32 MaterialFlags; uint32 MaterialFlags;
@ -104,22 +104,22 @@ struct CProgramIndex
{ {
enum TName enum TName
{ {
ModelView, ModelView,
ModelViewInverse, ModelViewInverse,
ModelViewTranspose, ModelViewTranspose,
ModelViewInverseTranspose, ModelViewInverseTranspose,
Projection, Projection,
ProjectionInverse, ProjectionInverse,
ProjectionTranspose, ProjectionTranspose,
ProjectionInverseTranspose, ProjectionInverseTranspose,
ModelViewProjection, ModelViewProjection,
ModelViewProjectionInverse, ModelViewProjectionInverse,
ModelViewProjectionTranspose, ModelViewProjectionTranspose,
ModelViewProjectionInverseTranspose, ModelViewProjectionInverseTranspose,
Fog, Fog,
NUM_UNIFORMS NUM_UNIFORMS
}; };
@ -148,22 +148,6 @@ public:
// nel - 0x31,type,bitfield // nel - 0x31,type,bitfield
nelvp = 0x31010001, // VP supported by CVertexProgramParser, similar to arbvp1, can be translated to vs_1_1 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 // opengl - 0x61,type,bitfield
// vertex programs // vertex programs
// vp20 = 0x61010001, // NV_vertex_program1_1, outdated // vp20 = 0x61010001, // NV_vertex_program1_1, outdated
@ -211,7 +195,7 @@ public:
/// Map with known parameter indices, used for assembly programs /// Map with known parameter indices, used for assembly programs
std::map<std::string, uint> ParamIndices; std::map<std::string, uint> ParamIndices;
private: private:
std::string SourceCopy; std::string SourceCopy;
}; };
@ -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 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); } 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 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(const std::string &name) const { return m_DrvInfo->getUniformIndex(name.c_str()); };
inline uint getUniformIndex(CProgramIndex::TName name) const { return m_Index.Indices[name]; } inline uint getUniformIndex(CProgramIndex::TName name) const { return m_Index.Indices[name]; }

View file

@ -287,7 +287,7 @@ public:
// misc // 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 */) {} virtual void setColorType(CVertexBuffer::TVertexColorType /* type */) {}
protected: protected:

View file

@ -470,7 +470,7 @@ public:
/** See if filter mode or wrap mode have been touched. /** 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 * 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; } bool filterOrWrapModeTouched() const { return _FilterOrWrapModeTouched; }

View file

@ -140,7 +140,7 @@ public:
enum TStencilFunc { never = 0, less, lessequal, equal, notequal, greaterequal, greater, always}; enum TStencilFunc { never = 0, less, lessequal, equal, notequal, greaterequal, greater, always};
// Existing drivers // Existing drivers
enum TDriver { Direct3d = 0, OpenGl, OpenGlEs }; enum TDriver { OpenGl = 1, OpenGlEs };
public: public:
/// The EventServer of this driver. Init after setDisplay()!! /// The EventServer of this driver. Init after setDisplay()!!
@ -157,10 +157,6 @@ public:
virtual ~UDriver(); 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 /// \name Disable Hardware Feature
/** Disable some Feature that may be supported by the Hardware /** Disable some Feature that may be supported by the Hardware
@ -200,7 +196,6 @@ public:
virtual void showWindow(bool show = true)=0; virtual void showWindow(bool show = true)=0;
/* Pass in dialog box mode. After having called this method, you can use normal GUI. /* 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 * \code
* Driver->beginDialogMode(); * Driver->beginDialogMode();
@ -215,7 +210,6 @@ public:
virtual void beginDialogMode() =0; virtual void beginDialogMode() =0;
/* Leave the dialog box mode. After having called this method, you can't use normal GUI anymore. /* 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; virtual void endDialogMode() =0;
@ -841,7 +835,7 @@ public:
/** /**
* This is the static function which build a UDriver, the root for all 3D functions. * 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); 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 enum TType
{ {
@ -1267,24 +1267,3 @@ inline void CVertexBuffer::unlock () const
#endif // NL_VERTEX_BUFFER_H #endif // NL_VERTEX_BUFFER_H
/* End of vertex_buffer.h */ /* End of vertex_buffer.h */

View file

@ -24,10 +24,10 @@
/** /**
* This class is a vertex program. * 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 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.. * - 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. * - Don't use macros.
* *
* -> Thoses programs work without any change under OpenGL. * -> 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)). * 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 ..) * 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 enum EOpcode
{ {
MOV = 0, MOV = 0,
ARL, // in D3D, is equivalent to MOV ARL,
MUL, MUL,
ADD, ADD,
MAD, MAD,
@ -266,4 +261,3 @@ private:
#endif #endif

View file

@ -46,7 +46,6 @@ public:
/// Standard PCM format. /// Standard PCM format.
FormatPcm = 1, FormatPcm = 1,
/// Intel/DVI ADPCM format, only available for 1 channel at 16 bits per sample, encoded at 4 bits per sample. /// 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, FormatDviAdpcm = 11,
/// No format set. Used when a TBufferFormat value has not been set to any value yet. /// No format set. Used when a TBufferFormat value has not been set to any value yet.
FormatNotSet = (~0), FormatNotSet = (~0),
@ -55,13 +54,13 @@ public:
enum TStorageMode enum TStorageMode
{ {
/// Put buffer in sound hardware memory if possible, else in machine ram. /// Put buffer in sound hardware memory if possible, else in machine ram.
StorageAuto, StorageAuto,
/// Put buffer in sound hardware memory (fails if not possible). It is recommended to use StorageAuto instead of StorageHardware. /// Put buffer in sound hardware memory (fails if not possible). It is recommended to use StorageAuto instead of StorageHardware.
StorageHardware, StorageHardware,
/// Put buffer in machine ram (used for streaming). It behaves as if OptionSoftwareBuffer and OptionLocalBufferCopy are both enabled. /// Put buffer in machine ram (used for streaming). It behaves as if OptionSoftwareBuffer and OptionLocalBufferCopy are both enabled.
StorageSoftware StorageSoftware
}; };
/** Preset the name of the buffer. Used for async loading to give a name /** Preset the name of the buffer. Used for async loading to give a name
* before the buffer is effectivly loaded. * before the buffer is effectivly loaded.
* If the name after loading of the buffer doesn't match the preset name, * If the name after loading of the buffer doesn't match the preset name,
@ -86,16 +85,16 @@ public:
virtual bool unlock(uint size) = 0; virtual bool unlock(uint size) = 0;
/// Copy the data with specified size into the buffer. A readable local copy is only guaranteed when OptionLocalBufferCopy is set. Returns true if ok. /// 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) = 0; virtual bool fill(const uint8 *src, uint size) = 0;
/// Return the size of the buffer, in bytes. /// Return the size of the buffer, in bytes.
virtual uint getSize() const = 0; virtual uint getSize() const = 0;
/// Return the duration (in ms) of the sample in the buffer. /// Return the duration (in ms) of the sample in the buffer.
virtual float getDuration() const = 0; virtual float getDuration() const = 0;
/// Return true if the buffer is stereo (multi-channel), false if mono. /// Return true if the buffer is stereo (multi-channel), false if mono.
virtual bool isStereo() const = 0; virtual bool isStereo() const = 0;
/// Return true if the buffer is loaded. Used for async load/unload. /// Return true if the buffer is loaded. Used for async load/unload.
virtual bool isBufferLoaded() const = 0; virtual bool isBufferLoaded() const = 0;
//@{ //@{
//\name ***deprecated*** //\name ***deprecated***
/// Set the sample format. Example: freq=44100. ***deprecated*** /// Set the sample format. Example: freq=44100. ***deprecated***
@ -115,7 +114,7 @@ public:
/// Return duration in seconds from pcm size in bytes. /// Return duration in seconds from pcm size in bytes.
static float getDurationFromPCMSize(uint size, uint8 channels, uint8 bitsPerSample, uint32 frequency); static float getDurationFromPCMSize(uint size, uint8 channels, uint8 bitsPerSample, uint32 frequency);
//@} //@}
//@{ //@{
//\name ADPCM and sample bank building utility methods //\name ADPCM and sample bank building utility methods
struct TADPCMState struct TADPCMState
@ -128,7 +127,7 @@ public:
/// Encode 16bit Mono PCM buffer into Mono ADPCM. /// Encode 16bit Mono PCM buffer into Mono ADPCM.
static void encodeADPCM(const sint16 *indata, uint8 *outdata, uint nbSample, TADPCMState &state); static void encodeADPCM(const sint16 *indata, uint8 *outdata, uint nbSample, TADPCMState &state);
/// Decode Mono ADPCM into 16bit Mono PCM. /// Decode Mono ADPCM into 16bit Mono PCM.
static void decodeADPCM(const uint8 *indata, sint16 *outdata, uint nbSample, TADPCMState &state); static void decodeADPCM(const uint8 *indata, sint16 *outdata, uint nbSample, TADPCMState &state);
/// Read a wav file. Data type uint8 is used as unspecified buffer format. /// Read a wav file. Data type uint8 is used as unspecified buffer format.
static bool readWav(const uint8 *wav, uint size, std::vector<uint8> &result, TBufferFormat &bufferFormat, uint8 &channels, uint8 &bitsPerSample, uint32 &frequency); static bool readWav(const uint8 *wav, uint size, std::vector<uint8> &result, TBufferFormat &bufferFormat, uint8 &channels, uint8 &bitsPerSample, uint32 &frequency);
/// Write a wav file. Data type uint8 does not imply a buffer of any format. /// Write a wav file. Data type uint8 does not imply a buffer of any format.
@ -138,20 +137,20 @@ public:
/// Convert 16bit Mono PCM buffer data to ADPCM. /// Convert 16bit Mono PCM buffer data to ADPCM.
static bool convertMono16PCMToMonoADPCM(const sint16 *buffer, uint samples, std::vector<uint8> &result); static bool convertMono16PCMToMonoADPCM(const sint16 *buffer, uint samples, std::vector<uint8> &result);
//@} //@}
private: private:
static const sint _IndexTable[16]; static const sint _IndexTable[16];
static const uint _StepsizeTable[89]; static const uint _StepsizeTable[89];
//@} //@}
protected: protected:
/// Constructor /// Constructor
IBuffer() { } IBuffer() { }
public: public:
/// Destructor /// Destructor
virtual ~IBuffer() { } virtual ~IBuffer() { }
}; };
} // NLSOUND } // NLSOUND

View file

@ -64,16 +64,12 @@ public:
/// Driver Creation Choice /// Driver Creation Choice
enum TDriver 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, DriverAuto = 0,
/// DriverFMod is a driver that runs on FMod, nice quality, but not fully implemented. /// DriverFMod is a driver that runs on FMod, nice quality, but not fully implemented.
DriverFMod, DriverFMod,
/// DriverOpenAl is the recommended driver, especially if you have hardware sound acceleration. /// DriverOpenAl is the recommended driver, especially if you have hardware sound acceleration.
DriverOpenAl, DriverOpenAl,
/// DriverDSound is deprecated.
DriverDSound,
/// DriverXAudio2 runs on a fully software-based audio processing API without artificial limits.
DriverXAudio2,
NumDrivers NumDrivers
}; };
@ -81,25 +77,25 @@ public:
enum TSoundOptions enum TSoundOptions
{ {
/// Enable EAX/I3DL2 environment effects. (not implemented on FMod driver). /// Enable EAX/I3DL2 environment effects. (not implemented on FMod driver).
OptionEnvironmentEffects = 0x01, OptionEnvironmentEffects = 0x01,
/// Allow the user to use the ADPCM encoding. (verify availability with getOption) /// Allow the user to use the ADPCM encoding. (verify availability with getOption)
OptionAllowADPCM = 0x02, OptionAllowADPCM = 0x02,
/// Force software buffering (always true for XAudio2). /// Force software buffering.
OptionSoftwareBuffer = 0x04, OptionSoftwareBuffer = 0x04,
/** /**
* Configuration to use manual or API (directx or open AL) rolloff factor. * Configuration to use manual or API (open AL) rolloff factor.
* 0 => API (directx, open AL, etc) rollOff control. * 0 => API (open AL, etc) rollOff control.
* ISource::setAlpha() will fail. * ISource::setAlpha() will fail.
* IListener::setRollOffFactor() works * IListener::setRollOffFactor() works
* 1 => Manual rollOff control * 1 => Manual rollOff control
* ISource::setAlpha() change the shape of attenuation (change the curve) * ISource::setAlpha() change the shape of attenuation (change the curve)
* IListener::setRollOffFactor() will fail * IListener::setRollOffFactor() will fail
*/ */
OptionManualRolloff = 0x08, OptionManualRolloff = 0x08,
/// Enable local copy of buffer (used by OpenAL driver, required to build sample bank). /// Enable local copy of buffer (used by OpenAL driver, required to build sample bank).
OptionLocalBufferCopy = 0x10, OptionLocalBufferCopy = 0x10,
/// Use to check availability of buffer streaming. (verify with getOption) /// Use to check availability of buffer streaming. (verify with getOption)
OptionHasBufferStreaming = 0x20, OptionHasBufferStreaming = 0x20,
}; };
/** The interface must be implemented and provided to the driver /** The interface must be implemented and provided to the driver
@ -137,7 +133,7 @@ public:
/// Return a list of available devices for the user. The value at index 0 is empty, and is used for automatic device selection. /// 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) = 0; virtual void getDevices(std::vector<std::string> &devices) = 0;
/** Initialize the driver with a user selected device. /** Initialize the driver with a user selected device.
* In case of failure, can throw one of these ESoundDriver exception objects: * In case of failure, can throw one of these ESoundDriver exception objects:
* ESoundDriverNotFound, ESoundDriverCorrupted, ESoundDriverOldVersion, ESoundDriverUnknownVersion * ESoundDriverNotFound, ESoundDriverCorrupted, ESoundDriverOldVersion, ESoundDriverUnknownVersion
* The driver instance should be deleted by the user after init failure. * The driver instance should be deleted by the user after init failure.
@ -171,10 +167,10 @@ public:
virtual uint countMaxSources() = 0; virtual uint countMaxSources() = 0;
/// Return the maximum number of effects that can be created /// Return the maximum number of effects that can be created
virtual uint countMaxEffects() { return 0; } virtual uint countMaxEffects() { return 0; }
/// Write information about the driver to the output stream. /// Write information about the driver to the output stream.
virtual void writeProfile(std::string& out) = 0; virtual void writeProfile(std::string& out) = 0;
/// Stuff /// Stuff
virtual void startBench() = 0; virtual void startBench() = 0;
virtual void endBench() = 0; virtual void endBench() = 0;
@ -182,7 +178,7 @@ public:
/// Filled at createDriver() /// Filled at createDriver()
const std::string &getDllName() const { return _DllName; } const std::string &getDllName() const { return _DllName; }
/// \name Stuff for drivers that have native music support /// \name Stuff for drivers that have native music support
//@{ //@{
/// Create a native music channel, only supported by the FMod driver. /// Create a native music channel, only supported by the FMod driver.
@ -198,10 +194,10 @@ public:
/// Return if a music extension is supported by the driver's music channel. /// Return if a music extension is supported by the driver's music channel.
virtual bool isMusicExtensionSupported(const std::string &extension) const = 0; virtual bool isMusicExtensionSupported(const std::string &extension) const = 0;
//@} //@}
private: private:
std::string _DllName; std::string _DllName;
}; };

View file

@ -33,7 +33,7 @@
#include "sound_driver.h" #include "sound_driver.h"
/** /**
* The minimum allowed gain is specified as 0.0f. * The minimum allowed gain is specified as 0.0f.
* Inverting the wave by specifying a negative gain is not allowed. * Inverting the wave by specifying a negative gain is not allowed.
* \brief Minimum allowed gain (volume). * \brief Minimum allowed gain (volume).
@ -41,7 +41,7 @@
#define NLSOUND_MIN_GAIN 0.0f #define NLSOUND_MIN_GAIN 0.0f
/** /**
* The maximum allowed gain is specified as 1.0f. * The maximum allowed gain is specified as 1.0f.
* OpenAL implementations may or may not clamp the gain to a maximum * OpenAL implementations may or may not clamp the gain to a maximum
* of 1.0f, so this maximum is forced on all implementations. * of 1.0f, so this maximum is forced on all implementations.
* If you pass a value outside the minimum and maximum bounds, * If you pass a value outside the minimum and maximum bounds,
* it will automatically be clamped between them. * it will automatically be clamped between them.
@ -58,10 +58,8 @@
#define NLSOUND_MIN_PITCH 0.0f #define NLSOUND_MIN_PITCH 0.0f
/** /**
* The maximum allowed pitch is specified as 8.0f. * The maximum allowed pitch is specified as 8.0f.
* Tests indicate that with OpenAL the pitch can be set to 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 * and with FMod to somewhere around 9.0f.
* uses this value directly to configure the maximum pitch, which can
* technically be as high as XAUDIO2_MAX_FREQ_RATIO which is 1024.0f.
* If you pass a value outside the minimum and maximum bounds, * If you pass a value outside the minimum and maximum bounds,
* it will automatically be clamped between them. * it will automatically be clamped between them.
* \brief Maximum allowed pitch. * \brief Maximum allowed pitch.
@ -123,8 +121,8 @@ namespace NLSOUND {
/** /**
* Sound source interface (implemented in sound driver dynamic library) * Sound source interface (implemented in sound driver dynamic library)
* *
* - If the buffer is mono, the source is played in 3D mode. For * - If the buffer is mono, the source is played in 3D mode. For
* arguments as 3D vectors, use the NeL vector coordinate system: * arguments as 3D vectors, use the NeL vector coordinate system:
\verbatim \verbatim
(top) (top)
@ -136,7 +134,7 @@ namespace NLSOUND {
* *
* - If the buffer is multi-channel, only distance rolloff is applied. * - If the buffer is multi-channel, only distance rolloff is applied.
* - All streaming related functionalities are thread-safe. * - All streaming related functionalities are thread-safe.
* *
* \author Olivier Cado * \author Olivier Cado
* \author Nevrax France * \author Nevrax France
* \author Jan Boon (Kaetemi) * \author Jan Boon (Kaetemi)
@ -148,70 +146,70 @@ class ISource
public: public:
enum TFilter enum TFilter
{ {
FilterLowPass, FilterLowPass,
FilterBandPass, FilterBandPass,
FilterHighPass, FilterHighPass,
}; };
/// Constructor /// Constructor
ISource() { } ISource() { }
/// Destructor /// Destructor
virtual ~ISource() { } virtual ~ISource() { }
/// \name Initialization /// \name Initialization
//@{ //@{
/** /**
* This function is used to switch between streaming and static * This function is used to switch between streaming and static
* buffer modes. By default, streaming mode is off. * buffer modes. By default, streaming mode is off.
* Streaming mode must be enabled before calling functions * Streaming mode must be enabled before calling functions
* related to buffer streaming, such as 'submitStreamingBuffer' * related to buffer streaming, such as 'submitStreamingBuffer'
* and 'countStreamingBuffers'. * and 'countStreamingBuffers'.
* In the default static buffer mode, only one buffer is set * In the default static buffer mode, only one buffer is set
* active on this source, and can be replayed or looped as many * active on this source, and can be replayed or looped as many
* times as needed. * times as needed.
* When in streaming mode, multiple buffers are chained after each * When in streaming mode, multiple buffers are chained after each
* other, and you must make sure that the source does not run out * other, and you must make sure that the source does not run out
* of data, to avoid sound stopping glitches. * of data, to avoid sound stopping glitches.
* The source must be stopped before trying to change the mode, * The source must be stopped before trying to change the mode,
* if a static buffer was set it must be detached as well. * if a static buffer was set it must be detached as well.
* \brief Switch between streaming and static buffer modes. * \brief Switch between streaming and static buffer modes.
* \param streaming Set to true to enable streaming mode, or * \param streaming Set to true to enable streaming mode, or
* false to use static buffers. If you omit this parameter, it * false to use static buffers. If you omit this parameter, it
* will be set as true, and streaming will be enabled. * will be set as true, and streaming will be enabled.
*/ */
virtual void setStreaming(bool streaming = true) = 0; virtual void setStreaming(bool streaming = true) = 0;
/** /**
* Sets the buffer that is used for playback by this source. * Sets the buffer that is used for playback by this source.
* The static buffer will remain active on the source until * The static buffer will remain active on the source until
* this function is called with a NULL parameter, or until the * this function is called with a NULL parameter, or until the
* mode is changed to streaming. It is possible to play or loop * mode is changed to streaming. It is possible to play or loop
* this buffer as often as needed, as long as it is attached * this buffer as often as needed, as long as it is attached
* to this source. * to this source.
* If you attach a multichannel (stereo) buffer, the source will * If you attach a multichannel (stereo) buffer, the source will
* automatically be set to relative mode. Setting a mono channel * automatically be set to relative mode. Setting a mono channel
* buffer will automatically set the relative mode back to it's * buffer will automatically set the relative mode back to it's
* original setting. It is not possible to enable relative mode * original setting. It is not possible to enable relative mode
* with a multichannel buffer, instead you must manually split * with a multichannel buffer, instead you must manually split
* the sound data into multiple channels and use multiple sources. * the sound data into multiple channels and use multiple sources.
* You cannot use this function in streaming mode, where you must * You cannot use this function in streaming mode, where you must
* use submitStreamingBuffer() instead. * use submitStreamingBuffer() instead.
* A buffer can be attached to more than once source. * A buffer can be attached to more than once source.
* Before destroying a buffer, it must be detached from all * Before destroying a buffer, it must be detached from all
* sources it's attached to, which can be done by calling this * sources it's attached to, which can be done by calling this
* function with a NULL parameter as buffer on all relevant sources. * function with a NULL parameter as buffer on all relevant sources.
* If you set the buffer while the source is already playing or in * If you set the buffer while the source is already playing or in
* paused status, this function does nothing. You must stop() the * paused status, this function does nothing. You must stop() the
* source, or wait until it isStopped() before changing the buffer. * source, or wait until it isStopped() before changing the buffer.
* \brief Attach a buffer to this source. * \brief Attach a buffer to this source.
* \param buffer The buffer to be attached on this source. It must * \param buffer The buffer to be attached on this source. It must
* be created on the same sound driver instance as this source. Set * be created on the same sound driver instance as this source. Set
* this parameter to NULL to detach a previously set buffer. * this parameter to NULL to detach a previously set buffer.
*/ */
virtual void setStaticBuffer(IBuffer *buffer) = 0; virtual void setStaticBuffer(IBuffer *buffer) = 0;
/** /**
* Returns the buffer that was attached to this source. A buffer * Returns the buffer that was attached to this source. A buffer
* can by attached to this source by calling setStaticBuffer(). * can by attached to this source by calling setStaticBuffer().
* If no static buffer is set, or if the source is in streaming * If no static buffer is set, or if the source is in streaming
* mode, this function will return NULL. * mode, this function will return NULL.
* \brief Get the buffer that is attached to this source. * \brief Get the buffer that is attached to this source.
* \return A pointer to the attached IBuffer, or NULL if none. * \return A pointer to the attached IBuffer, or NULL if none.
@ -222,16 +220,16 @@ public:
virtual void submitStreamingBuffer(IBuffer *buffer) = 0; virtual void submitStreamingBuffer(IBuffer *buffer) = 0;
/** /**
* Returns the amount of buffers that are currently in the queue. * Returns the amount of buffers that are currently in the queue.
* This includes buffers that are waiting to be played, as well as * This includes buffers that are waiting to be played, as well as
* the buffer that is currently playing. Buffers that have finished * the buffer that is currently playing. Buffers that have finished
* playing are removed from the queue, and do not count towards the * playing are removed from the queue, and do not count towards the
* result of this function. * result of this function.
* It is recommended to have at least 2 or 3 buffers queued up when * It is recommended to have at least 2 or 3 buffers queued up when
* streaming, to avoid sound stopping glitches. * streaming, to avoid sound stopping glitches.
* If you need to know the total amount of buffers that were added * If you need to know the total amount of buffers that were added
* into the queue, you should count them manually by increasing a * into the queue, you should count them manually by increasing a
* value each time 'submitStreamingBuffer' is called. * value each time 'submitStreamingBuffer' is called.
* This function always returns 0 when the source is in static * This function always returns 0 when the source is in static
* mode, when the source is stopped, or when no buffers have been * mode, when the source is stopped, or when no buffers have been
* added yet into the queue. * added yet into the queue.
* \brief Get the number of buffers in the streaming queue. * \brief Get the number of buffers in the streaming queue.
@ -239,100 +237,100 @@ public:
*/ */
virtual uint countStreamingBuffers() const = 0; virtual uint countStreamingBuffers() const = 0;
//@} //@}
/// \name Playback control /// \name Playback control
//@{ //@{
/** /**
* This function is used to enable or disable looping this source. * This function is used to enable or disable looping this source.
* By default, looping is off. The current looping status can be * By default, looping is off. The current looping status can be
* obtained by calling getLooping(). * obtained by calling getLooping().
* It is possible to call this function either before the source * It is possible to call this function either before the source
* has started playing, or while it is already playing. * has started playing, or while it is already playing.
* To cleanly exit a loop, you can call setLooping(false) instead * To cleanly exit a loop, you can call setLooping(false) instead
* of using stop(). Calling stop() on a source that is looping will * of using stop(). Calling stop() on a source that is looping will
* immediately stop the source, which may suffer sound clicks. * immediately stop the source, which may suffer sound clicks.
* The looping state is useful on static buffers only. Setting this * The looping state is useful on static buffers only. Setting this
* while in streaming mode will have no effect, however, the loop * while in streaming mode will have no effect, however, the loop
* setting will be remembered when switching back to static mode. * setting will be remembered when switching back to static mode.
* \brief Enable or disable looping this source. * \brief Enable or disable looping this source.
* \param l Set to true to enable, false to disable looping or to * \param l Set to true to enable, false to disable looping or to
* exit the current loop. * exit the current loop.
*/ */
virtual void setLooping(bool l = true) = 0; virtual void setLooping(bool l = true) = 0;
/** /**
* Returns the looping status that was last set by setLooping(). * Returns the looping status that was last set by setLooping().
* This function will always return the last set looping option. * This function will always return the last set looping option.
* If you call this while in streaming mode, the result will be the * If you call this while in streaming mode, the result will be the
* setting that will be used when you go back to static buffer mode. * setting that will be used when you go back to static buffer mode.
* Looping has no effect on streaming. * Looping has no effect on streaming.
* \brief Get the currently set looping status. * \brief Get the currently set looping status.
* \return Returns true if looping is enabled, false if disabled. * \return Returns true if looping is enabled, false if disabled.
*/ */
virtual bool getLooping() const = 0; virtual bool getLooping() const = 0;
/** /**
* This function is used to enter playing mode. It will return * This function is used to enter playing mode. It will return
* true in case of success. The playing status can also be verified * true in case of success. The playing status can also be verified
* by calling isPlaying() on this source. * by calling isPlaying() on this source.
* If the source is stopped, or has not started playing yet, the * If the source is stopped, or has not started playing yet, the
* source will start playing from the beginning from the currently * source will start playing from the beginning from the currently
* attached static buffer when in static mode. If no static buffer * attached static buffer when in static mode. If no static buffer
* was set, the source will remain in stopped mode, and this * was set, the source will remain in stopped mode, and this
* will return false. A buffer can be attached to this source by * will return false. A buffer can be attached to this source by
* calling the setStaticBuffer() method. * calling the setStaticBuffer() method.
* When the source is stopped and in streaming mode, this function * When the source is stopped and in streaming mode, this function
* will always enter playing state. If no buffers were queued yet, * will always enter playing state. If no buffers were queued yet,
* it will effectively start playing this source once the first * it will effectively start playing this source once the first
* buffer has been submitted. It is recommended to queue up the * buffer has been submitted. It is recommended to queue up the
* first few buffers before calling play() to avoid running out of * first few buffers before calling play() to avoid running out of
* buffers early. In streaming mode, buffers can be submitted to * buffers early. In streaming mode, buffers can be submitted to
* the queue by calling the submitStreamingBuffer() method. * the queue by calling the submitStreamingBuffer() method.
* If the source is in paused mode, it will simply resume. * If the source is in paused mode, it will simply resume.
* In case it was already in playing mode, the source will be * In case it was already in playing mode, the source will be
* automatically stopped before re-entering playing status. In * automatically stopped before re-entering playing status. In
* static buffer mode this is essentially the same as restarting * static buffer mode this is essentially the same as restarting
* the source from the beginning, while doing this in streaming * the source from the beginning, while doing this in streaming
* mode will result in the streaming queue being cleared. * mode will result in the streaming queue being cleared.
* \brief Start or resume playback. * \brief Start or resume playback.
* \return Returns true in case of success. * \return Returns true in case of success.
*/ */
virtual bool play() = 0; virtual bool play() = 0;
/** /**
* This function stops playing the source immediately. If the * This function stops playing the source immediately. If the
* source is already stopped, it does nothing. If the source was * source is already stopped, it does nothing. If the source was
* paused, this will do the same as if it was playing. * paused, this will do the same as if it was playing.
* When the source is in static mode, the attached buffer will * When the source is in static mode, the attached buffer will
* remain attached for later usage. To exit a loop, it is * remain attached for later usage. To exit a loop, it is
* recommended to call setLooping(false) instead of stop(), * recommended to call setLooping(false) instead of stop(),
* to avoid sound clicks. The source will enter stopped state * to avoid sound clicks. The source will enter stopped state
* automatically when it has finished playing. * automatically when it has finished playing.
* If this source uses streaming buffers, calling this function * If this source uses streaming buffers, calling this function
* will immediately stop output, and clear the buffer queue, which * will immediately stop output, and clear the buffer queue, which
* means that any queued buffers that have not played yet are lost. * means that any queued buffers that have not played yet are lost.
* \brief Stop playback. * \brief Stop playback.
*/ */
virtual void stop() = 0; virtual void stop() = 0;
/** /**
* This function pauses playback of this source at it's current * This function pauses playback of this source at it's current
* position. If the source is stopped or already paused, this * position. If the source is stopped or already paused, this
* function does nothing. You can verify if the source is paused * function does nothing. You can verify if the source is paused
* by calling isPaused(). To resume playback, you must call play(). * by calling isPaused(). To resume playback, you must call play().
* \brief Pause playback. * \brief Pause playback.
*/ */
virtual void pause() = 0; virtual void pause() = 0;
/** /**
* Returns if the source is currently playing. * Returns if the source is currently playing.
* In streaming mode this will return true, even if no buffers are * In streaming mode this will return true, even if no buffers are
* available for playback when in playing status. * available for playback when in playing status.
* This will also return true if the source is paused. To know if * This will also return true if the source is paused. To know if
* the source has been paused, use isPaused(). * the source has been paused, use isPaused().
* \brief Get the playing state. * \brief Get the playing state.
* \return Returns the playing state. * \return Returns the playing state.
*/ */
virtual bool isPlaying() const = 0; virtual bool isPlaying() const = 0;
/** /**
* Returns true if the source has not started playing yet, when it * Returns true if the source has not started playing yet, when it
* has been stopped using the stop() method, or when the static * has been stopped using the stop() method, or when the static
* buffer has finished playback. * buffer has finished playback.
* If the source is playing or paused, this returns false. * If the source is playing or paused, this returns false.
* \brief Get the stopped state. * \brief Get the stopped state.
@ -341,36 +339,36 @@ public:
virtual bool isStopped() const = 0; virtual bool isStopped() const = 0;
/** /**
* Returns true if the source has been paused by calling pause(). * Returns true if the source has been paused by calling pause().
* If the source is playing, stopped, or has finished playback * If the source is playing, stopped, or has finished playback
* this returns false. * this returns false.
* \brief Get the paused state. * \brief Get the paused state.
* \return Returns the paused state. * \return Returns the paused state.
*/ */
virtual bool isPaused() const = 0; virtual bool isPaused() const = 0;
/** /**
* Returns the number of milliseconds the current static buffer or * Returns the number of milliseconds the current static buffer or
* streaming queue has effectively been playing. * streaming queue has effectively been playing.
* In streaming mode, the time spent during buffer outruns is not * In streaming mode, the time spent during buffer outruns is not
* counted towards the playback time, and the playback time is * counted towards the playback time, and the playback time is
* be the current time position in the entire submitted queue. * be the current time position in the entire submitted queue.
* When using static buffers, the result is the total time that the * When using static buffers, the result is the total time that the
* attached buffer has been playing. If the source is looping, the * attached buffer has been playing. If the source is looping, the
* time will be the total of all playbacks of the buffer. * time will be the total of all playbacks of the buffer.
* When the source is stopped, this will return the time where the * When the source is stopped, this will return the time where the
* source was stopped. The value is reset to 0 when re-entering * source was stopped. The value is reset to 0 when re-entering
* playing status. * playing status.
* A buffer that is played at a higher pitch will result in a lower * A buffer that is played at a higher pitch will result in a lower
* playback time. The result is not the buffer's playback position, * playback time. The result is not the buffer's playback position,
* but the actual time that has passed playing. * but the actual time that has passed playing.
* It is not guaranteed that this function returns an accurate * It is not guaranteed that this function returns an accurate
* value, or that it even works. If it is not implemented, the result * value, or that it even works. If it is not implemented, the result
* will always be 0. * will always be 0.
* \brief Get the current playback time in milliseconds. * \brief Get the current playback time in milliseconds.
* \return Returns the current playback time in milliseconds. * \return Returns the current playback time in milliseconds.
*/ */
virtual uint32 getTime() = 0; virtual uint32 getTime() = 0;
//@} //@}
/// \name Source properties /// \name Source properties
//@{ //@{
/// Set the position vector (default: (0,0,0)). /// Set the position vector (default: (0,0,0)).
@ -405,29 +403,29 @@ public:
virtual void setCone(float innerAngle, float outerAngle, float outerGain) = 0; virtual void setCone(float innerAngle, float outerAngle, float outerGain) = 0;
/// Get the cone angles (in radian) /// Get the cone angles (in radian)
virtual void getCone(float& innerAngle, float& outerAngle, float& outerGain) const = 0; virtual void getCone(float& innerAngle, float& outerAngle, float& outerGain) const = 0;
/** /**
* Set the alpha value for the volume-distance curve. * Set the alpha value for the volume-distance curve.
* *
* Used only with OptionManualRolloff. * Used only with OptionManualRolloff.
* Value ranges from -1.0 to 1.0, the default is 0.0. * Value ranges from -1.0 to 1.0, the default is 0.0.
* *
* - alpha = 0.0: The volume will decrease linearly between 0dB * - alpha = 0.0: The volume will decrease linearly between 0dB
* and -100 dB. * and -100 dB.
* - alpha = 1.0: The volume will decrease linearly between 1.0f * - alpha = 1.0: The volume will decrease linearly between 1.0f
* and 0.0f (linear scale). * and 0.0f (linear scale).
* - alpha = -1.0: The volume will decrease inversely with the * - alpha = -1.0: The volume will decrease inversely with the
* distance (1/dist). This is the default distance attenuation * distance (1/dist). This is the default distance attenuation
* used without OptionManualRolloff. * used without OptionManualRolloff.
* *
* For any other value of alpha, an interpolation is be done * For any other value of alpha, an interpolation is be done
* between the two adjacent curves. For example, if alpha equals * between the two adjacent curves. For example, if alpha equals
* 0.5, the volume will be halfway between the linear dB curve and * 0.5, the volume will be halfway between the linear dB curve and
* the linear amplitude curve. * the linear amplitude curve.
* \brief Set the alpha value for the volume-distance curve * \brief Set the alpha value for the volume-distance curve
*/ */
virtual void setAlpha(double a) = 0; virtual void setAlpha(double a) = 0;
//@} //@}
/// \name Direct output /// \name Direct output
//@{ //@{
/// Enable or disable direct output [true/false], default: true /// Enable or disable direct output [true/false], default: true
@ -438,7 +436,7 @@ public:
virtual void setDirectGain(float gain = NLSOUND_DEFAULT_DIRECT_GAIN) = 0; virtual void setDirectGain(float gain = NLSOUND_DEFAULT_DIRECT_GAIN) = 0;
/// Get the gain for the direct path /// Get the gain for the direct path
virtual float getDirectGain() const = 0; virtual float getDirectGain() const = 0;
/// Enable or disable the filter for the direct channel /// Enable or disable the filter for the direct channel
virtual void enableDirectFilter(bool enable = true) = 0; virtual void enableDirectFilter(bool enable = true) = 0;
/// Check if the filter on the direct channel is enabled /// Check if the filter on the direct channel is enabled
@ -452,7 +450,7 @@ public:
/// Get the direct filter gain /// Get the direct filter gain
virtual float getDirectFilterPassGain() const = 0; virtual float getDirectFilterPassGain() const = 0;
//@} //@}
/// \name Effect output /// \name Effect output
//@{ //@{
/// Set the effect send for this source, NULL to disable. [IEffect], default: NULL /// Set the effect send for this source, NULL to disable. [IEffect], default: NULL
@ -463,7 +461,7 @@ public:
virtual void setEffectGain(float gain = NLSOUND_DEFAULT_EFFECT_GAIN) = 0; virtual void setEffectGain(float gain = NLSOUND_DEFAULT_EFFECT_GAIN) = 0;
/// Get the gain for the effect path /// Get the gain for the effect path
virtual float getEffectGain() const = 0; virtual float getEffectGain() const = 0;
/// Enable or disable the filter for the effect channel /// Enable or disable the filter for the effect channel
virtual void enableEffectFilter(bool enable = true) = 0; virtual void enableEffectFilter(bool enable = true) = 0;
/// Check if the filter on the effect channel is enabled /// Check if the filter on the effect channel is enabled
@ -477,9 +475,9 @@ public:
/// Get the effect filter gain /// Get the effect filter gain
virtual float getEffectFilterPassGain() const = 0; virtual float getEffectFilterPassGain() const = 0;
//@} //@}
protected: protected:
// common method used only with OptionManualRolloff. return the volume in 1/100th DB ( = mB)modified // common method used only with OptionManualRolloff. return the volume in 1/100th DB ( = mB)modified
static sint32 computeManualRollOff(sint32 volumeMB, sint32 mbMin, sint32 mbMax, double alpha, float sqrdist, float distMin, float distMax); static sint32 computeManualRollOff(sint32 volumeMB, sint32 mbMin, sint32 mbMax, double alpha, float sqrdist, float distMin, float distMax);
// common method used only with OptionManualRolloff. return the rolloff in amplitude ratio (gain) // common method used only with OptionManualRolloff. return the rolloff in amplitude ratio (gain)

View file

@ -82,8 +82,6 @@ public:
DriverAuto = 0, DriverAuto = 0,
DriverFMod, DriverFMod,
DriverOpenAl, DriverOpenAl,
DriverDSound,
DriverXAudio2,
NumDrivers NumDrivers
}; };
@ -124,42 +122,42 @@ public:
} }
} }
}; };
/// Initialization information for the audio mixer. Use instead of the long parametered init function for readability. *** Subject to change. *** /// Initialization information for the audio mixer. Use instead of the long parametered init function for readability. *** Subject to change. ***
struct CInitInfo struct CInitInfo
{ {
public: public:
CInitInfo() CInitInfo()
: MaxTrack(32), : MaxTrack(32),
EnableReverb(false), EnableReverb(false),
EnableOccludeObstruct(false), EnableOccludeObstruct(false),
UseADPCM(false), UseADPCM(false),
ForceSoftware(false), ForceSoftware(false),
ManualRolloff(true) ManualRolloff(true)
{ } { }
/// The number of allocated physical playback tracks. Default: 32. /// The number of allocated physical playback tracks. Default: 32.
uint MaxTrack; uint MaxTrack;
/// Enable environment reverberation effect. Default: false. /// Enable environment reverberation effect. Default: false.
bool EnableReverb; bool EnableReverb;
/// Enable occlusion and obstruction lowpass filters from walls and objects. Default: false. /// Enable occlusion and obstruction lowpass filters from walls and objects. Default: false.
bool EnableOccludeObstruct; bool EnableOccludeObstruct;
/// Use lower quality ADPCM encoded sources for lower memory usage. Default: false. /// Use lower quality ADPCM encoded sources for lower memory usage. Default: false.
bool UseADPCM; bool UseADPCM;
/// Force using a software sound device. Default: false. [KAETEMI TODO: Allow sound device selection.] /// Force using a software sound device. Default: false. [KAETEMI TODO: Allow sound device selection.]
bool ForceSoftware; bool ForceSoftware;
/// Use NeL's distance rolloff math. Default: true. /// Use NeL's distance rolloff math. Default: true.
bool ManualRolloff; bool ManualRolloff;
/// I forgot what this does, but it's fairly important. /// I forgot what this does, but it's fairly important.
bool AutoLoadSample; bool AutoLoadSample;
}; };
//@{ //@{
//@name Init methods //@name Init methods
/// Create the audio mixer singleton and return a pointer to its instance /// Create the audio mixer singleton and return a pointer to its instance
@ -175,7 +173,7 @@ public:
* mixer config file, you MUST set the sample path * mixer config file, you MUST set the sample path
* BEFORE calling init. * BEFORE calling init.
*/ */
virtual void setSamplePath(const std::string& path) = 0; virtual void setSamplePath(const std::string& path) = 0;
/** Set the global path to the sample banks /** Set the global path to the sample banks
* If you have specified some sample bank to load in the * If you have specified some sample bank to load in the
@ -199,17 +197,17 @@ public:
* deactivated. (lies!) * deactivated. (lies!)
* autoLoadSample is used for tools like georges or object viewer where you don't bother to * autoLoadSample is used for tools like georges or object viewer where you don't bother to
* specify each sample bank to load, you just want to ear the sound. * specify each sample bank to load, you just want to ear the sound.
* *
* Deprecated by initDriver/getDevices/initDevice. * Deprecated by initDriver/getDevices/initDevice.
* *
* \param forceSoftware: to force the driver to load in software buffer, not hardware * \param forceSoftware: to force the driver to load in software buffer, not hardware
*/ */
virtual void init(uint maxTrack = 32, bool useEax = true, bool useADPCM = true, NLMISC::IProgressCallback *progressCallBack = NULL, bool autoLoadSample = false, TDriver driverType = DriverAuto, bool forceSoftware = false, bool manualRolloff = true) = 0; virtual void init(uint maxTrack = 32, bool useEax = true, bool useADPCM = true, NLMISC::IProgressCallback *progressCallBack = NULL, bool autoLoadSample = false, TDriver driverType = DriverAuto, bool forceSoftware = false, bool manualRolloff = true) = 0;
/// Initialize the NeL Sound Driver with given driverName. /// Initialize the NeL Sound Driver with given driverName.
virtual void initDriver(const std::string &driverName) = 0; virtual void initDriver(const std::string &driverName) = 0;
/// Get the available devices on the loaded driver. /// Get the available devices on the loaded driver.
virtual void getDevices(std::vector<std::string> &devices) = 0; virtual void getDevices(std::vector<std::string> &devices) = 0;
/// Initialize the selected device on the currently initialized driver. Leave deviceName empty to select the default device. /// Initialize the selected device on the currently initialized driver. Leave deviceName empty to select the default device.
virtual void initDevice(const std::string &deviceName, const CInitInfo &initInfo, NLMISC::IProgressCallback *progressCallback = NULL) = 0; virtual void initDevice(const std::string &deviceName, const CInitInfo &initInfo, NLMISC::IProgressCallback *progressCallback = NULL) = 0;
@ -451,7 +449,7 @@ public:
virtual void setEventMusicVolume(float gain) =0; virtual void setEventMusicVolume(float gain) =0;
/** true if the event music is ended /** true if the event music is ended
*/ */
virtual bool isEventMusicEnded() =0; virtual bool isEventMusicEnded() =0;
/// Get audio/container extensions that are currently supported by nel or the used driver implementation. /// Get audio/container extensions that are currently supported by nel or the used driver implementation.
virtual void getMusicExtensions(std::vector<std::string> &extensions) = 0; virtual void getMusicExtensions(std::vector<std::string> &extensions) = 0;
//@} //@}

View file

@ -77,9 +77,9 @@ bool handleCheck(const CEGUI::EventArgs& e);
#endif // CEGUI_DATA_DIR #endif // CEGUI_DATA_DIR
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
int WINAPI WinMain( HINSTANCE hInstance, int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, LPSTR lpCmdLine,
int nCmdShow ) { int nCmdShow ) {
ghInstance = hInstance; ghInstance = hInstance;
#else #else
@ -100,7 +100,7 @@ int main(int argc, char **argv)
NELRENDERER_CREATE_PROC createNelRenderer = reinterpret_cast<NELRENDERER_CREATE_PROC>(driverLib.getSymbolAddress(NELRENDERER_CREATE_PROC_NAME)); NELRENDERER_CREATE_PROC createNelRenderer = reinterpret_cast<NELRENDERER_CREATE_PROC>(driverLib.getSymbolAddress(NELRENDERER_CREATE_PROC_NAME));
// CCeguiRendererNelLibrary *nelCeguiDriverLib = dynamic_cast<CCeguiRendererNelLibrary *>(driverLib.getNelLibraryInterface()); // CCeguiRendererNelLibrary *nelCeguiDriverLib = dynamic_cast<CCeguiRendererNelLibrary *>(driverLib.getNelLibraryInterface());
NL3D::UDriver *driver; NL3D::UDriver *driver;
// Create a driver // Create a driver
@ -108,9 +108,8 @@ int main(int argc, char **argv)
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
icon = (uint)LoadIcon(ghInstance,MAKEINTRESOURCE(IDI_ICON1)); icon = (uint)LoadIcon(ghInstance,MAKEINTRESOURCE(IDI_ICON1));
#endif #endif
bool useD3D = false;
#ifdef NL_INDEX_BUFFER_H //new 3d #ifdef NL_INDEX_BUFFER_H //new 3d
NL3D::UDriver *driver = NL3D::UDriver::createDriver(icon,useD3D); NL3D::UDriver *driver = NL3D::UDriver::createDriver(icon);
#else #else
driver = NL3D::UDriver::createDriver(icon); driver = NL3D::UDriver::createDriver(icon);
#endif #endif
@ -123,7 +122,7 @@ int main(int argc, char **argv)
// start up the Gui system. // start up the Gui system.
//gGuiLogger = nelCeguiDriverLib->createNelLogger(); //gGuiLogger = nelCeguiDriverLib->createNelLogger();
//gGuiRenderer = new CEGUI::NeLRenderer(driver); //gGuiRenderer = new CEGUI::NeLRenderer(driver);
gGuiRenderer = createNelRenderer(driver, true); gGuiRenderer = createNelRenderer(driver, true);
gGuiSystem = new CEGUI::System(gGuiRenderer); gGuiSystem = new CEGUI::System(gGuiRenderer);
CEGUI::NeLRenderer *rndr = (CEGUI::NeLRenderer *)gGuiRenderer; CEGUI::NeLRenderer *rndr = (CEGUI::NeLRenderer *)gGuiRenderer;
@ -134,7 +133,7 @@ int main(int argc, char **argv)
nlinfo("Start up and configure the GUI system."); nlinfo("Start up and configure the GUI system.");
try { try {
using namespace CEGUI; using namespace CEGUI;
Logger::getSingleton().setLoggingLevel(Insane); Logger::getSingleton().setLoggingLevel(Insane);
// load scheme and set up defaults // load scheme and set up defaults
@ -328,5 +327,3 @@ bool handleCheck(const CEGUI::EventArgs& e)
return true; return true;
} }

View file

@ -54,7 +54,7 @@ int main(int argc, char **argv)
#endif #endif
{ {
// look at 3dinit example // 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); NLMISC::CPath::addSearchPath(FONT_DIR);

View file

@ -51,18 +51,18 @@ QString nli18n(const char *label)
} /* anonymous namespace */ } /* anonymous namespace */
CGraphicsViewport::CGraphicsViewport(QWidget *parent) CGraphicsViewport::CGraphicsViewport(QWidget *parent)
: QWidget(parent), : QWidget(parent),
m_GraphicsConfig(NULL), m_GraphicsConfig(NULL),
m_Driver(NULL), m_Driver(NULL),
m_TextContext(NULL) m_TextContext(NULL)
{ {
} }
CGraphicsViewport::~CGraphicsViewport() CGraphicsViewport::~CGraphicsViewport()
{ {
} }
void CGraphicsViewport::init(CGraphicsConfig *graphicsConfig) void CGraphicsViewport::init(CGraphicsConfig *graphicsConfig)
@ -72,44 +72,35 @@ void CGraphicsViewport::init(CGraphicsConfig *graphicsConfig)
// copy parameters // copy parameters
m_GraphicsConfig = graphicsConfig; m_GraphicsConfig = graphicsConfig;
// check stuff we need // check stuff we need
nlassert(m_GraphicsConfig); nlassert(m_GraphicsConfig);
// create the driver // create the driver
nlassert(!m_Driver); nlassert(!m_Driver);
m_Direct3D = false;
std::string driver = m_GraphicsConfig->getGraphicsDriver(); std::string driver = m_GraphicsConfig->getGraphicsDriver();
if (driver == "Direct3D") m_Direct3D = true; //m_Driver = Direct3D; m_Driver = UDriver::createDriver(NULL, NULL);
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);
nlassert(m_Driver); nlassert(m_Driver);
// initialize the window with config file values // initialize the window with config file values
m_Driver->setDisplay(winId(), NL3D::UDriver::CMode(width(), height(), 32)); m_Driver->setDisplay(winId(), NL3D::UDriver::CMode(width(), height(), 32));
// register config callbacks // register config callbacks
connect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)), connect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)),
this, SLOT(cfcbBackgroundColor(NLMISC::CRGBA))); this, SLOT(cfcbBackgroundColor(NLMISC::CRGBA)));
m_BackgroundColor = m_GraphicsConfig->getBackgroundColor(); m_BackgroundColor = m_GraphicsConfig->getBackgroundColor();
// set the cache size for the font manager(in bytes) // set the cache size for the font manager(in bytes)
m_Driver->setFontManagerMaxMemory(2097152); m_Driver->setFontManagerMaxMemory(2097152);
// create the text context // create the text context
nlassert(!m_TextContext); nlassert(!m_TextContext);
m_TextContext = m_Driver->createTextContext(CPath::lookup( m_TextContext = m_Driver->createTextContext(CPath::lookup(
m_GraphicsConfig->getFontName())); m_GraphicsConfig->getFontName()));
nlassert(m_TextContext); nlassert(m_TextContext);
connect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)), connect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)),
this, SLOT(cfcbFontShadow(bool))); this, SLOT(cfcbFontShadow(bool)));
m_TextContext->setShaded(m_GraphicsConfig->getFontShadow()); m_TextContext->setShaded(m_GraphicsConfig->getFontShadow());
} }
void CGraphicsViewport::release() void CGraphicsViewport::release()
@ -119,14 +110,14 @@ void CGraphicsViewport::release()
// release text context // release text context
nlassert(m_TextContext); nlassert(m_TextContext);
disconnect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)), disconnect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)),
this, SLOT(cfcbFontShadow(bool))); this, SLOT(cfcbFontShadow(bool)));
m_Driver->deleteTextContext(m_TextContext); m_Driver->deleteTextContext(m_TextContext);
m_TextContext = NULL; m_TextContext = NULL;
// release driver // release driver
nlassert(m_Driver); nlassert(m_Driver);
disconnect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)), disconnect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)),
this, SLOT(cfcbBackgroundColor(NLMISC::CRGBA))); this, SLOT(cfcbBackgroundColor(NLMISC::CRGBA)));
m_Driver->release(); m_Driver->release();
delete m_Driver; delete m_Driver;
@ -185,7 +176,7 @@ void CGraphicsViewport::saveScreenshot(const string &name, bool jpg, bool png, b
//H_AUTO2 //H_AUTO2
// FIXME: create screenshot path if it doesn't exist! // FIXME: create screenshot path if it doesn't exist!
// empty bitmap // empty bitmap
CBitmap bitmap; CBitmap bitmap;
// copy the driver buffer to the bitmap // copy the driver buffer to the bitmap
@ -221,13 +212,12 @@ void CGraphicsViewport::saveScreenshot(const string &name, bool jpg, bool png, b
void CGraphicsViewport::resizeEvent(QResizeEvent *resizeEvent) void CGraphicsViewport::resizeEvent(QResizeEvent *resizeEvent)
{ {
QWidget::resizeEvent(resizeEvent); QWidget::resizeEvent(resizeEvent);
if (m_Driver && !m_Direct3D) if (m_Driver)
{ {
m_Driver->setMode(UDriver::CMode(resizeEvent->size().width(), resizeEvent->size().height(), 32)); m_Driver->setMode(UDriver::CMode(resizeEvent->size().width(), resizeEvent->size().height(), 32));
} }
// The OpenGL driver does not resize automatically. // 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. // Resizing the window after switching drivers a few times becomes slow.
// There is probably something inside the drivers not being released properly. // There is probably something inside the drivers not being released properly.

View file

@ -72,7 +72,7 @@ public:
inline NL3D::UTextContext *getTextContext() { return m_TextContext; } inline NL3D::UTextContext *getTextContext() { return m_TextContext; }
inline NL3D::UScene *getScene() { return m_Scene; } inline NL3D::UScene *getScene() { return m_Scene; }
public slots: public slots:
void saveScreenshot(); void saveScreenshot();
private slots: private slots:
@ -91,12 +91,10 @@ private:
NL3D::UTextContext *m_TextContext; NL3D::UTextContext *m_TextContext;
NL3D::UScene *m_Scene; NL3D::UScene *m_Scene;
bool m_Direct3D;
private: private:
CGraphicsViewport(const CGraphicsViewport &); CGraphicsViewport(const CGraphicsViewport &);
CGraphicsViewport &operator=(const CGraphicsViewport &); CGraphicsViewport &operator=(const CGraphicsViewport &);
}; /* class CGraphicsViewport */ }; /* class CGraphicsViewport */
} /* namespace NLQT */ } /* namespace NLQT */

View file

@ -55,9 +55,9 @@ LoginBackground = "login_background.dds";
// Graphics ////////////////////////////////////////////////////////////////// // Graphics //////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Use OpenGL or Direct3D (Windows) // Use OpenGL (Windows)
GraphicsEnabled = 1; GraphicsEnabled = 1;
GraphicsDrivers = { "OpenGL", "Direct3D" }; GraphicsDrivers = { "OpenGL" };
GraphicsDriver = "OpenGL"; GraphicsDriver = "OpenGL";
// Resolution of the screen // Resolution of the screen
@ -134,9 +134,9 @@ FpsSmoothing = 64;
// Sound ///////////////////////////////////////////////////////////////////// // Sound /////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// The sound driver, choose between "Auto", "FMod", "DSound" and "OpenAl" // The sound driver, choose between "Auto", "FMod" and "OpenAl"
SoundEnabled = 1; SoundEnabled = 1;
SoundDrivers = { "Auto", "OpenAL", "XAudio2", "FMod", "DSound" }; SoundDrivers = { "Auto", "OpenAL", "FMod" };
SoundDriver = "OpenAL"; SoundDriver = "OpenAL";
SoundDevice = ""; SoundDevice = "";
SoundMaxTrack = 48; SoundMaxTrack = 48;
@ -153,46 +153,46 @@ SoundAutoLoadSample = 1;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// This setting is used to bind keys to actions. // This setting is used to bind keys to actions.
// "key_handler", "args", "***", "Key1|Key2", // "key_handler", "args", "***", "Key1|Key2",
// *** -> CTRL, SHIFT, ALT don't matter // *** -> CTRL, SHIFT, ALT don't matter
// --- -> CTRL, SHIFT, ALT must all be disabled // --- -> CTRL, SHIFT, ALT must all be disabled
// -+- -> only SHIFT must be down // -+- -> only SHIFT must be down
KeySettings = { KeySettings = {
"screenshot", "", "***", "KeyF5", "screenshot", "", "***", "KeyF5",
"command", "set_state Exit", "-+-", "KeyESCAPE", "command", "set_state Exit", "-+-", "KeyESCAPE",
"command", "set_state Login", "+--", "KeyESCAPE", "command", "set_state Login", "+--", "KeyESCAPE",
"command", "set_state Unload", "***", "KeyF8", "command", "set_state Unload", "***", "KeyF8",
"command", "set_state Demo", "***", "KeyF7", "command", "set_state Demo", "***", "KeyF7",
"move_forward", "", "***", "KeyUP|KeyZ|KeyW", "move_forward", "", "***", "KeyUP|KeyZ|KeyW",
"move_backward", "", "***", "KeyDOWN|KeyS", "move_backward", "", "***", "KeyDOWN|KeyS",
"move_left", "", "***", "KeyLEFT|KeyQ|KeyA", "move_left", "", "***", "KeyLEFT|KeyQ|KeyA",
"move_right", "", "***", "KeyRIGHT|KeyD", "move_right", "", "***", "KeyRIGHT|KeyD",
"move_forward", "", "***", "KeyZ|KeyW", "move_forward", "", "***", "KeyZ|KeyW",
"move_backward", "", "***", "KeyS", "move_backward", "", "***", "KeyS",
"move_left", "", "***", "KeyQ|KeyA", "move_left", "", "***", "KeyQ|KeyA",
"move_right", "", "***", "KeyD", "move_right", "", "***", "KeyD",
"chat_begin", "", "***", "KeyT", "chat_begin", "", "***", "KeyT",
"chat_send", "", "***", "KeyENTER", "chat_send", "", "***", "KeyENTER",
"chat_leave", "", "***", "KeyESCAPE", "chat_leave", "", "***", "KeyESCAPE",
"display_test", "", "***", "KeyTAB", "display_test", "", "***", "KeyTAB",
"send_action", "0", "---", "Key1", "send_action", "0", "---", "Key1",
"send_action", "1", "---", "Key2", "send_action", "1", "---", "Key2",
"send_action", "2", "---", "Key3", "send_action", "2", "---", "Key3",
"send_action", "3", "---", "Key4", "send_action", "3", "---", "Key4",
"send_action", "4", "---", "Key5", "send_action", "4", "---", "Key5",
"send_action", "5", "---", "Key6", "send_action", "5", "---", "Key6",
"send_action", "6", "---", "Key7", "send_action", "6", "---", "Key7",
"send_action", "7", "---", "Key8", "send_action", "7", "---", "Key8",
"send_action", "8", "---", "Key9", "send_action", "8", "---", "Key9",
"send_action", "9", "---", "Key0", "send_action", "9", "---", "Key0",
"demo_crystal_spawn", "", "---", "KeyO", "demo_crystal_spawn", "", "---", "KeyO",
"demo_crystal_explode", "", "---", "KeyP", "demo_crystal_explode", "", "---", "KeyP",
"free_camera_forward", "", "---", "KeyNUMPAD8", "free_camera_forward", "", "---", "KeyNUMPAD8",
"free_camera_backward", "", "---", "KeyNUMPAD2", "free_camera_backward", "", "---", "KeyNUMPAD2",
"free_camera_left", "", "---", "KeyNUMPAD4", "free_camera_left", "", "---", "KeyNUMPAD4",
"free_camera_right", "", "---", "KeyNUMPAD6", "free_camera_right", "", "---", "KeyNUMPAD6",
"switch_camera", "", "---", "KeyF4", "switch_camera", "", "---", "KeyF4",
"switch_ui_visible" ,"", "---", "KeyF6", "switch_ui_visible" ,"", "---", "KeyF6",
}; };

View file

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

View file

@ -64,30 +64,28 @@ static void initSample()
new CApplicationContext(); new CApplicationContext();
CSheetId::initWithoutSheet(); CSheetId::initWithoutSheet();
CPath::addSearchPath(NL_SOUND_DATA"/data", true, false); CPath::addSearchPath(NL_SOUND_DATA"/data", true, false);
printf("Sample demonstrating OGG playback using stream file .sound sheets."); printf("Sample demonstrating OGG playback using stream file .sound sheets.");
printf("\n\n"); printf("\n\n");
s_AudioMixer = UAudioMixer::createAudioMixer(); s_AudioMixer = UAudioMixer::createAudioMixer();
// Set the sample path before init, this allow the mixer to build the sample banks // Set the sample path before init, this allow the mixer to build the sample banks
s_AudioMixer->setSamplePath(NL_SOUND_DATA"/data/samplebank"); s_AudioMixer->setSamplePath(NL_SOUND_DATA"/data/samplebank");
// Packed sheet option, this mean we want packed sheet generated in 'data' folder // Packed sheet option, this mean we want packed sheet generated in 'data' folder
s_AudioMixer->setPackedSheetOption(NL_SOUND_DATA"/data", true); s_AudioMixer->setPackedSheetOption(NL_SOUND_DATA"/data", true);
printf("Select NLSOUND Driver:\n"); printf("Select NLSOUND Driver:\n");
printf(" [1] FMod\n"); printf(" [1] FMod\n");
printf(" [2] OpenAl\n"); printf(" [2] OpenAl\n");
printf(" [3] DSound\n");
printf(" [4] XAudio2\n");
printf("> "); printf("> ");
int selection = getchar(); getchar(); int selection = getchar(); getchar();
printf("\n"); printf("\n");
// init with 8 tracks, EAX enabled, no ADPCM, and automatic sample bank loading // init with 8 tracks, EAX enabled, no ADPCM, and automatic sample bank loading
s_AudioMixer->init(8, true, false, NULL, true, (UAudioMixer::TDriver)(selection - '0')); s_AudioMixer->init(8, true, false, NULL, true, (UAudioMixer::TDriver)(selection - '0'));
s_AudioMixer->setLowWaterMark(1); s_AudioMixer->setLowWaterMark(1);
CVector initpos(0.0f, 0.0f, 0.0f); CVector initpos(0.0f, 0.0f, 0.0f);
CVector frontvec(0.0f, 1.0f, 0.0f); CVector frontvec(0.0f, 1.0f, 0.0f);
CVector upvec(0.0f, 0.0f, 1.0f); CVector upvec(0.0f, 0.0f, 1.0f);
@ -95,14 +93,14 @@ static void initSample()
s_AudioMixer->getListener()->setOrientation(frontvec, upvec); s_AudioMixer->getListener()->setOrientation(frontvec, upvec);
CPath::addSearchPath(RYZOM_DATA, true, false); CPath::addSearchPath(RYZOM_DATA, true, false);
//NLMISC::CHTimer::startBench(); //NLMISC::CHTimer::startBench();
s_Source = s_AudioMixer->createSource(CSheetId("stream_file.sound")); s_Source = s_AudioMixer->createSource(CSheetId("stream_file.sound"));
nlassert(s_Source); nlassert(s_Source);
s_StreamFileSource = dynamic_cast<CStreamFileSource *>(s_Source); s_StreamFileSource = dynamic_cast<CStreamFileSource *>(s_Source);
nlassert(s_StreamFileSource); nlassert(s_StreamFileSource);
// s_Source->setSourceRelativeMode(true); // s_Source->setSourceRelativeMode(true);
// s_Source->setPitch(2.0f); // s_Source->setPitch(2.0f);
s_GroupController = s_AudioMixer->getGroupController("sound:dialog"); s_GroupController = s_AudioMixer->getGroupController("sound:dialog");
@ -111,7 +109,7 @@ static void initSample()
static void runSample() static void runSample()
{ {
s_Source->play(); s_Source->play();
printf("Change volume with - and +\n"); printf("Change volume with - and +\n");
printf("Press ANY other key to exit\n"); printf("Press ANY other key to exit\n");
for (; ; ) for (; ; )
@ -154,7 +152,7 @@ static void runSample()
} }
s_AudioMixer->update(); s_AudioMixer->update();
nlSleep(40); nlSleep(40);
} }
} }

View file

@ -61,21 +61,19 @@ static void initSample()
new CApplicationContext(); new CApplicationContext();
CSheetId::initWithoutSheet(); CSheetId::initWithoutSheet();
CPath::addSearchPath(NL_SOUND_DATA"/database/build/", true, false); CPath::addSearchPath(NL_SOUND_DATA"/database/build/", true, false);
printf("Sample demonstrating OGG playback using UStreamSource."); printf("Sample demonstrating OGG playback using UStreamSource.");
printf("\n\n"); printf("\n\n");
s_AudioMixer = UAudioMixer::createAudioMixer(); s_AudioMixer = UAudioMixer::createAudioMixer();
printf("Select NLSOUND Driver:\n"); printf("Select NLSOUND Driver:\n");
printf(" [1] FMod\n"); printf(" [1] FMod\n");
printf(" [2] OpenAl\n"); printf(" [2] OpenAl\n");
printf(" [3] DSound\n");
printf(" [4] XAudio2\n");
printf("> "); printf("> ");
int selection = getchar(); getchar(); int selection = getchar(); getchar();
printf("\n"); printf("\n");
// init with 128 tracks, EAX enabled, no ADPCM, and automatic sample bank loading // init with 128 tracks, EAX enabled, no ADPCM, and automatic sample bank loading
s_AudioMixer->init(8, true, false, NULL, true, (UAudioMixer::TDriver)(selection - '0')); s_AudioMixer->init(8, true, false, NULL, true, (UAudioMixer::TDriver)(selection - '0'));
s_AudioMixer->setLowWaterMark(1); s_AudioMixer->setLowWaterMark(1);
@ -85,7 +83,7 @@ static void initSample()
CVector upvec(0.0f, 0.0f, 1.0f); CVector upvec(0.0f, 0.0f, 1.0f);
s_AudioMixer->getListener()->setPos(initpos); s_AudioMixer->getListener()->setPos(initpos);
s_AudioMixer->getListener()->setOrientation(frontvec, upvec); s_AudioMixer->getListener()->setOrientation(frontvec, upvec);
//NLMISC::CHTimer::startBench(); //NLMISC::CHTimer::startBench();
USource *source = s_AudioMixer->createSource(CSheetId("default_stream.sound")); USource *source = s_AudioMixer->createSource(CSheetId("default_stream.sound"));
@ -136,7 +134,7 @@ static void runSample()
//bufferMore(bytes); //bufferMore(bytes);
s_StreamSource->play(); s_StreamSource->play();
printf("Change volume with - and +\n"); printf("Change volume with - and +\n");
printf("Press ANY other key to exit\n"); printf("Press ANY other key to exit\n");
while (!s_AudioDecoder->isMusicEnded()) while (!s_AudioDecoder->isMusicEnded())
@ -177,13 +175,13 @@ static void runSample()
nlSleep(40); nlSleep(40);
s_AudioMixer->update(); s_AudioMixer->update();
} }
s_StreamSource->stop(); s_StreamSource->stop();
printf("End of song\n"); printf("End of song\n");
printf("Press ANY key to exit\n"); printf("Press ANY key to exit\n");
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
while (!_kbhit()) while (!_kbhit())
#else #else
char ch; char ch;
while (!read(0, &ch, 1)) while (!read(0, &ch, 1))

View file

@ -120,7 +120,7 @@ void CCoarseMeshManager::flushRender (IDriver *drv)
H_AUTO( NL3D_StaticLod_Render ); H_AUTO( NL3D_StaticLod_Render );
if (_Meshs.empty()) return; 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) if(!_VBuffer.isResident() && drv->getVertexColorFormat()==CVertexBuffer::TBGRA)
{ {
// since actually empty, no need to swap current memory // since actually empty, no need to swap current memory

View file

@ -5,9 +5,3 @@ ENDIF()
IF(WITH_DRIVER_OPENGLES) IF(WITH_DRIVER_OPENGLES)
ADD_SUBDIRECTORY(opengles) ADD_SUBDIRECTORY(opengles)
ENDIF() 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); typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
#endif #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 #ifndef EGL_NV_coverage_sample_resolve
#define EGL_NV_coverage_sample_resolve 1 #define EGL_NV_coverage_sample_resolve 1
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 #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 #define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
#endif #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 #ifndef EGL_KHR_create_context
#define EGL_KHR_create_context 1 #define EGL_KHR_create_context 1
#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION #define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION

View file

@ -1262,7 +1262,7 @@ sint CDriverGL::getTotalVideoMemory() const
nlwarning("3D: Unable to get renderer ID (%s)", CGLErrorString(error)); nlwarning("3D: Unable to get renderer ID (%s)", CGLErrorString(error));
} }
} }
CGLDestroyRendererInfo(rend); CGLDestroyRendererInfo(rend);
} }
else else
@ -2883,7 +2883,7 @@ IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType()
nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_NV, &result); nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_NV, &result);
OcclusionType = result != 0 ? NotOccluded : Occluded; OcclusionType = result != 0 ? NotOccluded : Occluded;
VisibleCount = (uint) result; 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 else

View file

@ -440,7 +440,7 @@ public:
virtual bool supportCloudRenderSinglePass() const; 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; virtual bool slowUnlockVertexBufferHard() const;
@ -1006,7 +1006,6 @@ private:
bool setScreenMode(const GfxMode &mode); bool setScreenMode(const GfxMode &mode);
// Test if cursor is in the client area. always true when software cursor is used and window visible // 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(); bool isSystemCursorInClientArea();
// Check if RGBA cursors are supported // Check if RGBA cursors are supported
@ -1337,7 +1336,7 @@ private:
virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const; virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const;
/** Compile the given vertex program, return if successful. /** Compile the given vertex program, return if successful.
* If a vertex program was set active before compilation, * If a vertex program was set active before compilation,
* the state of the active vertex program is undefined behaviour afterwards. * the state of the active vertex program is undefined behaviour afterwards.
*/ */
virtual bool compileVertexProgram(CVertexProgram *program); virtual bool compileVertexProgram(CVertexProgram *program);
@ -1364,7 +1363,7 @@ private:
virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::arbfp1) const; virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::arbfp1) const;
/** Compile the given pixel program, return if successful. /** Compile the given pixel program, return if successful.
* If a pixel program was set active before compilation, * If a pixel program was set active before compilation,
* the state of the active pixel program is undefined behaviour afterwards. * the state of the active pixel program is undefined behaviour afterwards.
*/ */
virtual bool compilePixelProgram(CPixelProgram *program); virtual bool compilePixelProgram(CPixelProgram *program);
@ -1391,7 +1390,7 @@ private:
virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; } virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; }
/** Compile the given pixel program, return if successful. /** Compile the given pixel program, return if successful.
* If a pixel program was set active before compilation, * If a pixel program was set active before compilation,
* the state of the active pixel program is undefined behaviour afterwards. * the state of the active pixel program is undefined behaviour afterwards.
*/ */
virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; } virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; }
@ -1464,7 +1463,7 @@ private:
bool activeARBPixelProgram (CPixelProgram *program); bool activeARBPixelProgram (CPixelProgram *program);
bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/); bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/);
//@} //@}
/// \fallback for material shaders /// \fallback for material shaders
// @{ // @{
@ -1477,7 +1476,7 @@ private:
// Don't use glIsEnabled, too slow. // Don't use glIsEnabled, too slow.
return _VertexProgramEnabled; return _VertexProgramEnabled;
} }
bool isPixelProgramEnabled () const bool isPixelProgramEnabled () const
{ {
// Don't use glIsEnabled, too slow. // Don't use glIsEnabled, too slow.
@ -1668,9 +1667,9 @@ public:
CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
virtual uint getUniformIndex(const char *name) const virtual uint getUniformIndex(const char *name) const
{ {
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name); std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second; if (it != ParamIndices.end()) return it->second;
return std::numeric_limits<uint>::max(); return std::numeric_limits<uint>::max();
}; };
@ -1683,14 +1682,14 @@ class CPixelProgamDrvInfosGL : public IProgramDrvInfos
public: public:
// The GL Id. // The GL Id.
GLuint ID; GLuint ID;
// The gl id is auto created here. // The gl id is auto created here.
CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
virtual uint getUniformIndex(const char *name) const virtual uint getUniformIndex(const char *name) const
{ {
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name); std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
if (it != ParamIndices.end()) return it->second; if (it != ParamIndices.end()) return it->second;
return std::numeric_limits<uint>::max(); return std::numeric_limits<uint>::max();
}; };

View file

@ -113,10 +113,6 @@ bool CDriverGL::isAlphaBlendedCursorSupported()
{ {
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
// Support starts with windows 2000 (not only from XP as seen in most docs) // 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; OSVERSIONINFO osvi;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osvi)) 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; _Driver = NULL;
// Create/Init Driver.
#if defined(NL_OS_WINDOWS)
if (driver == Direct3d)
_Driver= CDRU::createD3DDriver();
#endif
if (!_Driver && driver == OpenGl) if (!_Driver && driver == OpenGl)
_Driver= CDRU::createGlDriver(); _Driver= CDRU::createGlDriver();
@ -1840,13 +1834,6 @@ UDriver::TCullMode CDriverUser::getCullMode() const
return (TCullMode) _Driver->getCullMode(); return (TCullMode) _Driver->getCullMode();
} }
// ***************************************************************************
bool CDriverUser::isLost() const
{
NL3D_HAUTO_UI_DRIVER
return _Driver->isLost();
}
// *************************************************************************** // ***************************************************************************
void CDriverUser::beginDialogMode() void CDriverUser::beginDialogMode()
{ {

View file

@ -29,9 +29,6 @@
# include "config.h" # include "config.h"
#else #else
# define NL_OPENGL_AVAILABLE # define NL_OPENGL_AVAILABLE
# ifdef NL_OS_WINDOWS
# define NL_DIRECT3D_AVAILABLE
# endif
#endif // HAVE_CONFIG_H #endif // HAVE_CONFIG_H
#ifdef NL_OS_WINDOWS #ifdef NL_OS_WINDOWS
@ -66,10 +63,6 @@ const char *IDRV_VERSION_PROC_NAME = "NL3D_interfaceVersion";
extern IDriver* createGlDriverInstance (); extern IDriver* createGlDriverInstance ();
#endif #endif
#if defined(NL_OS_WINDOWS) && defined(NL_DIRECT3D_AVAILABLE)
extern IDriver* createD3DDriverInstance ();
#endif
#ifdef NL_OPENGLES_AVAILABLE #ifdef NL_OPENGLES_AVAILABLE
extern IDriver* createGlEsDriverInstance (); extern IDriver* createGlEsDriverInstance ();
#endif #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) void CDRU::drawBitmap (float x, float y, float width, float height, ITexture& texture, IDriver& driver, CViewport viewport, bool blend)
{ {
CMatrix mtx; 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); source->setSourcePtr(a_arbfp1);
m_PP->addSource(source); 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)) if (!drv->compilePixelProgram(m_PP))
{ {
nlwarning("3D: No supported pixel program for FXAA effect"); 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) if(VertexFormat & CVertexBuffer::PrimaryColorFlag)
{ {
ColorOff= vb.getColorOff(); ColorOff= vb.getColorOff();
// todo hulud d3d vertex color RGBA / BGRA
ColorPointer= Accessor.getColorPointer(); ColorPointer= Accessor.getColorPointer();
} }
else else

View file

@ -133,7 +133,7 @@ void CLight::setupAttenuation (float farAttenuationBegin, float farAttenuationEn
const float quadratic= 10.0f; 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), farAttenuationBegin (very big decrase if for instance farAttenuationBegin is near farAttenuationEnd),
hence I simulate it very badly by multiplying the farAttenuationEnd by some factor 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; _LockDone= true;
} }
// After lock, For D3D, the VertexColor may be in BGRA format
if(_VertexStream.isBRGA()) if(_VertexStream.isBRGA())
{ {
// then swap only the B and R (no cpu cycle added per vertex) // 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(); 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 // 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 (numTexStages == 3) numTexStages = 2;
if (forceBaseCaps) numTexStages = std::min(numTexStages, (uint) 2); if (forceBaseCaps) numTexStages = std::min(numTexStages, (uint) 2);
switch(getShader()) 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 (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
if (!rBS.deltaCol.empty()) if (!rBS.deltaCol.empty())
{ {
// todo hulud d3d vertex color RGBA / BGRA
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp); CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
CRGBAF rgbf(*pRGBA); CRGBAF rgbf(*pRGBA);
rgbf.R += rBS.deltaCol[j].R * rFactor; rgbf.R += rBS.deltaCol[j].R * rFactor;
@ -324,7 +323,6 @@ void CMeshMorpher::updateSkinned (std::vector<CAnimatedMorph> *pBSFactor)
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag) if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
if (!rBS.deltaCol.empty()) if (!rBS.deltaCol.empty())
{ {
// todo hulud d3d vertex color RGBA / BGRA
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp); CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
CRGBAF rgbf(*pRGBA); CRGBAF rgbf(*pRGBA);
rgbf.R += rBS.deltaCol[j].R * rFactor; rgbf.R += rBS.deltaCol[j].R * rFactor;
@ -440,13 +438,3 @@ void CMeshMorpher::updateRawSkin (CVertexBuffer *vbOri,
} // NL3D } // NL3D

View file

@ -76,8 +76,7 @@ static const char* WindTreeVPCodeEnd=
DP4 o[HPOS].z, c[2], R5; \n\ DP4 o[HPOS].z, c[2], R5; \n\
DP4 o[HPOS].w, c[3], R5; \n\ DP4 o[HPOS].w, c[3], R5; \n\
MOV o[TEX0], v[8]; \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\ DP4 o[FOGC].x, c[6], R5; \n\
END \n\ END \n\
"; ";
@ -288,13 +287,13 @@ inline void CMeshVPWindTree::setupPerMesh(IDriver *driver, CScene *scene)
// Setup common constants for each instances. // Setup common constants for each instances.
// c[8] take useful constants. // c[8] take useful constants.
driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[0], driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[0],
0, 1, 0.5f, 2); 0, 1, 0.5f, 2);
// c[9] take other useful constants. // c[9] take other useful constants.
driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[1], driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[1],
3.f, 0.f, -1.f, -2.f); 3.f, 0.f, -1.f, -2.f);
// c[10] take Number of phase (4) for level2 and 3. -0.01 to avoid int value == 4. // c[10] take Number of phase (4) for level2 and 3. -0.01 to avoid int value == 4.
driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[2], driver->setUniform4f(IDriver::VertexProgram, program->idx().ProgramConstants[2],
4-0.01f, 0, 0, 0); 4-0.01f, 0, 0, 0);
} }
@ -324,7 +323,7 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
setupLighting(scene, mbi, invertedModelMat); setupLighting(scene, mbi, invertedModelMat);
// c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix(); // c[0..3] take the ModelViewProjection Matrix. After setupModelMatrix();
driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::ModelViewProjection), driver->setUniformMatrix(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::ModelViewProjection),
IDriver::ModelViewProjection, IDriver::Identity); IDriver::ModelViewProjection, IDriver::Identity);
// c[4..7] take the ModelView Matrix. After setupModelMatrix();00 // c[4..7] take the ModelView Matrix. After setupModelMatrix();00
driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::Fog)); driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::Fog));
@ -334,7 +333,7 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
float f; float f;
f= _CurrentTime[0] + instancePhase; f= _CurrentTime[0] + instancePhase;
f= speedCos(f) + Bias[0]; f= speedCos(f) + Bias[0];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel1, driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel1,
maxDeltaPosOS[0]*f ); maxDeltaPosOS[0]*f );
@ -343,19 +342,19 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
float instTime1= _CurrentTime[1] + instancePhase; float instTime1= _CurrentTime[1] + instancePhase;
// phase 0. // phase 0.
f= speedCos( instTime1+0 ) + Bias[1]; f= speedCos( instTime1+0 ) + Bias[1];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[0], driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[0],
maxDeltaPosOS[1]*f); maxDeltaPosOS[1]*f);
// phase 1. // phase 1.
f= speedCos( instTime1+0.25f ) + Bias[1]; f= speedCos( instTime1+0.25f ) + Bias[1];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[1], driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[1],
maxDeltaPosOS[1]*f); maxDeltaPosOS[1]*f);
// phase 2. // phase 2.
f= speedCos( instTime1+0.50f ) + Bias[1]; f= speedCos( instTime1+0.50f ) + Bias[1];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[2], driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[2],
maxDeltaPosOS[1]*f); maxDeltaPosOS[1]*f);
// phase 3. // phase 3.
f= speedCos( instTime1+0.75f ) + Bias[1]; f= speedCos( instTime1+0.75f ) + Bias[1];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[3], driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel2[3],
maxDeltaPosOS[1]*f); maxDeltaPosOS[1]*f);
@ -364,19 +363,19 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
float instTime2= _CurrentTime[2] + instancePhase; float instTime2= _CurrentTime[2] + instancePhase;
// phase 0. // phase 0.
f= speedCos( instTime2+0 ) + Bias[2]; f= speedCos( instTime2+0 ) + Bias[2];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[0], driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[0],
maxDeltaPosOS[2]*f); maxDeltaPosOS[2]*f);
// phase 1. // phase 1.
f= speedCos( instTime2+0.25f ) + Bias[2]; f= speedCos( instTime2+0.25f ) + Bias[2];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[1], driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[1],
maxDeltaPosOS[2]*f); maxDeltaPosOS[2]*f);
// phase 2. // phase 2.
f= speedCos( instTime2+0.50f ) + Bias[2]; f= speedCos( instTime2+0.50f ) + Bias[2];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[2], driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[2],
maxDeltaPosOS[2]*f); maxDeltaPosOS[2]*f);
// phase 3. // phase 3.
f= speedCos( instTime2+0.75f ) + Bias[2]; f= speedCos( instTime2+0.75f ) + Bias[2];
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[3], driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel3[3],
maxDeltaPosOS[2]*f); maxDeltaPosOS[2]*f);
} }

View file

@ -51,7 +51,7 @@ CEventServer CNELU::EventServer;
CEventListenerAsync CNELU::AsyncListener; 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 // Init debug system
// NLMISC::InitDebug(); // NLMISC::InitDebug();
@ -61,13 +61,6 @@ bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow syst
CNELU::Driver = NULL; CNELU::Driver = NULL;
// Init driver. // Init driver.
#ifdef NL_OS_WINDOWS
if (direct3d)
{
CNELU::Driver= CDRU::createD3DDriver();
}
#endif
if (!CNELU::Driver) if (!CNELU::Driver)
{ {
CNELU::Driver= CDRU::createGlDriver(); 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(); NL3D::registerSerial3d();
if (initDriver(w,h,bpp,windowed,systemWindow,offscreen,direct3d)) if (initDriver(w,h,bpp,windowed,systemWindow,offscreen))
{ {
initScene(viewport); initScene(viewport);
initEventServer(); initEventServer();

View file

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

View file

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

View file

@ -485,7 +485,6 @@ void CPSQuad::updateVbColNUVForRender(CVertexBuffer &vb, uint32 startIndex, uint
if (_ColorScheme) if (_ColorScheme)
{ {
// compute the colors, each color is replicated 4 times // 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); _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"); nlwarning("Render trave begin");
#endif #endif
H_AUTO( NL3D_TravRender ); H_AUTO( NL3D_TravRender );
if (getDriver()->isLost()) return; // device is lost so no need to render anything
CTravCameraScene::update(); CTravCameraScene::update();
// Bind to Driver. // Bind to Driver.
setupDriverCamera(); setupDriverCamera();

View file

@ -179,7 +179,6 @@ CShadowMapManager::CShadowMapManager()
_ReceiveShadowMaterial.setTexCoordGen(0, true); _ReceiveShadowMaterial.setTexCoordGen(0, true);
_ReceiveShadowMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace); _ReceiveShadowMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace);
// Setup the stage so we interpolate ShadowColor and White (according to shadowmap alpha) // 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 // source alpha & inverse diffuse. then invert result at subsequent stage
_ReceiveShadowMaterial.texEnvOpRGB(0, CMaterial::Modulate); _ReceiveShadowMaterial.texEnvOpRGB(0, CMaterial::Modulate);
_ReceiveShadowMaterial.texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::InvSrcColor); _ReceiveShadowMaterial.texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::InvSrcColor);
@ -1242,4 +1241,3 @@ void CShadowMapManager::garbageShadowTextures(CScene *scene)
} // NL3D } // NL3D

View file

@ -596,7 +596,7 @@ public:
CSource *source = new CSource(); CSource *source = new CSource();
source->Profile = nelvp; source->Profile = nelvp;
source->DisplayName = "nelvp/Veget"; source->DisplayName = "nelvp/Veget";
// Init the Vertex Program. // Init the Vertex Program.
string vpgram; string vpgram;
// start always with Bend. // start always with Bend.
@ -711,7 +711,7 @@ private:
void CVegetableManager::initVertexProgram(uint vpType, bool fogEnabled) void CVegetableManager::initVertexProgram(uint vpType, bool fogEnabled)
{ {
nlassert(_LastDriver); // update driver should have been called at least once ! nlassert(_LastDriver); // update driver should have been called at least once !
// create VP. // create VP.
_VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgramVeget(vpType, fogEnabled); _VertexProgram[vpType][fogEnabled ? 1 : 0] = new CVertexProgramVeget(vpType, fogEnabled);
} }
@ -1335,7 +1335,6 @@ void CVegetableManager::addInstance(CVegetableInstanceGroup *ig,
uint dstBendOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_BENDINFO); uint dstBendOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_BENDINFO);
uint dstCenterOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_CENTER); uint dstCenterOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_CENTER);
// For D3D, If the VertexBuffer is in BGRA mode
if(allocator->isBGRA()) if(allocator->isBGRA())
{ {
// then swap only the B and R (no cpu cycle added per vertex) // then swap only the B and R (no cpu cycle added per vertex)
@ -1870,7 +1869,7 @@ public:
void CVegetableManager::setupVertexProgramConstants(IDriver *driver, bool fogEnabled) void CVegetableManager::setupVertexProgramConstants(IDriver *driver, bool fogEnabled)
{ {
nlassert(_ActiveVertexProgram); nlassert(_ActiveVertexProgram);
// Standard // Standard
// setup VertexProgram constants. // setup VertexProgram constants.
@ -2666,7 +2665,6 @@ uint CVegetableManager::updateInstanceLighting(CVegetableInstanceGroup *ig, uin
uint dstColor0Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR0); uint dstColor0Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR0);
uint dstColor1Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR1); uint dstColor1Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR1);
// For D3D, If the VertexBuffer is in BGRA mode
if(allocator->isBGRA()) if(allocator->isBGRA())
{ {
// then swap only the B and R (no cpu cycle added per vertex) // 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); CUV *dstUVBend= vbaOut.getTexCoordPointer(i, 1);
if(bendFromColor) if(bendFromColor)
{ {
// todo hulud d3d vertex color RGBA / BGRA
const CRGBA *srcColor= (const CRGBA*)vba.getColorPointer(i); const CRGBA *srcColor= (const CRGBA*)vba.getColorPointer(i);
// Copy and scale by MaxBendWeight // Copy and scale by MaxBendWeight
dstUVBend->U= (srcColor->R / 255.f) * vbuild.MaxBendWeight; dstUVBend->U= (srcColor->R / 255.f) * vbuild.MaxBendWeight;

View file

@ -6,20 +6,20 @@
* CAudioDecoderVorbis * CAudioDecoderVorbis
*/ */
/* /*
* Copyright (C) 2008-2012 by authors * Copyright (C) 2008-2012 by authors
* *
* This file is part of RYZOM CORE. * This file is part of RYZOM CORE.
* RYZOM CORE is free software: you can redistribute it and/or modify * RYZOM CORE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the * published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version. * License, or (at your option) any later version.
* *
* RYZOM CORE is distributed in the hope that it will be useful, but * RYZOM CORE is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details. * Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public * You should have received a copy of the GNU Affero General Public
* License along with RYZOM CORE. If not, see * License along with RYZOM CORE. If not, see
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
@ -56,7 +56,6 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence)
{ {
if (whence == SEEK_CUR && offset == 0) if (whence == SEEK_CUR && offset == 0)
{ {
// nlwarning(NLSOUND_XAUDIO2_PREFIX "This seek call doesn't do a damn thing, wtf.");
return 0; // ooookkaaaaaayyy return 0; // ooookkaaaaaayyy
} }
@ -75,7 +74,6 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence)
origin = NLMISC::IStream::end; origin = NLMISC::IStream::end;
break; break;
default: default:
// nlwarning(NLSOUND_XAUDIO2_PREFIX "Seeking to fake origin.");
return -1; return -1;
} }
@ -101,7 +99,7 @@ static ov_callbacks OV_CALLBACKS_NLMISC_STREAM = {
(long (*)(void *)) vorbisTellFunc (long (*)(void *)) vorbisTellFunc
}; };
CAudioDecoderVorbis::CAudioDecoderVorbis(NLMISC::IStream *stream, bool loop) CAudioDecoderVorbis::CAudioDecoderVorbis(NLMISC::IStream *stream, bool loop)
: _Stream(stream), _Loop(loop), _IsMusicEnded(false), _StreamSize(0) : _Stream(stream), _Loop(loop), _IsMusicEnded(false), _StreamSize(0)
{ {
_StreamOffset = stream->getPos(); _StreamOffset = stream->getPos();
@ -148,12 +146,11 @@ uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 m
do do
{ {
// signed 16-bit or unsigned 8-bit little-endian samples // signed 16-bit or unsigned 8-bit little-endian samples
sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read, sint br = ov_read(&_OggVorbisFile, (char *)&buffer[bytes_read], maximum - bytes_read,
endianness, // Specifies big or little endian byte packing. 0 for little endian, 1 for b ig endian. Typical value is 0. endianness, // Specifies big or little endian byte packing. 0 for little endian, 1 for b ig endian. Typical value is 0.
getBitsPerSample() == 8 ? 1 : 2, getBitsPerSample() == 8 ? 1 : 2,
getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1. getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1.
&current_section); &current_section);
// nlinfo(NLSOUND_XAUDIO2_PREFIX "current_section: %i", current_section);
if (br > 0) if (br > 0)
{ {
bytes_read += (uint32)br; bytes_read += (uint32)br;
@ -165,14 +162,14 @@ uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 m
ov_pcm_seek(&_OggVorbisFile, 0); ov_pcm_seek(&_OggVorbisFile, 0);
//_Stream->seek(0, NLMISC::IStream::begin); //_Stream->seek(0, NLMISC::IStream::begin);
} }
else else
{ {
_IsMusicEnded = true; _IsMusicEnded = true;
break; break;
} }
} }
else else
{ {
// error // error
switch(br) switch(br)
{ {

View file

@ -275,7 +275,7 @@ void CAudioMixerUser::reset()
_Leaving = true; _Leaving = true;
_SourceWaitingForPlay.clear(); _SourceWaitingForPlay.clear();
for (uint i = 0; i < _NbMusicChannelFaders; ++i) for (uint i = 0; i < _NbMusicChannelFaders; ++i)
_MusicChannelFaders[i].reset(); _MusicChannelFaders[i].reset();
@ -374,9 +374,7 @@ void CAudioMixerUser::initDriver(const std::string &driverName)
ISoundDriver::TDriver driverType; ISoundDriver::TDriver driverType;
if (dn == "auto") driverType = ISoundDriver::DriverAuto; if (dn == "auto") driverType = ISoundDriver::DriverAuto;
else if (dn == "fmod") driverType = ISoundDriver::DriverFMod; else if (dn == "fmod") driverType = ISoundDriver::DriverFMod;
else if (dn == "dsound") driverType = ISoundDriver::DriverDSound;
else if (dn == "openal") driverType = ISoundDriver::DriverOpenAl; else if (dn == "openal") driverType = ISoundDriver::DriverOpenAl;
else if (dn == "xaudio2") driverType = ISoundDriver::DriverXAudio2;
else else
{ {
driverType = ISoundDriver::DriverAuto; driverType = ISoundDriver::DriverAuto;
@ -510,7 +508,7 @@ void CAudioMixerUser::initDevice(const std::string &deviceName, const CInitInfo
if (!_ReverbEffect) if (!_ReverbEffect)
{ _UseEax = false; } { _UseEax = false; }
else // createEffect succeeded, add environments else // createEffect succeeded, add environments
{ {
nldebug("AM: Reverb OK"); nldebug("AM: Reverb OK");
// todo: loading this data from a file or something would be neat // todo: loading this data from a file or something would be neat
// also: check if this should go into clustered_sound (background_sound_manager also uses this stuff at one point, though) // also: check if this should go into clustered_sound (background_sound_manager also uses this stuff at one point, though)
@ -572,7 +570,7 @@ void CAudioMixerUser::initDevice(const std::string &deviceName, const CInitInfo
{ {
buildSampleBankList(); buildSampleBankList();
} }
// Init music channels // Init music channels
for (i = 0; i < _NbMusicChannelFaders; ++i) for (i = 0; i < _NbMusicChannelFaders; ++i)
_MusicChannelFaders[i].init(_SoundDriver); _MusicChannelFaders[i].init(_SoundDriver);
@ -1528,7 +1526,7 @@ void CAudioMixerUser::getPlayingSoundsPos(bool virtualPos, std::vector<std::pair
source->getSourceRelativeMode() source->getSourceRelativeMode()
? source->getPos() + _ListenPosition ? source->getPos() + _ListenPosition
: source->getPos())); : source->getPos()));
if (source->getTrack() == 0) if (source->getTrack() == 0)
nbmute++; nbmute++;
else else
@ -2833,5 +2831,3 @@ NLMISC_CATEGORISED_COMMAND(nel, displaySoundProfile, "Display information on sou
} // NLSOUND } // NLSOUND

View file

@ -158,7 +158,7 @@ CClusteredSound::CClusteredSound()
_LastEnv(CStringMapper::emptyId()), _LastEnv(CStringMapper::emptyId()),
_LastEnvSize(-1.0f) // size goes from 0.0f to 100.0f _LastEnvSize(-1.0f) // size goes from 0.0f to 100.0f
{ {
} }
@ -590,10 +590,10 @@ void CClusteredSound::soundTraverse(const std::vector<CCluster *> &clusters, CSo
CClusterSoundStatus css; CClusterSoundStatus css;
css.Gain = travContext.Gain; css.Gain = travContext.Gain;
CVector soundDir = (nearPos - travContext.ListenerPos).normed(); 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(); TStringId occId = portal->getOcclusionModelId();
TStringIntMap::iterator it(_IdToMaterial.find(occId)); 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 EAX_AVAILABLE == 1 // EAX_AVAILABLE no longer used => TODO: implement with EFX and remove when new implementation OK.
if (it != _IdToMaterial.end()) if (it != _IdToMaterial.end())
@ -612,14 +612,14 @@ void CClusteredSound::soundTraverse(const std::vector<CCluster *> &clusters, CSo
css.OcclusionRoomRatio = travContext.OcclusionRoomRatio; css.OcclusionRoomRatio = travContext.OcclusionRoomRatio;
} }
#else // EAX_AVAILABLE #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()) if (it != _IdToMaterial.end())
{ {
// found an occlusion material for this portal // found an occlusion material for this portal
uint matId = it->second; uint matId = it->second;
css.Gain *= EAX_MATERIAL_PARAM[matId]; 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 #endif // EAX_AVAILABLE
/* if (portal->getOcclusionModel() == "wood door") /* if (portal->getOcclusionModel() == "wood door")
{ {

View file

@ -25,11 +25,3 @@ ENDIF()
IF(WITH_DRIVER_FMOD) IF(WITH_DRIVER_FMOD)
ADD_SUBDIRECTORY(fmod) ADD_SUBDIRECTORY(fmod)
ENDIF() 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() ) if( !CSoundDriverFMod::getInstance()->fmodOk() )
return; return;
// clamp as in DSound.
clamp(f, 0.f, 10.f); clamp(f, 0.f, 10.f);
// set // set
@ -150,7 +149,6 @@ void CListenerFMod::setRolloffFactor( float f )
if(!CSoundDriverFMod::getInstance()->fmodOk()) if(!CSoundDriverFMod::getInstance()->fmodOk())
return; return;
// clamp as in DSound (FMod requirement)
clamp(f, 0.f, 10.f); clamp(f, 0.f, 10.f);
_RolloffFactor = f; _RolloffFactor = f;

View file

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

View file

@ -128,7 +128,7 @@ uint32 NLSOUND_interfaceVersion ()
CSoundDriverFMod::CSoundDriverFMod(ISoundDriver::IStringMapperProvider *stringMapper) CSoundDriverFMod::CSoundDriverFMod(ISoundDriver::IStringMapperProvider *stringMapper)
: _StringMapper(stringMapper), _FModOk(false), _MasterGain(1.f), _ForceSoftwareBuffer(false) : _StringMapper(stringMapper), _FModOk(false), _MasterGain(1.f), _ForceSoftwareBuffer(false)
{ {
} }
// ****************************************************************** // ******************************************************************
@ -187,7 +187,7 @@ void CSoundDriverFMod::initDevice(const std::string &device, TSoundOptions optio
{ {
// list of supported options in this driver // list of supported options in this driver
// no adpcm, no effects, no buffer streaming // no adpcm, no effects, no buffer streaming
const sint supportedOptions = const sint supportedOptions =
OptionSoftwareBuffer OptionSoftwareBuffer
| OptionManualRolloff | OptionManualRolloff
| OptionLocalBufferCopy; | OptionLocalBufferCopy;
@ -199,9 +199,6 @@ void CSoundDriverFMod::initDevice(const std::string &device, TSoundOptions optio
_Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions); _Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions);
uint initFlags = 0; uint initFlags = 0;
#ifdef NL_OS_WINDOWS
initFlags = FSOUND_INIT_DSOUND_DEFERRED;
#endif
// Init with 32 channels, and deferred sound // Init with 32 channels, and deferred sound
if (!FSOUND_Init(22050, 32, initFlags)) if (!FSOUND_Init(22050, 32, initFlags))
@ -495,7 +492,7 @@ bool getTag (std::string &result, const char *tag, FSOUND_STREAM *stream)
return false; return false;
} }
/** Get music info. Returns false if the song is not found or the function is not implemented. /** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver * \param filepath path to file, CPath::lookup done by driver
* \param artist returns the song artist (empty if not available) * \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available) * \param title returns the title (empty if not available)
@ -516,7 +513,7 @@ bool CSoundDriverFMod::getMusicInfo(const std::string &filepath, std::string &ar
if (CBigFile::getInstance().getFileInfo(pathName, fileSize, fileOffset)) if (CBigFile::getInstance().getFileInfo(pathName, fileSize, fileOffset))
{ {
// set pathname to bnp // set pathname to bnp
pathName = pathName.substr(0, pathName.find('@')); pathName = pathName.substr(0, pathName.find('@'));
} }
else else
{ {

View file

@ -35,7 +35,7 @@ namespace NLSOUND {
- EAX is not supported (setEnvironnement() / setEAXProperty() no-op) - EAX is not supported (setEnvironnement() / setEAXProperty() no-op)
- ADPCM is not supported (decompressed and the format change internaly ) - ADPCM is not supported (decompressed and the format change internaly )
- deffered param on ISource::setPos() etc... does not work. Always deffered. - 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???)
*/ */
@ -49,7 +49,7 @@ public:
CSoundDriverFMod(ISoundDriver::IStringMapperProvider *stringMapper); CSoundDriverFMod(ISoundDriver::IStringMapperProvider *stringMapper);
virtual ~CSoundDriverFMod(); virtual ~CSoundDriverFMod();
/// Return a list of available devices for the user. The value at index 0 is empty, and is used for automatic device selection. /// 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); 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. /// Initialize the driver with a user selected device. If device.empty(), the default or most appropriate device is used.
@ -110,7 +110,7 @@ public:
/// Create a music channel, destroy with destroyMusicChannel /// Create a music channel, destroy with destroyMusicChannel
virtual IMusicChannel *createMusicChannel(); virtual IMusicChannel *createMusicChannel();
/** Get music info. Returns false if the song is not found or the function is not implemented. /** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver * \param filepath path to file, CPath::lookup done by driver
* \param artist returns the song artist (empty if not available) * \param artist returns the song artist (empty if not available)
@ -133,7 +133,7 @@ public:
/// Return if a music extension is supported by the driver's music channel. /// Return if a music extension is supported by the driver's music channel.
virtual bool isMusicExtensionSupported(const std::string &extension) const; virtual bool isMusicExtensionSupported(const std::string &extension) const;
private: private:
virtual void startBench(); virtual void startBench();
virtual void endBench(); virtual void endBench();
virtual void displayBench(NLMISC::CLog *log); virtual void displayBench(NLMISC::CLog *log);

View file

@ -466,7 +466,7 @@ void CSourceFMod::updateVolume( const NLMISC::CVector& listener )
//// retransform to linear form //// retransform to linear form
//double attGain= pow((double)10.0, double(volumeDB)/2000.0); //double attGain= pow((double)10.0, double(volumeDB)/2000.0);
//clamp(attGain, 0.f, 1.f); //clamp(attGain, 0.f, 1.f);
float rolloff = ISource::computeManualRolloff(_Alpha, sqrdist, _MinDist, _MaxDist); float rolloff = ISource::computeManualRolloff(_Alpha, sqrdist, _MinDist, _MaxDist);
float volume = _Gain * rolloff; float volume = _Gain * rolloff;
@ -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.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 linearly between 1.0 and 0.0 (linear scale)
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This * 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 * 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 * adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
@ -548,7 +548,7 @@ void CSourceFMod::updateFModPosIfRelative()
/// Enable or disable direct output [true/false], default: true /// Enable or disable direct output [true/false], default: true
void CSourceFMod::setDirect(bool /* enable */) void CSourceFMod::setDirect(bool /* enable */)
{ {
} }
/// Return if the direct output is enabled /// Return if the direct output is enabled
@ -560,7 +560,7 @@ bool CSourceFMod::getDirect() const
/// Set the gain for the direct path /// Set the gain for the direct path
void CSourceFMod::setDirectGain(float /* gain */) void CSourceFMod::setDirectGain(float /* gain */)
{ {
} }
/// Get the gain for the direct path /// Get the gain for the direct path
@ -572,7 +572,7 @@ float CSourceFMod::getDirectGain() const
/// Enable or disable the filter for the direct channel /// Enable or disable the filter for the direct channel
void CSourceFMod::enableDirectFilter(bool /* enable */) void CSourceFMod::enableDirectFilter(bool /* enable */)
{ {
} }
/// Check if the filter on the direct channel is enabled /// Check if the filter on the direct channel is enabled
@ -584,22 +584,22 @@ bool CSourceFMod::isDirectFilterEnabled() const
/// Set the filter parameters for the direct channel /// Set the filter parameters for the direct channel
void CSourceFMod::setDirectFilter(TFilter /*filterType*/, float /*lowFrequency*/, float /*highFrequency*/, float /*passGain*/) void CSourceFMod::setDirectFilter(TFilter /*filterType*/, float /*lowFrequency*/, float /*highFrequency*/, float /*passGain*/)
{ {
} }
/// Get the filter parameters for the direct channel /// Get the filter parameters for the direct channel
void CSourceFMod::getDirectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const void CSourceFMod::getDirectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const
{ {
filterType = FilterLowPass; filterType = FilterLowPass;
lowFrequency = NLSOUND_DEFAULT_FILTER_PASS_LF; lowFrequency = NLSOUND_DEFAULT_FILTER_PASS_LF;
highFrequency = NLSOUND_DEFAULT_FILTER_PASS_HF; highFrequency = NLSOUND_DEFAULT_FILTER_PASS_HF;
passGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN; passGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN;
} }
/// Set the direct filter gain /// Set the direct filter gain
void CSourceFMod::setDirectFilterPassGain(float /*passGain*/) void CSourceFMod::setDirectFilterPassGain(float /*passGain*/)
{ {
} }
/// Get the direct filter gain /// Get the direct filter gain
@ -611,7 +611,7 @@ float CSourceFMod::getDirectFilterPassGain() const
/// Set the effect send for this source, NULL to disable. [IEffect], default: NULL /// Set the effect send for this source, NULL to disable. [IEffect], default: NULL
void CSourceFMod::setEffect(IReverbEffect * /* reverbEffect */) void CSourceFMod::setEffect(IReverbEffect * /* reverbEffect */)
{ {
} }
/// Get the effect send for this source /// Get the effect send for this source
@ -623,7 +623,7 @@ IEffect *CSourceFMod::getEffect() const
/// Set the gain for the effect path /// Set the gain for the effect path
void CSourceFMod::setEffectGain(float /* gain */) void CSourceFMod::setEffectGain(float /* gain */)
{ {
} }
/// Get the gain for the effect path /// Get the gain for the effect path
@ -635,7 +635,7 @@ float CSourceFMod::getEffectGain() const
/// Enable or disable the filter for the effect channel /// Enable or disable the filter for the effect channel
void CSourceFMod::enableEffectFilter(bool /* enable */) void CSourceFMod::enableEffectFilter(bool /* enable */)
{ {
} }
/// Check if the filter on the effect channel is enabled /// Check if the filter on the effect channel is enabled
@ -647,22 +647,22 @@ bool CSourceFMod::isEffectFilterEnabled() const
/// Set the filter parameters for the effect channel /// Set the filter parameters for the effect channel
void CSourceFMod::setEffectFilter(TFilter /*filterType*/, float /*lowFrequency*/, float /*highFrequency*/, float /*passGain*/) void CSourceFMod::setEffectFilter(TFilter /*filterType*/, float /*lowFrequency*/, float /*highFrequency*/, float /*passGain*/)
{ {
} }
/// Get the filter parameters for the effect channel /// Get the filter parameters for the effect channel
void CSourceFMod::getEffectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const void CSourceFMod::getEffectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const
{ {
filterType = FilterLowPass; filterType = FilterLowPass;
lowFrequency = NLSOUND_DEFAULT_FILTER_PASS_LF; lowFrequency = NLSOUND_DEFAULT_FILTER_PASS_LF;
highFrequency = NLSOUND_DEFAULT_FILTER_PASS_HF; highFrequency = NLSOUND_DEFAULT_FILTER_PASS_HF;
passGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN; passGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN;
} }
/// Set the effect filter gain /// Set the effect filter gain
void CSourceFMod::setEffectFilterPassGain(float /*passGain*/) void CSourceFMod::setEffectFilterPassGain(float /*passGain*/)
{ {
} }
/// Get the effect filter gain /// Get the effect filter gain

View file

@ -25,11 +25,11 @@ namespace NLSOUND {
class CBufferFMod; class CBufferFMod;
// TODO: Doc comments in FMod driver are wrong. // 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?)! // Fix drivername, author and date (2004?)!
/** /**
* DirectSound sound source * FMOD sound source
* *
* For arguments as 3D vectors, use the NeL vector coordinate system * For arguments as 3D vectors, use the NeL vector coordinate system
@ -41,16 +41,16 @@ namespace NLSOUND {
class CSourceFMod : public ISource class CSourceFMod : public ISource
{ {
friend class CSoundDriverFMod; friend class CSoundDriverFMod;
public: public:
/// Constructor /// Constructor
CSourceFMod( uint sourcename = 0 ); CSourceFMod( uint sourcename = 0 );
/// Destructor /// Destructor
virtual ~CSourceFMod(); virtual ~CSourceFMod();
/// Initialize the DirectSound buffers. Called by the sound driver only. /// Initialize the FMOD buffers. Called by the sound driver only.
void init(); void init();
/// \name Initialization /// \name Initialization
//@{ //@{
/// Enable or disable streaming mode. Source must be stopped to call this. /// Enable or disable streaming mode. Source must be stopped to call this.
@ -68,14 +68,14 @@ public:
/// Return the amount of buffers in the queue (playing and waiting). 3 buffers is optimal. /// Return the amount of buffers in the queue (playing and waiting). 3 buffers is optimal.
virtual uint countStreamingBuffers() const; virtual uint countStreamingBuffers() const;
//@} //@}
/// \name Playback control /// \name Playback control
//@{ //@{
/// Set looping on/off for future playbacks (default: off), not available for streaming /// Set looping on/off for future playbacks (default: off), not available for streaming
virtual void setLooping(bool l); virtual void setLooping(bool l);
/// Return the looping state /// Return the looping state
virtual bool getLooping() const; virtual bool getLooping() const;
/** Play the static buffer (or stream in and play). /** Play the static buffer (or stream in and play).
* This method can return false if the sample for this sound is unloaded. * This method can return false if the sample for this sound is unloaded.
*/ */
@ -93,7 +93,7 @@ public:
/// Returns the number of milliseconds the source has been playing /// Returns the number of milliseconds the source has been playing
virtual uint32 getTime(); virtual uint32 getTime();
//@} //@}
/// \name Source properties /// \name Source properties
//@{ //@{
/** Set the position vector (default: (0,0,0)). /** Set the position vector (default: (0,0,0)).
@ -147,7 +147,7 @@ public:
* alpha.0: the volume will decrease linearly between 0dB and -100 dB * 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 linearly between 1.0 and 0.0 (linear scale)
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This * 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 * 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 * adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
@ -155,7 +155,7 @@ public:
*/ */
virtual void setAlpha(double a); virtual void setAlpha(double a);
//@} //@}
/// \name Direct output /// \name Direct output
//@{ //@{
/// Enable or disable direct output [true/false], default: true /// Enable or disable direct output [true/false], default: true
@ -166,7 +166,7 @@ public:
virtual void setDirectGain(float gain); virtual void setDirectGain(float gain);
/// Get the gain for the direct path /// Get the gain for the direct path
virtual float getDirectGain() const; virtual float getDirectGain() const;
/// Enable or disable the filter for the direct channel /// Enable or disable the filter for the direct channel
virtual void enableDirectFilter(bool enable = true); virtual void enableDirectFilter(bool enable = true);
/// Check if the filter on the direct channel is enabled /// Check if the filter on the direct channel is enabled
@ -180,7 +180,7 @@ public:
/// Get the direct filter gain /// Get the direct filter gain
virtual float getDirectFilterPassGain() const; virtual float getDirectFilterPassGain() const;
//@} //@}
/// \name Effect output /// \name Effect output
//@{ //@{
/// Set the effect send for this source, NULL to disable. [IEffect], default: NULL /// Set the effect send for this source, NULL to disable. [IEffect], default: NULL
@ -191,7 +191,7 @@ public:
virtual void setEffectGain(float gain); virtual void setEffectGain(float gain);
/// Get the gain for the effect path /// Get the gain for the effect path
virtual float getEffectGain() const; virtual float getEffectGain() const;
/// Enable or disable the filter for the effect channel /// Enable or disable the filter for the effect channel
virtual void enableEffectFilter(bool enable = true); virtual void enableEffectFilter(bool enable = true);
/// Check if the filter on the effect channel is enabled /// Check if the filter on the effect channel is enabled
@ -205,29 +205,29 @@ public:
/// Get the effect filter gain /// Get the effect filter gain
virtual float getEffectFilterPassGain() const; virtual float getEffectFilterPassGain() const;
//@} //@}
/// Return the OpenAL source name /// Return the OpenAL source name
uint sourceName() { return _SourceName; } uint sourceName() { return _SourceName; }
/// Reset the source before reuse /// Reset the source before reuse
void reset(); void reset();
/// Update the source (e.g. continue to stream the data in) /// Update the source (e.g. continue to stream the data in)
bool update(); bool update();
/** Update the source's volume according to its distance and fade out curve. /** Update the source's volume according to its distance and fade out curve.
* It takes the current position of the listener as argument. * It takes the current position of the listener as argument.
* Called only with OptionManualRolloff * Called only with OptionManualRolloff
*/ */
void updateVolume(const NLMISC::CVector& listener); void updateVolume(const NLMISC::CVector& listener);
bool needsUpdate(); bool needsUpdate();
void updateFModPosIfRelative(); void updateFModPosIfRelative();
private: private:
void copySampleTo16BitsTrack(void *dst, void *src, uint nbSample, TSampleFormat sourceFormat); void copySampleTo16BitsTrack(void *dst, void *src, uint nbSample, TSampleFormat sourceFormat);
enum TSourceState enum TSourceState
{ {
source_stopped, source_stopped,
@ -235,19 +235,19 @@ private:
source_silencing, source_silencing,
source_swap_pending source_swap_pending
}; };
/// Release all DirectSound resources /// Release all FMod resources
void release(); void release();
// Source name // Source name
uint _SourceName; uint _SourceName;
TSourceState _State; TSourceState _State;
IBuffer *_Sample; IBuffer *_Sample;
IBuffer *_NextSample; IBuffer *_NextSample;
sint _FModChannel; sint _FModChannel;
// States // States
bool _PosRelative; bool _PosRelative;
bool _Loop; bool _Loop;
@ -258,9 +258,9 @@ private:
NLMISC::CVector _Vel; NLMISC::CVector _Vel;
NLMISC::CVector _Front; NLMISC::CVector _Front;
float _MinDist, _MaxDist; float _MinDist, _MaxDist;
void updateFModPos(); void updateFModPos();
}; };

View file

@ -184,8 +184,8 @@ uint32 NLSOUND_interfaceVersion ()
/* /*
* Constructor * Constructor
*/ */
CSoundDriverAL::CSoundDriverAL(ISoundDriver::IStringMapperProvider *stringMapper) CSoundDriverAL::CSoundDriverAL(ISoundDriver::IStringMapperProvider *stringMapper)
: _StringMapper(stringMapper), _AlDevice(NULL), _AlContext(NULL), : _StringMapper(stringMapper), _AlDevice(NULL), _AlContext(NULL),
_NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f) _NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f)
{ {
alExtInit(); alExtInit();
@ -196,9 +196,9 @@ _NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f)
*/ */
CSoundDriverAL::~CSoundDriverAL() CSoundDriverAL::~CSoundDriverAL()
{ {
// WARNING: Only internal resources are released here, // WARNING: Only internal resources are released here,
// the created instances must still be released by the user! // the created instances must still be released by the user!
// Remove the allocated (but not exported) source and buffer names- // Remove the allocated (but not exported) source and buffer names-
// Release internal resources of all remaining ISource instances // Release internal resources of all remaining ISource instances
if (!_Sources.empty()) if (!_Sources.empty())
@ -208,7 +208,7 @@ CSoundDriverAL::~CSoundDriverAL()
for (; it != end; ++it) (*it)->release(); // CSourceAL will be deleted by user for (; it != end; ++it) (*it)->release(); // CSourceAL will be deleted by user
_Sources.clear(); _Sources.clear();
} }
if (!_Buffers.empty()) alDeleteBuffers(compactAliveNames(_Buffers, alIsBuffer), &*_Buffers.begin()); if (!_Buffers.empty()) alDeleteBuffers(compactAliveNames(_Buffers, alIsBuffer), &*_Buffers.begin());
// Release internal resources of all remaining IEffect instances // Release internal resources of all remaining IEffect instances
if (!_Effects.empty()) if (!_Effects.empty())
{ {
@ -229,7 +229,7 @@ void CSoundDriverAL::getDevices(std::vector<std::string> &devices)
devices.push_back(""); // empty devices.push_back(""); // empty
if (AlEnumerateAllExt) if (AlEnumerateAllExt)
{ {
const ALchar* deviceNames = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); const ALchar* deviceNames = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
// const ALchar* defaultDevice = NULL; // const ALchar* defaultDevice = NULL;
if(!strlen(deviceNames)) if(!strlen(deviceNames))
@ -257,7 +257,7 @@ static const ALchar *getDeviceInternal(const std::string &device)
{ {
if (device.empty()) return NULL; if (device.empty()) return NULL;
if (AlEnumerateAllExt) if (AlEnumerateAllExt)
{ {
const ALchar* deviceNames = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); const ALchar* deviceNames = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
if(!strlen(deviceNames)) if(!strlen(deviceNames))
{ {
@ -286,7 +286,7 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
{ {
// list of supported options in this driver // list of supported options in this driver
// no adpcm, no manual rolloff (for now) // no adpcm, no manual rolloff (for now)
const sint supportedOptions = const sint supportedOptions =
OptionEnvironmentEffects OptionEnvironmentEffects
| OptionSoftwareBuffer | OptionSoftwareBuffer
| OptionManualRolloff | OptionManualRolloff
@ -298,7 +298,7 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
// set the options // set the options
_Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions); _Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions);
/* TODO: multichannel */ /* TODO: multichannel */
// OpenAL initialization // OpenAL initialization
@ -309,8 +309,8 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
if (!_AlDevice) throw ESoundDriver("AL: Failed to open device"); if (!_AlDevice) throw ESoundDriver("AL: Failed to open device");
nldebug("AL: ALC_DEVICE_SPECIFIER: '%s'", alcGetString(_AlDevice, ALC_DEVICE_SPECIFIER)); nldebug("AL: ALC_DEVICE_SPECIFIER: '%s'", alcGetString(_AlDevice, ALC_DEVICE_SPECIFIER));
//int attrlist[] = { ALC_FREQUENCY, 48000, //int attrlist[] = { ALC_FREQUENCY, 48000,
// ALC_MONO_SOURCES, 12, // ALC_MONO_SOURCES, 12,
// ALC_STEREO_SOURCES, 4, // ALC_STEREO_SOURCES, 4,
// ALC_INVALID }; // ALC_INVALID };
_AlContext = alcCreateContext(_AlDevice, NULL); // attrlist); _AlContext = alcCreateContext(_AlDevice, NULL); // attrlist);
if (!_AlContext) { alcCloseDevice(_AlDevice); throw ESoundDriver("AL: Failed to create context"); } if (!_AlContext) { alcCloseDevice(_AlDevice); throw ESoundDriver("AL: Failed to create context"); }
@ -330,20 +330,20 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
// Load and display extensions // Load and display extensions
alExtInitDevice(_AlDevice); alExtInitDevice(_AlDevice);
#if EAX_AVAILABLE #if EAX_AVAILABLE
nlinfo("AL: EAX: %s, EAX-RAM: %s, ALC_EXT_EFX: %s", nlinfo("AL: EAX: %s, EAX-RAM: %s, ALC_EXT_EFX: %s",
AlExtEax ? "Present" : "Not available", AlExtEax ? "Present" : "Not available",
AlExtXRam ? "Present" : "Not available", AlExtXRam ? "Present" : "Not available",
AlExtEfx ? "Present" : "Not available"); AlExtEfx ? "Present" : "Not available");
#else #else
nldebug("AL: EAX-RAM: %s, ALC_EXT_EFX: %s", nldebug("AL: EAX-RAM: %s, ALC_EXT_EFX: %s",
AlExtXRam ? "Present" : "Not available", AlExtXRam ? "Present" : "Not available",
AlExtEfx ? "Present" : "Not available"); AlExtEfx ? "Present" : "Not available");
#endif #endif
alTestError(); alTestError();
nldebug("AL: Max. sources: %u, Max. effects: %u", (uint32)countMaxSources(), (uint32)countMaxEffects()); nldebug("AL: Max. sources: %u, Max. effects: %u", (uint32)countMaxSources(), (uint32)countMaxEffects());
if (getOption(OptionEnvironmentEffects)) if (getOption(OptionEnvironmentEffects))
{ {
if (!AlExtEfx) if (!AlExtEfx)
{ {
@ -351,13 +351,13 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
_Options = (TSoundOptions)((uint)_Options & ~OptionEnvironmentEffects); _Options = (TSoundOptions)((uint)_Options & ~OptionEnvironmentEffects);
} }
else if (!countMaxEffects()) else if (!countMaxEffects())
{ {
nlwarning("AL: No effects available, environment effects disabled"); nlwarning("AL: No effects available, environment effects disabled");
_Options = (TSoundOptions)((uint)_Options & ~OptionEnvironmentEffects); _Options = (TSoundOptions)((uint)_Options & ~OptionEnvironmentEffects);
} }
} }
// Choose the I3DL2 model (same as DirectSound3D if not manual) // Choose the I3DL2 model
if (getOption(OptionManualRolloff)) alDistanceModel(AL_NONE); if (getOption(OptionManualRolloff)) alDistanceModel(AL_NONE);
else alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); else alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
alTestError(); alTestError();
@ -456,7 +456,7 @@ IReverbEffect *CSoundDriverAL::createReverbEffect()
{ {
IReverbEffect *ieffect = NULL; IReverbEffect *ieffect = NULL;
CEffectAL *effectal = NULL; CEffectAL *effectal = NULL;
ALuint slot = AL_NONE; ALuint slot = AL_NONE;
alGenAuxiliaryEffectSlots(1, &slot); alGenAuxiliaryEffectSlots(1, &slot);
if (alGetError() != AL_NO_ERROR) if (alGetError() != AL_NO_ERROR)
@ -464,7 +464,7 @@ IReverbEffect *CSoundDriverAL::createReverbEffect()
nlwarning("AL: alGenAuxiliaryEffectSlots failed"); nlwarning("AL: alGenAuxiliaryEffectSlots failed");
return NULL; return NULL;
} }
ALuint effect = AL_NONE; ALuint effect = AL_NONE;
alGenEffects(1, &effect); alGenEffects(1, &effect);
if (alGetError() != AL_NO_ERROR) if (alGetError() != AL_NO_ERROR)
@ -491,7 +491,7 @@ IReverbEffect *CSoundDriverAL::createReverbEffect()
_Effects.insert(effectal); _Effects.insert(effectal);
return ieffect; return ieffect;
} }
#endif #endif
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
if (alGetError() != AL_NO_ERROR) if (alGetError() != AL_NO_ERROR)
@ -520,16 +520,16 @@ static uint getMaxNumSourcesInternal()
ALuint sources[256]; ALuint sources[256];
memset(sources, 0, sizeofarray(sources)); memset(sources, 0, sizeofarray(sources));
uint sourceCount = 0; uint sourceCount = 0;
alGetError(); alGetError();
for (; sourceCount < 256; ++sourceCount) for (; sourceCount < 256; ++sourceCount)
{ {
alGenSources(1, &sources[sourceCount]); alGenSources(1, &sources[sourceCount]);
if (alGetError() != AL_NO_ERROR) if (alGetError() != AL_NO_ERROR)
break; break;
} }
alDeleteSources(sourceCount, sources); alDeleteSources(sourceCount, sources);
if (alGetError() != AL_NO_ERROR) if (alGetError() != AL_NO_ERROR)
{ {

View file

@ -35,20 +35,20 @@ namespace NLSOUND {
CSourceAL::CSourceAL(CSoundDriverAL *soundDriver) : CSourceAL::CSourceAL(CSoundDriverAL *soundDriver) :
_SoundDriver(NULL), _Buffer(NULL), _Source(AL_NONE), _SoundDriver(NULL), _Buffer(NULL), _Source(AL_NONE),
_DirectFilter(AL_FILTER_NULL), _EffectFilter(AL_FILTER_NULL), _DirectFilter(AL_FILTER_NULL), _EffectFilter(AL_FILTER_NULL),
_IsPlaying(false), _IsPaused(false), _StartTime(0), _IsStreaming(false), _RelativeMode(false), _IsPlaying(false), _IsPaused(false), _StartTime(0), _IsStreaming(false), _RelativeMode(false),
_Pos(0.0f, 0.0f, 0.0f), _Gain(NLSOUND_DEFAULT_GAIN), _Alpha(1.0), _Pos(0.0f, 0.0f, 0.0f), _Gain(NLSOUND_DEFAULT_GAIN), _Alpha(1.0),
_MinDistance(1.0f), _MaxDistance(sqrt(numeric_limits<float>::max())), _MinDistance(1.0f), _MaxDistance(sqrt(numeric_limits<float>::max())),
_Effect(NULL), _Direct(true), _Effect(NULL), _Direct(true),
_DirectGain(NLSOUND_DEFAULT_DIRECT_GAIN), _EffectGain(NLSOUND_DEFAULT_EFFECT_GAIN), _DirectGain(NLSOUND_DEFAULT_DIRECT_GAIN), _EffectGain(NLSOUND_DEFAULT_EFFECT_GAIN),
_DirectFilterType(ISource::FilterLowPass), _EffectFilterType(ISource::FilterLowPass), _DirectFilterType(ISource::FilterLowPass), _EffectFilterType(ISource::FilterLowPass),
_DirectFilterEnabled(false), _EffectFilterEnabled(false), _DirectFilterEnabled(false), _EffectFilterEnabled(false),
_DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN) _DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN)
{ {
// create the al source // create the al source
alGenSources(1, &_Source); alGenSources(1, &_Source);
alTestError(); alTestError();
// configure rolloff // configure rolloff
if (soundDriver->getOption(ISoundDriver::OptionManualRolloff)) if (soundDriver->getOption(ISoundDriver::OptionManualRolloff))
{ {
@ -60,7 +60,7 @@ _DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(N
alSourcef(_Source, AL_ROLLOFF_FACTOR, soundDriver->getRolloffFactor()); alSourcef(_Source, AL_ROLLOFF_FACTOR, soundDriver->getRolloffFactor());
alTestError(); alTestError();
} }
// create filters // create filters
if (soundDriver->getOption(ISoundDriver::OptionEnvironmentEffects)) if (soundDriver->getOption(ISoundDriver::OptionEnvironmentEffects))
{ {
@ -75,7 +75,7 @@ _DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(N
alFilterf(_EffectFilter, AL_LOWPASS_GAINHF, NLSOUND_DEFAULT_FILTER_PASS_GAIN); alFilterf(_EffectFilter, AL_LOWPASS_GAINHF, NLSOUND_DEFAULT_FILTER_PASS_GAIN);
alTestError(); alTestError();
} }
// if everything went well, the source will be added in the sounddriver // if everything went well, the source will be added in the sounddriver
_SoundDriver = soundDriver; _SoundDriver = soundDriver;
} }
@ -166,17 +166,17 @@ void CSourceAL::submitStreamingBuffer(IBuffer *buffer)
CBufferAL *bufferAL = static_cast<CBufferAL *>(buffer); CBufferAL *bufferAL = static_cast<CBufferAL *>(buffer);
ALuint bufferName = bufferAL->bufferName(); ALuint bufferName = bufferAL->bufferName();
nlassert(bufferName); nlassert(bufferName);
if (!bufferAL->isBufferLoaded()) if (!bufferAL->isBufferLoaded())
{ {
nlwarning("AL: MUSICBUG: Streaming buffer was not loaded, skipping buffer. This should not happen."); nlwarning("AL: MUSICBUG: Streaming buffer was not loaded, skipping buffer. This should not happen.");
return; return;
} }
alSourceQueueBuffers(_Source, 1, &bufferName); alSourceQueueBuffers(_Source, 1, &bufferName);
alTestError(); alTestError();
_QueuedBuffers.push(bufferAL); _QueuedBuffers.push(bufferAL);
// Resume playback if the internal OpenAL source stopped due to buffer underrun. // Resume playback if the internal OpenAL source stopped due to buffer underrun.
ALint srcstate; ALint srcstate;
alGetSourcei(_Source, AL_SOURCE_STATE, &srcstate); alGetSourcei(_Source, AL_SOURCE_STATE, &srcstate);
@ -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.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 linearly between 1.0 and 0.0 (linear scale)
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This * 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 * 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 * 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