Purging DirectX libraries (3D, sound, input).
This commit is contained in:
parent
edb19ee4d8
commit
790e55bf0c
211 changed files with 1346 additions and 31376 deletions
|
@ -1055,7 +1055,7 @@ Windows client build:
|
||||||
- find codebis -type f -name "*.rc" -exec unix2dos {} \;
|
- find codebis -type f -name "*.rc" -exec unix2dos {} \;
|
||||||
- mkdir -p build
|
- mkdir -p build
|
||||||
- cd build
|
- cd build
|
||||||
- wine cmake.exe -DWITH_RYZOM_CUSTOM_PATCH_SERVER=ON -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_PATCH=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_TOOLS=OFF -DWITH_TOOLS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_LUA53=ON -DWITH_LUA51=OFF -DWITH_STLPORT=OFF -DWITH_DRIVER_DSOUND=ON -G "NMake Makefiles JOM" -DWITH_STATIC=ON -DWITH_STATIC_DRIVERS=ON -DWITH_DRIVER_OPENAL=OFF -DWITH_DRIVER_DSOUND=ON -DWITH_DRIVER_XAUDIO2=ON -DWITH_DRIVER_FMOD=ON -DWITH_DRIVER_DIRECT3D=ON ../codebis
|
- wine cmake.exe -DWITH_RYZOM_CUSTOM_PATCH_SERVER=ON -DWITH_RYZOM_SERVER=OFF -DWITH_RYZOM_TOOLS=OFF -DWITH_RYZOM_CLIENT=ON -DWITH_RYZOM_PATCH=ON -DWITH_NEL_TESTS=OFF -DWITH_NEL_TOOLS=OFF -DWITH_TOOLS=OFF -DWITH_NEL_SAMPLES=OFF -DWITH_LUA53=ON -DWITH_LUA51=OFF -DWITH_STLPORT=OFF -G "NMake Makefiles JOM" -DWITH_STATIC=ON -DWITH_STATIC_DRIVERS=ON -DWITH_DRIVER_OPENAL=OFF -DWITH_DRIVER_FMOD=ON ../codebis
|
||||||
- wine jom.exe
|
- wine jom.exe
|
||||||
artifacts:
|
artifacts:
|
||||||
name: "khanat-client-windows-$CI_COMMIT_REF_NAME"
|
name: "khanat-client-windows-$CI_COMMIT_REF_NAME"
|
||||||
|
|
|
@ -10,10 +10,6 @@ MACRO(NL_CONFIGURE_CHECKS)
|
||||||
SET(NL_OPENGLES_AVAILABLE 1)
|
SET(NL_OPENGLES_AVAILABLE 1)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(WITH_DRIVER_DIRECT3D)
|
|
||||||
SET(NL_DIRECT3D_AVAILABLE 1)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# sound drivers
|
# sound drivers
|
||||||
IF(WITH_DRIVER_FMOD)
|
IF(WITH_DRIVER_FMOD)
|
||||||
SET(NL_FMOD_AVAILABLE 1)
|
SET(NL_FMOD_AVAILABLE 1)
|
||||||
|
@ -23,14 +19,6 @@ MACRO(NL_CONFIGURE_CHECKS)
|
||||||
SET(NL_OPENAL_AVAILABLE 1)
|
SET(NL_OPENAL_AVAILABLE 1)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(WITH_DRIVER_DSOUND)
|
|
||||||
SET(NL_DSOUND_AVAILABLE 1)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(WITH_DRIVER_XAUDIO2)
|
|
||||||
SET(NL_XAUDIO2_AVAILABLE 1)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(NOT RYZOM_VERSION_MAJOR)
|
IF(NOT RYZOM_VERSION_MAJOR)
|
||||||
SET(RYZOM_VERSION_MAJOR ${NL_VERSION_MAJOR})
|
SET(RYZOM_VERSION_MAJOR ${NL_VERSION_MAJOR})
|
||||||
SET(RYZOM_VERSION_MINOR ${NL_VERSION_MINOR})
|
SET(RYZOM_VERSION_MINOR ${NL_VERSION_MINOR})
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
# - Find DirectInput
|
|
||||||
# Find the DirectSound includes and libraries
|
|
||||||
#
|
|
||||||
# MAXSDK_DIR - 3DSMAX SDK root directory
|
# MAXSDK_DIR - 3DSMAX SDK root directory
|
||||||
# MAXSDK_INCLUDE_DIR - where to find baseinterface.h
|
# MAXSDK_INCLUDE_DIR - where to find baseinterface.h
|
||||||
# MAXSDK_LIBRARIES - List of libraries when using 3DSMAX.
|
# MAXSDK_LIBRARIES - List of libraries when using 3DSMAX.
|
||||||
|
|
|
@ -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
|
FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES libmysql mysqlclient
|
||||||
PATHS
|
PATHS
|
||||||
$ENV{ProgramFiles}/MySQL/*/lib/opt
|
$ENV{ProgramFiles}/MySQL/*/lib/opt
|
||||||
$ENV{SystemDrive}/MySQL/*/lib/opt)
|
$ENV{SystemDrive}/MySQL/*/lib/opt
|
||||||
|
$ENV{ProgramFiles}/MySQL/*/lib
|
||||||
|
$ENV{SystemDrive}/MySQL/*/lib)
|
||||||
|
|
||||||
FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES libmysqld mysqlclientd
|
FIND_LIBRARY(MYSQL_LIBRARY_DEBUG NAMES libmysqld mysqlclientd
|
||||||
PATHS
|
PATHS
|
||||||
$ENV{ProgramFiles}/MySQL/*/lib/opt
|
$ENV{ProgramFiles}/MySQL/*/lib/opt
|
||||||
$ENV{SystemDrive}/MySQL/*/lib/opt)
|
$ENV{SystemDrive}/MySQL/*/lib/opt
|
||||||
|
$ENV{ProgramFiles}/MySQL/*/lib
|
||||||
|
$ENV{SystemDrive}/MySQL/*/lib)
|
||||||
ELSE()
|
ELSE()
|
||||||
FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient
|
FIND_LIBRARY(MYSQL_LIBRARY_RELEASE NAMES mysqlclient
|
||||||
PATHS
|
PATHS
|
||||||
|
|
|
@ -122,12 +122,6 @@ ENDMACRO(NL_ADD_RUNTIME_FLAGS)
|
||||||
|
|
||||||
MACRO(NL_ADD_STATIC_VID_DRIVERS name)
|
MACRO(NL_ADD_STATIC_VID_DRIVERS name)
|
||||||
IF(WITH_STATIC_DRIVERS)
|
IF(WITH_STATIC_DRIVERS)
|
||||||
IF(WIN32)
|
|
||||||
IF(WITH_DRIVER_DIRECT3D)
|
|
||||||
TARGET_LINK_LIBRARIES(${name} nel_drv_direct3d_win)
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(WITH_DRIVER_OPENGL)
|
IF(WITH_DRIVER_OPENGL)
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
TARGET_LINK_LIBRARIES(${name} nel_drv_opengl_win)
|
TARGET_LINK_LIBRARIES(${name} nel_drv_opengl_win)
|
||||||
|
@ -149,14 +143,6 @@ ENDMACRO(NL_ADD_STATIC_VID_DRIVERS)
|
||||||
MACRO(NL_ADD_STATIC_SND_DRIVERS name)
|
MACRO(NL_ADD_STATIC_SND_DRIVERS name)
|
||||||
IF(WITH_STATIC_DRIVERS)
|
IF(WITH_STATIC_DRIVERS)
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
IF(WITH_DRIVER_DSOUND)
|
|
||||||
TARGET_LINK_LIBRARIES(${name} nel_drv_dsound_win)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(WITH_DRIVER_XAUDIO2)
|
|
||||||
TARGET_LINK_LIBRARIES(${name} nel_drv_xaudio2_win)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(WITH_DRIVER_OPENAL)
|
IF(WITH_DRIVER_OPENAL)
|
||||||
TARGET_LINK_LIBRARIES(${name} nel_drv_openal_win)
|
TARGET_LINK_LIBRARIES(${name} nel_drv_openal_win)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@ -299,11 +285,8 @@ MACRO(NL_SETUP_NEL_DEFAULT_OPTIONS)
|
||||||
###
|
###
|
||||||
OPTION(WITH_DRIVER_OPENGL "Build OpenGL Driver (3D)" ON )
|
OPTION(WITH_DRIVER_OPENGL "Build OpenGL Driver (3D)" ON )
|
||||||
OPTION(WITH_DRIVER_OPENGLES "Build OpenGL ES Driver (3D)" OFF)
|
OPTION(WITH_DRIVER_OPENGLES "Build OpenGL ES Driver (3D)" OFF)
|
||||||
OPTION(WITH_DRIVER_DIRECT3D "Build Direct3D Driver (3D)" OFF)
|
|
||||||
OPTION(WITH_DRIVER_OPENAL "Build OpenAL Driver (Sound)" ON )
|
OPTION(WITH_DRIVER_OPENAL "Build OpenAL Driver (Sound)" ON )
|
||||||
OPTION(WITH_DRIVER_FMOD "Build FMOD Driver (Sound)" OFF)
|
OPTION(WITH_DRIVER_FMOD "Build FMOD Driver (Sound)" OFF)
|
||||||
OPTION(WITH_DRIVER_DSOUND "Build DirectSound Driver (Sound)" OFF)
|
|
||||||
OPTION(WITH_DRIVER_XAUDIO2 "Build XAudio2 Driver (Sound)" OFF)
|
|
||||||
|
|
||||||
###
|
###
|
||||||
# Optional support
|
# Optional support
|
||||||
|
@ -1198,14 +1181,6 @@ MACRO(SETUP_EXTERNAL)
|
||||||
INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${STLPORT_INCLUDE_DIR})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
# Must include DXSDK before WINSDK
|
|
||||||
FIND_PACKAGE(DirectXSDK REQUIRED)
|
|
||||||
# IF(DXSDK_INCLUDE_DIR)
|
|
||||||
# INCLUDE_DIRECTORIES(${DXSDK_INCLUDE_DIR})
|
|
||||||
# ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
FIND_PACKAGE(MSVC REQUIRED)
|
FIND_PACKAGE(MSVC REQUIRED)
|
||||||
FIND_PACKAGE(WindowsSDK REQUIRED)
|
FIND_PACKAGE(WindowsSDK REQUIRED)
|
||||||
|
|
|
@ -3,12 +3,9 @@
|
||||||
|
|
||||||
#cmakedefine NL_OPENGL_AVAILABLE ${NL_OPENGL_AVAILABLE}
|
#cmakedefine NL_OPENGL_AVAILABLE ${NL_OPENGL_AVAILABLE}
|
||||||
#cmakedefine NL_OPENGLES_AVAILABLE ${NL_OPENGLES_AVAILABLE}
|
#cmakedefine NL_OPENGLES_AVAILABLE ${NL_OPENGLES_AVAILABLE}
|
||||||
#cmakedefine NL_DIRECT3D_AVAILABLE ${NL_DIRECT3D_AVAILABLE}
|
|
||||||
|
|
||||||
#cmakedefine NL_FMOD_AVAILABLE ${NL_FMOD_AVAILABLE}
|
#cmakedefine NL_FMOD_AVAILABLE ${NL_FMOD_AVAILABLE}
|
||||||
#cmakedefine NL_OPENAL_AVAILABLE ${NL_OPENAL_AVAILABLE}
|
#cmakedefine NL_OPENAL_AVAILABLE ${NL_OPENAL_AVAILABLE}
|
||||||
#cmakedefine NL_DSOUND_AVAILABLE ${NL_DSOUND_AVAILABLE}
|
|
||||||
#cmakedefine NL_XAUDIO2_AVAILABLE ${NL_XAUDIO2_AVAILABLE}
|
|
||||||
|
|
||||||
#cmakedefine NL_STEREO_AVAILABLE ${NL_STEREO_AVAILABLE}
|
#cmakedefine NL_STEREO_AVAILABLE ${NL_STEREO_AVAILABLE}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class CTextureUser;
|
||||||
//---------------------------------------- CBloomEffect -----------------------------------------------------
|
//---------------------------------------- CBloomEffect -----------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------------
|
||||||
// CBloomEffect class apply a bloom effect on the whole scene. The whole scene is rendered in a
|
// CBloomEffect class apply a bloom effect on the whole scene. The whole scene is rendered in a
|
||||||
// render target (a Frame Buffer Object on OpengL, the normal back buffer in Direct3D) which is stretched
|
// render target (a Frame Buffer Object on OpengL) which is stretched
|
||||||
// in a 256*256 another render target.
|
// in a 256*256 another render target.
|
||||||
// We apply a horizontal blur on this 256*256 render target, then a vertical blur on the result of this first pass.
|
// We apply a horizontal blur on this 256*256 render target, then a vertical blur on the result of this first pass.
|
||||||
// The final blurred render target is blend with the initial render target of scene, with a dest + src - dest*src
|
// The final blurred render target is blend with the initial render target of scene, with a dest + src - dest*src
|
||||||
|
@ -93,7 +93,6 @@ public:
|
||||||
// to keep Z tests correct.
|
// to keep Z tests correct.
|
||||||
// This method is called at the end of interfaces display in the main loop, to display final render target
|
// This method is called at the end of interfaces display in the main loop, to display final render target
|
||||||
// (with added interfaces) in the color frame buffer.
|
// (with added interfaces) in the color frame buffer.
|
||||||
// NB : In Direct3D, the final render target is displayed at the end of endBloom call.
|
|
||||||
// void endInterfacesDisplayBloom();
|
// void endInterfacesDisplayBloom();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -188,9 +188,6 @@ public:
|
||||||
/// Before rendering via a driver in a thread, must activate() (per thread).
|
/// Before rendering via a driver in a thread, must activate() (per thread).
|
||||||
virtual bool activate() = 0;
|
virtual bool activate() = 0;
|
||||||
|
|
||||||
// Test if the device is lost. Can only happen with D3D.
|
|
||||||
// The calling application may skip some part of its rendering when it is the case (this is not a requirement, but may save cpu for other applications)
|
|
||||||
virtual bool isLost() const = 0;
|
|
||||||
|
|
||||||
/// Return true if driver is still active. Return false else. If he user close the window, must return false.
|
/// Return true if driver is still active. Return false else. If he user close the window, must return false.
|
||||||
virtual bool isActive() = 0;
|
virtual bool isActive() = 0;
|
||||||
|
@ -437,8 +434,7 @@ public:
|
||||||
virtual uint getNbTextureStages() const = 0;
|
virtual uint getNbTextureStages() const = 0;
|
||||||
|
|
||||||
/** Get max number of per stage constant that can be used simultaneously.
|
/** Get max number of per stage constant that can be used simultaneously.
|
||||||
* This will usually match the number of texture stages, but with a D3D driver, this feature is not available most of the time
|
* This will usually match the number of texture stages. If pixel shaders are available this will be fully supported.
|
||||||
* so it is emulated. If pixel shaders are available this will be fully supported.
|
|
||||||
* Under OpenGL this simply returns the maximum number of texture stages (getNbTextureStages) in both return values.
|
* Under OpenGL this simply returns the maximum number of texture stages (getNbTextureStages) in both return values.
|
||||||
*/
|
*/
|
||||||
virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0;
|
virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const = 0;
|
||||||
|
@ -1363,7 +1359,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool setAdapter(uint adapter) = 0;
|
virtual bool setAdapter(uint adapter) = 0;
|
||||||
|
|
||||||
/** Tell if the vertex color memory format is RGBA (openGL) or BGRA (directx)
|
/** Tell if the vertex color memory format is RGBA (openGL) or BGRA
|
||||||
* BGRA :
|
* BGRA :
|
||||||
* *****************************************************************
|
* *****************************************************************
|
||||||
* Offset: * 0 * 1 * 2 * 3 *
|
* Offset: * 0 * 1 * 2 * 3 *
|
||||||
|
@ -1446,4 +1442,3 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NL_DRV_H
|
#endif // NL_DRV_H
|
||||||
|
|
||||||
|
|
|
@ -133,8 +133,6 @@ public:
|
||||||
virtual ~CDriverUser();
|
virtual ~CDriverUser();
|
||||||
// @}
|
// @}
|
||||||
|
|
||||||
virtual bool isLost() const;
|
|
||||||
|
|
||||||
/// \name Window / driver management.
|
/// \name Window / driver management.
|
||||||
// @{
|
// @{
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,9 @@
|
||||||
#if defined (NL_COMP_MINGW)
|
#if defined (NL_COMP_MINGW)
|
||||||
# define NL3D_GL_DLL_NAME "libnel_drv_opengl_win"
|
# define NL3D_GL_DLL_NAME "libnel_drv_opengl_win"
|
||||||
# define NL3D_GLES_DLL_NAME "libnel_drv_opengles_win"
|
# define NL3D_GLES_DLL_NAME "libnel_drv_opengles_win"
|
||||||
# define NL3D_D3D_DLL_NAME "libnel_drv_direct3d_win"
|
|
||||||
#elif defined (NL_OS_WINDOWS)
|
#elif defined (NL_OS_WINDOWS)
|
||||||
# define NL3D_GL_DLL_NAME "nel_drv_opengl_win"
|
# define NL3D_GL_DLL_NAME "nel_drv_opengl_win"
|
||||||
# define NL3D_GLES_DLL_NAME "nel_drv_opengles_win"
|
# define NL3D_GLES_DLL_NAME "nel_drv_opengles_win"
|
||||||
# define NL3D_D3D_DLL_NAME "nel_drv_direct3d_win"
|
|
||||||
#elif defined (NL_OS_UNIX)
|
#elif defined (NL_OS_UNIX)
|
||||||
# define NL3D_GL_DLL_NAME "nel_drv_opengl"
|
# define NL3D_GL_DLL_NAME "nel_drv_opengl"
|
||||||
# define NL3D_GLES_DLL_NAME "nel_drv_opengles"
|
# define NL3D_GLES_DLL_NAME "nel_drv_opengles"
|
||||||
|
@ -100,34 +98,6 @@ struct EDruOpenglEsDriverCantCreateDriver : public EDru
|
||||||
EDruOpenglEsDriverCantCreateDriver() : EDru( NL3D_GLES_DLL_NAME " can't create driver" ) {}
|
EDruOpenglEsDriverCantCreateDriver() : EDru( NL3D_GLES_DLL_NAME " can't create driver" ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
// Direct3D
|
|
||||||
struct EDruDirect3dDriverNotFound : public EDru
|
|
||||||
{
|
|
||||||
EDruDirect3dDriverNotFound() : EDru( NL3D_D3D_DLL_NAME " not found" ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EDruDirect3dDriverCorrupted : public EDru
|
|
||||||
{
|
|
||||||
EDruDirect3dDriverCorrupted() : EDru( "Can't get NL3D_createIDriverInstance from " NL3D_D3D_DLL_NAME " (Bad dll?)" ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EDruDirect3dDriverOldVersion : public EDru
|
|
||||||
{
|
|
||||||
EDruDirect3dDriverOldVersion() : EDru( NL3D_D3D_DLL_NAME " is a too old version. Ask for a more recent file" ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EDruDirect3dDriverUnknownVersion : public EDru
|
|
||||||
{
|
|
||||||
EDruDirect3dDriverUnknownVersion() : EDru( NL3D_D3D_DLL_NAME " is more recent than the application" ) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EDruDirect3dDriverCantCreateDriver : public EDru
|
|
||||||
{
|
|
||||||
EDruDirect3dDriverCantCreateDriver() : EDru( NL3D_D3D_DLL_NAME " can't create driver" ) {}
|
|
||||||
};
|
|
||||||
#endif // NL_OS_WINDOWS
|
|
||||||
|
|
||||||
/// The driver Utilities class of static.
|
/// The driver Utilities class of static.
|
||||||
class CDRU
|
class CDRU
|
||||||
{
|
{
|
||||||
|
@ -139,11 +109,6 @@ public:
|
||||||
/// Portable Function which create a GL ES Driver (using gl dll...).
|
/// Portable Function which create a GL ES Driver (using gl dll...).
|
||||||
static IDriver *createGlEsDriver() throw(EDru);
|
static IDriver *createGlEsDriver() throw(EDru);
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
/// Windows Function which create a Direct3d Driver.
|
|
||||||
static IDriver *createD3DDriver() throw(EDru);
|
|
||||||
#endif // NL_OS_WINDOWS
|
|
||||||
|
|
||||||
/// \name 2D render.
|
/// \name 2D render.
|
||||||
// @{
|
// @{
|
||||||
/// Draw a bitmap 2D. Warning: this is slow...
|
/// Draw a bitmap 2D. Warning: this is slow...
|
||||||
|
|
|
@ -223,8 +223,7 @@ public:
|
||||||
|
|
||||||
/** \name Texture Addressing Modes. They are valid only with the normal texture shader.
|
/** \name Texture Addressing Modes. They are valid only with the normal texture shader.
|
||||||
* All modes are not supported everywhere, so you should check for it in the driver.
|
* All modes are not supported everywhere, so you should check for it in the driver.
|
||||||
* The modes are similar to those introduced with DirectX 8.0 Pixel Shaders and OpenGL
|
* The modes are similar to those introduced with OpenGL TEXTURE_SHADERS_NV
|
||||||
* TEXTURE_SHADERS_NV
|
|
||||||
*/
|
*/
|
||||||
// @{
|
// @{
|
||||||
enum TTexAddressingMode {
|
enum TTexAddressingMode {
|
||||||
|
@ -416,7 +415,7 @@ public:
|
||||||
*
|
*
|
||||||
* For compatibility problems:
|
* For compatibility problems:
|
||||||
* - no scaling is allowed (some cards do not implement this well).
|
* - no scaling is allowed (some cards do not implement this well).
|
||||||
* - Texture can be the source only for Arg0 (DirectX restriction). nlassert...
|
* - Texture can be the source only for Arg0. nlassert...
|
||||||
*
|
*
|
||||||
* NB: for Alpha Aguments, only operands SrcAlpha and InvSrcAlpha are valid (nlassert..).
|
* NB: for Alpha Aguments, only operands SrcAlpha and InvSrcAlpha are valid (nlassert..).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
*
|
*
|
||||||
* You can access the driver with CNELU::Driver.
|
* You can access the driver with CNELU::Driver.
|
||||||
*/
|
*/
|
||||||
static bool initDriver(uint w, uint h, uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen=false, bool direct3d=false) throw(EDru);
|
static bool initDriver(uint w, uint h, uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen=false) throw(EDru);
|
||||||
|
|
||||||
/** Init all that we need for a Scene.
|
/** Init all that we need for a Scene.
|
||||||
* - register scene basics models,
|
* - register scene basics models,
|
||||||
|
@ -108,7 +108,7 @@ public:
|
||||||
* - initScene();
|
* - initScene();
|
||||||
* - initEventServer();
|
* - initEventServer();
|
||||||
*/
|
*/
|
||||||
static bool init(uint w, uint h, CViewport viewport=CViewport(), uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen = false, bool direct3d = false) throw(EDru);
|
static bool init(uint w, uint h, CViewport viewport=CViewport(), uint bpp=32, bool windowed=true, nlWindow systemWindow=EmptyWindow, bool offscreen = false) throw(EDru);
|
||||||
|
|
||||||
/** Delete all:
|
/** Delete all:
|
||||||
* - releaseEventServer();
|
* - releaseEventServer();
|
||||||
|
|
|
@ -148,22 +148,6 @@ public:
|
||||||
// nel - 0x31,type,bitfield
|
// nel - 0x31,type,bitfield
|
||||||
nelvp = 0x31010001, // VP supported by CVertexProgramParser, similar to arbvp1, can be translated to vs_1_1
|
nelvp = 0x31010001, // VP supported by CVertexProgramParser, similar to arbvp1, can be translated to vs_1_1
|
||||||
|
|
||||||
// direct3d - 0xD9,type,major,minor
|
|
||||||
// vertex programs
|
|
||||||
vs_1_1 = 0xD9010101,
|
|
||||||
vs_2_0 = 0xD9010200,
|
|
||||||
// vs_2_sw = 0xD9010201, // not sure...
|
|
||||||
// vs_2_x = 0xD9010202, // not sure...
|
|
||||||
// vs_3_0 = 0xD9010300, // not supported
|
|
||||||
// pixel programs
|
|
||||||
ps_1_1 = 0xD9020101,
|
|
||||||
ps_1_2 = 0xD9020102,
|
|
||||||
ps_1_3 = 0xD9020103,
|
|
||||||
ps_1_4 = 0xD9020104,
|
|
||||||
ps_2_0 = 0xD9020200,
|
|
||||||
// ps_2_x = 0xD9020201, // not sure...
|
|
||||||
// ps_3_0 = 0xD9020300, // not supported
|
|
||||||
|
|
||||||
// opengl - 0x61,type,bitfield
|
// opengl - 0x61,type,bitfield
|
||||||
// vertex programs
|
// vertex programs
|
||||||
// vp20 = 0x61010001, // NV_vertex_program1_1, outdated
|
// vp20 = 0x61010001, // NV_vertex_program1_1, outdated
|
||||||
|
@ -227,7 +211,7 @@ public:
|
||||||
inline size_t addSource(CSource *source) { nlassert(!m_Source); m_Sources.push_back(source); return (m_Sources.size() - 1); }
|
inline size_t addSource(CSource *source) { nlassert(!m_Source); m_Sources.push_back(source); return (m_Sources.size() - 1); }
|
||||||
inline void removeSource(size_t i) { nlassert(!m_Source); m_Sources.erase(m_Sources.begin() + i); }
|
inline void removeSource(size_t i) { nlassert(!m_Source); m_Sources.erase(m_Sources.begin() + i); }
|
||||||
|
|
||||||
// Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0
|
// Get the idx of a parameter (ogl: uniform, etcetera) by name. Invalid name returns ~0
|
||||||
inline uint getUniformIndex(const char *name) const { return m_DrvInfo->getUniformIndex(name); };
|
inline uint getUniformIndex(const char *name) const { return m_DrvInfo->getUniformIndex(name); };
|
||||||
inline uint getUniformIndex(const std::string &name) const { return m_DrvInfo->getUniformIndex(name.c_str()); };
|
inline uint getUniformIndex(const std::string &name) const { return m_DrvInfo->getUniformIndex(name.c_str()); };
|
||||||
inline uint getUniformIndex(CProgramIndex::TName name) const { return m_Index.Indices[name]; }
|
inline uint getUniformIndex(CProgramIndex::TName name) const { return m_Index.Indices[name]; }
|
||||||
|
|
|
@ -287,7 +287,7 @@ public:
|
||||||
|
|
||||||
// misc
|
// misc
|
||||||
|
|
||||||
// used by colors only : set the internal color format. useful to write in vertex buffer (format differs between D3D & OpenGL)
|
// used by colors only : set the internal color format. useful to write in vertex buffer
|
||||||
virtual void setColorType(CVertexBuffer::TVertexColorType /* type */) {}
|
virtual void setColorType(CVertexBuffer::TVertexColorType /* type */) {}
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
@ -470,7 +470,7 @@ public:
|
||||||
|
|
||||||
/** See if filter mode or wrap mode have been touched.
|
/** See if filter mode or wrap mode have been touched.
|
||||||
* If this is the case, the driver should resetup them for that texture (If driver stores filter & wrap mode
|
* If this is the case, the driver should resetup them for that texture (If driver stores filter & wrap mode
|
||||||
* per texture (OpenGL) rather than globally (D3D))
|
* per texture (OpenGL))
|
||||||
*/
|
*/
|
||||||
bool filterOrWrapModeTouched() const { return _FilterOrWrapModeTouched; }
|
bool filterOrWrapModeTouched() const { return _FilterOrWrapModeTouched; }
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ public:
|
||||||
enum TStencilFunc { never = 0, less, lessequal, equal, notequal, greaterequal, greater, always};
|
enum TStencilFunc { never = 0, less, lessequal, equal, notequal, greaterequal, greater, always};
|
||||||
|
|
||||||
// Existing drivers
|
// Existing drivers
|
||||||
enum TDriver { Direct3d = 0, OpenGl, OpenGlEs };
|
enum TDriver { OpenGl = 1, OpenGlEs };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The EventServer of this driver. Init after setDisplay()!!
|
/// The EventServer of this driver. Init after setDisplay()!!
|
||||||
|
@ -157,10 +157,6 @@ public:
|
||||||
virtual ~UDriver();
|
virtual ~UDriver();
|
||||||
// @}
|
// @}
|
||||||
|
|
||||||
// Test if the device is lost. Can only happen with D3D.
|
|
||||||
// The calling application may skip some part of its rendering when it is the case (this is not a requirement, but may save cpu for other applications)
|
|
||||||
virtual bool isLost() const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/// \name Disable Hardware Feature
|
/// \name Disable Hardware Feature
|
||||||
/** Disable some Feature that may be supported by the Hardware
|
/** Disable some Feature that may be supported by the Hardware
|
||||||
|
@ -200,7 +196,6 @@ public:
|
||||||
virtual void showWindow(bool show = true)=0;
|
virtual void showWindow(bool show = true)=0;
|
||||||
|
|
||||||
/* Pass in dialog box mode. After having called this method, you can use normal GUI.
|
/* Pass in dialog box mode. After having called this method, you can use normal GUI.
|
||||||
* In fullscreen under direct3d, the main 3d window is minimized.
|
|
||||||
*
|
*
|
||||||
* \code
|
* \code
|
||||||
* Driver->beginDialogMode();
|
* Driver->beginDialogMode();
|
||||||
|
@ -215,7 +210,6 @@ public:
|
||||||
virtual void beginDialogMode() =0;
|
virtual void beginDialogMode() =0;
|
||||||
|
|
||||||
/* Leave the dialog box mode. After having called this method, you can't use normal GUI anymore.
|
/* Leave the dialog box mode. After having called this method, you can't use normal GUI anymore.
|
||||||
* In fullscreen under direct3d, the main 3d window is maximized.
|
|
||||||
*/
|
*/
|
||||||
virtual void endDialogMode() =0;
|
virtual void endDialogMode() =0;
|
||||||
|
|
||||||
|
@ -841,7 +835,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* This is the static function which build a UDriver, the root for all 3D functions.
|
* This is the static function which build a UDriver, the root for all 3D functions.
|
||||||
*/
|
*/
|
||||||
static UDriver *createDriver(uintptr_t windowIcon = 0, bool direct3d = false, emptyProc exitFunc = 0);
|
static UDriver *createDriver(uintptr_t windowIcon = 0, emptyProc exitFunc = 0);
|
||||||
static UDriver *createDriver(uintptr_t windowIcon, TDriver driver, emptyProc exitFunc = 0);
|
static UDriver *createDriver(uintptr_t windowIcon, TDriver driver, emptyProc exitFunc = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -178,7 +178,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value type, there is 13 kind of value type as in DirectX8 and gl_vertex_program used in exteneded mode
|
* Value type, there is 13 kind of value type as in gl_vertex_program used in exteneded mode
|
||||||
*/
|
*/
|
||||||
enum TType
|
enum TType
|
||||||
{
|
{
|
||||||
|
@ -1267,24 +1267,3 @@ inline void CVertexBuffer::unlock () const
|
||||||
#endif // NL_VERTEX_BUFFER_H
|
#endif // NL_VERTEX_BUFFER_H
|
||||||
|
|
||||||
/* End of vertex_buffer.h */
|
/* End of vertex_buffer.h */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
/**
|
/**
|
||||||
* This class is a vertex program.
|
* This class is a vertex program.
|
||||||
*
|
*
|
||||||
* D3D / OPENGL compatibility notes:
|
* OPENGL compatibility notes:
|
||||||
* ---------------------------------
|
* ---------------------------------
|
||||||
*
|
*
|
||||||
* To make your program compatible with D3D and OPENGL nel drivers, please follow thoses directives to write your vertex programs
|
* To make your program compatible with OPENGL nel drivers, please follow thoses directives to write your vertex programs
|
||||||
*
|
*
|
||||||
* - Use only v[0], v[1] etc.. syntax for input registers. Don't use v0, v1 or v[OPOS] etc..
|
* - Use only v[0], v[1] etc.. syntax for input registers. Don't use v0, v1 or v[OPOS] etc..
|
||||||
* - Use only c[0], c[1] etc.. syntax for constant registers. Don't use c0, c1 etc..
|
* - Use only c[0], c[1] etc.. syntax for constant registers. Don't use c0, c1 etc..
|
||||||
|
@ -39,11 +39,6 @@
|
||||||
* - Don't use macros.
|
* - Don't use macros.
|
||||||
*
|
*
|
||||||
* -> Thoses programs work without any change under OpenGL.
|
* -> Thoses programs work without any change under OpenGL.
|
||||||
* -> Direct3D driver implementation will have to modify the syntax on the fly before the setup like this:
|
|
||||||
* - "v[0]" must be changed in "v0" etc..
|
|
||||||
* - "o[HPOS]" must be changed in oPos etc..
|
|
||||||
* - Semicolon must be changed in line return character.
|
|
||||||
* - ARL instruction must be changed in MOV.
|
|
||||||
*
|
*
|
||||||
* Behaviour of LOG may change depending on implementation: You can only expect to have dest.z = log2(abs(src.w)).
|
* Behaviour of LOG may change depending on implementation: You can only expect to have dest.z = log2(abs(src.w)).
|
||||||
* LIT may or may not clamp the specular exponent to [-128, 128] (not done when EXT_vertex_shader is used for example ..)
|
* LIT may or may not clamp the specular exponent to [-128, 128] (not done when EXT_vertex_shader is used for example ..)
|
||||||
|
@ -166,7 +161,7 @@ struct CVPInstruction
|
||||||
enum EOpcode
|
enum EOpcode
|
||||||
{
|
{
|
||||||
MOV = 0,
|
MOV = 0,
|
||||||
ARL, // in D3D, is equivalent to MOV
|
ARL,
|
||||||
MUL,
|
MUL,
|
||||||
ADD,
|
ADD,
|
||||||
MAD,
|
MAD,
|
||||||
|
@ -266,4 +261,3 @@ private:
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ public:
|
||||||
/// Standard PCM format.
|
/// Standard PCM format.
|
||||||
FormatPcm = 1,
|
FormatPcm = 1,
|
||||||
/// Intel/DVI ADPCM format, only available for 1 channel at 16 bits per sample, encoded at 4 bits per sample.
|
/// Intel/DVI ADPCM format, only available for 1 channel at 16 bits per sample, encoded at 4 bits per sample.
|
||||||
/// This is only implemented in the DSound and XAudio2 driver.
|
|
||||||
FormatDviAdpcm = 11,
|
FormatDviAdpcm = 11,
|
||||||
/// No format set. Used when a TBufferFormat value has not been set to any value yet.
|
/// No format set. Used when a TBufferFormat value has not been set to any value yet.
|
||||||
FormatNotSet = (~0),
|
FormatNotSet = (~0),
|
||||||
|
|
|
@ -64,16 +64,12 @@ public:
|
||||||
/// Driver Creation Choice
|
/// Driver Creation Choice
|
||||||
enum TDriver
|
enum TDriver
|
||||||
{
|
{
|
||||||
/// DriverAuto automatically picks the most awesome driver (picks first available in this order: FMod, OpenAl, XAudio2, DSound).
|
/// DriverAuto automatically picks the most awesome driver (picks first available in this order: FMod, OpenAl).
|
||||||
DriverAuto = 0,
|
DriverAuto = 0,
|
||||||
/// DriverFMod is a driver that runs on FMod, nice quality, but not fully implemented.
|
/// DriverFMod is a driver that runs on FMod, nice quality, but not fully implemented.
|
||||||
DriverFMod,
|
DriverFMod,
|
||||||
/// DriverOpenAl is the recommended driver, especially if you have hardware sound acceleration.
|
/// DriverOpenAl is the recommended driver, especially if you have hardware sound acceleration.
|
||||||
DriverOpenAl,
|
DriverOpenAl,
|
||||||
/// DriverDSound is deprecated.
|
|
||||||
DriverDSound,
|
|
||||||
/// DriverXAudio2 runs on a fully software-based audio processing API without artificial limits.
|
|
||||||
DriverXAudio2,
|
|
||||||
NumDrivers
|
NumDrivers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,11 +80,11 @@ public:
|
||||||
OptionEnvironmentEffects = 0x01,
|
OptionEnvironmentEffects = 0x01,
|
||||||
/// Allow the user to use the ADPCM encoding. (verify availability with getOption)
|
/// Allow the user to use the ADPCM encoding. (verify availability with getOption)
|
||||||
OptionAllowADPCM = 0x02,
|
OptionAllowADPCM = 0x02,
|
||||||
/// Force software buffering (always true for XAudio2).
|
/// Force software buffering.
|
||||||
OptionSoftwareBuffer = 0x04,
|
OptionSoftwareBuffer = 0x04,
|
||||||
/**
|
/**
|
||||||
* Configuration to use manual or API (directx or open AL) rolloff factor.
|
* Configuration to use manual or API (open AL) rolloff factor.
|
||||||
* 0 => API (directx, open AL, etc) rollOff control.
|
* 0 => API (open AL, etc) rollOff control.
|
||||||
* ISource::setAlpha() will fail.
|
* ISource::setAlpha() will fail.
|
||||||
* IListener::setRollOffFactor() works
|
* IListener::setRollOffFactor() works
|
||||||
* 1 => Manual rollOff control
|
* 1 => Manual rollOff control
|
||||||
|
|
|
@ -59,9 +59,7 @@
|
||||||
/**
|
/**
|
||||||
* The maximum allowed pitch is specified as 8.0f.
|
* The maximum allowed pitch is specified as 8.0f.
|
||||||
* Tests indicate that with OpenAL the pitch can be set to 8.0f,
|
* Tests indicate that with OpenAL the pitch can be set to 8.0f,
|
||||||
* and with FMod to somewhere around 9.0f. The XAudio2 implementation
|
* and with FMod to somewhere around 9.0f.
|
||||||
* uses this value directly to configure the maximum pitch, which can
|
|
||||||
* technically be as high as XAUDIO2_MAX_FREQ_RATIO which is 1024.0f.
|
|
||||||
* If you pass a value outside the minimum and maximum bounds,
|
* If you pass a value outside the minimum and maximum bounds,
|
||||||
* it will automatically be clamped between them.
|
* it will automatically be clamped between them.
|
||||||
* \brief Maximum allowed pitch.
|
* \brief Maximum allowed pitch.
|
||||||
|
|
|
@ -82,8 +82,6 @@ public:
|
||||||
DriverAuto = 0,
|
DriverAuto = 0,
|
||||||
DriverFMod,
|
DriverFMod,
|
||||||
DriverOpenAl,
|
DriverOpenAl,
|
||||||
DriverDSound,
|
|
||||||
DriverXAudio2,
|
|
||||||
NumDrivers
|
NumDrivers
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -108,9 +108,8 @@ int main(int argc, char **argv)
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
icon = (uint)LoadIcon(ghInstance,MAKEINTRESOURCE(IDI_ICON1));
|
icon = (uint)LoadIcon(ghInstance,MAKEINTRESOURCE(IDI_ICON1));
|
||||||
#endif
|
#endif
|
||||||
bool useD3D = false;
|
|
||||||
#ifdef NL_INDEX_BUFFER_H //new 3d
|
#ifdef NL_INDEX_BUFFER_H //new 3d
|
||||||
NL3D::UDriver *driver = NL3D::UDriver::createDriver(icon,useD3D);
|
NL3D::UDriver *driver = NL3D::UDriver::createDriver(icon);
|
||||||
#else
|
#else
|
||||||
driver = NL3D::UDriver::createDriver(icon);
|
driver = NL3D::UDriver::createDriver(icon);
|
||||||
#endif
|
#endif
|
||||||
|
@ -328,5 +327,3 @@ bool handleCheck(const CEGUI::EventArgs& e)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// look at 3dinit example
|
// look at 3dinit example
|
||||||
CNELU::init (800, 600, CViewport(), 32, true, 0, false, false);
|
CNELU::init (800, 600, CViewport(), 32, true, 0, false);
|
||||||
|
|
||||||
NLMISC::CPath::addSearchPath(FONT_DIR);
|
NLMISC::CPath::addSearchPath(FONT_DIR);
|
||||||
|
|
||||||
|
|
|
@ -78,17 +78,8 @@ void CGraphicsViewport::init(CGraphicsConfig *graphicsConfig)
|
||||||
|
|
||||||
// create the driver
|
// create the driver
|
||||||
nlassert(!m_Driver);
|
nlassert(!m_Driver);
|
||||||
m_Direct3D = false;
|
|
||||||
std::string driver = m_GraphicsConfig->getGraphicsDriver();
|
std::string driver = m_GraphicsConfig->getGraphicsDriver();
|
||||||
if (driver == "Direct3D") m_Direct3D = true; //m_Driver = Direct3D;
|
m_Driver = UDriver::createDriver(NULL, NULL);
|
||||||
else if (driver == "OpenGL") m_Direct3D = false; //m_Driver = OpenGL;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nlwarning("Invalid driver specified, defaulting to OpenGL");
|
|
||||||
//m_Configuration->getConfigFile().getVar("GraphicsDriver").forceAsString("OpenGL");
|
|
||||||
//m_Driver = OpenGL;
|
|
||||||
}
|
|
||||||
m_Driver = UDriver::createDriver(NULL, m_Direct3D, NULL);
|
|
||||||
nlassert(m_Driver);
|
nlassert(m_Driver);
|
||||||
|
|
||||||
// initialize the window with config file values
|
// initialize the window with config file values
|
||||||
|
@ -221,13 +212,12 @@ void CGraphicsViewport::saveScreenshot(const string &name, bool jpg, bool png, b
|
||||||
void CGraphicsViewport::resizeEvent(QResizeEvent *resizeEvent)
|
void CGraphicsViewport::resizeEvent(QResizeEvent *resizeEvent)
|
||||||
{
|
{
|
||||||
QWidget::resizeEvent(resizeEvent);
|
QWidget::resizeEvent(resizeEvent);
|
||||||
if (m_Driver && !m_Direct3D)
|
if (m_Driver)
|
||||||
{
|
{
|
||||||
m_Driver->setMode(UDriver::CMode(resizeEvent->size().width(), resizeEvent->size().height(), 32));
|
m_Driver->setMode(UDriver::CMode(resizeEvent->size().width(), resizeEvent->size().height(), 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The OpenGL driver does not resize automatically.
|
// The OpenGL driver does not resize automatically.
|
||||||
// The Direct3D driver breaks the window mode to include window borders when calling setMode windowed.
|
|
||||||
|
|
||||||
// Resizing the window after switching drivers a few times becomes slow.
|
// Resizing the window after switching drivers a few times becomes slow.
|
||||||
// There is probably something inside the drivers not being released properly.
|
// There is probably something inside the drivers not being released properly.
|
||||||
|
|
|
@ -91,8 +91,6 @@ private:
|
||||||
NL3D::UTextContext *m_TextContext;
|
NL3D::UTextContext *m_TextContext;
|
||||||
NL3D::UScene *m_Scene;
|
NL3D::UScene *m_Scene;
|
||||||
|
|
||||||
bool m_Direct3D;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGraphicsViewport(const CGraphicsViewport &);
|
CGraphicsViewport(const CGraphicsViewport &);
|
||||||
CGraphicsViewport &operator=(const CGraphicsViewport &);
|
CGraphicsViewport &operator=(const CGraphicsViewport &);
|
||||||
|
|
|
@ -55,9 +55,9 @@ LoginBackground = "login_background.dds";
|
||||||
// Graphics //////////////////////////////////////////////////////////////////
|
// Graphics //////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Use OpenGL or Direct3D (Windows)
|
// Use OpenGL (Windows)
|
||||||
GraphicsEnabled = 1;
|
GraphicsEnabled = 1;
|
||||||
GraphicsDrivers = { "OpenGL", "Direct3D" };
|
GraphicsDrivers = { "OpenGL" };
|
||||||
GraphicsDriver = "OpenGL";
|
GraphicsDriver = "OpenGL";
|
||||||
|
|
||||||
// Resolution of the screen
|
// Resolution of the screen
|
||||||
|
@ -134,9 +134,9 @@ FpsSmoothing = 64;
|
||||||
// Sound /////////////////////////////////////////////////////////////////////
|
// Sound /////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// The sound driver, choose between "Auto", "FMod", "DSound" and "OpenAl"
|
// The sound driver, choose between "Auto", "FMod" and "OpenAl"
|
||||||
SoundEnabled = 1;
|
SoundEnabled = 1;
|
||||||
SoundDrivers = { "Auto", "OpenAL", "XAudio2", "FMod", "DSound" };
|
SoundDrivers = { "Auto", "OpenAL", "FMod" };
|
||||||
SoundDriver = "OpenAL";
|
SoundDriver = "OpenAL";
|
||||||
SoundDevice = "";
|
SoundDevice = "";
|
||||||
SoundMaxTrack = 48;
|
SoundMaxTrack = 48;
|
||||||
|
|
|
@ -67,8 +67,6 @@ void Init()
|
||||||
printf("Select NLSOUND Driver:\n");
|
printf("Select NLSOUND Driver:\n");
|
||||||
printf(" [1] FMod\n");
|
printf(" [1] FMod\n");
|
||||||
printf(" [2] OpenAl\n");
|
printf(" [2] OpenAl\n");
|
||||||
printf(" [3] DSound\n");
|
|
||||||
printf(" [4] XAudio2\n");
|
|
||||||
printf("> ");
|
printf("> ");
|
||||||
int selection = getchar();
|
int selection = getchar();
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
|
@ -78,8 +78,6 @@ static void initSample()
|
||||||
printf("Select NLSOUND Driver:\n");
|
printf("Select NLSOUND Driver:\n");
|
||||||
printf(" [1] FMod\n");
|
printf(" [1] FMod\n");
|
||||||
printf(" [2] OpenAl\n");
|
printf(" [2] OpenAl\n");
|
||||||
printf(" [3] DSound\n");
|
|
||||||
printf(" [4] XAudio2\n");
|
|
||||||
printf("> ");
|
printf("> ");
|
||||||
int selection = getchar(); getchar();
|
int selection = getchar(); getchar();
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
|
@ -70,8 +70,6 @@ static void initSample()
|
||||||
printf("Select NLSOUND Driver:\n");
|
printf("Select NLSOUND Driver:\n");
|
||||||
printf(" [1] FMod\n");
|
printf(" [1] FMod\n");
|
||||||
printf(" [2] OpenAl\n");
|
printf(" [2] OpenAl\n");
|
||||||
printf(" [3] DSound\n");
|
|
||||||
printf(" [4] XAudio2\n");
|
|
||||||
printf("> ");
|
printf("> ");
|
||||||
int selection = getchar(); getchar();
|
int selection = getchar(); getchar();
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
|
@ -120,7 +120,7 @@ void CCoarseMeshManager::flushRender (IDriver *drv)
|
||||||
H_AUTO( NL3D_StaticLod_Render );
|
H_AUTO( NL3D_StaticLod_Render );
|
||||||
if (_Meshs.empty()) return;
|
if (_Meshs.empty()) return;
|
||||||
|
|
||||||
// if the driver is BGRA (Direct3D), then invert color format
|
// if the driver is BGRA, then invert color format
|
||||||
if(!_VBuffer.isResident() && drv->getVertexColorFormat()==CVertexBuffer::TBGRA)
|
if(!_VBuffer.isResident() && drv->getVertexColorFormat()==CVertexBuffer::TBGRA)
|
||||||
{
|
{
|
||||||
// since actually empty, no need to swap current memory
|
// since actually empty, no need to swap current memory
|
||||||
|
|
|
@ -5,9 +5,3 @@ ENDIF()
|
||||||
IF(WITH_DRIVER_OPENGLES)
|
IF(WITH_DRIVER_OPENGLES)
|
||||||
ADD_SUBDIRECTORY(opengles)
|
ADD_SUBDIRECTORY(opengles)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
IF(WITH_DRIVER_DIRECT3D)
|
|
||||||
ADD_SUBDIRECTORY(direct3d)
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
|
@ -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);
|
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
|
|
||||||
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
|
|
||||||
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EGL_NV_coverage_sample_resolve
|
#ifndef EGL_NV_coverage_sample_resolve
|
||||||
#define EGL_NV_coverage_sample_resolve 1
|
#define EGL_NV_coverage_sample_resolve 1
|
||||||
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
|
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
|
||||||
|
@ -435,11 +430,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, E
|
||||||
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
|
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
|
|
||||||
#define EGL_ANGLE_d3d_share_handle_client_buffer 1
|
|
||||||
/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef EGL_KHR_create_context
|
#ifndef EGL_KHR_create_context
|
||||||
#define EGL_KHR_create_context 1
|
#define EGL_KHR_create_context 1
|
||||||
#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
|
#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
|
||||||
|
|
|
@ -2883,7 +2883,7 @@ IOcclusionQuery::TOcclusionType COcclusionQueryGL::getOcclusionType()
|
||||||
nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_NV, &result);
|
nglGetOcclusionQueryuivNV(ID, GL_PIXEL_COUNT_NV, &result);
|
||||||
OcclusionType = result != 0 ? NotOccluded : Occluded;
|
OcclusionType = result != 0 ? NotOccluded : Occluded;
|
||||||
VisibleCount = (uint) result;
|
VisibleCount = (uint) result;
|
||||||
// Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation (Direct3D ...)
|
// Note : we could return the exact number of pixels that passed the z-test, but this value is not supported by all implementation ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -440,7 +440,7 @@ public:
|
||||||
|
|
||||||
virtual bool supportCloudRenderSinglePass() const;
|
virtual bool supportCloudRenderSinglePass() const;
|
||||||
|
|
||||||
virtual bool supportIndexOffset() const { return false; /* feature only supported in D3D for now */ }
|
virtual bool supportIndexOffset() const { return false; }
|
||||||
|
|
||||||
|
|
||||||
virtual bool slowUnlockVertexBufferHard() const;
|
virtual bool slowUnlockVertexBufferHard() const;
|
||||||
|
@ -1006,7 +1006,6 @@ private:
|
||||||
bool setScreenMode(const GfxMode &mode);
|
bool setScreenMode(const GfxMode &mode);
|
||||||
|
|
||||||
// Test if cursor is in the client area. always true when software cursor is used and window visible
|
// Test if cursor is in the client area. always true when software cursor is used and window visible
|
||||||
// (displayed in software when DirectInput is used)
|
|
||||||
bool isSystemCursorInClientArea();
|
bool isSystemCursorInClientArea();
|
||||||
|
|
||||||
// Check if RGBA cursors are supported
|
// Check if RGBA cursors are supported
|
||||||
|
|
|
@ -113,10 +113,6 @@ bool CDriverGL::isAlphaBlendedCursorSupported()
|
||||||
{
|
{
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
// Support starts with windows 2000 (not only from XP as seen in most docs)
|
// Support starts with windows 2000 (not only from XP as seen in most docs)
|
||||||
// NB : Additionnaly, could query D3D caps to know if
|
|
||||||
// color hardware cursor is supported, not only emulated,
|
|
||||||
// but can't be sure that using the win32 api 'SetCursor' uses the same resources
|
|
||||||
// So far, seems to be supported on any modern card used by the game anyway ...
|
|
||||||
OSVERSIONINFO osvi;
|
OSVERSIONINFO osvi;
|
||||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||||
if (GetVersionEx(&osvi))
|
if (GetVersionEx(&osvi))
|
||||||
|
|
|
@ -88,9 +88,9 @@ void UDriver::setMatrixMode2D43()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
UDriver *UDriver::createDriver(uintptr_t windowIcon, bool direct3d, emptyProc exitFunc)
|
UDriver *UDriver::createDriver(uintptr_t windowIcon, emptyProc exitFunc)
|
||||||
{
|
{
|
||||||
return new CDriverUser (windowIcon, direct3d ? CDriverUser::Direct3d:CDriverUser::OpenGl, exitFunc);
|
return new CDriverUser (windowIcon, CDriverUser::OpenGl, exitFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
@ -128,12 +128,6 @@ CDriverUser::CDriverUser (uintptr_t windowIcon, TDriver driver, emptyProc exitFu
|
||||||
|
|
||||||
_Driver = NULL;
|
_Driver = NULL;
|
||||||
|
|
||||||
// Create/Init Driver.
|
|
||||||
#if defined(NL_OS_WINDOWS)
|
|
||||||
if (driver == Direct3d)
|
|
||||||
_Driver= CDRU::createD3DDriver();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!_Driver && driver == OpenGl)
|
if (!_Driver && driver == OpenGl)
|
||||||
_Driver= CDRU::createGlDriver();
|
_Driver= CDRU::createGlDriver();
|
||||||
|
|
||||||
|
@ -1840,13 +1834,6 @@ UDriver::TCullMode CDriverUser::getCullMode() const
|
||||||
return (TCullMode) _Driver->getCullMode();
|
return (TCullMode) _Driver->getCullMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
bool CDriverUser::isLost() const
|
|
||||||
{
|
|
||||||
NL3D_HAUTO_UI_DRIVER
|
|
||||||
return _Driver->isLost();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
void CDriverUser::beginDialogMode()
|
void CDriverUser::beginDialogMode()
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,9 +29,6 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#else
|
#else
|
||||||
# define NL_OPENGL_AVAILABLE
|
# define NL_OPENGL_AVAILABLE
|
||||||
# ifdef NL_OS_WINDOWS
|
|
||||||
# define NL_DIRECT3D_AVAILABLE
|
|
||||||
# endif
|
|
||||||
#endif // HAVE_CONFIG_H
|
#endif // HAVE_CONFIG_H
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
|
@ -66,10 +63,6 @@ const char *IDRV_VERSION_PROC_NAME = "NL3D_interfaceVersion";
|
||||||
extern IDriver* createGlDriverInstance ();
|
extern IDriver* createGlDriverInstance ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(NL_OS_WINDOWS) && defined(NL_DIRECT3D_AVAILABLE)
|
|
||||||
extern IDriver* createD3DDriverInstance ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NL_OPENGLES_AVAILABLE
|
#ifdef NL_OPENGLES_AVAILABLE
|
||||||
extern IDriver* createGlEsDriverInstance ();
|
extern IDriver* createGlEsDriverInstance ();
|
||||||
#endif
|
#endif
|
||||||
|
@ -186,60 +179,6 @@ IDriver *CDRU::createGlEsDriver() throw (EDru)
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
IDriver *CDRU::createD3DDriver() throw (EDru)
|
|
||||||
{
|
|
||||||
#ifdef NL_STATIC
|
|
||||||
|
|
||||||
#ifdef NL_DIRECT3D_AVAILABLE
|
|
||||||
return createD3DDriverInstance ();
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif // NL_DIRECT3D_AVAILABLE
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
IDRV_CREATE_PROC createDriver = NULL;
|
|
||||||
IDRV_VERSION_PROC versionDriver = NULL;
|
|
||||||
|
|
||||||
CLibrary driverLib;
|
|
||||||
|
|
||||||
if (!driverLib.loadLibrary(NL3D_D3D_DLL_NAME, true, true, false))
|
|
||||||
{
|
|
||||||
throw EDruDirect3dDriverNotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
nlinfo ("Using the library '" NL3D_D3D_DLL_NAME "' that is in the directory: '%s'", driverLib.getLibFileName().c_str());
|
|
||||||
|
|
||||||
createDriver = (IDRV_CREATE_PROC) driverLib.getSymbolAddress(IDRV_CREATE_PROC_NAME);
|
|
||||||
if (createDriver == NULL)
|
|
||||||
{
|
|
||||||
throw EDruDirect3dDriverCorrupted();
|
|
||||||
}
|
|
||||||
|
|
||||||
versionDriver = (IDRV_VERSION_PROC) driverLib.getSymbolAddress(IDRV_VERSION_PROC_NAME);
|
|
||||||
if (versionDriver != NULL)
|
|
||||||
{
|
|
||||||
if (versionDriver()<IDriver::InterfaceVersion)
|
|
||||||
throw EDruDirect3dDriverOldVersion();
|
|
||||||
else if (versionDriver()>IDriver::InterfaceVersion)
|
|
||||||
throw EDruDirect3dDriverUnknownVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
IDriver *ret= createDriver();
|
|
||||||
if (ret == NULL)
|
|
||||||
{
|
|
||||||
throw EDruDirect3dDriverCantCreateDriver();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif // NL_OS_WINDOWS
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
|
|
||||||
void CDRU::drawBitmap (float x, float y, float width, float height, ITexture& texture, IDriver& driver, CViewport viewport, bool blend)
|
void CDRU::drawBitmap (float x, float y, float width, float height, ITexture& texture, IDriver& driver, CViewport viewport, bool blend)
|
||||||
{
|
{
|
||||||
CMatrix mtx;
|
CMatrix mtx;
|
||||||
|
|
|
@ -78,14 +78,6 @@ CFXAA::CFXAA(NL3D::UDriver *driver) : m_Driver(driver), m_VP(NULL), m_PP(NULL),
|
||||||
source->setSourcePtr(a_arbfp1);
|
source->setSourcePtr(a_arbfp1);
|
||||||
m_PP->addSource(source);
|
m_PP->addSource(source);
|
||||||
}
|
}
|
||||||
// ps_2_0
|
|
||||||
{
|
|
||||||
IProgram::CSource *source = new IProgram::CSource();
|
|
||||||
source->Features.MaterialFlags = CProgramFeatures::TextureStages;
|
|
||||||
source->Profile = IProgram::ps_2_0;
|
|
||||||
source->setSourcePtr(a_ps_2_0);
|
|
||||||
m_PP->addSource(source);
|
|
||||||
}
|
|
||||||
if (!drv->compilePixelProgram(m_PP))
|
if (!drv->compilePixelProgram(m_PP))
|
||||||
{
|
{
|
||||||
nlwarning("3D: No supported pixel program for FXAA effect");
|
nlwarning("3D: No supported pixel program for FXAA effect");
|
||||||
|
|
|
@ -105,7 +105,6 @@ void CFarVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb, bool forVertexP
|
||||||
if(VertexFormat & CVertexBuffer::PrimaryColorFlag)
|
if(VertexFormat & CVertexBuffer::PrimaryColorFlag)
|
||||||
{
|
{
|
||||||
ColorOff= vb.getColorOff();
|
ColorOff= vb.getColorOff();
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
ColorPointer= Accessor.getColorPointer();
|
ColorPointer= Accessor.getColorPointer();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -133,7 +133,7 @@ void CLight::setupAttenuation (float farAttenuationBegin, float farAttenuationEn
|
||||||
const float quadratic= 10.0f;
|
const float quadratic= 10.0f;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
With GL/D3D 'att=1/(c+l*r+q*r2)' formula, I think it is impossible to simulate correctly
|
With GL 'att=1/(c+l*r+q*r2)' formula, I think it is impossible to simulate correctly
|
||||||
farAttenuationBegin (very big decrase if for instance farAttenuationBegin is near farAttenuationEnd),
|
farAttenuationBegin (very big decrase if for instance farAttenuationBegin is near farAttenuationEnd),
|
||||||
hence I simulate it very badly by multiplying the farAttenuationEnd by some factor
|
hence I simulate it very badly by multiplying the farAttenuationEnd by some factor
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -444,7 +444,6 @@ bool CLodCharacterManager::addRenderCharacterKey(CLodCharacterInstance &instan
|
||||||
_LockDone= true;
|
_LockDone= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// After lock, For D3D, the VertexColor may be in BGRA format
|
|
||||||
if(_VertexStream.isBRGA())
|
if(_VertexStream.isBRGA())
|
||||||
{
|
{
|
||||||
// then swap only the B and R (no cpu cycle added per vertex)
|
// then swap only the B and R (no cpu cycle added per vertex)
|
||||||
|
|
|
@ -580,7 +580,6 @@ bool CMaterial::isSupportedByDriver(IDriver &drv, bool forceBaseCaps) const
|
||||||
{
|
{
|
||||||
uint numTexStages = drv.getNbTextureStages();
|
uint numTexStages = drv.getNbTextureStages();
|
||||||
// special case for radeon : though 3 stages are supported, do as if there were only 2, because of the texEnvColor feature
|
// special case for radeon : though 3 stages are supported, do as if there were only 2, because of the texEnvColor feature
|
||||||
// not managed in Direct3D : emulation is provided, but for no more than 2 constants (and if diffuse is not used)
|
|
||||||
if (numTexStages == 3) numTexStages = 2;
|
if (numTexStages == 3) numTexStages = 2;
|
||||||
if (forceBaseCaps) numTexStages = std::min(numTexStages, (uint) 2);
|
if (forceBaseCaps) numTexStages = std::min(numTexStages, (uint) 2);
|
||||||
switch(getShader())
|
switch(getShader())
|
||||||
|
@ -628,4 +627,3 @@ bool CMaterial::isSupportedByDriver(IDriver &drv, bool forceBaseCaps) const
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,6 @@ void CMeshMorpher::update (std::vector<CAnimatedMorph> *pBSFactor)
|
||||||
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
|
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
|
||||||
if (!rBS.deltaCol.empty())
|
if (!rBS.deltaCol.empty())
|
||||||
{
|
{
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
|
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
|
||||||
CRGBAF rgbf(*pRGBA);
|
CRGBAF rgbf(*pRGBA);
|
||||||
rgbf.R += rBS.deltaCol[j].R * rFactor;
|
rgbf.R += rBS.deltaCol[j].R * rFactor;
|
||||||
|
@ -324,7 +323,6 @@ void CMeshMorpher::updateSkinned (std::vector<CAnimatedMorph> *pBSFactor)
|
||||||
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
|
if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
|
||||||
if (!rBS.deltaCol.empty())
|
if (!rBS.deltaCol.empty())
|
||||||
{
|
{
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
|
CRGBA *pRGBA = (CRGBA*)dstvba.getColorPointer (vp);
|
||||||
CRGBAF rgbf(*pRGBA);
|
CRGBAF rgbf(*pRGBA);
|
||||||
rgbf.R += rBS.deltaCol[j].R * rFactor;
|
rgbf.R += rBS.deltaCol[j].R * rFactor;
|
||||||
|
@ -440,13 +438,3 @@ void CMeshMorpher::updateRawSkin (CVertexBuffer *vbOri,
|
||||||
|
|
||||||
|
|
||||||
} // NL3D
|
} // NL3D
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,7 @@ static const char* WindTreeVPCodeEnd=
|
||||||
DP4 o[HPOS].z, c[2], R5; \n\
|
DP4 o[HPOS].z, c[2], R5; \n\
|
||||||
DP4 o[HPOS].w, c[3], R5; \n\
|
DP4 o[HPOS].w, c[3], R5; \n\
|
||||||
MOV o[TEX0], v[8]; \n\
|
MOV o[TEX0], v[8]; \n\
|
||||||
# hulud : remove this line for the moment because it doesn't work under d3d, if it is needed, we will have to create 2 CVertexProgram objects.\n\
|
MOV o[TEX1], v[9]; \n\
|
||||||
#MOV o[TEX1], v[9]; \n\
|
|
||||||
DP4 o[FOGC].x, c[6], R5; \n\
|
DP4 o[FOGC].x, c[6], R5; \n\
|
||||||
END \n\
|
END \n\
|
||||||
";
|
";
|
||||||
|
|
|
@ -51,7 +51,7 @@ CEventServer CNELU::EventServer;
|
||||||
CEventListenerAsync CNELU::AsyncListener;
|
CEventListenerAsync CNELU::AsyncListener;
|
||||||
|
|
||||||
|
|
||||||
bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen, bool direct3d) throw(EDru)
|
bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen) throw(EDru)
|
||||||
{
|
{
|
||||||
// Init debug system
|
// Init debug system
|
||||||
// NLMISC::InitDebug();
|
// NLMISC::InitDebug();
|
||||||
|
@ -61,13 +61,6 @@ bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow syst
|
||||||
CNELU::Driver = NULL;
|
CNELU::Driver = NULL;
|
||||||
|
|
||||||
// Init driver.
|
// Init driver.
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
if (direct3d)
|
|
||||||
{
|
|
||||||
CNELU::Driver= CDRU::createD3DDriver();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!CNELU::Driver)
|
if (!CNELU::Driver)
|
||||||
{
|
{
|
||||||
CNELU::Driver= CDRU::createGlDriver();
|
CNELU::Driver= CDRU::createGlDriver();
|
||||||
|
@ -183,10 +176,10 @@ void CNELU::releaseDriver()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNELU::init (uint w, uint h, CViewport viewport, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen, bool direct3d) throw(EDru)
|
bool CNELU::init (uint w, uint h, CViewport viewport, uint bpp, bool windowed, nlWindow systemWindow, bool offscreen) throw(EDru)
|
||||||
{
|
{
|
||||||
NL3D::registerSerial3d();
|
NL3D::registerSerial3d();
|
||||||
if (initDriver(w,h,bpp,windowed,systemWindow,offscreen,direct3d))
|
if (initDriver(w,h,bpp,windowed,systemWindow,offscreen))
|
||||||
{
|
{
|
||||||
initScene(viewport);
|
initScene(viewport);
|
||||||
initEventServer();
|
initEventServer();
|
||||||
|
|
|
@ -185,7 +185,6 @@ void CNoise3d::render2passes (CQuadUV &qc, float wpos, float alpha)
|
||||||
|
|
||||||
uint8 finalAlpha = (uint8)(255*alphaPos*alpha);
|
uint8 finalAlpha = (uint8)(255*alphaPos*alpha);
|
||||||
|
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
uint8 *pColA = (uint8*)vba.getColorPointer(_NbVertices) + 3;
|
uint8 *pColA = (uint8*)vba.getColorPointer(_NbVertices) + 3;
|
||||||
*pColA = finalAlpha; pColA = ((uint8*)pColA) + nVSize;
|
*pColA = finalAlpha; pColA = ((uint8*)pColA) + nVSize;
|
||||||
*pColA = finalAlpha; pColA = ((uint8*)pColA) + nVSize;
|
*pColA = finalAlpha; pColA = ((uint8*)pColA) + nVSize;
|
||||||
|
@ -260,7 +259,6 @@ void CNoise3d::render (CQuadUV &qc, float wpos, float intensity)
|
||||||
pUV = (CUV*)( ((uint8*)pUV) + nVSize );
|
pUV = (CUV*)( ((uint8*)pUV) + nVSize );
|
||||||
*pUV = CUV(qc.Uv3.U*_ScaleW+_OffS[nSlice2].U, qc.Uv3.V*_ScaleH+_OffS[nSlice2].V);
|
*pUV = CUV(qc.Uv3.U*_ScaleW+_OffS[nSlice2].U, qc.Uv3.V*_ScaleH+_OffS[nSlice2].V);
|
||||||
|
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
uint8 *pColA = (uint8*)vba.getColorPointer(_NbVertices) + 3;
|
uint8 *pColA = (uint8*)vba.getColorPointer(_NbVertices) + 3;
|
||||||
*pColA = nAlphaPos; pColA = ((uint8*)pColA) + nVSize;
|
*pColA = nAlphaPos; pColA = ((uint8*)pColA) + nVSize;
|
||||||
*pColA = nAlphaPos; pColA = ((uint8*)pColA) + nVSize;
|
*pColA = nAlphaPos; pColA = ((uint8*)pColA) + nVSize;
|
||||||
|
@ -306,7 +304,6 @@ void CNoise3d::renderGrid (uint32 nbw, uint32 nbh, uint32 w, uint32 h,
|
||||||
pVertices = vba.getVertexCoordPointer(0);
|
pVertices = vba.getVertexCoordPointer(0);
|
||||||
pUV0 = vba.getTexCoordPointer (0, 0);
|
pUV0 = vba.getTexCoordPointer (0, 0);
|
||||||
pUV1 = vba.getTexCoordPointer (0, 1);
|
pUV1 = vba.getTexCoordPointer (0, 1);
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
pColA = (uint8*)vba.getColorPointer(0) + 3;
|
pColA = (uint8*)vba.getColorPointer(0) + 3;
|
||||||
|
|
||||||
for (j = 0; j < nbh; ++j)
|
for (j = 0; j < nbh; ++j)
|
||||||
|
@ -374,7 +371,6 @@ void CNoise3d::renderGrid2passes (uint32 nbw, uint32 nbh, uint32 w, uint32 h,
|
||||||
|
|
||||||
pVertices = vba.getVertexCoordPointer(0);
|
pVertices = vba.getVertexCoordPointer(0);
|
||||||
pUV0 = vba.getTexCoordPointer (0, 0);
|
pUV0 = vba.getTexCoordPointer (0, 0);
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
pColA = (uint8*)vba.getColorPointer(0) + 3;
|
pColA = (uint8*)vba.getColorPointer(0) + 3;
|
||||||
|
|
||||||
for (j = 0; j < nbh; ++j)
|
for (j = 0; j < nbh; ++j)
|
||||||
|
@ -471,4 +467,3 @@ uint32 CNoise3d::getDepth ()
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace NL3D
|
} // namespace NL3D
|
||||||
|
|
||||||
|
|
|
@ -1952,7 +1952,6 @@ void CPSConstraintMesh::computeColors(CVertexBuffer &outVB, const CVertexBuffer
|
||||||
// TODO: optimisation : avoid to duplicate colors...
|
// TODO: optimisation : avoid to duplicate colors...
|
||||||
_ColorScheme->makeN(_Owner, startIndex, vba.getColorPointer(), outVB.getVertexSize(), toProcess, inVB.getNumVertices(), srcStep);
|
_ColorScheme->makeN(_Owner, startIndex, vba.getColorPointer(), outVB.getVertexSize(), toProcess, inVB.getNumVertices(), srcStep);
|
||||||
// modulate from the source mesh
|
// modulate from the source mesh
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
uint8 *vDest = (uint8 *) vba.getColorPointer();
|
uint8 *vDest = (uint8 *) vba.getColorPointer();
|
||||||
uint8 *vSrc = (uint8 *) vbaIn.getColorPointer();
|
uint8 *vSrc = (uint8 *) vbaIn.getColorPointer();
|
||||||
const uint vSize = outVB.getVertexSize();
|
const uint vSize = outVB.getVertexSize();
|
||||||
|
|
|
@ -485,7 +485,6 @@ void CPSQuad::updateVbColNUVForRender(CVertexBuffer &vb, uint32 startIndex, uint
|
||||||
if (_ColorScheme)
|
if (_ColorScheme)
|
||||||
{
|
{
|
||||||
// compute the colors, each color is replicated 4 times
|
// compute the colors, each color is replicated 4 times
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
_ColorScheme->make4(_Owner, startIndex, vba.getColorPointer(), vb.getVertexSize(), size, srcStep);
|
_ColorScheme->make4(_Owner, startIndex, vba.getColorPointer(), vb.getVertexSize(), size, srcStep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,6 @@ void CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender, bool
|
||||||
nlwarning("Render trave begin");
|
nlwarning("Render trave begin");
|
||||||
#endif
|
#endif
|
||||||
H_AUTO( NL3D_TravRender );
|
H_AUTO( NL3D_TravRender );
|
||||||
if (getDriver()->isLost()) return; // device is lost so no need to render anything
|
|
||||||
CTravCameraScene::update();
|
CTravCameraScene::update();
|
||||||
// Bind to Driver.
|
// Bind to Driver.
|
||||||
setupDriverCamera();
|
setupDriverCamera();
|
||||||
|
|
|
@ -179,7 +179,6 @@ CShadowMapManager::CShadowMapManager()
|
||||||
_ReceiveShadowMaterial.setTexCoordGen(0, true);
|
_ReceiveShadowMaterial.setTexCoordGen(0, true);
|
||||||
_ReceiveShadowMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace);
|
_ReceiveShadowMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace);
|
||||||
// Setup the stage so we interpolate ShadowColor and White (according to shadowmap alpha)
|
// Setup the stage so we interpolate ShadowColor and White (according to shadowmap alpha)
|
||||||
// nico : with D3D driver, limitation of the number of per stage constant (Only 1 if diffuse is used), so do a blend between inv diffuse & black (instead of diffuse & white), which resolve to a modulate between
|
|
||||||
// source alpha & inverse diffuse. then invert result at subsequent stage
|
// source alpha & inverse diffuse. then invert result at subsequent stage
|
||||||
_ReceiveShadowMaterial.texEnvOpRGB(0, CMaterial::Modulate);
|
_ReceiveShadowMaterial.texEnvOpRGB(0, CMaterial::Modulate);
|
||||||
_ReceiveShadowMaterial.texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::InvSrcColor);
|
_ReceiveShadowMaterial.texEnvArg0RGB(0, CMaterial::Diffuse, CMaterial::InvSrcColor);
|
||||||
|
@ -1242,4 +1241,3 @@ void CShadowMapManager::garbageShadowTextures(CScene *scene)
|
||||||
|
|
||||||
|
|
||||||
} // NL3D
|
} // NL3D
|
||||||
|
|
||||||
|
|
|
@ -1335,7 +1335,6 @@ void CVegetableManager::addInstance(CVegetableInstanceGroup *ig,
|
||||||
uint dstBendOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_BENDINFO);
|
uint dstBendOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_BENDINFO);
|
||||||
uint dstCenterOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_CENTER);
|
uint dstCenterOff= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_CENTER);
|
||||||
|
|
||||||
// For D3D, If the VertexBuffer is in BGRA mode
|
|
||||||
if(allocator->isBGRA())
|
if(allocator->isBGRA())
|
||||||
{
|
{
|
||||||
// then swap only the B and R (no cpu cycle added per vertex)
|
// then swap only the B and R (no cpu cycle added per vertex)
|
||||||
|
@ -2666,7 +2665,6 @@ uint CVegetableManager::updateInstanceLighting(CVegetableInstanceGroup *ig, uin
|
||||||
uint dstColor0Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR0);
|
uint dstColor0Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR0);
|
||||||
uint dstColor1Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR1);
|
uint dstColor1Off= dstVBInfo.getValueOffEx(NL3D_VEGETABLE_VPPOS_COLOR1);
|
||||||
|
|
||||||
// For D3D, If the VertexBuffer is in BGRA mode
|
|
||||||
if(allocator->isBGRA())
|
if(allocator->isBGRA())
|
||||||
{
|
{
|
||||||
// then swap only the B and R (no cpu cycle added per vertex)
|
// then swap only the B and R (no cpu cycle added per vertex)
|
||||||
|
|
|
@ -153,7 +153,6 @@ void CVegetableShape::build(CVegetableShapeBuild &vbuild)
|
||||||
CUV *dstUVBend= vbaOut.getTexCoordPointer(i, 1);
|
CUV *dstUVBend= vbaOut.getTexCoordPointer(i, 1);
|
||||||
if(bendFromColor)
|
if(bendFromColor)
|
||||||
{
|
{
|
||||||
// todo hulud d3d vertex color RGBA / BGRA
|
|
||||||
const CRGBA *srcColor= (const CRGBA*)vba.getColorPointer(i);
|
const CRGBA *srcColor= (const CRGBA*)vba.getColorPointer(i);
|
||||||
// Copy and scale by MaxBendWeight
|
// Copy and scale by MaxBendWeight
|
||||||
dstUVBend->U= (srcColor->R / 255.f) * vbuild.MaxBendWeight;
|
dstUVBend->U= (srcColor->R / 255.f) * vbuild.MaxBendWeight;
|
||||||
|
|
|
@ -56,7 +56,6 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence)
|
||||||
{
|
{
|
||||||
if (whence == SEEK_CUR && offset == 0)
|
if (whence == SEEK_CUR && offset == 0)
|
||||||
{
|
{
|
||||||
// nlwarning(NLSOUND_XAUDIO2_PREFIX "This seek call doesn't do a damn thing, wtf.");
|
|
||||||
return 0; // ooookkaaaaaayyy
|
return 0; // ooookkaaaaaayyy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +74,6 @@ int vorbisSeekFunc(void *datasource, ogg_int64_t offset, int whence)
|
||||||
origin = NLMISC::IStream::end;
|
origin = NLMISC::IStream::end;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// nlwarning(NLSOUND_XAUDIO2_PREFIX "Seeking to fake origin.");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +151,6 @@ uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 m
|
||||||
getBitsPerSample() == 8 ? 1 : 2,
|
getBitsPerSample() == 8 ? 1 : 2,
|
||||||
getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1.
|
getBitsPerSample() == 8 ? 0 : 1, // Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1.
|
||||||
¤t_section);
|
¤t_section);
|
||||||
// nlinfo(NLSOUND_XAUDIO2_PREFIX "current_section: %i", current_section);
|
|
||||||
if (br > 0)
|
if (br > 0)
|
||||||
{
|
{
|
||||||
bytes_read += (uint32)br;
|
bytes_read += (uint32)br;
|
||||||
|
|
|
@ -374,9 +374,7 @@ void CAudioMixerUser::initDriver(const std::string &driverName)
|
||||||
ISoundDriver::TDriver driverType;
|
ISoundDriver::TDriver driverType;
|
||||||
if (dn == "auto") driverType = ISoundDriver::DriverAuto;
|
if (dn == "auto") driverType = ISoundDriver::DriverAuto;
|
||||||
else if (dn == "fmod") driverType = ISoundDriver::DriverFMod;
|
else if (dn == "fmod") driverType = ISoundDriver::DriverFMod;
|
||||||
else if (dn == "dsound") driverType = ISoundDriver::DriverDSound;
|
|
||||||
else if (dn == "openal") driverType = ISoundDriver::DriverOpenAl;
|
else if (dn == "openal") driverType = ISoundDriver::DriverOpenAl;
|
||||||
else if (dn == "xaudio2") driverType = ISoundDriver::DriverXAudio2;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
driverType = ISoundDriver::DriverAuto;
|
driverType = ISoundDriver::DriverAuto;
|
||||||
|
@ -2833,5 +2831,3 @@ NLMISC_CATEGORISED_COMMAND(nel, displaySoundProfile, "Display information on sou
|
||||||
|
|
||||||
|
|
||||||
} // NLSOUND
|
} // NLSOUND
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -590,10 +590,10 @@ void CClusteredSound::soundTraverse(const std::vector<CCluster *> &clusters, CSo
|
||||||
CClusterSoundStatus css;
|
CClusterSoundStatus css;
|
||||||
css.Gain = travContext.Gain;
|
css.Gain = travContext.Gain;
|
||||||
CVector soundDir = (nearPos - travContext.ListenerPos).normed();
|
CVector soundDir = (nearPos - travContext.ListenerPos).normed();
|
||||||
/* ****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
|
/* ****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
|
||||||
TStringId occId = portal->getOcclusionModelId();
|
TStringId occId = portal->getOcclusionModelId();
|
||||||
TStringIntMap::iterator it(_IdToMaterial.find(occId));
|
TStringIntMap::iterator it(_IdToMaterial.find(occId));
|
||||||
****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
|
****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
|
||||||
|
|
||||||
#if EAX_AVAILABLE == 1 // EAX_AVAILABLE no longer used => TODO: implement with EFX and remove when new implementation OK.
|
#if EAX_AVAILABLE == 1 // EAX_AVAILABLE no longer used => TODO: implement with EFX and remove when new implementation OK.
|
||||||
if (it != _IdToMaterial.end())
|
if (it != _IdToMaterial.end())
|
||||||
|
@ -612,14 +612,14 @@ void CClusteredSound::soundTraverse(const std::vector<CCluster *> &clusters, CSo
|
||||||
css.OcclusionRoomRatio = travContext.OcclusionRoomRatio;
|
css.OcclusionRoomRatio = travContext.OcclusionRoomRatio;
|
||||||
}
|
}
|
||||||
#else // EAX_AVAILABLE
|
#else // EAX_AVAILABLE
|
||||||
/* ****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
|
/* ****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ******
|
||||||
if (it != _IdToMaterial.end())
|
if (it != _IdToMaterial.end())
|
||||||
{
|
{
|
||||||
// found an occlusion material for this portal
|
// found an occlusion material for this portal
|
||||||
uint matId = it->second;
|
uint matId = it->second;
|
||||||
css.Gain *= EAX_MATERIAL_PARAM[matId];
|
css.Gain *= EAX_MATERIAL_PARAM[matId];
|
||||||
}
|
}
|
||||||
****** Todo: OpenAL EFX & XAudio2 implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
|
****** Todo: OpenAL EFX implementation of Occlusion & Obstruction (not implemented for fmod anyways) !!! ****** */
|
||||||
#endif // EAX_AVAILABLE
|
#endif // EAX_AVAILABLE
|
||||||
/* if (portal->getOcclusionModel() == "wood door")
|
/* if (portal->getOcclusionModel() == "wood door")
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,11 +25,3 @@ ENDIF()
|
||||||
IF(WITH_DRIVER_FMOD)
|
IF(WITH_DRIVER_FMOD)
|
||||||
ADD_SUBDIRECTORY(fmod)
|
ADD_SUBDIRECTORY(fmod)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(WITH_DRIVER_DSOUND)
|
|
||||||
ADD_SUBDIRECTORY(dsound)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(WITH_DRIVER_XAUDIO2)
|
|
||||||
ADD_SUBDIRECTORY(xaudio2)
|
|
||||||
ENDIF()
|
|
||||||
|
|
|
@ -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() )
|
if( !CSoundDriverFMod::getInstance()->fmodOk() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// clamp as in DSound.
|
|
||||||
clamp(f, 0.f, 10.f);
|
clamp(f, 0.f, 10.f);
|
||||||
|
|
||||||
// set
|
// set
|
||||||
|
@ -150,7 +149,6 @@ void CListenerFMod::setRolloffFactor( float f )
|
||||||
if(!CSoundDriverFMod::getInstance()->fmodOk())
|
if(!CSoundDriverFMod::getInstance()->fmodOk())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// clamp as in DSound (FMod requirement)
|
|
||||||
clamp(f, 0.f, 10.f);
|
clamp(f, 0.f, 10.f);
|
||||||
|
|
||||||
_RolloffFactor = f;
|
_RolloffFactor = f;
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// Release all DirectSound resources
|
/// Release all FMOD resources
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
// Nel Basis
|
// Nel Basis
|
||||||
|
@ -128,4 +128,3 @@ private:
|
||||||
|
|
||||||
|
|
||||||
#endif // NL_LISTENER_FMOD_H
|
#endif // NL_LISTENER_FMOD_H
|
||||||
|
|
||||||
|
|
|
@ -199,9 +199,6 @@ void CSoundDriverFMod::initDevice(const std::string &device, TSoundOptions optio
|
||||||
_Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions);
|
_Options = (TSoundOptions)(((sint)options & supportedOptions) | forcedOptions);
|
||||||
|
|
||||||
uint initFlags = 0;
|
uint initFlags = 0;
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
initFlags = FSOUND_INIT_DSOUND_DEFERRED;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Init with 32 channels, and deferred sound
|
// Init with 32 channels, and deferred sound
|
||||||
if (!FSOUND_Init(22050, 32, initFlags))
|
if (!FSOUND_Init(22050, 32, initFlags))
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace NLSOUND {
|
||||||
- EAX is not supported (setEnvironnement() / setEAXProperty() no-op)
|
- EAX is not supported (setEnvironnement() / setEAXProperty() no-op)
|
||||||
- ADPCM is not supported (decompressed and the format change internaly )
|
- ADPCM is not supported (decompressed and the format change internaly )
|
||||||
- deffered param on ISource::setPos() etc... does not work. Always deffered.
|
- deffered param on ISource::setPos() etc... does not work. Always deffered.
|
||||||
- No cooperative level change in FMod as in DSOUND (default???)
|
- No cooperative level change in FMod (default???)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -495,7 +495,7 @@ void CSourceFMod::getCone( float& /* innerAngle */, float& /* outerAngle */, flo
|
||||||
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
|
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
|
||||||
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
||||||
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
||||||
* is the default used by DirectSound/OpenAL
|
* is the default used by OpenAL
|
||||||
*
|
*
|
||||||
* For any other value of alpha, an interpolation is be done between the two
|
* For any other value of alpha, an interpolation is be done between the two
|
||||||
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
||||||
|
|
|
@ -25,11 +25,11 @@ namespace NLSOUND {
|
||||||
class CBufferFMod;
|
class CBufferFMod;
|
||||||
|
|
||||||
// TODO: Doc comments in FMod driver are wrong.
|
// TODO: Doc comments in FMod driver are wrong.
|
||||||
// Bad copy pastes from DSound & OpenAL drivers.
|
// Bad copy pastes from OpenAL drivers.
|
||||||
// Fix drivername, author and date (2004?)!
|
// Fix drivername, author and date (2004?)!
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DirectSound sound source
|
* FMOD sound source
|
||||||
*
|
*
|
||||||
|
|
||||||
* For arguments as 3D vectors, use the NeL vector coordinate system
|
* For arguments as 3D vectors, use the NeL vector coordinate system
|
||||||
|
@ -48,7 +48,7 @@ public:
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~CSourceFMod();
|
virtual ~CSourceFMod();
|
||||||
|
|
||||||
/// Initialize the DirectSound buffers. Called by the sound driver only.
|
/// Initialize the FMOD buffers. Called by the sound driver only.
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
/// \name Initialization
|
/// \name Initialization
|
||||||
|
@ -147,7 +147,7 @@ public:
|
||||||
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
|
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
|
||||||
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
||||||
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
||||||
* is the default used by DirectSound/OpenAL
|
* is the default used by OpenAL
|
||||||
*
|
*
|
||||||
* For any other value of alpha, an interpolation is be done between the two
|
* For any other value of alpha, an interpolation is be done between the two
|
||||||
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
||||||
|
@ -236,7 +236,7 @@ private:
|
||||||
source_swap_pending
|
source_swap_pending
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Release all DirectSound resources
|
/// Release all FMod resources
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
// Source name
|
// Source name
|
||||||
|
|
|
@ -357,7 +357,7 @@ void CSoundDriverAL::initDevice(const std::string &device, ISoundDriver::TSoundO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose the I3DL2 model (same as DirectSound3D if not manual)
|
// Choose the I3DL2 model
|
||||||
if (getOption(OptionManualRolloff)) alDistanceModel(AL_NONE);
|
if (getOption(OptionManualRolloff)) alDistanceModel(AL_NONE);
|
||||||
else alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
else alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||||
alTestError();
|
alTestError();
|
||||||
|
|
|
@ -584,7 +584,7 @@ void CSourceAL::getCone( float& innerAngle, float& outerAngle, float& outerGain
|
||||||
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
|
* alpha.0: the volume will decrease linearly between 0dB and -100 dB
|
||||||
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
* alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
|
||||||
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
* alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
|
||||||
* is the default used by DirectSound/OpenAL
|
* is the default used by OpenAL
|
||||||
*
|
*
|
||||||
* For any other value of alpha, an interpolation is be done between the two
|
* For any other value of alpha, an interpolation is be done between the two
|
||||||
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
* adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue