Purging DirectX libraries (3D, sound, input).
This commit is contained in:
parent
edb19ee4d8
commit
790e55bf0c
211 changed files with 1346 additions and 31376 deletions
|
@ -22,7 +22,7 @@
|
|||
# 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 --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 ubuntu_amd64_17_10 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 {} \;
|
||||
- mkdir -p build
|
||||
- cd build
|
||||
- wine cmake.exe -DWITH_RYZOM_CUSTOM_PATCH_SERVER=ON -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_PATCH=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_TOOLS=OFF -DWITH_TOOLS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_LUA53=ON -DWITH_LUA51=OFF -DWITH_STLPORT=OFF -DWITH_DRIVER_DSOUND=ON -G "NMake Makefiles JOM" -DWITH_STATIC=ON -DWITH_STATIC_DRIVERS=ON -DWITH_DRIVER_OPENAL=OFF -DWITH_DRIVER_DSOUND=ON -DWITH_DRIVER_XAUDIO2=ON -DWITH_DRIVER_FMOD=ON -DWITH_DRIVER_DIRECT3D=ON ../codebis
|
||||
- wine cmake.exe -DWITH_RYZOM_CUSTOM_PATCH_SERVER=ON -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_PATCH=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_TOOLS=OFF -DWITH_TOOLS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_LUA53=ON -DWITH_LUA51=OFF -DWITH_STLPORT=OFF -G "NMake Makefiles JOM" -DWITH_STATIC=ON -DWITH_STATIC_DRIVERS=ON -DWITH_DRIVER_OPENAL=OFF -DWITH_DRIVER_FMOD=ON ../codebis
|
||||
- wine jom.exe
|
||||
artifacts:
|
||||
name: "khanat-client-windows-$CI_COMMIT_REF_NAME"
|
||||
|
@ -1104,7 +1104,7 @@ Linux client test:
|
|||
- ./khanat-$(echo $CI_BUILD_REF | head -c 7 )-$CI_PIPELINE_ID-Linux-x86_64.run
|
||||
dependencies:
|
||||
- Linux client build
|
||||
|
||||
|
||||
.OSX client test:
|
||||
stage: test
|
||||
only:
|
||||
|
@ -1120,7 +1120,7 @@ Linux client test:
|
|||
|
||||
##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:
|
||||
stage: staging
|
||||
environment: Staging
|
||||
|
@ -1138,9 +1138,9 @@ Linux client test:
|
|||
- OSX client test
|
||||
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:
|
||||
stage: production
|
||||
environment: Production
|
||||
|
|
|
@ -10,10 +10,6 @@ MACRO(NL_CONFIGURE_CHECKS)
|
|||
SET(NL_OPENGLES_AVAILABLE 1)
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_DRIVER_DIRECT3D)
|
||||
SET(NL_DIRECT3D_AVAILABLE 1)
|
||||
ENDIF()
|
||||
|
||||
# sound drivers
|
||||
IF(WITH_DRIVER_FMOD)
|
||||
SET(NL_FMOD_AVAILABLE 1)
|
||||
|
@ -23,14 +19,6 @@ MACRO(NL_CONFIGURE_CHECKS)
|
|||
SET(NL_OPENAL_AVAILABLE 1)
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_DRIVER_DSOUND)
|
||||
SET(NL_DSOUND_AVAILABLE 1)
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_DRIVER_XAUDIO2)
|
||||
SET(NL_XAUDIO2_AVAILABLE 1)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT RYZOM_VERSION_MAJOR)
|
||||
SET(RYZOM_VERSION_MAJOR ${NL_VERSION_MAJOR})
|
||||
SET(RYZOM_VERSION_MINOR ${NL_VERSION_MINOR})
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# - Find DirectInput
|
||||
# Find the DirectSound includes and libraries
|
||||
#
|
||||
# MAXSDK_DIR - 3DSMAX SDK root directory
|
||||
# MAXSDK_INCLUDE_DIR - where to find baseinterface.h
|
||||
# MAXSDK_LIBRARIES - List of libraries when using 3DSMAX.
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
|
@ -30,12 +30,16 @@ ELSE()
|
|||
FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES libmysql mysqlclient
|
||||
PATHS
|
||||
$ENV{ProgramFiles}/MySQL/*/lib/opt
|
||||
$ENV{SystemDrive}/MySQL/*/lib/opt)
|
||||
$ENV{SystemDrive}/MySQL/*/lib/opt
|
||||
$ENV{ProgramFiles}/MySQL/*/lib
|
||||
$ENV{SystemDrive}/MySQL/*/lib)
|
||||
|
||||
FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES libmysqld mysqlclientd
|
||||
PATHS
|
||||
$ENV{ProgramFiles}/MySQL/*/lib/opt
|
||||
$ENV{SystemDrive}/MySQL/*/lib/opt)
|
||||
$ENV{SystemDrive}/MySQL/*/lib/opt
|
||||
$ENV{ProgramFiles}/MySQL/*/lib
|
||||
$ENV{SystemDrive}/MySQL/*/lib)
|
||||
ELSE()
|
||||
FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient
|
||||
PATHS
|
||||
|
|
|
@ -122,12 +122,6 @@ ENDMACRO(NL_ADD_RUNTIME_FLAGS)
|
|||
|
||||
MACRO(NL_ADD_STATIC_VID_DRIVERS name)
|
||||
IF(WITH_STATIC_DRIVERS)
|
||||
IF(WIN32)
|
||||
IF(WITH_DRIVER_DIRECT3D)
|
||||
TARGET_LINK_LIBRARIES(${name} nel_drv_direct3d_win)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_DRIVER_OPENGL)
|
||||
IF(WIN32)
|
||||
TARGET_LINK_LIBRARIES(${name} nel_drv_opengl_win)
|
||||
|
@ -149,14 +143,6 @@ ENDMACRO(NL_ADD_STATIC_VID_DRIVERS)
|
|||
MACRO(NL_ADD_STATIC_SND_DRIVERS name)
|
||||
IF(WITH_STATIC_DRIVERS)
|
||||
IF(WIN32)
|
||||
IF(WITH_DRIVER_DSOUND)
|
||||
TARGET_LINK_LIBRARIES(${name} nel_drv_dsound_win)
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_DRIVER_XAUDIO2)
|
||||
TARGET_LINK_LIBRARIES(${name} nel_drv_xaudio2_win)
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_DRIVER_OPENAL)
|
||||
TARGET_LINK_LIBRARIES(${name} nel_drv_openal_win)
|
||||
ENDIF()
|
||||
|
@ -299,11 +285,8 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
|
|||
###
|
||||
OPTION(WITH_DRIVER_OPENGL "Build OpenGL Driver (3D)" ON )
|
||||
OPTION(WITH_DRIVER_OPENGLES "Build OpenGL ES Driver (3D)" OFF)
|
||||
OPTION(WITH_DRIVER_DIRECT3D "Build Direct3D Driver (3D)" OFF)
|
||||
OPTION(WITH_DRIVER_OPENAL "Build OpenAL Driver (Sound)" ON )
|
||||
OPTION(WITH_DRIVER_FMOD "Build FMOD Driver (Sound)" OFF)
|
||||
OPTION(WITH_DRIVER_DSOUND "Build DirectSound Driver (Sound)" OFF)
|
||||
OPTION(WITH_DRIVER_XAUDIO2 "Build XAudio2 Driver (Sound)" OFF)
|
||||
|
||||
###
|
||||
# Optional support
|
||||
|
@ -665,7 +648,7 @@ MACRO(NL_SETUP_BUILD)
|
|||
|
||||
IF(APPLE)
|
||||
SET(OBJC_FLAGS -fobjc-abi-version=2 -fobjc-legacy-dispatch -fobjc-weak)
|
||||
|
||||
|
||||
IF(NOT XCODE)
|
||||
IF(CMAKE_OSX_ARCHITECTURES)
|
||||
SET(TARGETS_COUNT 0)
|
||||
|
@ -1198,14 +1181,6 @@ MACRO(SETUP_EXTERNAL)
|
|||
INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR})
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
# Must include DXSDK before WINSDK
|
||||
FIND_PACKAGE(DirectXSDK REQUIRED)
|
||||
# IF(DXSDK_INCLUDE_DIR)
|
||||
# INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR})
|
||||
# ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(MSVC)
|
||||
FIND_PACKAGE(MSVC REQUIRED)
|
||||
FIND_PACKAGE(WindowsSDK REQUIRED)
|
||||
|
|
|
@ -3,12 +3,9 @@
|
|||
|
||||
#cmakedefine NL_OPENGL_AVAILABLE ${NL_OPENGL_AVAILABLE}
|
||||
#cmakedefine NL_OPENGLES_AVAILABLE ${NL_OPENGLES_AVAILABLE}
|
||||
#cmakedefine NL_DIRECT3D_AVAILABLE ${NL_DIRECT3D_AVAILABLE}
|
||||
|
||||
#cmakedefine NL_FMOD_AVAILABLE ${NL_FMOD_AVAILABLE}
|
||||
#cmakedefine NL_OPENAL_AVAILABLE ${NL_OPENAL_AVAILABLE}
|
||||
#cmakedefine NL_DSOUND_AVAILABLE ${NL_DSOUND_AVAILABLE}
|
||||
#cmakedefine NL_XAUDIO2_AVAILABLE ${NL_XAUDIO2_AVAILABLE}
|
||||
|
||||
#cmakedefine NL_STEREO_AVAILABLE ${NL_STEREO_AVAILABLE}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class CTextureUser;
|
|||
//---------------------------------------- CBloomEffect -----------------------------------------------------
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
// CBloomEffect class apply a bloom effect on the whole scene. The whole scene is rendered in a
|
||||
// render target (a Frame Buffer Object on OpengL, the normal back buffer in Direct3D) which is stretched
|
||||
// render target (a Frame Buffer Object on OpengL) which is stretched
|
||||
// in a 256*256 another render target.
|
||||
// We apply a horizontal blur on this 256*256 render target, then a vertical blur on the result of this first pass.
|
||||
// The final blurred render target is blend with the initial render target of scene, with a dest + src - dest*src
|
||||
|
@ -93,7 +93,6 @@ public:
|
|||
// to keep Z tests correct.
|
||||
// This method is called at the end of interfaces display in the main loop, to display final render target
|
||||
// (with added interfaces) in the color frame buffer.
|
||||
// NB : In Direct3D, the final render target is displayed at the end of endBloom call.
|
||||
// void endInterfacesDisplayBloom();
|
||||
|
||||
private:
|
||||
|
|
|
@ -188,9 +188,6 @@ public:
|
|||
/// Before rendering via a driver in a thread, must activate() (per thread).
|
||||
virtual bool activate() = 0;
|
||||
|
||||
// Test if the device is lost. Can only happen with D3D.
|
||||
// The calling application may skip some part of its rendering when it is the case (this is not a requirement, but may save cpu for other applications)
|
||||
virtual bool isLost() const = 0;
|
||||
|
||||
/// Return true if driver is still active. Return false else. If he user close the window, must return false.
|
||||
virtual bool isActive() = 0;
|
||||
|
@ -437,8 +434,7 @@ public:
|
|||
virtual uint getNbTextureStages() const = 0;
|
||||
|
||||
/** Get max number of per stage constant that can be used simultaneously.
|
||||
* This will usually match the number of texture stages, but with a D3D driver, this feature is not available most of the time
|
||||
* so it is emulated. If pixel shaders are available this will be fully supported.
|
||||
* This will usually match the number of texture stages. If pixel shaders are available this will be fully supported.
|
||||
* Under OpenGL this simply returns the maximum number of texture stages (getNbTextureStages) in both return values.
|
||||
*/
|
||||
virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0;
|
||||
|
@ -1363,7 +1359,7 @@ public:
|
|||
*/
|
||||
virtual bool setAdapter(uint adapter) = 0;
|
||||
|
||||
/** Tell if the vertex color memory format is RGBA (openGL) or BGRA (directx)
|
||||
/** Tell if the vertex color memory format is RGBA (openGL) or BGRA
|
||||
* BGRA :
|
||||
* *****************************************************************
|
||||
* Offset: * 0 * 1 * 2 * 3 *
|
||||
|
@ -1446,4 +1442,3 @@ private:
|
|||
}
|
||||
|
||||
#endif // NL_DRV_H
|
||||
|
||||
|
|
|
@ -133,8 +133,6 @@ public:
|
|||
virtual ~CDriverUser();
|
||||
// @}
|
||||
|
||||
virtual bool isLost() const;
|
||||
|
||||
/// \name Window / driver management.
|
||||
// @{
|
||||
|
||||
|
|
|
@ -27,11 +27,9 @@
|
|||
#if defined (NL_COMP_MINGW)
|
||||
# define NL3D_GL_DLL_NAME "libnel_drv_opengl_win"
|
||||
# define NL3D_GLES_DLL_NAME "libnel_drv_opengles_win"
|
||||
# define NL3D_D3D_DLL_NAME "libnel_drv_direct3d_win"
|
||||
#elif defined (NL_OS_WINDOWS)
|
||||
# define NL3D_GL_DLL_NAME "nel_drv_opengl_win"
|
||||
# define NL3D_GLES_DLL_NAME "nel_drv_opengles_win"
|
||||
# define NL3D_D3D_DLL_NAME "nel_drv_direct3d_win"
|
||||
#elif defined (NL_OS_UNIX)
|
||||
# define NL3D_GL_DLL_NAME "nel_drv_opengl"
|
||||
# define NL3D_GLES_DLL_NAME "nel_drv_opengles"
|
||||
|
@ -100,34 +98,6 @@ struct EDruOpenglEsDriverCantCreateDriver : public EDru
|
|||
EDruOpenglEsDriverCantCreateDriver() : EDru( NL3D_GLES_DLL_NAME " can't create driver" ) {}
|
||||
};
|
||||
|
||||
#ifdef NL_OS_WINDOWS
|
||||
// Direct3D
|
||||
struct EDruDirect3dDriverNotFound : public EDru
|
||||
{
|
||||
EDruDirect3dDriverNotFound() : EDru( NL3D_D3D_DLL_NAME " not found" ) {}
|
||||
};
|
||||
|
||||
struct EDruDirect3dDriverCorrupted : public EDru
|
||||
{
|
||||
EDruDirect3dDriverCorrupted() : EDru( "Can't get NL3D_createIDriverInstance from " NL3D_D3D_DLL_NAME " (Bad dll?)" ) {}
|
||||
};
|
||||
|
||||
struct EDruDirect3dDriverOldVersion : public EDru
|
||||
{
|
||||
EDruDirect3dDriverOldVersion() : EDru( NL3D_D3D_DLL_NAME " is a too old version. Ask for a more recent file" ) {}
|
||||
};
|
||||
|
||||
struct EDruDirect3dDriverUnknownVersion : public EDru
|
||||
{
|
||||
EDruDirect3dDriverUnknownVersion() : EDru( NL3D_D3D_DLL_NAME " is more recent than the application" ) {}
|
||||
};
|
||||
|
||||
struct EDruDirect3dDriverCantCreateDriver : public EDru
|
||||
{
|
||||
EDruDirect3dDriverCantCreateDriver() : EDru( NL3D_D3D_DLL_NAME " can't create driver" ) {}
|
||||
};
|
||||
#endif // NL_OS_WINDOWS
|
||||
|
||||
/// The driver Utilities class of static.
|
||||
class CDRU
|
||||
{
|
||||
|
@ -139,11 +109,6 @@ public:
|
|||
/// Portable Function which create a GL ES Driver (using gl dll...).
|
||||
static IDriver *createGlEsDriver() throw(EDru);
|
||||
|
||||
#ifdef NL_OS_WINDOWS
|
||||
/// Windows Function which create a Direct3d Driver.
|
||||
static IDriver *createD3DDriver() throw(EDru);
|
||||
#endif // NL_OS_WINDOWS
|
||||
|
||||
/// \name 2D render.
|
||||
// @{
|
||||
/// Draw a bitmap 2D. Warning: this is slow...
|
||||
|
|
|
@ -223,8 +223,7 @@ public:
|
|||
|
||||
/** \name Texture Addressing Modes. They are valid only with the normal texture shader.
|
||||
* All modes are not supported everywhere, so you should check for it in the driver.
|
||||
* The modes are similar to those introduced with DirectX 8.0 Pixel Shaders and OpenGL
|
||||
* TEXTURE_SHADERS_NV
|
||||
* The modes are similar to those introduced with OpenGL TEXTURE_SHADERS_NV
|
||||
*/
|
||||
// @{
|
||||
enum TTexAddressingMode {
|
||||
|
@ -416,7 +415,7 @@ public:
|
|||
*
|
||||
* For compatibility problems:
|
||||
* - no scaling is allowed (some cards do not implement this well).
|
||||
* - Texture can be the source only for Arg0 (DirectX restriction). nlassert...
|
||||
* - Texture can be the source only for Arg0. nlassert...
|
||||
*
|
||||
* NB: for Alpha Aguments, only operands SrcAlpha and InvSrcAlpha are valid (nlassert..).
|
||||
*/
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
*
|
||||
* You can access the driver with CNELU::Driver.
|
||||
*/
|
||||
static bool initDriver(uint w, uint h, uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen=false, bool direct3d=false) throw(EDru);
|
||||
static bool initDriver(uint w, uint h, uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen=false) throw(EDru);
|
||||
|
||||
/** Init all that we need for a Scene.
|
||||
* - register scene basics models,
|
||||
|
@ -108,7 +108,7 @@ public:
|
|||
* - initScene();
|
||||
* - initEventServer();
|
||||
*/
|
||||
static bool init(uint w, uint h, CViewport viewport=CViewport(), uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen = false, bool direct3d = false) throw(EDru);
|
||||
static bool init(uint w, uint h, CViewport viewport=CViewport(), uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen = false) throw(EDru);
|
||||
|
||||
/** Delete all:
|
||||
* - releaseEventServer();
|
||||
|
|
|
@ -6,20 +6,20 @@
|
|||
* IProgram
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2013 by authors
|
||||
*
|
||||
*
|
||||
* This file is part of NL3D.
|
||||
* NL3D 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.
|
||||
*
|
||||
*
|
||||
* NL3D 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 NL3D. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
};
|
||||
|
||||
// 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.
|
||||
// Builtin shaders should set all flags to 0.
|
||||
// Example:
|
||||
|
@ -81,18 +81,18 @@ struct CProgramFeatures
|
|||
enum TDriverFlags
|
||||
{
|
||||
// Matrices
|
||||
Matrices = 0x00000001,
|
||||
Matrices = 0x00000001,
|
||||
|
||||
// Fog
|
||||
Fog = 0x00000002,
|
||||
Fog = 0x00000002,
|
||||
};
|
||||
uint32 DriverFlags;
|
||||
|
||||
enum TMaterialFlags
|
||||
{
|
||||
/// Use the CMaterial texture stages as the textures for a Pixel Program
|
||||
TextureStages = 0x00000001,
|
||||
TextureMatrices = 0x00000002,
|
||||
TextureStages = 0x00000001,
|
||||
TextureMatrices = 0x00000002,
|
||||
};
|
||||
// Material builtin parameters
|
||||
uint32 MaterialFlags;
|
||||
|
@ -104,22 +104,22 @@ struct CProgramIndex
|
|||
{
|
||||
enum TName
|
||||
{
|
||||
ModelView,
|
||||
ModelViewInverse,
|
||||
ModelViewTranspose,
|
||||
ModelViewInverseTranspose,
|
||||
ModelView,
|
||||
ModelViewInverse,
|
||||
ModelViewTranspose,
|
||||
ModelViewInverseTranspose,
|
||||
|
||||
Projection,
|
||||
ProjectionInverse,
|
||||
ProjectionTranspose,
|
||||
ProjectionInverseTranspose,
|
||||
Projection,
|
||||
ProjectionInverse,
|
||||
ProjectionTranspose,
|
||||
ProjectionInverseTranspose,
|
||||
|
||||
ModelViewProjection,
|
||||
ModelViewProjectionInverse,
|
||||
ModelViewProjectionTranspose,
|
||||
ModelViewProjectionInverseTranspose,
|
||||
ModelViewProjection,
|
||||
ModelViewProjectionInverse,
|
||||
ModelViewProjectionTranspose,
|
||||
ModelViewProjectionInverseTranspose,
|
||||
|
||||
Fog,
|
||||
Fog,
|
||||
|
||||
NUM_UNIFORMS
|
||||
};
|
||||
|
@ -148,22 +148,6 @@ public:
|
|||
// nel - 0x31,type,bitfield
|
||||
nelvp = 0x31010001, // VP supported by CVertexProgramParser, similar to arbvp1, can be translated to vs_1_1
|
||||
|
||||
// direct3d - 0xD9,type,major,minor
|
||||
// vertex programs
|
||||
vs_1_1 = 0xD9010101,
|
||||
vs_2_0 = 0xD9010200,
|
||||
// vs_2_sw = 0xD9010201, // not sure...
|
||||
// vs_2_x = 0xD9010202, // not sure...
|
||||
// vs_3_0 = 0xD9010300, // not supported
|
||||
// pixel programs
|
||||
ps_1_1 = 0xD9020101,
|
||||
ps_1_2 = 0xD9020102,
|
||||
ps_1_3 = 0xD9020103,
|
||||
ps_1_4 = 0xD9020104,
|
||||
ps_2_0 = 0xD9020200,
|
||||
// ps_2_x = 0xD9020201, // not sure...
|
||||
// ps_3_0 = 0xD9020300, // not supported
|
||||
|
||||
// opengl - 0x61,type,bitfield
|
||||
// vertex programs
|
||||
// vp20 = 0x61010001, // NV_vertex_program1_1, outdated
|
||||
|
@ -211,7 +195,7 @@ public:
|
|||
|
||||
/// Map with known parameter indices, used for assembly programs
|
||||
std::map<std::string, uint> ParamIndices;
|
||||
|
||||
|
||||
private:
|
||||
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 void removeSource(size_t i) { nlassert(!m_Source); m_Sources.erase(m_Sources.begin() + i); }
|
||||
|
||||
// Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0
|
||||
// Get the idx of a parameter (ogl: uniform, etcetera) by name. Invalid name returns ~0
|
||||
inline uint getUniformIndex(const char *name) const { return m_DrvInfo->getUniformIndex(name); };
|
||||
inline uint getUniformIndex(const std::string &name) const { return m_DrvInfo->getUniformIndex(name.c_str()); };
|
||||
inline uint getUniformIndex(CProgramIndex::TName name) const { return m_Index.Indices[name]; }
|
||||
|
|
|
@ -287,7 +287,7 @@ public:
|
|||
|
||||
// misc
|
||||
|
||||
// used by colors only : set the internal color format. useful to write in vertex buffer (format differs between D3D & OpenGL)
|
||||
// used by colors only : set the internal color format. useful to write in vertex buffer
|
||||
virtual void setColorType(CVertexBuffer::TVertexColorType /* type */) {}
|
||||
protected:
|
||||
|
||||
|
|
|
@ -470,7 +470,7 @@ public:
|
|||
|
||||
/** See if filter mode or wrap mode have been touched.
|
||||
* If this is the case, the driver should resetup them for that texture (If driver stores filter & wrap mode
|
||||
* per texture (OpenGL) rather than globally (D3D))
|
||||
* per texture (OpenGL))
|
||||
*/
|
||||
bool filterOrWrapModeTouched() const { return _FilterOrWrapModeTouched; }
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ public:
|
|||
enum TStencilFunc { never = 0, less, lessequal, equal, notequal, greaterequal, greater, always};
|
||||
|
||||
// Existing drivers
|
||||
enum TDriver { Direct3d = 0, OpenGl, OpenGlEs };
|
||||
enum TDriver { OpenGl = 1, OpenGlEs };
|
||||
|
||||
public:
|
||||
/// The EventServer of this driver. Init after setDisplay()!!
|
||||
|
@ -157,10 +157,6 @@ public:
|
|||
virtual ~UDriver();
|
||||
// @}
|
||||
|
||||
// Test if the device is lost. Can only happen with D3D.
|
||||
// The calling application may skip some part of its rendering when it is the case (this is not a requirement, but may save cpu for other applications)
|
||||
virtual bool isLost() const = 0;
|
||||
|
||||
|
||||
/// \name Disable Hardware Feature
|
||||
/** Disable some Feature that may be supported by the Hardware
|
||||
|
@ -200,7 +196,6 @@ public:
|
|||
virtual void showWindow(bool show = true)=0;
|
||||
|
||||
/* Pass in dialog box mode. After having called this method, you can use normal GUI.
|
||||
* In fullscreen under direct3d, the main 3d window is minimized.
|
||||
*
|
||||
* \code
|
||||
* Driver->beginDialogMode();
|
||||
|
@ -215,7 +210,6 @@ public:
|
|||
virtual void beginDialogMode() =0;
|
||||
|
||||
/* Leave the dialog box mode. After having called this method, you can't use normal GUI anymore.
|
||||
* In fullscreen under direct3d, the main 3d window is maximized.
|
||||
*/
|
||||
virtual void endDialogMode() =0;
|
||||
|
||||
|
@ -841,7 +835,7 @@ public:
|
|||
/**
|
||||
* This is the static function which build a UDriver, the root for all 3D functions.
|
||||
*/
|
||||
static UDriver *createDriver(uintptr_t windowIcon = 0, bool direct3d = false, emptyProc exitFunc = 0);
|
||||
static UDriver *createDriver(uintptr_t windowIcon = 0, emptyProc exitFunc = 0);
|
||||
static UDriver *createDriver(uintptr_t windowIcon, TDriver driver, emptyProc exitFunc = 0);
|
||||
|
||||
/**
|
||||
|
|
|
@ -178,7 +178,7 @@ public:
|
|||
|
||||
|
||||
/**
|
||||
* Value type, there is 13 kind of value type as in DirectX8 and gl_vertex_program used in exteneded mode
|
||||
* Value type, there is 13 kind of value type as in gl_vertex_program used in exteneded mode
|
||||
*/
|
||||
enum TType
|
||||
{
|
||||
|
@ -1267,24 +1267,3 @@ inline void CVertexBuffer::unlock () const
|
|||
#endif // NL_VERTEX_BUFFER_H
|
||||
|
||||
/* End of vertex_buffer.h */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -24,10 +24,10 @@
|
|||
/**
|
||||
* This class is a vertex program.
|
||||
*
|
||||
* D3D / OPENGL compatibility notes:
|
||||
* OPENGL compatibility notes:
|
||||
* ---------------------------------
|
||||
*
|
||||
* To make your program compatible with D3D and OPENGL nel drivers, please follow thoses directives to write your vertex programs
|
||||
* To make your program compatible with OPENGL nel drivers, please follow thoses directives to write your vertex programs
|
||||
*
|
||||
* - Use only v[0], v[1] etc.. syntax for input registers. Don't use v0, v1 or v[OPOS] etc..
|
||||
* - Use only c[0], c[1] etc.. syntax for constant registers. Don't use c0, c1 etc..
|
||||
|
@ -39,11 +39,6 @@
|
|||
* - Don't use macros.
|
||||
*
|
||||
* -> Thoses programs work without any change under OpenGL.
|
||||
* -> Direct3D driver implementation will have to modify the syntax on the fly before the setup like this:
|
||||
* - "v[0]" must be changed in "v0" etc..
|
||||
* - "o[HPOS]" must be changed in oPos etc..
|
||||
* - Semicolon must be changed in line return character.
|
||||
* - ARL instruction must be changed in MOV.
|
||||
*
|
||||
* Behaviour of LOG may change depending on implementation: You can only expect to have dest.z = log2(abs(src.w)).
|
||||
* LIT may or may not clamp the specular exponent to [-128, 128] (not done when EXT_vertex_shader is used for example ..)
|
||||
|
@ -166,7 +161,7 @@ struct CVPInstruction
|
|||
enum EOpcode
|
||||
{
|
||||
MOV = 0,
|
||||
ARL, // in D3D, is equivalent to MOV
|
||||
ARL,
|
||||
MUL,
|
||||
ADD,
|
||||
MAD,
|
||||
|
@ -266,4 +261,3 @@ private:
|
|||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ public:
|
|||
/// Standard PCM format.
|
||||
FormatPcm = 1,
|
||||
/// Intel/DVI ADPCM format, only available for 1 channel at 16 bits per sample, encoded at 4 bits per sample.
|
||||
/// This is only implemented in the DSound and XAudio2 driver.
|
||||
FormatDviAdpcm = 11,
|
||||
/// No format set. Used when a TBufferFormat value has not been set to any value yet.
|
||||
FormatNotSet = (~0),
|
||||
|
@ -55,13 +54,13 @@ public:
|
|||
enum TStorageMode
|
||||
{
|
||||
/// 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.
|
||||
StorageHardware,
|
||||
StorageHardware,
|
||||
/// Put buffer in machine ram (used for streaming). It behaves as if OptionSoftwareBuffer and OptionLocalBufferCopy are both enabled.
|
||||
StorageSoftware
|
||||
};
|
||||
|
||||
|
||||
/** 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,
|
||||
|
@ -86,16 +85,16 @@ public:
|
|||
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.
|
||||
virtual bool fill(const uint8 *src, uint size) = 0;
|
||||
|
||||
|
||||
/// Return the size of the buffer, in bytes.
|
||||
virtual uint getSize() const = 0;
|
||||
/// Return the duration (in ms) of the sample in the buffer.
|
||||
virtual float getDuration() const = 0;
|
||||
/// 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.
|
||||
virtual bool isBufferLoaded() const = 0;
|
||||
|
||||
|
||||
//@{
|
||||
//\name ***deprecated***
|
||||
/// Set the sample format. Example: freq=44100. ***deprecated***
|
||||
|
@ -115,7 +114,7 @@ public:
|
|||
/// Return duration in seconds from pcm size in bytes.
|
||||
static float getDurationFromPCMSize(uint size, uint8 channels, uint8 bitsPerSample, uint32 frequency);
|
||||
//@}
|
||||
|
||||
|
||||
//@{
|
||||
//\name ADPCM and sample bank building utility methods
|
||||
struct TADPCMState
|
||||
|
@ -128,7 +127,7 @@ public:
|
|||
/// Encode 16bit Mono PCM buffer into Mono ADPCM.
|
||||
static void encodeADPCM(const sint16 *indata, uint8 *outdata, uint nbSample, TADPCMState &state);
|
||||
/// 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.
|
||||
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.
|
||||
|
@ -138,20 +137,20 @@ public:
|
|||
/// Convert 16bit Mono PCM buffer data to ADPCM.
|
||||
static bool convertMono16PCMToMonoADPCM(const sint16 *buffer, uint samples, std::vector<uint8> &result);
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
static const sint _IndexTable[16];
|
||||
static const uint _StepsizeTable[89];
|
||||
//@}
|
||||
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
IBuffer() { }
|
||||
|
||||
|
||||
public:
|
||||
/// Destructor
|
||||
virtual ~IBuffer() { }
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // NLSOUND
|
||||
|
|
|
@ -64,16 +64,12 @@ public:
|
|||
/// Driver Creation Choice
|
||||
enum TDriver
|
||||
{
|
||||
/// DriverAuto automatically picks the most awesome driver (picks first available in this order: FMod, OpenAl, XAudio2, DSound).
|
||||
/// DriverAuto automatically picks the most awesome driver (picks first available in this order: FMod, OpenAl).
|
||||
DriverAuto = 0,
|
||||
/// DriverFMod is a driver that runs on FMod, nice quality, but not fully implemented.
|
||||
DriverFMod,
|
||||
/// DriverOpenAl is the recommended driver, especially if you have hardware sound acceleration.
|
||||
DriverOpenAl,
|
||||
/// DriverDSound is deprecated.
|
||||
DriverDSound,
|
||||
/// DriverXAudio2 runs on a fully software-based audio processing API without artificial limits.
|
||||
DriverXAudio2,
|
||||
NumDrivers
|
||||
};
|
||||
|
||||
|
@ -81,25 +77,25 @@ public:
|
|||
enum TSoundOptions
|
||||
{
|
||||
/// 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)
|
||||
OptionAllowADPCM = 0x02,
|
||||
/// Force software buffering (always true for XAudio2).
|
||||
OptionSoftwareBuffer = 0x04,
|
||||
OptionAllowADPCM = 0x02,
|
||||
/// Force software buffering.
|
||||
OptionSoftwareBuffer = 0x04,
|
||||
/**
|
||||
* Configuration to use manual or API (directx or open AL) rolloff factor.
|
||||
* 0 => API (directx, open AL, etc) rollOff control.
|
||||
* Configuration to use manual or API (open AL) rolloff factor.
|
||||
* 0 => API (open AL, etc) rollOff control.
|
||||
* ISource::setAlpha() will fail.
|
||||
* IListener::setRollOffFactor() works
|
||||
* 1 => Manual rollOff control
|
||||
* ISource::setAlpha() change the shape of attenuation (change the curve)
|
||||
* IListener::setRollOffFactor() will fail
|
||||
*/
|
||||
OptionManualRolloff = 0x08,
|
||||
OptionManualRolloff = 0x08,
|
||||
/// 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)
|
||||
OptionHasBufferStreaming = 0x20,
|
||||
OptionHasBufferStreaming = 0x20,
|
||||
};
|
||||
|
||||
/** 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.
|
||||
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:
|
||||
* ESoundDriverNotFound, ESoundDriverCorrupted, ESoundDriverOldVersion, ESoundDriverUnknownVersion
|
||||
* The driver instance should be deleted by the user after init failure.
|
||||
|
@ -171,10 +167,10 @@ public:
|
|||
virtual uint countMaxSources() = 0;
|
||||
/// Return the maximum number of effects that can be created
|
||||
virtual uint countMaxEffects() { return 0; }
|
||||
|
||||
|
||||
/// Write information about the driver to the output stream.
|
||||
virtual void writeProfile(std::string& out) = 0;
|
||||
|
||||
|
||||
/// Stuff
|
||||
virtual void startBench() = 0;
|
||||
virtual void endBench() = 0;
|
||||
|
@ -182,7 +178,7 @@ public:
|
|||
|
||||
/// Filled at createDriver()
|
||||
const std::string &getDllName() const { return _DllName; }
|
||||
|
||||
|
||||
/// \name Stuff for drivers that have native music support
|
||||
//@{
|
||||
/// 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.
|
||||
virtual bool isMusicExtensionSupported(const std::string &extension) const = 0;
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
std::string _DllName;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include "sound_driver.h"
|
||||
|
||||
/**
|
||||
/**
|
||||
* The minimum allowed gain is specified as 0.0f.
|
||||
* Inverting the wave by specifying a negative gain is not allowed.
|
||||
* \brief Minimum allowed gain (volume).
|
||||
|
@ -41,7 +41,7 @@
|
|||
#define NLSOUND_MIN_GAIN 0.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.
|
||||
* If you pass a value outside the minimum and maximum bounds,
|
||||
* it will automatically be clamped between them.
|
||||
|
@ -58,10 +58,8 @@
|
|||
#define NLSOUND_MIN_PITCH 0.0f
|
||||
/**
|
||||
* The maximum allowed pitch is specified as 8.0f.
|
||||
* Tests indicate that with OpenAL the pitch can be set to 8.0f,
|
||||
* and with FMod to somewhere around 9.0f. The XAudio2 implementation
|
||||
* uses this value directly to configure the maximum pitch, which can
|
||||
* technically be as high as XAUDIO2_MAX_FREQ_RATIO which is 1024.0f.
|
||||
* Tests indicate that with OpenAL the pitch can be set to 8.0f,
|
||||
* and with FMod to somewhere around 9.0f.
|
||||
* If you pass a value outside the minimum and maximum bounds,
|
||||
* it will automatically be clamped between them.
|
||||
* \brief Maximum allowed pitch.
|
||||
|
@ -123,8 +121,8 @@ namespace NLSOUND {
|
|||
|
||||
/**
|
||||
* 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:
|
||||
\verbatim
|
||||
(top)
|
||||
|
@ -136,7 +134,7 @@ namespace NLSOUND {
|
|||
*
|
||||
* - If the buffer is multi-channel, only distance rolloff is applied.
|
||||
* - All streaming related functionalities are thread-safe.
|
||||
*
|
||||
*
|
||||
* \author Olivier Cado
|
||||
* \author Nevrax France
|
||||
* \author Jan Boon (Kaetemi)
|
||||
|
@ -148,70 +146,70 @@ class ISource
|
|||
public:
|
||||
enum TFilter
|
||||
{
|
||||
FilterLowPass,
|
||||
FilterBandPass,
|
||||
FilterHighPass,
|
||||
FilterLowPass,
|
||||
FilterBandPass,
|
||||
FilterHighPass,
|
||||
};
|
||||
|
||||
|
||||
/// Constructor
|
||||
ISource() { }
|
||||
/// Destructor
|
||||
virtual ~ISource() { }
|
||||
|
||||
|
||||
/// \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.
|
||||
* Streaming mode must be enabled before calling functions
|
||||
* related to buffer streaming, such as 'submitStreamingBuffer'
|
||||
* Streaming mode must be enabled before calling functions
|
||||
* related to buffer streaming, such as 'submitStreamingBuffer'
|
||||
* and 'countStreamingBuffers'.
|
||||
* In the default static buffer mode, only one buffer is set
|
||||
* active on this source, and can be replayed or looped as many
|
||||
* In the default static buffer mode, only one buffer is set
|
||||
* active on this source, and can be replayed or looped as many
|
||||
* times as needed.
|
||||
* 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.
|
||||
* 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.
|
||||
* \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
|
||||
* will be set as true, and streaming will be enabled.
|
||||
*/
|
||||
virtual void setStreaming(bool streaming = true) = 0;
|
||||
/**
|
||||
* Sets the buffer that is used for playback by this source.
|
||||
* The static buffer will remain active on the source until
|
||||
* this function is called with a NULL parameter, or until the
|
||||
* mode is changed to streaming. It is possible to play or loop
|
||||
* this buffer as often as needed, as long as it is attached
|
||||
* The static buffer will remain active on the source until
|
||||
* this function is called with a NULL parameter, or until the
|
||||
* mode is changed to streaming. It is possible to play or loop
|
||||
* this buffer as often as needed, as long as it is attached
|
||||
* to this source.
|
||||
* If you attach a multichannel (stereo) buffer, the source will
|
||||
* automatically be set to relative mode. Setting a mono channel
|
||||
* If you attach a multichannel (stereo) buffer, the source will
|
||||
* automatically be set to relative mode. Setting a mono channel
|
||||
* buffer will automatically set the relative mode back to it's
|
||||
* original setting. It is not possible to enable relative mode
|
||||
* with a multichannel buffer, instead you must manually split
|
||||
* original setting. It is not possible to enable relative mode
|
||||
* with a multichannel buffer, instead you must manually split
|
||||
* 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.
|
||||
* A buffer can be attached to more than once source.
|
||||
* Before destroying a buffer, it must be detached from all
|
||||
* sources it's attached to, which can be done by calling this
|
||||
* Before destroying a buffer, it must be detached from all
|
||||
* sources it's attached to, which can be done by calling this
|
||||
* function with a NULL parameter as buffer on all relevant sources.
|
||||
* 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.
|
||||
* \brief Attach a buffer to this source.
|
||||
* \param buffer The buffer to be attached on this source. It must
|
||||
* be created on the same sound driver instance as this source. Set
|
||||
* \param buffer The buffer to be attached on this source. It must
|
||||
* be created on the same sound driver instance as this source. Set
|
||||
* this parameter to NULL to detach a previously set buffer.
|
||||
*/
|
||||
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().
|
||||
* 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.
|
||||
* \brief Get the buffer that is attached to this source.
|
||||
* \return A pointer to the attached IBuffer, or NULL if none.
|
||||
|
@ -222,16 +220,16 @@ public:
|
|||
virtual void submitStreamingBuffer(IBuffer *buffer) = 0;
|
||||
/**
|
||||
* Returns the amount of buffers that are currently in the queue.
|
||||
* This includes buffers that are waiting to be played, as well as
|
||||
* the buffer that is currently playing. Buffers that have finished
|
||||
* playing are removed from the queue, and do not count towards the
|
||||
* This includes buffers that are waiting to be played, as well as
|
||||
* the buffer that is currently playing. Buffers that have finished
|
||||
* playing are removed from the queue, and do not count towards the
|
||||
* 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.
|
||||
* If you need to know the total amount of buffers that were added
|
||||
* into the queue, you should count them manually by increasing a
|
||||
* If you need to know the total amount of buffers that were added
|
||||
* into the queue, you should count them manually by increasing a
|
||||
* 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
|
||||
* added yet into the queue.
|
||||
* \brief Get the number of buffers in the streaming queue.
|
||||
|
@ -239,100 +237,100 @@ public:
|
|||
*/
|
||||
virtual uint countStreamingBuffers() const = 0;
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Playback control
|
||||
//@{
|
||||
/**
|
||||
* 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().
|
||||
* 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.
|
||||
* To cleanly exit a loop, you can call setLooping(false) instead
|
||||
* of using stop(). Calling stop() on a source that is looping will
|
||||
* To cleanly exit a loop, you can call setLooping(false) instead
|
||||
* of using stop(). Calling stop() on a source that is looping will
|
||||
* 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
|
||||
* setting will be remembered when switching back to static mode.
|
||||
* \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.
|
||||
*/
|
||||
virtual void setLooping(bool l = true) = 0;
|
||||
/**
|
||||
* Returns the looping status that was last set by setLooping().
|
||||
* 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.
|
||||
* Looping has no effect on streaming.
|
||||
* \brief Get the currently set looping status.
|
||||
* \return Returns true if looping is enabled, false if disabled.
|
||||
*/
|
||||
virtual bool getLooping() const = 0;
|
||||
|
||||
|
||||
/**
|
||||
* This function is used to enter playing mode. It will return
|
||||
* true in case of success. The playing status can also be verified
|
||||
* This function is used to enter playing mode. It will return
|
||||
* true in case of success. The playing status can also be verified
|
||||
* by calling isPlaying() on this source.
|
||||
* If the source is stopped, or has not started playing yet, the
|
||||
* source will start playing from the beginning from the currently
|
||||
* attached static buffer when in static mode. If no static buffer
|
||||
* was set, the source will remain in stopped mode, and this
|
||||
* will return false. A buffer can be attached to this source by
|
||||
* If the source is stopped, or has not started playing yet, the
|
||||
* source will start playing from the beginning from the currently
|
||||
* attached static buffer when in static mode. If no static buffer
|
||||
* was set, the source will remain in stopped mode, and this
|
||||
* will return false. A buffer can be attached to this source by
|
||||
* calling the setStaticBuffer() method.
|
||||
* When the source is stopped and in streaming mode, this function
|
||||
* will always enter playing state. If no buffers were queued yet,
|
||||
* it will effectively start playing this source once the first
|
||||
* buffer has been submitted. It is recommended to queue up the
|
||||
* first few buffers before calling play() to avoid running out of
|
||||
* buffers early. In streaming mode, buffers can be submitted to
|
||||
* When the source is stopped and in streaming mode, this function
|
||||
* will always enter playing state. If no buffers were queued yet,
|
||||
* it will effectively start playing this source once the first
|
||||
* buffer has been submitted. It is recommended to queue up the
|
||||
* first few buffers before calling play() to avoid running out of
|
||||
* buffers early. In streaming mode, buffers can be submitted to
|
||||
* the queue by calling the submitStreamingBuffer() method.
|
||||
* If the source is in paused mode, it will simply resume.
|
||||
* In case it was already in playing mode, the source will be
|
||||
* automatically stopped before re-entering playing status. In
|
||||
* static buffer mode this is essentially the same as restarting
|
||||
* the source from the beginning, while doing this in streaming
|
||||
* If the source is in paused mode, it will simply resume.
|
||||
* In case it was already in playing mode, the source will be
|
||||
* automatically stopped before re-entering playing status. In
|
||||
* static buffer mode this is essentially the same as restarting
|
||||
* the source from the beginning, while doing this in streaming
|
||||
* mode will result in the streaming queue being cleared.
|
||||
* \brief Start or resume playback.
|
||||
* \return Returns true in case of success.
|
||||
*/
|
||||
virtual bool play() = 0;
|
||||
/**
|
||||
* This function stops playing the source immediately. If the
|
||||
* source is already stopped, it does nothing. If the source was
|
||||
* This function stops playing the source immediately. If the
|
||||
* source is already stopped, it does nothing. If the source was
|
||||
* paused, this will do the same as if it was playing.
|
||||
* When the source is in static mode, the attached buffer will
|
||||
* remain attached for later usage. To exit a loop, it is
|
||||
* recommended to call setLooping(false) instead of stop(),
|
||||
* to avoid sound clicks. The source will enter stopped state
|
||||
* When the source is in static mode, the attached buffer will
|
||||
* remain attached for later usage. To exit a loop, it is
|
||||
* recommended to call setLooping(false) instead of stop(),
|
||||
* to avoid sound clicks. The source will enter stopped state
|
||||
* automatically when it has finished playing.
|
||||
* If this source uses streaming buffers, calling this function
|
||||
* will immediately stop output, and clear the buffer queue, which
|
||||
* If this source uses streaming buffers, calling this function
|
||||
* will immediately stop output, and clear the buffer queue, which
|
||||
* means that any queued buffers that have not played yet are lost.
|
||||
* \brief Stop playback.
|
||||
*/
|
||||
virtual void stop() = 0;
|
||||
/**
|
||||
* This function pauses playback of this source at it's current
|
||||
* position. If the source is stopped or already paused, this
|
||||
* function does nothing. You can verify if the source is paused
|
||||
* This function pauses playback of this source at it's current
|
||||
* position. If the source is stopped or already paused, this
|
||||
* function does nothing. You can verify if the source is paused
|
||||
* by calling isPaused(). To resume playback, you must call play().
|
||||
* \brief Pause playback.
|
||||
*/
|
||||
virtual void pause() = 0;
|
||||
/**
|
||||
* 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.
|
||||
* 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().
|
||||
* \brief Get the playing state.
|
||||
* \return Returns the playing state.
|
||||
*/
|
||||
virtual bool isPlaying() const = 0;
|
||||
/**
|
||||
* Returns true if the source has not started playing yet, when it
|
||||
* has been stopped using the stop() method, or when the static
|
||||
* Returns true if the source has not started playing yet, when it
|
||||
* has been stopped using the stop() method, or when the static
|
||||
* buffer has finished playback.
|
||||
* If the source is playing or paused, this returns false.
|
||||
* \brief Get the stopped state.
|
||||
|
@ -341,36 +339,36 @@ public:
|
|||
virtual bool isStopped() const = 0;
|
||||
/**
|
||||
* 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.
|
||||
* \brief Get the paused state.
|
||||
* \return Returns the paused state.
|
||||
*/
|
||||
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.
|
||||
* In streaming mode, the time spent during buffer outruns is not
|
||||
* counted towards the playback time, and the playback time is
|
||||
* In streaming mode, the time spent during buffer outruns is not
|
||||
* counted towards the playback time, and the playback time is
|
||||
* be the current time position in the entire submitted queue.
|
||||
* When using static buffers, the result is the total time that the
|
||||
* attached buffer has been playing. If the source is looping, the
|
||||
* When using static buffers, the result is the total time that the
|
||||
* attached buffer has been playing. If the source is looping, the
|
||||
* time will be the total of all playbacks of the buffer.
|
||||
* When the source is stopped, this will return the time where the
|
||||
* source was stopped. The value is reset to 0 when re-entering
|
||||
* When the source is stopped, this will return the time where the
|
||||
* source was stopped. The value is reset to 0 when re-entering
|
||||
* playing status.
|
||||
* 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,
|
||||
* 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,
|
||||
* but the actual time that has passed playing.
|
||||
* It is not guaranteed that this function returns an accurate
|
||||
* value, or that it even works. If it is not implemented, the result
|
||||
* It is not guaranteed that this function returns an accurate
|
||||
* value, or that it even works. If it is not implemented, the result
|
||||
* will always be 0.
|
||||
* \brief Get the current playback time in milliseconds.
|
||||
* \return Returns the current playback time in milliseconds.
|
||||
*/
|
||||
virtual uint32 getTime() = 0;
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Source properties
|
||||
//@{
|
||||
/// Set the position vector (default: (0,0,0)).
|
||||
|
@ -405,29 +403,29 @@ public:
|
|||
virtual void setCone(float innerAngle, float outerAngle, float outerGain) = 0;
|
||||
/// Get the cone angles (in radian)
|
||||
virtual void getCone(float& innerAngle, float& outerAngle, float& outerGain) const = 0;
|
||||
/**
|
||||
/**
|
||||
* Set the alpha value for the volume-distance curve.
|
||||
*
|
||||
*
|
||||
* Used only with OptionManualRolloff.
|
||||
* 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.
|
||||
* - 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).
|
||||
* - alpha = -1.0: The volume will decrease inversely with the
|
||||
* distance (1/dist). This is the default distance attenuation
|
||||
* - alpha = -1.0: The volume will decrease inversely with the
|
||||
* distance (1/dist). This is the default distance attenuation
|
||||
* used without OptionManualRolloff.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
* \brief Set the alpha value for the volume-distance curve
|
||||
*/
|
||||
virtual void setAlpha(double a) = 0;
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Direct output
|
||||
//@{
|
||||
/// Enable or disable direct output [true/false], default: true
|
||||
|
@ -438,7 +436,7 @@ public:
|
|||
virtual void setDirectGain(float gain = NLSOUND_DEFAULT_DIRECT_GAIN) = 0;
|
||||
/// Get the gain for the direct path
|
||||
virtual float getDirectGain() const = 0;
|
||||
|
||||
|
||||
/// Enable or disable the filter for the direct channel
|
||||
virtual void enableDirectFilter(bool enable = true) = 0;
|
||||
/// Check if the filter on the direct channel is enabled
|
||||
|
@ -452,7 +450,7 @@ public:
|
|||
/// Get the direct filter gain
|
||||
virtual float getDirectFilterPassGain() const = 0;
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Effect output
|
||||
//@{
|
||||
/// 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;
|
||||
/// Get the gain for the effect path
|
||||
virtual float getEffectGain() const = 0;
|
||||
|
||||
|
||||
/// Enable or disable the filter for the effect channel
|
||||
virtual void enableEffectFilter(bool enable = true) = 0;
|
||||
/// Check if the filter on the effect channel is enabled
|
||||
|
@ -477,9 +475,9 @@ public:
|
|||
/// Get the effect filter gain
|
||||
virtual float getEffectFilterPassGain() const = 0;
|
||||
//@}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
// 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);
|
||||
// common method used only with OptionManualRolloff. return the rolloff in amplitude ratio (gain)
|
||||
|
|
|
@ -82,8 +82,6 @@ public:
|
|||
DriverAuto = 0,
|
||||
DriverFMod,
|
||||
DriverOpenAl,
|
||||
DriverDSound,
|
||||
DriverXAudio2,
|
||||
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. ***
|
||||
struct CInitInfo
|
||||
{
|
||||
public:
|
||||
CInitInfo()
|
||||
: MaxTrack(32),
|
||||
EnableReverb(false),
|
||||
EnableOccludeObstruct(false),
|
||||
UseADPCM(false),
|
||||
ForceSoftware(false),
|
||||
CInitInfo()
|
||||
: MaxTrack(32),
|
||||
EnableReverb(false),
|
||||
EnableOccludeObstruct(false),
|
||||
UseADPCM(false),
|
||||
ForceSoftware(false),
|
||||
ManualRolloff(true)
|
||||
{ }
|
||||
|
||||
/// The number of allocated physical playback tracks. Default: 32.
|
||||
uint MaxTrack;
|
||||
|
||||
|
||||
/// Enable environment reverberation effect. Default: false.
|
||||
bool EnableReverb;
|
||||
|
||||
/// Enable occlusion and obstruction lowpass filters from walls and objects. Default: false.
|
||||
bool EnableOccludeObstruct;
|
||||
|
||||
|
||||
/// Use lower quality ADPCM encoded sources for lower memory usage. Default: false.
|
||||
bool UseADPCM;
|
||||
|
||||
/// Force using a software sound device. Default: false. [KAETEMI TODO: Allow sound device selection.]
|
||||
bool ForceSoftware;
|
||||
|
||||
|
||||
/// Use NeL's distance rolloff math. Default: true.
|
||||
bool ManualRolloff;
|
||||
|
||||
/// I forgot what this does, but it's fairly important.
|
||||
bool AutoLoadSample;
|
||||
};
|
||||
|
||||
|
||||
//@{
|
||||
//@name Init methods
|
||||
/// 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
|
||||
* BEFORE calling init.
|
||||
*/
|
||||
|
||||
|
||||
virtual void setSamplePath(const std::string& path) = 0;
|
||||
/** Set the global path to the sample banks
|
||||
* If you have specified some sample bank to load in the
|
||||
|
@ -199,17 +197,17 @@ public:
|
|||
* deactivated. (lies!)
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* Deprecated by initDriver/getDevices/initDevice.
|
||||
*
|
||||
*
|
||||
* \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;
|
||||
|
||||
|
||||
/// Initialize the NeL Sound Driver with given driverName.
|
||||
virtual void initDriver(const std::string &driverName) = 0;
|
||||
/// 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.
|
||||
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;
|
||||
/** 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.
|
||||
virtual void getMusicExtensions(std::vector<std::string> &extensions) = 0;
|
||||
//@}
|
||||
|
|
|
@ -77,9 +77,9 @@ bool handleCheck(const CEGUI::EventArgs& e);
|
|||
#endif // CEGUI_DATA_DIR
|
||||
|
||||
#ifdef NL_OS_WINDOWS
|
||||
int WINAPI WinMain( HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int WINAPI WinMain( HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow ) {
|
||||
ghInstance = hInstance;
|
||||
#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));
|
||||
|
||||
// CCeguiRendererNelLibrary *nelCeguiDriverLib = dynamic_cast<CCeguiRendererNelLibrary *>(driverLib.getNelLibraryInterface());
|
||||
|
||||
|
||||
NL3D::UDriver *driver;
|
||||
|
||||
// Create a driver
|
||||
|
@ -108,9 +108,8 @@ int main(int argc, char **argv)
|
|||
#ifdef NL_OS_WINDOWS
|
||||
icon = (uint)LoadIcon(ghInstance,MAKEINTRESOURCE(IDI_ICON1));
|
||||
#endif
|
||||
bool useD3D = false;
|
||||
#ifdef NL_INDEX_BUFFER_H //new 3d
|
||||
NL3D::UDriver *driver = NL3D::UDriver::createDriver(icon,useD3D);
|
||||
NL3D::UDriver *driver = NL3D::UDriver::createDriver(icon);
|
||||
#else
|
||||
driver = NL3D::UDriver::createDriver(icon);
|
||||
#endif
|
||||
|
@ -123,7 +122,7 @@ int main(int argc, char **argv)
|
|||
// start up the Gui system.
|
||||
//gGuiLogger = nelCeguiDriverLib->createNelLogger();
|
||||
//gGuiRenderer = new CEGUI::NeLRenderer(driver);
|
||||
|
||||
|
||||
gGuiRenderer = createNelRenderer(driver, true);
|
||||
gGuiSystem = new CEGUI::System(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.");
|
||||
try {
|
||||
using namespace CEGUI;
|
||||
|
||||
|
||||
Logger::getSingleton().setLoggingLevel(Insane);
|
||||
|
||||
// load scheme and set up defaults
|
||||
|
@ -328,5 +327,3 @@ bool handleCheck(const CEGUI::EventArgs& e)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
{
|
||||
// look at 3dinit example
|
||||
CNELU::init (800, 600, CViewport(), 32, true, 0, false, false);
|
||||
CNELU::init (800, 600, CViewport(), 32, true, 0, false);
|
||||
|
||||
NLMISC::CPath::addSearchPath(FONT_DIR);
|
||||
|
||||
|
|
|
@ -51,18 +51,18 @@ QString nli18n(const char *label)
|
|||
|
||||
} /* anonymous namespace */
|
||||
|
||||
CGraphicsViewport::CGraphicsViewport(QWidget *parent)
|
||||
CGraphicsViewport::CGraphicsViewport(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_GraphicsConfig(NULL),
|
||||
m_Driver(NULL),
|
||||
m_GraphicsConfig(NULL),
|
||||
m_Driver(NULL),
|
||||
m_TextContext(NULL)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
CGraphicsViewport::~CGraphicsViewport()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CGraphicsViewport::init(CGraphicsConfig *graphicsConfig)
|
||||
|
@ -72,44 +72,35 @@ void CGraphicsViewport::init(CGraphicsConfig *graphicsConfig)
|
|||
|
||||
// copy parameters
|
||||
m_GraphicsConfig = graphicsConfig;
|
||||
|
||||
|
||||
// check stuff we need
|
||||
nlassert(m_GraphicsConfig);
|
||||
|
||||
// create the driver
|
||||
nlassert(!m_Driver);
|
||||
m_Direct3D = false;
|
||||
std::string driver = m_GraphicsConfig->getGraphicsDriver();
|
||||
if (driver == "Direct3D") m_Direct3D = true; //m_Driver = Direct3D;
|
||||
else if (driver == "OpenGL") m_Direct3D = false; //m_Driver = OpenGL;
|
||||
else
|
||||
{
|
||||
nlwarning("Invalid driver specified, defaulting to OpenGL");
|
||||
//m_Configuration->getConfigFile().getVar("GraphicsDriver").forceAsString("OpenGL");
|
||||
//m_Driver = OpenGL;
|
||||
}
|
||||
m_Driver = UDriver::createDriver(NULL, m_Direct3D, NULL);
|
||||
m_Driver = UDriver::createDriver(NULL, NULL);
|
||||
nlassert(m_Driver);
|
||||
|
||||
// initialize the window with config file values
|
||||
m_Driver->setDisplay(winId(), NL3D::UDriver::CMode(width(), height(), 32));
|
||||
|
||||
// register config callbacks
|
||||
connect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)),
|
||||
connect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)),
|
||||
this, SLOT(cfcbBackgroundColor(NLMISC::CRGBA)));
|
||||
m_BackgroundColor = m_GraphicsConfig->getBackgroundColor();
|
||||
|
||||
// set the cache size for the font manager(in bytes)
|
||||
m_Driver->setFontManagerMaxMemory(2097152);
|
||||
|
||||
|
||||
// create the text context
|
||||
nlassert(!m_TextContext);
|
||||
m_TextContext = m_Driver->createTextContext(CPath::lookup(
|
||||
m_GraphicsConfig->getFontName()));
|
||||
nlassert(m_TextContext);
|
||||
connect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)),
|
||||
connect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)),
|
||||
this, SLOT(cfcbFontShadow(bool)));
|
||||
m_TextContext->setShaded(m_GraphicsConfig->getFontShadow());
|
||||
m_TextContext->setShaded(m_GraphicsConfig->getFontShadow());
|
||||
}
|
||||
|
||||
void CGraphicsViewport::release()
|
||||
|
@ -119,14 +110,14 @@ void CGraphicsViewport::release()
|
|||
|
||||
// release text context
|
||||
nlassert(m_TextContext);
|
||||
disconnect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)),
|
||||
disconnect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)),
|
||||
this, SLOT(cfcbFontShadow(bool)));
|
||||
m_Driver->deleteTextContext(m_TextContext);
|
||||
m_TextContext = NULL;
|
||||
|
||||
// release driver
|
||||
nlassert(m_Driver);
|
||||
disconnect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)),
|
||||
disconnect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)),
|
||||
this, SLOT(cfcbBackgroundColor(NLMISC::CRGBA)));
|
||||
m_Driver->release();
|
||||
delete m_Driver;
|
||||
|
@ -185,7 +176,7 @@ void CGraphicsViewport::saveScreenshot(const string &name, bool jpg, bool png, b
|
|||
//H_AUTO2
|
||||
|
||||
// FIXME: create screenshot path if it doesn't exist!
|
||||
|
||||
|
||||
// empty bitmap
|
||||
CBitmap 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)
|
||||
{
|
||||
QWidget::resizeEvent(resizeEvent);
|
||||
if (m_Driver && !m_Direct3D)
|
||||
if (m_Driver)
|
||||
{
|
||||
m_Driver->setMode(UDriver::CMode(resizeEvent->size().width(), resizeEvent->size().height(), 32));
|
||||
}
|
||||
|
||||
// The OpenGL driver does not resize automatically.
|
||||
// The Direct3D driver breaks the window mode to include window borders when calling setMode windowed.
|
||||
|
||||
// Resizing the window after switching drivers a few times becomes slow.
|
||||
// There is probably something inside the drivers not being released properly.
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
inline NL3D::UTextContext *getTextContext() { return m_TextContext; }
|
||||
inline NL3D::UScene *getScene() { return m_Scene; }
|
||||
|
||||
public slots:
|
||||
public slots:
|
||||
void saveScreenshot();
|
||||
|
||||
private slots:
|
||||
|
@ -91,12 +91,10 @@ private:
|
|||
NL3D::UTextContext *m_TextContext;
|
||||
NL3D::UScene *m_Scene;
|
||||
|
||||
bool m_Direct3D;
|
||||
|
||||
private:
|
||||
CGraphicsViewport(const CGraphicsViewport &);
|
||||
CGraphicsViewport &operator=(const CGraphicsViewport &);
|
||||
|
||||
|
||||
}; /* class CGraphicsViewport */
|
||||
|
||||
} /* namespace NLQT */
|
||||
|
|
|
@ -55,9 +55,9 @@ LoginBackground = "login_background.dds";
|
|||
// Graphics //////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Use OpenGL or Direct3D (Windows)
|
||||
// Use OpenGL (Windows)
|
||||
GraphicsEnabled = 1;
|
||||
GraphicsDrivers = { "OpenGL", "Direct3D" };
|
||||
GraphicsDrivers = { "OpenGL" };
|
||||
GraphicsDriver = "OpenGL";
|
||||
|
||||
// Resolution of the screen
|
||||
|
@ -134,9 +134,9 @@ FpsSmoothing = 64;
|
|||
// Sound /////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The sound driver, choose between "Auto", "FMod", "DSound" and "OpenAl"
|
||||
// The sound driver, choose between "Auto", "FMod" and "OpenAl"
|
||||
SoundEnabled = 1;
|
||||
SoundDrivers = { "Auto", "OpenAL", "XAudio2", "FMod", "DSound" };
|
||||
SoundDrivers = { "Auto", "OpenAL", "FMod" };
|
||||
SoundDriver = "OpenAL";
|
||||
SoundDevice = "";
|
||||
SoundMaxTrack = 48;
|
||||
|
@ -153,46 +153,46 @@ SoundAutoLoadSample = 1;
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 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 must all be disabled
|
||||
// -+- -> only SHIFT must be down
|
||||
KeySettings = {
|
||||
"screenshot", "", "***", "KeyF5",
|
||||
"command", "set_state Exit", "-+-", "KeyESCAPE",
|
||||
"command", "set_state Login", "+--", "KeyESCAPE",
|
||||
"command", "set_state Unload", "***", "KeyF8",
|
||||
"command", "set_state Demo", "***", "KeyF7",
|
||||
"move_forward", "", "***", "KeyUP|KeyZ|KeyW",
|
||||
"move_backward", "", "***", "KeyDOWN|KeyS",
|
||||
"move_left", "", "***", "KeyLEFT|KeyQ|KeyA",
|
||||
"move_right", "", "***", "KeyRIGHT|KeyD",
|
||||
"move_forward", "", "***", "KeyZ|KeyW",
|
||||
"move_backward", "", "***", "KeyS",
|
||||
"move_left", "", "***", "KeyQ|KeyA",
|
||||
"move_right", "", "***", "KeyD",
|
||||
"chat_begin", "", "***", "KeyT",
|
||||
"chat_send", "", "***", "KeyENTER",
|
||||
"chat_leave", "", "***", "KeyESCAPE",
|
||||
"display_test", "", "***", "KeyTAB",
|
||||
"send_action", "0", "---", "Key1",
|
||||
"send_action", "1", "---", "Key2",
|
||||
"send_action", "2", "---", "Key3",
|
||||
"send_action", "3", "---", "Key4",
|
||||
"send_action", "4", "---", "Key5",
|
||||
"send_action", "5", "---", "Key6",
|
||||
"send_action", "6", "---", "Key7",
|
||||
"send_action", "7", "---", "Key8",
|
||||
"send_action", "8", "---", "Key9",
|
||||
"send_action", "9", "---", "Key0",
|
||||
"demo_crystal_spawn", "", "---", "KeyO",
|
||||
"demo_crystal_explode", "", "---", "KeyP",
|
||||
"free_camera_forward", "", "---", "KeyNUMPAD8",
|
||||
"free_camera_backward", "", "---", "KeyNUMPAD2",
|
||||
"free_camera_left", "", "---", "KeyNUMPAD4",
|
||||
"free_camera_right", "", "---", "KeyNUMPAD6",
|
||||
"switch_camera", "", "---", "KeyF4",
|
||||
"switch_ui_visible" ,"", "---", "KeyF6",
|
||||
"screenshot", "", "***", "KeyF5",
|
||||
"command", "set_state Exit", "-+-", "KeyESCAPE",
|
||||
"command", "set_state Login", "+--", "KeyESCAPE",
|
||||
"command", "set_state Unload", "***", "KeyF8",
|
||||
"command", "set_state Demo", "***", "KeyF7",
|
||||
"move_forward", "", "***", "KeyUP|KeyZ|KeyW",
|
||||
"move_backward", "", "***", "KeyDOWN|KeyS",
|
||||
"move_left", "", "***", "KeyLEFT|KeyQ|KeyA",
|
||||
"move_right", "", "***", "KeyRIGHT|KeyD",
|
||||
"move_forward", "", "***", "KeyZ|KeyW",
|
||||
"move_backward", "", "***", "KeyS",
|
||||
"move_left", "", "***", "KeyQ|KeyA",
|
||||
"move_right", "", "***", "KeyD",
|
||||
"chat_begin", "", "***", "KeyT",
|
||||
"chat_send", "", "***", "KeyENTER",
|
||||
"chat_leave", "", "***", "KeyESCAPE",
|
||||
"display_test", "", "***", "KeyTAB",
|
||||
"send_action", "0", "---", "Key1",
|
||||
"send_action", "1", "---", "Key2",
|
||||
"send_action", "2", "---", "Key3",
|
||||
"send_action", "3", "---", "Key4",
|
||||
"send_action", "4", "---", "Key5",
|
||||
"send_action", "5", "---", "Key6",
|
||||
"send_action", "6", "---", "Key7",
|
||||
"send_action", "7", "---", "Key8",
|
||||
"send_action", "8", "---", "Key9",
|
||||
"send_action", "9", "---", "Key0",
|
||||
"demo_crystal_spawn", "", "---", "KeyO",
|
||||
"demo_crystal_explode", "", "---", "KeyP",
|
||||
"free_camera_forward", "", "---", "KeyNUMPAD8",
|
||||
"free_camera_backward", "", "---", "KeyNUMPAD2",
|
||||
"free_camera_left", "", "---", "KeyNUMPAD4",
|
||||
"free_camera_right", "", "---", "KeyNUMPAD6",
|
||||
"switch_camera", "", "---", "KeyF4",
|
||||
"switch_ui_visible" ,"", "---", "KeyF6",
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -67,8 +67,6 @@ void Init()
|
|||
printf("Select NLSOUND Driver:\n");
|
||||
printf(" [1] FMod\n");
|
||||
printf(" [2] OpenAl\n");
|
||||
printf(" [3] DSound\n");
|
||||
printf(" [4] XAudio2\n");
|
||||
printf("> ");
|
||||
int selection = getchar();
|
||||
printf("\n");
|
||||
|
|
|
@ -64,30 +64,28 @@ static void initSample()
|
|||
new CApplicationContext();
|
||||
CSheetId::initWithoutSheet();
|
||||
CPath::addSearchPath(NL_SOUND_DATA"/data", true, false);
|
||||
|
||||
|
||||
printf("Sample demonstrating OGG playback using stream file .sound sheets.");
|
||||
printf("\n\n");
|
||||
|
||||
|
||||
s_AudioMixer = UAudioMixer::createAudioMixer();
|
||||
|
||||
|
||||
// Set the sample path before init, this allow the mixer to build the sample banks
|
||||
s_AudioMixer->setSamplePath(NL_SOUND_DATA"/data/samplebank");
|
||||
// Packed sheet option, this mean we want packed sheet generated in 'data' folder
|
||||
s_AudioMixer->setPackedSheetOption(NL_SOUND_DATA"/data", true);
|
||||
|
||||
|
||||
printf("Select NLSOUND Driver:\n");
|
||||
printf(" [1] FMod\n");
|
||||
printf(" [2] OpenAl\n");
|
||||
printf(" [3] DSound\n");
|
||||
printf(" [4] XAudio2\n");
|
||||
printf("> ");
|
||||
int selection = getchar(); getchar();
|
||||
printf("\n");
|
||||
|
||||
|
||||
// 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->setLowWaterMark(1);
|
||||
|
||||
|
||||
CVector initpos(0.0f, 0.0f, 0.0f);
|
||||
CVector frontvec(0.0f, 1.0f, 0.0f);
|
||||
CVector upvec(0.0f, 0.0f, 1.0f);
|
||||
|
@ -95,14 +93,14 @@ static void initSample()
|
|||
s_AudioMixer->getListener()->setOrientation(frontvec, upvec);
|
||||
|
||||
CPath::addSearchPath(RYZOM_DATA, true, false);
|
||||
|
||||
|
||||
//NLMISC::CHTimer::startBench();
|
||||
|
||||
s_Source = s_AudioMixer->createSource(CSheetId("stream_file.sound"));
|
||||
nlassert(s_Source);
|
||||
s_StreamFileSource = dynamic_cast<CStreamFileSource *>(s_Source);
|
||||
nlassert(s_StreamFileSource);
|
||||
// s_Source->setSourceRelativeMode(true);
|
||||
// s_Source->setSourceRelativeMode(true);
|
||||
// s_Source->setPitch(2.0f);
|
||||
|
||||
s_GroupController = s_AudioMixer->getGroupController("sound:dialog");
|
||||
|
@ -111,7 +109,7 @@ static void initSample()
|
|||
static void runSample()
|
||||
{
|
||||
s_Source->play();
|
||||
|
||||
|
||||
printf("Change volume with - and +\n");
|
||||
printf("Press ANY other key to exit\n");
|
||||
for (; ; )
|
||||
|
@ -154,7 +152,7 @@ static void runSample()
|
|||
}
|
||||
|
||||
s_AudioMixer->update();
|
||||
|
||||
|
||||
nlSleep(40);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,21 +61,19 @@ static void initSample()
|
|||
new CApplicationContext();
|
||||
CSheetId::initWithoutSheet();
|
||||
CPath::addSearchPath(NL_SOUND_DATA"/database/build/", true, false);
|
||||
|
||||
|
||||
printf("Sample demonstrating OGG playback using UStreamSource.");
|
||||
printf("\n\n");
|
||||
|
||||
|
||||
s_AudioMixer = UAudioMixer::createAudioMixer();
|
||||
|
||||
|
||||
printf("Select NLSOUND Driver:\n");
|
||||
printf(" [1] FMod\n");
|
||||
printf(" [2] OpenAl\n");
|
||||
printf(" [3] DSound\n");
|
||||
printf(" [4] XAudio2\n");
|
||||
printf("> ");
|
||||
int selection = getchar(); getchar();
|
||||
printf("\n");
|
||||
|
||||
|
||||
// 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->setLowWaterMark(1);
|
||||
|
@ -85,7 +83,7 @@ static void initSample()
|
|||
CVector upvec(0.0f, 0.0f, 1.0f);
|
||||
s_AudioMixer->getListener()->setPos(initpos);
|
||||
s_AudioMixer->getListener()->setOrientation(frontvec, upvec);
|
||||
|
||||
|
||||
//NLMISC::CHTimer::startBench();
|
||||
|
||||
USource *source = s_AudioMixer->createSource(CSheetId("default_stream.sound"));
|
||||
|
@ -136,7 +134,7 @@ static void runSample()
|
|||
//bufferMore(bytes);
|
||||
|
||||
s_StreamSource->play();
|
||||
|
||||
|
||||
printf("Change volume with - and +\n");
|
||||
printf("Press ANY other key to exit\n");
|
||||
while (!s_AudioDecoder->isMusicEnded())
|
||||
|
@ -177,13 +175,13 @@ static void runSample()
|
|||
nlSleep(40);
|
||||
s_AudioMixer->update();
|
||||
}
|
||||
|
||||
|
||||
s_StreamSource->stop();
|
||||
|
||||
|
||||
printf("End of song\n");
|
||||
printf("Press ANY key to exit\n");
|
||||
#ifdef NL_OS_WINDOWS
|
||||
while (!_kbhit())
|
||||
while (!_kbhit())
|
||||
#else
|
||||
char ch;
|
||||
while (!read(0, &ch, 1))
|
||||
|
|
|
@ -120,7 +120,7 @@ void CCoarseMeshManager::flushRender (IDriver *drv)
|
|||
H_AUTO( NL3D_StaticLod_Render );
|
||||
if (_Meshs.empty()) return;
|
||||
|
||||
// if the driver is BGRA (Direct3D), then invert color format
|
||||
// if the driver is BGRA, then invert color format
|
||||
if(!_VBuffer.isResident() && drv->getVertexColorFormat()==CVertexBuffer::TBGRA)
|
||||
{
|
||||
// since actually empty, no need to swap current memory
|
||||
|
|
|
@ -5,9 +5,3 @@ ENDIF()
|
|||
IF(WITH_DRIVER_OPENGLES)
|
||||
ADD_SUBDIRECTORY(opengles)
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
IF(WITH_DRIVER_DIRECT3D)
|
||||
ADD_SUBDIRECTORY(direct3d)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
|
|
@ -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
|
@ -1,3 +0,0 @@
|
|||
EXPORTS
|
||||
NL3D_createIDriverInstance
|
||||
NL3D_interfaceVersion
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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 ¶ms)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
} // NL3D
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -320,11 +320,6 @@ EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface
|
|||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
|
||||
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
|
||||
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
|
||||
#endif
|
||||
|
||||
#ifndef EGL_NV_coverage_sample_resolve
|
||||
#define EGL_NV_coverage_sample_resolve 1
|
||||
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
|
||||
|
@ -435,11 +430,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, E
|
|||
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
|
||||
#endif
|
||||
|
||||
#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
|
||||
#define EGL_ANGLE_d3d_share_handle_client_buffer 1
|
||||
/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */
|
||||
#endif
|
||||
|
||||
#ifndef EGL_KHR_create_context
|
||||
#define EGL_KHR_create_context 1
|
||||
#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
|
||||
|
|
|
@ -1262,7 +1262,7 @@ sint CDriverGL::getTotalVideoMemory() const
|
|||
nlwarning("3D: Unable to get renderer ID (%s)", CGLErrorString(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CGLDestroyRendererInfo(rend);
|
||||
}
|
||||
else
|
||||
|
@ -2883,7 +2883,7 @@ IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType()
|
|||
nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_NV, &result);
|
||||
OcclusionType = result != 0 ? NotOccluded : Occluded;
|
||||
VisibleCount = (uint) result;
|
||||
// Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation (Direct3D ...)
|
||||
// Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation ...
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -440,7 +440,7 @@ public:
|
|||
|
||||
virtual bool supportCloudRenderSinglePass() const;
|
||||
|
||||
virtual bool supportIndexOffset() const { return false; /* feature only supported in D3D for now */ }
|
||||
virtual bool supportIndexOffset() const { return false; }
|
||||
|
||||
|
||||
virtual bool slowUnlockVertexBufferHard() const;
|
||||
|
@ -1006,7 +1006,6 @@ private:
|
|||
bool setScreenMode(const GfxMode &mode);
|
||||
|
||||
// Test if cursor is in the client area. always true when software cursor is used and window visible
|
||||
// (displayed in software when DirectInput is used)
|
||||
bool isSystemCursorInClientArea();
|
||||
|
||||
// Check if RGBA cursors are supported
|
||||
|
@ -1337,7 +1336,7 @@ private:
|
|||
virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
virtual bool compileVertexProgram(CVertexProgram *program);
|
||||
|
@ -1364,7 +1363,7 @@ private:
|
|||
virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::arbfp1) const;
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
virtual bool compilePixelProgram(CPixelProgram *program);
|
||||
|
@ -1391,7 +1390,7 @@ private:
|
|||
virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; }
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; }
|
||||
|
@ -1464,7 +1463,7 @@ private:
|
|||
bool activeARBPixelProgram (CPixelProgram *program);
|
||||
bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/);
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
/// \fallback for material shaders
|
||||
// @{
|
||||
|
@ -1477,7 +1476,7 @@ private:
|
|||
// Don't use glIsEnabled, too slow.
|
||||
return _VertexProgramEnabled;
|
||||
}
|
||||
|
||||
|
||||
bool isPixelProgramEnabled () const
|
||||
{
|
||||
// Don't use glIsEnabled, too slow.
|
||||
|
@ -1668,9 +1667,9 @@ public:
|
|||
CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
|
||||
|
||||
virtual uint getUniformIndex(const char *name) const
|
||||
{
|
||||
{
|
||||
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();
|
||||
};
|
||||
|
||||
|
@ -1683,14 +1682,14 @@ class CPixelProgamDrvInfosGL : public IProgramDrvInfos
|
|||
public:
|
||||
// The GL Id.
|
||||
GLuint ID;
|
||||
|
||||
|
||||
// The gl id is auto created here.
|
||||
CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
|
||||
|
||||
virtual uint getUniformIndex(const char *name) const
|
||||
{
|
||||
{
|
||||
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();
|
||||
};
|
||||
|
||||
|
|
|
@ -113,10 +113,6 @@ bool CDriverGL::isAlphaBlendedCursorSupported()
|
|||
{
|
||||
#ifdef NL_OS_WINDOWS
|
||||
// Support starts with windows 2000 (not only from XP as seen in most docs)
|
||||
// NB : Additionnaly, could query D3D caps to know if
|
||||
// color hardware cursor is supported, not only emulated,
|
||||
// but can't be sure that using the win32 api 'SetCursor' uses the same resources
|
||||
// So far, seems to be supported on any modern card used by the game anyway ...
|
||||
OSVERSIONINFO osvi;
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
if (GetVersionEx(&osvi))
|
||||
|
|
|
@ -88,9 +88,9 @@ void UDriver::setMatrixMode2D43()
|
|||
}
|
||||
|
||||
// ***************************************************************************
|
||||
UDriver *UDriver::createDriver(uintptr_t windowIcon, bool direct3d, emptyProc exitFunc)
|
||||
UDriver *UDriver::createDriver(uintptr_t windowIcon, emptyProc exitFunc)
|
||||
{
|
||||
return new CDriverUser (windowIcon, direct3d ? CDriverUser::Direct3d:CDriverUser::OpenGl, exitFunc);
|
||||
return new CDriverUser (windowIcon, CDriverUser::OpenGl, exitFunc);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -128,12 +128,6 @@ CDriverUser::CDriverUser (uintptr_t windowIcon, TDriver driver, emptyProc exitFu
|
|||
|
||||
_Driver = NULL;
|
||||
|
||||
// Create/Init Driver.
|
||||
#if defined(NL_OS_WINDOWS)
|
||||
if (driver == Direct3d)
|
||||
_Driver= CDRU::createD3DDriver();
|
||||
#endif
|
||||
|
||||
if (!_Driver && driver == OpenGl)
|
||||
_Driver= CDRU::createGlDriver();
|
||||
|
||||
|
@ -1840,13 +1834,6 @@ UDriver::TCullMode CDriverUser::getCullMode() const
|
|||
return (TCullMode) _Driver->getCullMode();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverUser::isLost() const
|
||||
{
|
||||
NL3D_HAUTO_UI_DRIVER
|
||||
return _Driver->isLost();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CDriverUser::beginDialogMode()
|
||||
{
|
||||
|
|
|
@ -29,9 +29,6 @@
|
|||
# include "config.h"
|
||||
#else
|
||||
# define NL_OPENGL_AVAILABLE
|
||||
# ifdef NL_OS_WINDOWS
|
||||
# define NL_DIRECT3D_AVAILABLE
|
||||
# endif
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#ifdef NL_OS_WINDOWS
|
||||
|
@ -66,10 +63,6 @@ const char *IDRV_VERSION_PROC_NAME = "NL3D_interfaceVersion";
|
|||
extern IDriver* createGlDriverInstance ();
|
||||
#endif
|
||||
|
||||
#if defined(NL_OS_WINDOWS) && defined(NL_DIRECT3D_AVAILABLE)
|
||||
extern IDriver* createD3DDriverInstance ();
|
||||
#endif
|
||||
|
||||
#ifdef NL_OPENGLES_AVAILABLE
|
||||
extern IDriver* createGlEsDriverInstance ();
|
||||
#endif
|
||||
|
@ -186,60 +179,6 @@ IDriver *CDRU::createGlEsDriver() throw (EDru)
|
|||
|
||||
// ***************************************************************************
|
||||
|
||||
#ifdef NL_OS_WINDOWS
|
||||
|
||||
IDriver *CDRU::createD3DDriver() throw (EDru)
|
||||
{
|
||||
#ifdef NL_STATIC
|
||||
|
||||
#ifdef NL_DIRECT3D_AVAILABLE
|
||||
return createD3DDriverInstance ();
|
||||
#else
|
||||
return NULL;
|
||||
#endif // NL_DIRECT3D_AVAILABLE
|
||||
|
||||
#else
|
||||
|
||||
IDRV_CREATE_PROC createDriver = NULL;
|
||||
IDRV_VERSION_PROC versionDriver = NULL;
|
||||
|
||||
CLibrary driverLib;
|
||||
|
||||
if (!driverLib.loadLibrary(NL3D_D3D_DLL_NAME, true, true, false))
|
||||
{
|
||||
throw EDruDirect3dDriverNotFound();
|
||||
}
|
||||
|
||||
nlinfo ("Using the library '" NL3D_D3D_DLL_NAME "' that is in the directory: '%s'", driverLib.getLibFileName().c_str());
|
||||
|
||||
createDriver = (IDRV_CREATE_PROC) driverLib.getSymbolAddress(IDRV_CREATE_PROC_NAME);
|
||||
if (createDriver == NULL)
|
||||
{
|
||||
throw EDruDirect3dDriverCorrupted();
|
||||
}
|
||||
|
||||
versionDriver = (IDRV_VERSION_PROC) driverLib.getSymbolAddress(IDRV_VERSION_PROC_NAME);
|
||||
if (versionDriver != NULL)
|
||||
{
|
||||
if (versionDriver()<IDriver::InterfaceVersion)
|
||||
throw EDruDirect3dDriverOldVersion();
|
||||
else if (versionDriver()>IDriver::InterfaceVersion)
|
||||
throw EDruDirect3dDriverUnknownVersion();
|
||||
}
|
||||
|
||||
IDriver *ret= createDriver();
|
||||
if (ret == NULL)
|
||||
{
|
||||
throw EDruDirect3dDriverCantCreateDriver();
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
#endif // NL_OS_WINDOWS
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDRU::drawBitmap (float x, float y, float width, float height, ITexture& texture, IDriver& driver, CViewport viewport, bool blend)
|
||||
{
|
||||
CMatrix mtx;
|
||||
|
|
|
@ -78,14 +78,6 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_VP(NULL), m_PP(NULL),
|
|||
source->setSourcePtr(a_arbfp1);
|
||||
m_PP->addSource(source);
|
||||
}
|
||||
// ps_2_0
|
||||
{
|
||||
IProgram::CSource *source = new IProgram::CSource();
|
||||
source->Features.MaterialFlags = CProgramFeatures::TextureStages;
|
||||
source->Profile = IProgram::ps_2_0;
|
||||
source->setSourcePtr(a_ps_2_0);
|
||||
m_PP->addSource(source);
|
||||
}
|
||||
if (!drv->compilePixelProgram(m_PP))
|
||||
{
|
||||
nlwarning("3D: No supported pixel program for FXAA effect");
|
||||
|
|
|
@ -105,7 +105,6 @@ void CFarVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb, bool forVertexP
|
|||
if(VertexFormat & CVertexBuffer::PrimaryColorFlag)
|
||||
{
|
||||
ColorOff= vb.getColorOff();
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
ColorPointer= Accessor.getColorPointer();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -133,7 +133,7 @@ void CLight::setupAttenuation (float farAttenuationBegin, float farAttenuationEn
|
|||
const float quadratic= 10.0f;
|
||||
|
||||
/*
|
||||
With GL/D3D 'att=1/(c+l*r+q*r2)' formula, I think it is impossible to simulate correctly
|
||||
With GL 'att=1/(c+l*r+q*r2)' formula, I think it is impossible to simulate correctly
|
||||
farAttenuationBegin (very big decrase if for instance farAttenuationBegin is near farAttenuationEnd),
|
||||
hence I simulate it very badly by multiplying the farAttenuationEnd by some factor
|
||||
*/
|
||||
|
|
|
@ -444,7 +444,6 @@ bool CLodCharacterManager::addRenderCharacterKey(CLodCharacterInstance &instan
|
|||
_LockDone= true;
|
||||
}
|
||||
|
||||
// After lock, For D3D, the VertexColor may be in BGRA format
|
||||
if(_VertexStream.isBRGA())
|
||||
{
|
||||
// then swap only the B and R (no cpu cycle added per vertex)
|
||||
|
|
|
@ -580,7 +580,6 @@ bool CMaterial::isSupportedByDriver(IDriver &drv, bool forceBaseCaps) const
|
|||
{
|
||||
uint numTexStages = drv.getNbTextureStages();
|
||||
// special case for radeon : though 3 stages are supported, do as if there were only 2, because of the texEnvColor feature
|
||||
// not managed in Direct3D : emulation is provided, but for no more than 2 constants (and if diffuse is not used)
|
||||
if (numTexStages == 3) numTexStages = 2;
|
||||
if (forceBaseCaps) numTexStages = std::min(numTexStages, (uint) 2);
|
||||
switch(getShader())
|
||||
|
@ -628,4 +627,3 @@ bool CMaterial::isSupportedByDriver(IDriver &drv, bool forceBaseCaps) const
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -196,7 +196,6 @@ void CMeshMorpher::update (std::vector<CAnimatedMorph> *pBSFactor)
|
|||
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
|
||||
if (!rBS.deltaCol.empty())
|
||||
{
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
|
||||
CRGBAF rgbf(*pRGBA);
|
||||
rgbf.R += rBS.deltaCol[j].R * rFactor;
|
||||
|
@ -324,7 +323,6 @@ void CMeshMorpher::updateSkinned (std::vector<CAnimatedMorph> *pBSFactor)
|
|||
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
|
||||
if (!rBS.deltaCol.empty())
|
||||
{
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
|
||||
CRGBAF rgbf(*pRGBA);
|
||||
rgbf.R += rBS.deltaCol[j].R * rFactor;
|
||||
|
@ -440,13 +438,3 @@ void CMeshMorpher::updateRawSkin (CVertexBuffer *vbOri,
|
|||
|
||||
|
||||
} // NL3D
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -76,8 +76,7 @@ static const char* WindTreeVPCodeEnd=
|
|||
DP4 o[HPOS].z, c[2], R5; \n\
|
||||
DP4 o[HPOS].w, c[3], R5; \n\
|
||||
MOV o[TEX0], v[8]; \n\
|
||||
# hulud : remove this line for the moment because it doesn't work under d3d, if it is needed, we will have to create 2 CVertexProgram objects.\n\
|
||||
#MOV o[TEX1], v[9]; \n\
|
||||
MOV o[TEX1], v[9]; \n\
|
||||
DP4 o[FOGC].x, c[6], R5; \n\
|
||||
END \n\
|
||||
";
|
||||
|
@ -288,13 +287,13 @@ inline void CMeshVPWindTree::setupPerMesh(IDriver *driver, CScene *scene)
|
|||
|
||||
// Setup common constants for each instances.
|
||||
// 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);
|
||||
// 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);
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -324,7 +323,7 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
|
|||
setupLighting(scene, mbi, invertedModelMat);
|
||||
|
||||
// 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);
|
||||
// c[4..7] take the ModelView Matrix. After setupModelMatrix();00
|
||||
driver->setUniformFog(IDriver::VertexProgram, program->getUniformIndex(CProgramIndex::Fog));
|
||||
|
@ -334,7 +333,7 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
|
|||
float f;
|
||||
f= _CurrentTime[0] + instancePhase;
|
||||
f= speedCos(f) + Bias[0];
|
||||
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel1,
|
||||
driver->setUniform3f(IDriver::VertexProgram, program->idx().WindLevel1,
|
||||
maxDeltaPosOS[0]*f );
|
||||
|
||||
|
||||
|
@ -343,19 +342,19 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
|
|||
float instTime1= _CurrentTime[1] + instancePhase;
|
||||
// phase 0.
|
||||
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);
|
||||
// phase 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);
|
||||
// phase 2.
|
||||
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);
|
||||
// phase 3.
|
||||
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);
|
||||
|
||||
|
||||
|
@ -364,19 +363,19 @@ inline void CMeshVPWindTree::setupPerInstanceConstants(IDriver *driver, CScene
|
|||
float instTime2= _CurrentTime[2] + instancePhase;
|
||||
// phase 0.
|
||||
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);
|
||||
// phase 1.
|
||||
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);
|
||||
// phase 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);
|
||||
// phase 3.
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ CEventServer CNELU::EventServer;
|
|||
CEventListenerAsync CNELU::AsyncListener;
|
||||
|
||||
|
||||
bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen, bool direct3d) throw(EDru)
|
||||
bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen) throw(EDru)
|
||||
{
|
||||
// Init debug system
|
||||
// NLMISC::InitDebug();
|
||||
|
@ -61,13 +61,6 @@ bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow syst
|
|||
CNELU::Driver = NULL;
|
||||
|
||||
// Init driver.
|
||||
#ifdef NL_OS_WINDOWS
|
||||
if (direct3d)
|
||||
{
|
||||
CNELU::Driver= CDRU::createD3DDriver();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!CNELU::Driver)
|
||||
{
|
||||
CNELU::Driver= CDRU::createGlDriver();
|
||||
|
@ -183,10 +176,10 @@ void CNELU::releaseDriver()
|
|||
}
|
||||
}
|
||||
|
||||
bool CNELU::init (uint w, uint h, CViewport viewport, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen, bool direct3d) throw(EDru)
|
||||
bool CNELU::init (uint w, uint h, CViewport viewport, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen) throw(EDru)
|
||||
{
|
||||
NL3D::registerSerial3d();
|
||||
if (initDriver(w,h,bpp,windowed,systemWindow,offscreen,direct3d))
|
||||
if (initDriver(w,h,bpp,windowed,systemWindow,offscreen))
|
||||
{
|
||||
initScene(viewport);
|
||||
initEventServer();
|
||||
|
|
|
@ -185,7 +185,6 @@ void CNoise3d::render2passes (CQuadUV &qc, float wpos, float alpha)
|
|||
|
||||
uint8 finalAlpha = (uint8)(255*alphaPos*alpha);
|
||||
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
uint8 *pColA = (uint8*)vba.getColorPointer(_NbVertices) + 3;
|
||||
*pColA = finalAlpha; pColA = ((uint8*)pColA) + nVSize;
|
||||
*pColA = finalAlpha; pColA = ((uint8*)pColA) + nVSize;
|
||||
|
@ -260,7 +259,6 @@ void CNoise3d::render (CQuadUV &qc, float wpos, float intensity)
|
|||
pUV = (CUV*)( ((uint8*)pUV) + nVSize );
|
||||
*pUV = CUV(qc.Uv3.U*_ScaleW+_OffS[nSlice2].U, qc.Uv3.V*_ScaleH+_OffS[nSlice2].V);
|
||||
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
uint8 *pColA = (uint8*)vba.getColorPointer(_NbVertices) + 3;
|
||||
*pColA = nAlphaPos; pColA = ((uint8*)pColA) + nVSize;
|
||||
*pColA = nAlphaPos; pColA = ((uint8*)pColA) + nVSize;
|
||||
|
@ -306,7 +304,6 @@ void CNoise3d::renderGrid (uint32 nbw, uint32 nbh, uint32 w, uint32 h,
|
|||
pVertices = vba.getVertexCoordPointer(0);
|
||||
pUV0 = vba.getTexCoordPointer (0, 0);
|
||||
pUV1 = vba.getTexCoordPointer (0, 1);
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
pColA = (uint8*)vba.getColorPointer(0) + 3;
|
||||
|
||||
for (j = 0; j < nbh; ++j)
|
||||
|
@ -374,7 +371,6 @@ void CNoise3d::renderGrid2passes (uint32 nbw, uint32 nbh, uint32 w, uint32 h,
|
|||
|
||||
pVertices = vba.getVertexCoordPointer(0);
|
||||
pUV0 = vba.getTexCoordPointer (0, 0);
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
pColA = (uint8*)vba.getColorPointer(0) + 3;
|
||||
|
||||
for (j = 0; j < nbh; ++j)
|
||||
|
@ -471,4 +467,3 @@ uint32 CNoise3d::getDepth ()
|
|||
}
|
||||
|
||||
} // namespace NL3D
|
||||
|
||||
|
|
|
@ -1952,7 +1952,6 @@ void CPSConstraintMesh::computeColors(CVertexBuffer &outVB, const CVertexBuffer
|
|||
// TODO: optimisation : avoid to duplicate colors...
|
||||
_ColorScheme->makeN(_Owner, startIndex, vba.getColorPointer(), outVB.getVertexSize(), toProcess, inVB.getNumVertices(), srcStep);
|
||||
// modulate from the source mesh
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
uint8 *vDest = (uint8 *) vba.getColorPointer();
|
||||
uint8 *vSrc = (uint8 *) vbaIn.getColorPointer();
|
||||
const uint vSize = outVB.getVertexSize();
|
||||
|
|
|
@ -485,7 +485,6 @@ void CPSQuad::updateVbColNUVForRender(CVertexBuffer &vb, uint32 startIndex, uint
|
|||
if (_ColorScheme)
|
||||
{
|
||||
// compute the colors, each color is replicated 4 times
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
_ColorScheme->make4(_Owner, startIndex, vba.getColorPointer(), vb.getVertexSize(), size, srcStep);
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,6 @@ void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender, bool
|
|||
nlwarning("Render trave begin");
|
||||
#endif
|
||||
H_AUTO( NL3D_TravRender );
|
||||
if (getDriver()->isLost()) return; // device is lost so no need to render anything
|
||||
CTravCameraScene::update();
|
||||
// Bind to Driver.
|
||||
setupDriverCamera();
|
||||
|
|
|
@ -179,7 +179,6 @@ CShadowMapManager::CShadowMapManager()
|
|||
_ReceiveShadowMaterial.setTexCoordGen(0, true);
|
||||
_ReceiveShadowMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace);
|
||||
// Setup the stage so we interpolate ShadowColor and White (according to shadowmap alpha)
|
||||
// nico : with D3D driver, limitation of the number of per stage constant (Only 1 if diffuse is used), so do a blend between inv diffuse & black (instead of diffuse & white), which resolve to a modulate between
|
||||
// source alpha & inverse diffuse. then invert result at subsequent stage
|
||||
_ReceiveShadowMaterial.texEnvOpRGB(0, CMaterial::Modulate);
|
||||
_ReceiveShadowMaterial.texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::InvSrcColor);
|
||||
|
@ -1242,4 +1241,3 @@ void CShadowMapManager::garbageShadowTextures(CScene *scene)
|
|||
|
||||
|
||||
} // NL3D
|
||||
|
||||
|
|
|
@ -596,7 +596,7 @@ public:
|
|||
CSource *source = new CSource();
|
||||
source->Profile = nelvp;
|
||||
source->DisplayName = "nelvp/Veget";
|
||||
|
||||
|
||||
// Init the Vertex Program.
|
||||
string vpgram;
|
||||
// start always with Bend.
|
||||
|
@ -711,7 +711,7 @@ private:
|
|||
void CVegetableManager::initVertexProgram(uint vpType, bool fogEnabled)
|
||||
{
|
||||
nlassert(_LastDriver); // update driver should have been called at least once !
|
||||
|
||||
|
||||
// create VP.
|
||||
_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 dstCenterOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_CENTER);
|
||||
|
||||
// For D3D, If the VertexBuffer is in BGRA mode
|
||||
if(allocator->isBGRA())
|
||||
{
|
||||
// then swap only the B and R (no cpu cycle added per vertex)
|
||||
|
@ -1870,7 +1869,7 @@ public:
|
|||
void CVegetableManager::setupVertexProgramConstants(IDriver *driver, bool fogEnabled)
|
||||
{
|
||||
nlassert(_ActiveVertexProgram);
|
||||
|
||||
|
||||
|
||||
// Standard
|
||||
// setup VertexProgram constants.
|
||||
|
@ -2666,7 +2665,6 @@ uint CVegetableManager::updateInstanceLighting(CVegetableInstanceGroup *ig, uin
|
|||
uint dstColor0Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR0);
|
||||
uint dstColor1Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR1);
|
||||
|
||||
// For D3D, If the VertexBuffer is in BGRA mode
|
||||
if(allocator->isBGRA())
|
||||
{
|
||||
// then swap only the B and R (no cpu cycle added per vertex)
|
||||
|
|
|
@ -153,7 +153,6 @@ void CVegetableShape::build(CVegetableShapeBuild &vbuild)
|
|||
CUV *dstUVBend= vbaOut.getTexCoordPointer(i, 1);
|
||||
if(bendFromColor)
|
||||
{
|
||||
// todo hulud d3d vertex color RGBA / BGRA
|
||||
const CRGBA *srcColor= (const CRGBA*)vba.getColorPointer(i);
|
||||
// Copy and scale by MaxBendWeight
|
||||
dstUVBend->U= (srcColor->R / 255.f) * vbuild.MaxBendWeight;
|
||||
|
|
|
@ -6,20 +6,20 @@
|
|||
* CAudioDecoderVorbis
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2012 by authors
|
||||
*
|
||||
*
|
||||
* This file is part of RYZOM CORE.
|
||||
* RYZOM CORE 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.
|
||||
*
|
||||
*
|
||||
* RYZOM CORE 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 RYZOM CORE. If not, see
|
||||
* <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)
|
||||
{
|
||||
// nlwarning(NLSOUND_XAUDIO2_PREFIX "This seek call doesn't do a damn thing, wtf.");
|
||||
return 0; // ooookkaaaaaayyy
|
||||
}
|
||||
|
||||
|
@ -75,7 +74,6 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence)
|
|||
origin = NLMISC::IStream::end;
|
||||
break;
|
||||
default:
|
||||
// nlwarning(NLSOUND_XAUDIO2_PREFIX "Seeking to fake origin.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -101,7 +99,7 @@ static ov_callbacks OV_CALLBACKS_NLMISC_STREAM = {
|
|||
(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)
|
||||
{
|
||||
_StreamOffset = stream->getPos();
|
||||
|
@ -148,12 +146,11 @@ uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 m
|
|||
do
|
||||
{
|
||||
// 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.
|
||||
getBitsPerSample() == 8 ? 1 : 2,
|
||||
getBitsPerSample() == 8 ? 1 : 2,
|
||||
getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1.
|
||||
¤t_section);
|
||||
// nlinfo(NLSOUND_XAUDIO2_PREFIX "current_section: %i", current_section);
|
||||
if (br > 0)
|
||||
{
|
||||
bytes_read += (uint32)br;
|
||||
|
@ -165,14 +162,14 @@ uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 m
|
|||
ov_pcm_seek(&_OggVorbisFile, 0);
|
||||
//_Stream->seek(0, NLMISC::IStream::begin);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
_IsMusicEnded = true;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
// error
|
||||
switch(br)
|
||||
{
|
||||
|
|
|
@ -275,7 +275,7 @@ void CAudioMixerUser::reset()
|
|||
_Leaving = true;
|
||||
|
||||
_SourceWaitingForPlay.clear();
|
||||
|
||||
|
||||
for (uint i = 0; i < _NbMusicChannelFaders; ++i)
|
||||
_MusicChannelFaders[i].reset();
|
||||
|
||||
|
@ -374,9 +374,7 @@ void CAudioMixerUser::initDriver(const std::string &driverName)
|
|||
ISoundDriver::TDriver driverType;
|
||||
if (dn == "auto") driverType = ISoundDriver::DriverAuto;
|
||||
else if (dn == "fmod") driverType = ISoundDriver::DriverFMod;
|
||||
else if (dn == "dsound") driverType = ISoundDriver::DriverDSound;
|
||||
else if (dn == "openal") driverType = ISoundDriver::DriverOpenAl;
|
||||
else if (dn == "xaudio2") driverType = ISoundDriver::DriverXAudio2;
|
||||
else
|
||||
{
|
||||
driverType = ISoundDriver::DriverAuto;
|
||||
|
@ -510,7 +508,7 @@ void CAudioMixerUser::initDevice(const std::string &deviceName, const CInitInfo
|
|||
if (!_ReverbEffect)
|
||||
{ _UseEax = false; }
|
||||
else // createEffect succeeded, add environments
|
||||
{
|
||||
{
|
||||
nldebug("AM: Reverb OK");
|
||||
// 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)
|
||||
|
@ -572,7 +570,7 @@ void CAudioMixerUser::initDevice(const std::string &deviceName, const CInitInfo
|
|||
{
|
||||
buildSampleBankList();
|
||||
}
|
||||
|
||||
|
||||
// Init music channels
|
||||
for (i = 0; i < _NbMusicChannelFaders; ++i)
|
||||
_MusicChannelFaders[i].init(_SoundDriver);
|
||||
|
@ -1528,7 +1526,7 @@ void CAudioMixerUser::getPlayingSoundsPos(bool virtualPos, std::vector<std::pair
|
|||
source->getSourceRelativeMode()
|
||||
? source->getPos() + _ListenPosition
|
||||
: source->getPos()));
|
||||
|
||||
|
||||
if (source->getTrack() == 0)
|
||||
nbmute++;
|
||||
else
|
||||
|
@ -2833,5 +2831,3 @@ NLMISC_CATEGORISED_COMMAND(nel, displaySoundProfile, "Display information on sou
|
|||
|
||||
|
||||
} // NLSOUND
|
||||
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ CClusteredSound::CClusteredSound()
|
|||
_LastEnv(CStringMapper::emptyId()),
|
||||
_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;
|
||||
css.Gain = travContext.Gain;
|
||||
CVector soundDir = (nearPos - travContext.ListenerPos).normed();
|
||||
/* ****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
|
||||
/* ****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
|
||||
TStringId occId = portal->getOcclusionModelId();
|
||||
TStringIntMap::iterator it(_IdToMaterial.find(occId));
|
||||
****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
|
||||
****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
|
||||
|
||||
#if EAX_AVAILABLE == 1 // EAX_AVAILABLE no longer used => TODO: implement with EFX and remove when new implementation OK.
|
||||
if (it != _IdToMaterial.end())
|
||||
|
@ -612,14 +612,14 @@ void CClusteredSound::soundTraverse(const std::vector<CCluster *> &clusters, CSo
|
|||
css.OcclusionRoomRatio = travContext.OcclusionRoomRatio;
|
||||
}
|
||||
#else // EAX_AVAILABLE
|
||||
/* ****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
|
||||
/* ****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
|
||||
if (it != _IdToMaterial.end())
|
||||
{
|
||||
// found an occlusion material for this portal
|
||||
uint matId = it->second;
|
||||
css.Gain *= EAX_MATERIAL_PARAM[matId];
|
||||
}
|
||||
****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
|
||||
****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
|
||||
#endif // EAX_AVAILABLE
|
||||
/* if (portal->getOcclusionModel() == "wood door")
|
||||
{
|
||||
|
|
|
@ -25,11 +25,3 @@ ENDIF()
|
|||
IF(WITH_DRIVER_FMOD)
|
||||
ADD_SUBDIRECTORY(fmod)
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_DRIVER_DSOUND)
|
||||
ADD_SUBDIRECTORY(dsound)
|
||||
ENDIF()
|
||||
|
||||
IF(WITH_DRIVER_XAUDIO2)
|
||||
ADD_SUBDIRECTORY(xaudio2)
|
||||
ENDIF()
|
||||
|
|
|
@ -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()
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
EXPORTS NLSOUND_createISoundDriverInstance
|
||||
EXPORTS NLSOUND_interfaceVersion
|
||||
EXPORTS NLSOUND_outputProfile
|
||||
EXPORTS NLSOUND_getDriverType
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
@ -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
|
@ -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 */
|
|
@ -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"
|
|
@ -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 */
|
|
@ -131,7 +131,6 @@ void CListenerFMod::setDopplerFactor( float f )
|
|||
if( !CSoundDriverFMod::getInstance()->fmodOk() )
|
||||
return;
|
||||
|
||||
// clamp as in DSound.
|
||||
clamp(f, 0.f, 10.f);
|
||||
|
||||
// set
|
||||
|
@ -150,7 +149,6 @@ void CListenerFMod::setRolloffFactor( float f )
|
|||
if(!CSoundDriverFMod::getInstance()->fmodOk())
|
||||
return;
|
||||
|
||||
// clamp as in DSound (FMod requirement)
|
||||
clamp(f, 0.f, 10.f);
|
||||
|
||||
_RolloffFactor = f;
|
||||
|
|
|
@ -105,7 +105,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
/// Release all DirectSound resources
|
||||
/// Release all FMOD resources
|
||||
void release();
|
||||
|
||||
// Nel Basis
|
||||
|
@ -128,4 +128,3 @@ private:
|
|||
|
||||
|
||||
#endif // NL_LISTENER_FMOD_H
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ uint32 NLSOUND_interfaceVersion ()
|
|||
CSoundDriverFMod::CSoundDriverFMod(ISoundDriver::IStringMapperProvider *stringMapper)
|
||||
: _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
|
||||
// no adpcm, no effects, no buffer streaming
|
||||
const sint supportedOptions =
|
||||
const sint supportedOptions =
|
||||
OptionSoftwareBuffer
|
||||
| OptionManualRolloff
|
||||
| OptionLocalBufferCopy;
|
||||
|
@ -199,9 +199,6 @@ void CSoundDriverFMod::initDevice(const std::string &device, TSoundOptions optio
|
|||
_Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions);
|
||||
|
||||
uint initFlags = 0;
|
||||
#ifdef NL_OS_WINDOWS
|
||||
initFlags = FSOUND_INIT_DSOUND_DEFERRED;
|
||||
#endif
|
||||
|
||||
// Init with 32 channels, and deferred sound
|
||||
if (!FSOUND_Init(22050, 32, initFlags))
|
||||
|
@ -495,7 +492,7 @@ bool getTag (std::string &result, const char *tag, FSOUND_STREAM *stream)
|
|||
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 artist returns the song artist (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))
|
||||
{
|
||||
// set pathname to bnp
|
||||
pathName = pathName.substr(0, pathName.find('@'));
|
||||
pathName = pathName.substr(0, pathName.find('@'));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace NLSOUND {
|
|||
- EAX is not supported (setEnvironnement() / setEAXProperty() no-op)
|
||||
- ADPCM is not supported (decompressed and the format change internaly )
|
||||
- deffered param on ISource::setPos() etc... does not work. Always deffered.
|
||||
- No cooperative level change in FMod as in DSOUND (default???)
|
||||
- No cooperative level change in FMod (default???)
|
||||
|
||||
*/
|
||||
|
||||
|
@ -49,7 +49,7 @@ public:
|
|||
CSoundDriverFMod(ISoundDriver::IStringMapperProvider *stringMapper);
|
||||
|
||||
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.
|
||||
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.
|
||||
|
@ -110,7 +110,7 @@ public:
|
|||
|
||||
/// Create a music channel, destroy with destroyMusicChannel
|
||||
virtual IMusicChannel *createMusicChannel();
|
||||
|
||||
|
||||
/** 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 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.
|
||||
virtual bool isMusicExtensionSupported(const std::string &extension) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
virtual void startBench();
|
||||
virtual void endBench();
|
||||
virtual void displayBench(NLMISC::CLog *log);
|
||||
|
|
|
@ -466,7 +466,7 @@ void CSourceFMod::updateVolume( const NLMISC::CVector& listener )
|
|||
//// retransform to linear form
|
||||
//double attGain= pow((double)10.0, double(volumeDB)/2000.0);
|
||||
//clamp(attGain, 0.f, 1.f);
|
||||
|
||||
|
||||
float rolloff = ISource::computeManualRolloff(_Alpha, sqrdist, _MinDist, _MaxDist);
|
||||
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 = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
||||
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
||||
* is the default used by DirectSound/OpenAL
|
||||
* is the default used by OpenAL
|
||||
*
|
||||
* For any other value of alpha, an interpolation is be done between the two
|
||||
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
||||
|
@ -548,7 +548,7 @@ void CSourceFMod::updateFModPosIfRelative()
|
|||
/// Enable or disable direct output [true/false], default: true
|
||||
void CSourceFMod::setDirect(bool /* enable */)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Return if the direct output is enabled
|
||||
|
@ -560,7 +560,7 @@ bool CSourceFMod::getDirect() const
|
|||
/// Set the gain for the direct path
|
||||
void CSourceFMod::setDirectGain(float /* gain */)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Get the gain for the direct path
|
||||
|
@ -572,7 +572,7 @@ float CSourceFMod::getDirectGain() const
|
|||
/// Enable or disable the filter for the direct channel
|
||||
void CSourceFMod::enableDirectFilter(bool /* enable */)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// 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
|
||||
void CSourceFMod::setDirectFilter(TFilter /*filterType*/, float /*lowFrequency*/, float /*highFrequency*/, float /*passGain*/)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Get the filter parameters for the direct channel
|
||||
void CSourceFMod::getDirectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const
|
||||
{
|
||||
filterType = FilterLowPass;
|
||||
lowFrequency = NLSOUND_DEFAULT_FILTER_PASS_LF;
|
||||
highFrequency = NLSOUND_DEFAULT_FILTER_PASS_HF;
|
||||
lowFrequency = NLSOUND_DEFAULT_FILTER_PASS_LF;
|
||||
highFrequency = NLSOUND_DEFAULT_FILTER_PASS_HF;
|
||||
passGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN;
|
||||
}
|
||||
|
||||
/// Set the direct filter gain
|
||||
void CSourceFMod::setDirectFilterPassGain(float /*passGain*/)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// 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
|
||||
void CSourceFMod::setEffect(IReverbEffect * /* reverbEffect */)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Get the effect send for this source
|
||||
|
@ -623,7 +623,7 @@ IEffect *CSourceFMod::getEffect() const
|
|||
/// Set the gain for the effect path
|
||||
void CSourceFMod::setEffectGain(float /* gain */)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Get the gain for the effect path
|
||||
|
@ -635,7 +635,7 @@ float CSourceFMod::getEffectGain() const
|
|||
/// Enable or disable the filter for the effect channel
|
||||
void CSourceFMod::enableEffectFilter(bool /* enable */)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// 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
|
||||
void CSourceFMod::setEffectFilter(TFilter /*filterType*/, float /*lowFrequency*/, float /*highFrequency*/, float /*passGain*/)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Get the filter parameters for the effect channel
|
||||
void CSourceFMod::getEffectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const
|
||||
{
|
||||
filterType = FilterLowPass;
|
||||
lowFrequency = NLSOUND_DEFAULT_FILTER_PASS_LF;
|
||||
highFrequency = NLSOUND_DEFAULT_FILTER_PASS_HF;
|
||||
lowFrequency = NLSOUND_DEFAULT_FILTER_PASS_LF;
|
||||
highFrequency = NLSOUND_DEFAULT_FILTER_PASS_HF;
|
||||
passGain = NLSOUND_DEFAULT_FILTER_PASS_GAIN;
|
||||
}
|
||||
|
||||
/// Set the effect filter gain
|
||||
void CSourceFMod::setEffectFilterPassGain(float /*passGain*/)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Get the effect filter gain
|
||||
|
|
|
@ -25,11 +25,11 @@ namespace NLSOUND {
|
|||
class CBufferFMod;
|
||||
|
||||
// TODO: Doc comments in FMod driver are wrong.
|
||||
// Bad copy pastes from DSound & OpenAL drivers.
|
||||
// Bad copy pastes from OpenAL drivers.
|
||||
// Fix drivername, author and date (2004?)!
|
||||
|
||||
/**
|
||||
* DirectSound sound source
|
||||
* FMOD sound source
|
||||
*
|
||||
|
||||
* For arguments as 3D vectors, use the NeL vector coordinate system
|
||||
|
@ -41,16 +41,16 @@ namespace NLSOUND {
|
|||
class CSourceFMod : public ISource
|
||||
{
|
||||
friend class CSoundDriverFMod;
|
||||
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
CSourceFMod( uint sourcename = 0 );
|
||||
/// Destructor
|
||||
virtual ~CSourceFMod();
|
||||
|
||||
/// Initialize the DirectSound buffers. Called by the sound driver only.
|
||||
|
||||
/// Initialize the FMOD buffers. Called by the sound driver only.
|
||||
void init();
|
||||
|
||||
|
||||
/// \name Initialization
|
||||
//@{
|
||||
/// 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.
|
||||
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.
|
||||
*/
|
||||
|
@ -93,7 +93,7 @@ public:
|
|||
/// Returns the number of milliseconds the source has been playing
|
||||
virtual uint32 getTime();
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Source properties
|
||||
//@{
|
||||
/** 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 = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
||||
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
||||
* is the default used by DirectSound/OpenAL
|
||||
* is the default used by OpenAL
|
||||
*
|
||||
* For any other value of alpha, an interpolation is be done between the two
|
||||
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
||||
|
@ -155,7 +155,7 @@ public:
|
|||
*/
|
||||
virtual void setAlpha(double a);
|
||||
//@}
|
||||
|
||||
|
||||
/// \name Direct output
|
||||
//@{
|
||||
/// Enable or disable direct output [true/false], default: true
|
||||
|
@ -166,7 +166,7 @@ public:
|
|||
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
|
||||
|
@ -180,7 +180,7 @@ public:
|
|||
/// 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
|
||||
|
@ -191,7 +191,7 @@ public:
|
|||
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
|
||||
|
@ -205,29 +205,29 @@ public:
|
|||
/// Get the effect filter gain
|
||||
virtual float getEffectFilterPassGain() const;
|
||||
//@}
|
||||
|
||||
|
||||
/// Return the OpenAL source name
|
||||
uint sourceName() { return _SourceName; }
|
||||
|
||||
|
||||
/// 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.
|
||||
* Called only with OptionManualRolloff
|
||||
*/
|
||||
void updateVolume(const NLMISC::CVector& listener);
|
||||
|
||||
|
||||
bool needsUpdate();
|
||||
|
||||
|
||||
void updateFModPosIfRelative();
|
||||
|
||||
|
||||
private:
|
||||
void copySampleTo16BitsTrack(void *dst, void *src, uint nbSample, TSampleFormat sourceFormat);
|
||||
|
||||
|
||||
enum TSourceState
|
||||
{
|
||||
source_stopped,
|
||||
|
@ -235,19 +235,19 @@ private:
|
|||
source_silencing,
|
||||
source_swap_pending
|
||||
};
|
||||
|
||||
/// Release all DirectSound resources
|
||||
|
||||
/// Release all FMod resources
|
||||
void release();
|
||||
|
||||
|
||||
// Source name
|
||||
uint _SourceName;
|
||||
|
||||
|
||||
TSourceState _State;
|
||||
|
||||
|
||||
IBuffer *_Sample;
|
||||
IBuffer *_NextSample;
|
||||
sint _FModChannel;
|
||||
|
||||
|
||||
// States
|
||||
bool _PosRelative;
|
||||
bool _Loop;
|
||||
|
@ -258,9 +258,9 @@ private:
|
|||
NLMISC::CVector _Vel;
|
||||
NLMISC::CVector _Front;
|
||||
float _MinDist, _MaxDist;
|
||||
|
||||
|
||||
void updateFModPos();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -184,8 +184,8 @@ uint32 NLSOUND_interfaceVersion ()
|
|||
/*
|
||||
* Constructor
|
||||
*/
|
||||
CSoundDriverAL::CSoundDriverAL(ISoundDriver::IStringMapperProvider *stringMapper)
|
||||
: _StringMapper(stringMapper), _AlDevice(NULL), _AlContext(NULL),
|
||||
CSoundDriverAL::CSoundDriverAL(ISoundDriver::IStringMapperProvider *stringMapper)
|
||||
: _StringMapper(stringMapper), _AlDevice(NULL), _AlContext(NULL),
|
||||
_NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f)
|
||||
{
|
||||
alExtInit();
|
||||
|
@ -196,9 +196,9 @@ _NbExpBuffers(0), _NbExpSources(0), _RolloffFactor(1.f)
|
|||
*/
|
||||
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!
|
||||
|
||||
|
||||
// Remove the allocated (but not exported) source and buffer names-
|
||||
// Release internal resources of all remaining ISource instances
|
||||
if (!_Sources.empty())
|
||||
|
@ -208,7 +208,7 @@ CSoundDriverAL::~CSoundDriverAL()
|
|||
for (; it != end; ++it) (*it)->release(); // CSourceAL will be deleted by user
|
||||
_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
|
||||
if (!_Effects.empty())
|
||||
{
|
||||
|
@ -229,7 +229,7 @@ void CSoundDriverAL::getDevices(std::vector<std::string> &devices)
|
|||
devices.push_back(""); // empty
|
||||
|
||||
if (AlEnumerateAllExt)
|
||||
{
|
||||
{
|
||||
const ALchar* deviceNames = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
|
||||
// const ALchar* defaultDevice = NULL;
|
||||
if(!strlen(deviceNames))
|
||||
|
@ -257,7 +257,7 @@ static const ALchar *getDeviceInternal(const std::string &device)
|
|||
{
|
||||
if (device.empty()) return NULL;
|
||||
if (AlEnumerateAllExt)
|
||||
{
|
||||
{
|
||||
const ALchar* deviceNames = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
|
||||
if(!strlen(deviceNames))
|
||||
{
|
||||
|
@ -286,7 +286,7 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
|
|||
{
|
||||
// list of supported options in this driver
|
||||
// no adpcm, no manual rolloff (for now)
|
||||
const sint supportedOptions =
|
||||
const sint supportedOptions =
|
||||
OptionEnvironmentEffects
|
||||
| OptionSoftwareBuffer
|
||||
| OptionManualRolloff
|
||||
|
@ -298,7 +298,7 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
|
|||
|
||||
// set the options
|
||||
_Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions);
|
||||
|
||||
|
||||
/* TODO: multichannel */
|
||||
|
||||
// OpenAL initialization
|
||||
|
@ -309,8 +309,8 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
|
|||
if (!_AlDevice) throw ESoundDriver("AL: Failed to open device");
|
||||
nldebug("AL: ALC_DEVICE_SPECIFIER: '%s'", alcGetString(_AlDevice, ALC_DEVICE_SPECIFIER));
|
||||
//int attrlist[] = { ALC_FREQUENCY, 48000,
|
||||
// ALC_MONO_SOURCES, 12,
|
||||
// ALC_STEREO_SOURCES, 4,
|
||||
// ALC_MONO_SOURCES, 12,
|
||||
// ALC_STEREO_SOURCES, 4,
|
||||
// ALC_INVALID };
|
||||
_AlContext = alcCreateContext(_AlDevice, NULL); // attrlist);
|
||||
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
|
||||
alExtInitDevice(_AlDevice);
|
||||
#if EAX_AVAILABLE
|
||||
nlinfo("AL: EAX: %s, EAX-RAM: %s, ALC_EXT_EFX: %s",
|
||||
AlExtEax ? "Present" : "Not available",
|
||||
AlExtXRam ? "Present" : "Not available",
|
||||
nlinfo("AL: EAX: %s, EAX-RAM: %s, ALC_EXT_EFX: %s",
|
||||
AlExtEax ? "Present" : "Not available",
|
||||
AlExtXRam ? "Present" : "Not available",
|
||||
AlExtEfx ? "Present" : "Not available");
|
||||
#else
|
||||
nldebug("AL: EAX-RAM: %s, ALC_EXT_EFX: %s",
|
||||
AlExtXRam ? "Present" : "Not available",
|
||||
nldebug("AL: EAX-RAM: %s, ALC_EXT_EFX: %s",
|
||||
AlExtXRam ? "Present" : "Not available",
|
||||
AlExtEfx ? "Present" : "Not available");
|
||||
#endif
|
||||
alTestError();
|
||||
|
||||
nldebug("AL: Max. sources: %u, Max. effects: %u", (uint32)countMaxSources(), (uint32)countMaxEffects());
|
||||
|
||||
if (getOption(OptionEnvironmentEffects))
|
||||
if (getOption(OptionEnvironmentEffects))
|
||||
{
|
||||
if (!AlExtEfx)
|
||||
{
|
||||
|
@ -351,13 +351,13 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
|
|||
_Options = (TSoundOptions)((uint)_Options & ~OptionEnvironmentEffects);
|
||||
}
|
||||
else if (!countMaxEffects())
|
||||
{
|
||||
{
|
||||
nlwarning("AL: No effects available, environment effects disabled");
|
||||
_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);
|
||||
else alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
alTestError();
|
||||
|
@ -456,7 +456,7 @@ IReverbEffect *CSoundDriverAL::createReverbEffect()
|
|||
{
|
||||
IReverbEffect *ieffect = NULL;
|
||||
CEffectAL *effectal = NULL;
|
||||
|
||||
|
||||
ALuint slot = AL_NONE;
|
||||
alGenAuxiliaryEffectSlots(1, &slot);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
|
@ -464,7 +464,7 @@ IReverbEffect *CSoundDriverAL::createReverbEffect()
|
|||
nlwarning("AL: alGenAuxiliaryEffectSlots failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ALuint effect = AL_NONE;
|
||||
alGenEffects(1, &effect);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
|
@ -491,7 +491,7 @@ IReverbEffect *CSoundDriverAL::createReverbEffect()
|
|||
_Effects.insert(effectal);
|
||||
return ieffect;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
|
@ -520,16 +520,16 @@ static uint getMaxNumSourcesInternal()
|
|||
ALuint sources[256];
|
||||
memset(sources, 0, sizeofarray(sources));
|
||||
uint sourceCount = 0;
|
||||
|
||||
|
||||
alGetError();
|
||||
|
||||
|
||||
for (; sourceCount < 256; ++sourceCount)
|
||||
{
|
||||
alGenSources(1, &sources[sourceCount]);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
alDeleteSources(sourceCount, sources);
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
|
|
|
@ -35,20 +35,20 @@ namespace NLSOUND {
|
|||
|
||||
CSourceAL::CSourceAL(CSoundDriverAL *soundDriver) :
|
||||
_SoundDriver(NULL), _Buffer(NULL), _Source(AL_NONE),
|
||||
_DirectFilter(AL_FILTER_NULL), _EffectFilter(AL_FILTER_NULL),
|
||||
_IsPlaying(false), _IsPaused(false), _StartTime(0), _IsStreaming(false), _RelativeMode(false),
|
||||
_Pos(0.0f, 0.0f, 0.0f), _Gain(NLSOUND_DEFAULT_GAIN), _Alpha(1.0),
|
||||
_MinDistance(1.0f), _MaxDistance(sqrt(numeric_limits<float>::max())),
|
||||
_Effect(NULL), _Direct(true),
|
||||
_DirectGain(NLSOUND_DEFAULT_DIRECT_GAIN), _EffectGain(NLSOUND_DEFAULT_EFFECT_GAIN),
|
||||
_DirectFilterType(ISource::FilterLowPass), _EffectFilterType(ISource::FilterLowPass),
|
||||
_DirectFilterEnabled(false), _EffectFilterEnabled(false),
|
||||
_DirectFilter(AL_FILTER_NULL), _EffectFilter(AL_FILTER_NULL),
|
||||
_IsPlaying(false), _IsPaused(false), _StartTime(0), _IsStreaming(false), _RelativeMode(false),
|
||||
_Pos(0.0f, 0.0f, 0.0f), _Gain(NLSOUND_DEFAULT_GAIN), _Alpha(1.0),
|
||||
_MinDistance(1.0f), _MaxDistance(sqrt(numeric_limits<float>::max())),
|
||||
_Effect(NULL), _Direct(true),
|
||||
_DirectGain(NLSOUND_DEFAULT_DIRECT_GAIN), _EffectGain(NLSOUND_DEFAULT_EFFECT_GAIN),
|
||||
_DirectFilterType(ISource::FilterLowPass), _EffectFilterType(ISource::FilterLowPass),
|
||||
_DirectFilterEnabled(false), _EffectFilterEnabled(false),
|
||||
_DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN)
|
||||
{
|
||||
// create the al source
|
||||
alGenSources(1, &_Source);
|
||||
alTestError();
|
||||
|
||||
|
||||
// configure rolloff
|
||||
if (soundDriver->getOption(ISoundDriver::OptionManualRolloff))
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ _DirectFilterPassGain(NLSOUND_DEFAULT_FILTER_PASS_GAIN), _EffectFilterPassGain(N
|
|||
alSourcef(_Source, AL_ROLLOFF_FACTOR, soundDriver->getRolloffFactor());
|
||||
alTestError();
|
||||
}
|
||||
|
||||
|
||||
// create filters
|
||||
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);
|
||||
alTestError();
|
||||
}
|
||||
|
||||
|
||||
// if everything went well, the source will be added in the sounddriver
|
||||
_SoundDriver = soundDriver;
|
||||
}
|
||||
|
@ -166,17 +166,17 @@ void CSourceAL::submitStreamingBuffer(IBuffer *buffer)
|
|||
CBufferAL *bufferAL = static_cast<CBufferAL *>(buffer);
|
||||
ALuint bufferName = bufferAL->bufferName();
|
||||
nlassert(bufferName);
|
||||
|
||||
|
||||
if (!bufferAL->isBufferLoaded())
|
||||
{
|
||||
nlwarning("AL: MUSICBUG: Streaming buffer was not loaded, skipping buffer. This should not happen.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
alSourceQueueBuffers(_Source, 1, &bufferName);
|
||||
alTestError();
|
||||
_QueuedBuffers.push(bufferAL);
|
||||
|
||||
|
||||
// Resume playback if the internal OpenAL source stopped due to buffer underrun.
|
||||
ALint 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 = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
||||
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
||||
* is the default used by DirectSound/OpenAL
|
||||
* is the default used by OpenAL
|
||||
*
|
||||
* For any other value of alpha, an interpolation is be done between the two
|
||||
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue